Now wtmp_init() does try to lookup the uid for "username" and the gid for
  "groupname" if configured and - if successfull - chown the wtmp file to this
  combination.

  (The lookup of uid/gid is neccessary here as 'context->c0' is no yet
   initialized at the point wtmp_init() is called.)

Signed-off-by: Maximilian Wilhelm <m...@rfc2324.org>
---
 wtmp.c |   47 +++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/wtmp.c b/wtmp.c
index 50dd5f9..374cf53 100644
--- a/wtmp.c
+++ b/wtmp.c
@@ -12,14 +12,16 @@

 #define _GNU_SOURCE

-#include <assert.h>
+#include <assert.h>    /* assert() */
 #include <dirent.h>    /* opendir() */
+#include <pwd.h>       /* struct passwd */
 #include <stdio.h>     /* fopen() */
 #include <stdlib.h>    /* *alloc(), free() */
 #include <string.h>    /* strncpy(), strlen() */
 #include <sys/stat.h>  /* stat() */
 #include <sys/time.h>  /* struct timeval */
-#include <sys/types.h> /* opendir() */
+#include <sys/types.h> /* opendir() chown()  */
+#include <unistd.h>    /* chown() */
 #include <utmp.h>      /* utmp foo */

 #include "openvpn.h"   /* struct context* */
@@ -46,12 +48,20 @@ wtmp_init (const struct options *vpn_options)

        struct stat wtmp_stat;

+       /* These will be used when getting the uid/gid to chown the wtmp file */
+       struct passwd *pw;
+       struct group *grp;
+       unsigned short do_chmod = 2;
+       uid_t uid = -1;
+       gid_t gid = -1;
+
+       /* The wtmp file we're going to write to */
        char *wtmp_file_path;

        char *wtmp_file_dirname;
        char *wtmp_file_path_copy;

-       assert (options);
+       assert (vpn_options);

        /* Only initialize once */
        if (wtmp_active == 1)
@@ -66,6 +76,24 @@ wtmp_init (const struct options *vpn_options)
        wtmp_file_path_copy = strdup (wtmp_file_path);
        wtmp_file_dirname = dirname (wtmp_file_path_copy);

+       /* Get UID and GID of the configured user and group */
+       if (vpn_options->username) {
+               pw = getpwnam (vpn_options->username);
+               if (pw)
+                       uid = pw->pw_uid;
+               else
+                       do_chmod -= 1;
+       }
+
+       if (vpn_options->groupname) {
+               grp = getgrnam (vpn_options->groupname);
+               if (grp)
+                       gid = grp->gr_gid;
+               else
+                       do_chmod -= 1;
+
+       }
+
        /* Check if WTMP_DIR exists and try to create it if not */
        if (! opendir (wtmp_file_dirname)) {
                fprintf (stderr, "%s: wtmp_file_dirname %s does not exist. 
Trying to create it.\n",
@@ -99,6 +127,17 @@ wtmp_init (const struct options *vpn_options)
                        __FUNCTION__, wtmp_file_path);
        } /* [ ! -f wtmp_file ] */

+       /* Maybe one changed "username" and "group" config options */
+       if (do_chmod == 2) {
+               if (chown (wtmp_file_path, uid, gid)) {
+                       fprintf (stderr, "%s: Could not set owner/group of wtmp 
file %s.\n",
+                               __FUNCTION__, wtmp_file_path);
+                               wtmp_active = 0;
+                               goto out;
+               }
+       }
+
+
        /* OK wtmp_file is (now) there, use it */
        utmpname (wtmp_file_path);

@@ -223,7 +262,7 @@ set_utmp_line (const struct multi_instance *mi, struct utmp 
*entry)
        struct gc_arena gc = gc_new ();

        char *temp;
-       unsigned int server_id
+       unsigned int server_id;

        assert (mi);
        assert (entry);
-- 
1.5.2.4


Reply via email to