nss_wrapper: add support for getgrouplist.
authorGünther Deschner <gd@samba.org>
Fri, 29 May 2009 07:19:16 +0000 (09:19 +0200)
committerGünther Deschner <gd@samba.org>
Fri, 29 May 2009 22:06:00 +0000 (00:06 +0200)
Guenther

lib/nss_wrapper/nss_wrapper.c
lib/nss_wrapper/nss_wrapper.h

index 1875dc3e4fc0f3a46dc4597e04fadb19fcad1d25..b62be61d1228704f90a3c8dc48f9e698bb6fc45e 100644 (file)
@@ -90,6 +90,7 @@
 #define real_initgroups_dyn    initgroups_dyn
 */
 #define real_initgroups                initgroups
+#define real_getgrouplist      getgrouplist
 
 #define real_getgrnam          getgrnam
 #define real_getgrnam_r                getgrnam_r
@@ -1222,3 +1223,81 @@ _PUBLIC_ void nwrap_endgrent(void)
 
        nwrap_files_endgrent();
 }
+
+static int nwrap_files_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups)
+{
+       struct group *grp;
+       gid_t *groups_tmp;
+       int count = 1;
+       const char *name_of_group = NULL;
+
+       NWRAP_DEBUG(("%s: getgrouplist called for %s\n", __location__, user));
+
+       groups_tmp = (gid_t *)malloc(count * sizeof(gid_t));
+       if (!groups_tmp) {
+               NWRAP_ERROR(("%s:calloc failed\n",__location__));
+               errno = ENOMEM;
+               return -1;
+       }
+
+       memcpy(groups_tmp, &group, sizeof(gid_t));
+
+       grp = nwrap_getgrgid(group);
+       if (grp) {
+               name_of_group = grp->gr_name;
+       }
+
+       nwrap_files_setgrent();
+       while ((grp = nwrap_files_getgrent()) != NULL) {
+               int i = 0;
+
+               NWRAP_VERBOSE(("%s: inspecting %s for group membership\n",
+                              __location__, grp->gr_name));
+
+               for (i=0; grp->gr_mem && grp->gr_mem[i] != NULL; i++) {
+
+                       if ((strcmp(user, grp->gr_mem[i]) == 0) &&
+                           (strcmp(name_of_group, grp->gr_name) != 0)) {
+
+                               NWRAP_DEBUG(("%s: %s is member of %s\n",
+                                       __location__, user, grp->gr_name));
+
+                               groups_tmp = (gid_t *)realloc(groups_tmp, (count + 1) * sizeof(gid_t));
+                               if (!groups_tmp) {
+                                       NWRAP_ERROR(("%s:calloc failed\n",__location__));
+                                       errno = ENOMEM;
+                                       return -1;
+                               }
+
+                               memcpy(&groups_tmp[count], &grp->gr_gid, sizeof(gid_t));
+                               count++;
+                       }
+               }
+       }
+       nwrap_files_endgrent();
+
+       NWRAP_VERBOSE(("%s: %s is member of %d groups: %d\n",
+                      __location__, user, *ngroups));
+
+       if (*ngroups < count) {
+               *ngroups = count;
+               free(groups_tmp);
+               return -1;
+       }
+
+       *ngroups = count;
+       memcpy(groups, groups_tmp, count * sizeof(gid_t));
+       free(groups_tmp);
+
+       return count;
+}
+
+_PUBLIC_ int nwrap_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups)
+{
+       if (!nwrap_enabled()) {
+               return real_getgrouplist(user, group, groups, ngroups);
+       }
+
+       return nwrap_files_getgrouplist(user, group, groups, ngroups);
+}
+
index 35a47348a83ef1a0e0b6e7afcb1c088c4eae3277..5bcd42ead40ac729bbc42692d031150bb9050ec1 100644 (file)
@@ -46,6 +46,7 @@ int nwrap_getpwent_r(struct passwd *pwbuf, char *buf,
                     size_t buflen, struct passwd **pwbufp);
 void nwrap_endpwent(void);
 int nwrap_initgroups(const char *user, gid_t group);
+int nwrap_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups);
 struct group *nwrap_getgrnam(const char *name);
 int nwrap_getgrnam_r(const char *name, struct group *gbuf,
                     char *buf, size_t buflen, struct group **gbufp);
@@ -120,6 +121,11 @@ void nwrap_endgrent(void);
 #endif
 #define initgroups     nwrap_initgroups
 
+#ifdef getgrouplist
+#undef getgrouplist
+#endif
+#define getgrouplist   nwrap_getgrouplist
+
 #ifdef getgrnam
 #undef getgrnam
 #endif