]> arthur.barton.de Git - netatalk.git/commitdiff
Reload groups when reloading volumes
authorRalph Boehme <sloowfranklin@gmail.com>
Thu, 21 Feb 2013 14:19:02 +0000 (15:19 +0100)
committerRalph Boehme <sloowfranklin@gmail.com>
Thu, 21 Feb 2013 14:20:38 +0000 (15:20 +0100)
Reload the user groups every time the volume configuration changes
and also to call initgroups() again with the possibly changed groups.

FR #71

NEWS
etc/afpd/auth.c
include/atalk/unix.h
libatalk/util/netatalk_conf.c
libatalk/util/unix.c

diff --git a/NEWS b/NEWS
index c0ec36194aaff6ab63d4c446755ae101d4cdf107..070b773c353605796414bb1646cd3f5368255a32 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -21,6 +21,7 @@ Changes in 3.0.3
        system security configuration files.       
 * NEW: dtrace probes, cf include/atalk/afp_dtrace.d for available
        probes.
+* UPD: Reload groups when reloading volumes. FR #71.
 
 Changes in 3.0.2
 ================
index fa60b192796739d2f3ab1fd50cf0d136928d2cd6..bec624dc6cd32efc72b9838381a5b8f12ad6593b 100644 (file)
@@ -39,6 +39,7 @@ extern void afp_get_cmdline( int *ac, char ***av );
 #include <atalk/server_ipc.h>
 #include <atalk/uuid.h>
 #include <atalk/globals.h>
+#include <atalk/unix.h>
 
 #include "auth.h"
 #include "uam_auth.h"
@@ -210,23 +211,6 @@ static int set_auth_switch(const AFPObj *obj, int expired)
     return AFP_OK;
 }
 
-#define GROUPSTR_BUFSIZE 1024
-static const char *print_groups(int ngroups, gid_t *groups)
-{
-    static char groupsstr[GROUPSTR_BUFSIZE];
-    int i;
-    char *s = groupsstr;
-
-    if (ngroups == 0)
-        return "-";
-
-    for (i = 0; (i < ngroups) && (s < &groupsstr[GROUPSTR_BUFSIZE]); i++) {
-        s += snprintf(s, &groupsstr[GROUPSTR_BUFSIZE] - s, " %u", groups[i]);
-    }
-
-    return groupsstr;
-}
-
 static int login(AFPObj *obj, struct passwd *pwd, void (*logout)(void), int expired)
 {
 #ifdef ADMIN_GRP
@@ -241,32 +225,8 @@ static int login(AFPObj *obj, struct passwd *pwd, void (*logout)(void), int expi
     LOG(log_note, logtype_afpd, "%s Login by %s",
         afp_versions[afp_version_index].av_name, pwd->pw_name);
 
-    if (initgroups( pwd->pw_name, pwd->pw_gid ) < 0) {
-#ifdef RUN_AS_USER
-        LOG(log_info, logtype_afpd, "running with uid %d", geteuid());
-#else /* RUN_AS_USER */
-        LOG(log_error, logtype_afpd, "login: %s", strerror(errno));
-        return AFPERR_BADUAM;
-#endif /* RUN_AS_USER */
-
-    }
-
-    /* Basically if the user is in the admin group, we stay root */
-
-    if ((obj->ngroups = getgroups( 0, NULL )) < 0 ) {
-        LOG(log_error, logtype_afpd, "login: %s getgroups: %s", pwd->pw_name, strerror(errno) );
-        return AFPERR_BADUAM;
-    }
-
-    if ( NULL == (obj->groups = calloc(obj->ngroups, sizeof(gid_t))) ) {
-        LOG(log_error, logtype_afpd, "login: %s calloc: %d", obj->ngroups);
+    if (set_groups(obj, pwd) != 0)
         return AFPERR_BADUAM;
-    }
-
-    if (( obj->ngroups = getgroups(obj->ngroups, obj->groups )) < 0 ) {
-        LOG(log_error, logtype_afpd, "login: %s getgroups: %s", pwd->pw_name, strerror(errno) );
-        return AFPERR_BADUAM;
-    }
 
 #ifdef ADMIN_GRP
     LOG(log_debug, logtype_afpd, "obj->options.admingid == %d", obj->options.admingid);
index d3378ccb2134640b629f50d1bbde5ab974650b6f..c12bf5bc0919f296934cf404435ceedd8b3e9772 100644 (file)
@@ -23,6 +23,8 @@
 #include <sys/types.h>
 #include <dirent.h>
 
+#include <atalk/globals.h>
+
 #define NETATALK_DIOSZ_STACK 65536
 #define NETATALK_DIOSZ_HEAP  (1024*1024)
 
@@ -48,5 +50,6 @@ extern int copy_ea(const char *ea, int sfd, const char *src, const char *dst, mo
 extern void become_root(void);
 extern void unbecome_root(void);
 extern int gmem(gid_t gid, int ngroups, gid_t *groups);
-
+extern int set_groups(AFPObj *obj, struct passwd *pwd);
+extern const char *print_groups(int ngroups, gid_t *groups);
 #endif  /* ATALK_UNIX_H */
index 7556124559a2aacb6439a1532905f0da355ca7c7..b51b2a0d13cffad8d1b7c70bbcc4e3077c22e5f2 100644 (file)
@@ -1323,6 +1323,9 @@ int load_volumes(AFPObj *obj)
 
     LOG(log_debug, logtype_afpd, "load_volumes: BEGIN");
 
+    if (obj->uid)
+        pwent = getpwuid(obj->uid);
+
     if (Volumes) {
         if (!volfile_changed(&obj->options))
             goto EC_CLEANUP;
@@ -1330,6 +1333,15 @@ int load_volumes(AFPObj *obj)
         for (vol = Volumes; vol; vol = vol->v_next) {
             vol->v_deleted = 1;
         }
+        if (obj->uid) {
+            become_root();
+            ret = set_groups(obj, pwent);
+            unbecome_root();
+            if (ret != 0) {
+                LOG(log_error, logtype_afpd, "load_volumes: set_groups: %s", strerror(errno));
+                EC_FAIL;
+            }
+        }
     } else {
         LOG(log_debug, logtype_afpd, "load_volumes: no volumes yet");
         EC_ZERO_LOG( lstat(obj->options.configfile, &st) );
@@ -1354,9 +1366,6 @@ int load_volumes(AFPObj *obj)
         break;
     }
 
-    if (obj->uid)
-        pwent = getpwuid(obj->uid);
-
     if (obj->iniconfig)
         iniparser_freedict(obj->iniconfig);
     LOG(log_debug, logtype_afpd, "load_volumes: loading: %s", obj->options.configfile);
index 7c80e22d5d761085503fd990b05b63b38157a569..37bfe140fe3d1d0101ab966a55ee90db3f67b9d8 100644 (file)
@@ -507,3 +507,45 @@ char *strtok_quote(char *s, const char *delim)
     }
     return token;
 }
+
+int set_groups(AFPObj *obj, struct passwd *pwd)
+{
+    if (initgroups(pwd->pw_name, pwd->pw_gid) < 0)
+        LOG(log_error, logtype_afpd, "initgroups(%s, %d): %s", pwd->pw_name, pwd->pw_gid, strerror(errno));
+
+    if ((obj->ngroups = getgroups(0, NULL)) < 0) {
+        LOG(log_error, logtype_afpd, "login: %s getgroups: %s", pwd->pw_name, strerror(errno));
+        return -1;
+    }
+
+    if (obj->groups)
+        free(obj->groups);
+    if (NULL == (obj->groups = calloc(obj->ngroups, sizeof(gid_t))) ) {
+        LOG(log_error, logtype_afpd, "login: %s calloc: %d", obj->ngroups);
+        return -1;
+    }
+
+    if ((obj->ngroups = getgroups(obj->ngroups, obj->groups)) < 0 ) {
+        LOG(log_error, logtype_afpd, "login: %s getgroups: %s", pwd->pw_name, strerror(errno));
+        return -1;
+    }
+
+    return 0;
+}
+
+#define GROUPSTR_BUFSIZE 1024
+const char *print_groups(int ngroups, gid_t *groups)
+{
+    static char groupsstr[GROUPSTR_BUFSIZE];
+    int i;
+    char *s = groupsstr;
+
+    if (ngroups == 0)
+        return "-";
+
+    for (i = 0; (i < ngroups) && (s < &groupsstr[GROUPSTR_BUFSIZE]); i++) {
+        s += snprintf(s, &groupsstr[GROUPSTR_BUFSIZE] - s, " %u", groups[i]);
+    }
+
+    return groupsstr;
+}