]> andersk Git - nss_nonlocal.git/commitdiff
Allow nonlocal users in local groups containing MAGIC_NONLOCAL_USERNAME
authorAnders Kaseorg <andersk@mit.edu>
Wed, 9 Mar 2011 06:57:58 +0000 (01:57 -0500)
committerAnders Kaseorg <andersk@mit.edu>
Wed, 30 Mar 2011 08:56:27 +0000 (04:56 -0400)
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
README
nonlocal-group.c
nonlocal-passwd.c
nonlocal.h

diff --git a/README b/README
index 6dc464b02ff67a569f791895af36a1c7265396d0..27ede52c0e501c803490c3d0fc143e7c855d4ff4 100644 (file)
--- a/README
+++ b/README
@@ -9,8 +9,8 @@ passwd_nonlocal: hesiod
 group:          compat nonlocal
 group_nonlocal: hesiod
 
-The module also assigns special properties to two local groups, if
-they exist:
+The module also assigns special properties to two local groups and one
+local user, if they exist:
 
 • If the local group ‘nss-nonlocal-users’ exists, then nonlocal users
   will be automatically added to it.  Furthermore, if a local user is
@@ -20,6 +20,10 @@ they exist:
 • If the local group ‘nss-local-users’ exists, then local users will
   be automatically added to it.
 
+• If the local user ‘nss-nonlocal-users’ is added to a local group,
+  then the local group will inherit the nonlocal membership of a group
+  of the same gid.
+
 Copyright © 2007–2010 Anders Kaseorg <andersk@mit.edu> and Tim Abbott
 <tabbott@mit.edu>
 
index 8ceeb237ddac4830b442516fe55025e1e52955a0..5b4dd7d40c89311463a8f0fad185cd5d0adecc15 100644 (file)
  */
 #define MAGIC_LOCAL_GROUPNAME "nss-local-users"
 
+/*
+ * If the MAGIC_NONLOCAL_USERNAME local user is added to a local
+ * group, then the local group will inherit the nonlocal membership of
+ * a group of the same gid.
+ */
+#define MAGIC_NONLOCAL_USERNAME "nss-nonlocal-users"
+
 
 enum nss_status
 _nss_nonlocal_getgrnam_r(const char *name, struct group *grp,
@@ -84,7 +91,7 @@ __nss_group_nonlocal_lookup(service_user **ni, const char *fct_name,
 
 
 enum nss_status
-check_nonlocal_gid(const char *user, gid_t gid, int *errnop)
+check_nonlocal_gid(const char *user, const char *group, gid_t gid, int *errnop)
 {
     enum nss_status status;
     struct group gbuf;
@@ -99,15 +106,30 @@ check_nonlocal_gid(const char *user, gid_t gid, int *errnop)
 #include "walk_nss.h"
 #undef args
 
-    if (status == NSS_STATUS_SUCCESS) {
-       syslog(LOG_DEBUG, "nss_nonlocal: removing local group %u (%s) from non-local user %s\n", gbuf.gr_gid, gbuf.gr_name, user);
-       free(buf);
-       status = NSS_STATUS_NOTFOUND;
-    } else if (status != NSS_STATUS_TRYAGAIN) {
-       status = NSS_STATUS_SUCCESS;
+    if (status == NSS_STATUS_TRYAGAIN)
+       return status;
+    else if (status != NSS_STATUS_SUCCESS)
+       return NSS_STATUS_SUCCESS;
+
+    if (group == NULL || strcmp(gbuf.gr_name, group) == 0) {
+       char *const *mem;
+       for (mem = gbuf.gr_mem; *mem != NULL; mem++)
+           if (strcmp(*mem, MAGIC_NONLOCAL_USERNAME) == 0) {
+               status = check_nonlocal_user(*mem, errnop);
+               if (status == NSS_STATUS_TRYAGAIN) {
+                   free(buf);
+                   return status;
+               } else if (status == NSS_STATUS_NOTFOUND) {
+                   free(buf);
+                   return NSS_STATUS_SUCCESS;
+               }
+               break;
+           }
     }
 
-    return status;
+    syslog(LOG_DEBUG, "nss_nonlocal: removing local group %u (%s) from non-local user %s\n", gbuf.gr_gid, gbuf.gr_name, user);
+    free(buf);
+    return NSS_STATUS_NOTFOUND;
 }
 
 enum nss_status
@@ -122,13 +144,13 @@ check_nonlocal_group(const char *user, struct group *grp, int *errnop)
     gid = strtoul(grp->gr_name, &end, 10);
     if (errno == 0 && *end == '\0' && (gid_t)gid == gid) {
        errno = old_errno;
-       status = check_nonlocal_gid(user, gid, errnop);
+       status = check_nonlocal_gid(user, grp->gr_name, gid, errnop);
     } else
        errno = old_errno;
     if (status != NSS_STATUS_SUCCESS)
        return status;
 
-    return check_nonlocal_gid(user, grp->gr_gid, errnop);
+    return check_nonlocal_gid(user, grp->gr_name, grp->gr_gid, errnop);
 }
 
 enum nss_status
@@ -391,7 +413,7 @@ _nss_nonlocal_initgroups_dyn(const char *user, gid_t group, long int *start,
 
                if (status == NSS_STATUS_SUCCESS) {
                    nonlocal_errno = *errnop;
-                   status = check_nonlocal_gid(user, pwbuf.pw_gid,
+                   status = check_nonlocal_gid(user, NULL, pwbuf.pw_gid,
                                                &nonlocal_errno);
                    free(buf);
                }
@@ -434,7 +456,8 @@ _nss_nonlocal_initgroups_dyn(const char *user, gid_t group, long int *start,
        if (i < out)
            continue;
 
-       status = check_nonlocal_gid(user, (*groupsp)[in], &nonlocal_errno);
+       status = check_nonlocal_gid(user, NULL, (*groupsp)[in],
+                                   &nonlocal_errno);
        if (status == NSS_STATUS_SUCCESS) {
            (*groupsp)[out++] = (*groupsp)[in];
        } else if (status == NSS_STATUS_TRYAGAIN) {
index a401c49320e95c3c5b9a7cb2333ff109cf8dcd62..7529d9b886a1c45b08579add50aeb465c6259de4 100644 (file)
@@ -279,7 +279,7 @@ _nss_nonlocal_getpwnam_r(const char *name, struct passwd *pwd,
     if (status != NSS_STATUS_SUCCESS)
        return status;
 
-    if (check_nonlocal_gid(name, pwd->pw_gid, &group_errno) !=
+    if (check_nonlocal_gid(name, NULL, pwd->pw_gid, &group_errno) !=
        NSS_STATUS_SUCCESS)
        pwd->pw_gid = 65534 /* nogroup */;
     return NSS_STATUS_SUCCESS;
@@ -316,7 +316,7 @@ _nss_nonlocal_getpwuid_r(uid_t uid, struct passwd *pwd,
     if (status != NSS_STATUS_SUCCESS)
        return status;
 
-    if (check_nonlocal_gid(pwd->pw_name, pwd->pw_gid, &group_errno) !=
+    if (check_nonlocal_gid(pwd->pw_name, NULL, pwd->pw_gid, &group_errno) !=
        NSS_STATUS_SUCCESS)
        pwd->pw_gid = 65534 /* nogroup */;
     return NSS_STATUS_SUCCESS;
index da9294c7d8471d39cdfed478dc3dabf4150b782f..9574ff8f99d6bce8f57ed5930a6bf1d9788b5bd1 100644 (file)
@@ -58,7 +58,8 @@ struct walk_nss {
 };
 
 enum nss_status check_nonlocal_uid(const char *user, uid_t uid, int *errnop);
-enum nss_status check_nonlocal_gid(const char *user, gid_t gid, int *errnop);
+enum nss_status check_nonlocal_gid(const char *user, const char *group,
+                                  gid_t gid, int *errnop);
 enum nss_status check_nonlocal_user(const char *user, int *errnop);
 enum nss_status get_nonlocal_passwd(const char *name, struct passwd *pwd,
                                    char **buffer, int *errnop);
This page took 0.519085 seconds and 5 git commands to generate.