summaryrefslogtreecommitdiff
path: root/lib/nss_wrapper/nss_wrapper.c
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2009-05-29 09:19:16 +0200
committerGünther Deschner <gd@samba.org>2009-05-30 00:06:00 +0200
commit8db4917290a2a69b7e0179649a37777d11e72f9d (patch)
tree788cb6a84faa6a49d9eabdb7e2ea74df4156f6f0 /lib/nss_wrapper/nss_wrapper.c
parent684d3dddd6d7d753f236e4c53893f993de2aa2b7 (diff)
downloadsamba-8db4917290a2a69b7e0179649a37777d11e72f9d.tar.gz
samba-8db4917290a2a69b7e0179649a37777d11e72f9d.tar.bz2
samba-8db4917290a2a69b7e0179649a37777d11e72f9d.zip
nss_wrapper: add support for getgrouplist.
Guenther
Diffstat (limited to 'lib/nss_wrapper/nss_wrapper.c')
-rw-r--r--lib/nss_wrapper/nss_wrapper.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/lib/nss_wrapper/nss_wrapper.c b/lib/nss_wrapper/nss_wrapper.c
index 1875dc3e4f..b62be61d12 100644
--- a/lib/nss_wrapper/nss_wrapper.c
+++ b/lib/nss_wrapper/nss_wrapper.c
@@ -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);
+}
+