ports/152987: [patch] net/nss_ldap, option nss_initgroups_ignoreusers ignored

Konstantin Menshikov k.menshikov at peterhost.ru
Fri Dec 10 13:00:30 UTC 2010


>Number:         152987
>Category:       ports
>Synopsis:       [patch] net/nss_ldap, option nss_initgroups_ignoreusers ignored
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Dec 10 13:00:29 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Konstantin Menshikov
>Release:        FreeBSD 8.1-RELEASE amd64
>Organization:
>Environment:
FreeBSD nscd.kmenshikov.devel.hostcomm.ru 8.1-RELEASE FreeBSD 8.1-RELEASE #0: Thu Sep  2 02:56:24 UTC 2010     root at tinderbox.infra.hc.ru:/usr/obj/usr/src/sys/GENERIC  amd64
>Description:
Option nss_initgroups_ignoreusers for net/nss_ldap not working for function getgrouplist(), getgrouplist() called from initgroups().
Call getgroplist() on freebsd used nss_ldap function __nss_compat_getgrent_r(),
because not realized function for "getgroupmembership".
Option nss_initgroups_ignoreusers checked in _nss_ldap_initgroups_dyn().
Therefore option not working.

I`m found patch http://lists.freebsd.org/pipermail/freebsd-current/2007-July/075131.html (for bsdnss.c) and corrected it.
This implemented special function for getgroupmembership search.
Run and testing on my freebsd box, option nss_initgroups_ignoreusers works fine.

>How-To-Repeat:
Configure you system for authentication in LDAP http://www.freebsd.org/doc/en_US.ISO8859-1/articles/ldap-auth/index.html

Add in /usr/local/etc/nss_ldap.conf "nss_initgroups_ignoreusers nobody", run "id nobody".
Look ldap server logs (you see search loockup for get group list) or build net/nss_ldap with debug (CFLAGS+=-DDEBUG in make.conf) and see debug trace.

>Fix:
Need apply patch to bsdnss.c and rebuild nss_ldap.

Patch attached with submission follows:

--- bsdnss.c.old	2010-12-09 13:04:25.000000000 +0000
+++ bsdnss.c	2010-12-09 13:02:37.000000000 +0000
@@ -1,9 +1,11 @@
 #include <errno.h>
+#include <stdlib.h>
 #include <sys/param.h>
 #include <netinet/in.h>
 #include <pwd.h>
 #include <grp.h>
 #include <nss.h>
+#include <nsswitch.h>
 #include <netdb.h>
 
 extern enum nss_status _nss_ldap_getgrent_r(struct group *, char *, size_t,
@@ -14,6 +16,8 @@
     size_t, int *);
 extern enum nss_status _nss_ldap_setgrent(void);
 extern enum nss_status _nss_ldap_endgrent(void);
+extern enum nss_status _nss_ldap_initgroups_dyn(const char *, gid_t, long int *,
+			   long int *, gid_t **, long int, int *);
 
 extern enum nss_status _nss_ldap_getpwent_r(struct passwd *, char *, size_t,
     int *);
@@ -40,6 +44,7 @@
 NSS_METHOD_PROTOTYPE(__nss_compat_getgrent_r);
 NSS_METHOD_PROTOTYPE(__nss_compat_setgrent);
 NSS_METHOD_PROTOTYPE(__nss_compat_endgrent);
+static NSS_METHOD_PROTOTYPE(__freebsd_getgroupmembership);
 
 NSS_METHOD_PROTOTYPE(__nss_compat_getpwnam_r);
 NSS_METHOD_PROTOTYPE(__nss_compat_getpwuid_r);
@@ -57,6 +62,7 @@
 { NSDB_GROUP, "getgrent_r", __nss_compat_getgrent_r, _nss_ldap_getgrent_r },
 { NSDB_GROUP, "setgrent",   __nss_compat_setgrent,   _nss_ldap_setgrent },
 { NSDB_GROUP, "endgrent",   __nss_compat_endgrent,   _nss_ldap_endgrent },
+{ NSDB_GROUP, "getgroupmembership",  __freebsd_getgroupmembership, NULL },
 
 { NSDB_PASSWD, "getpwnam_r", __nss_compat_getpwnam_r, _nss_ldap_getpwnam_r },
 { NSDB_PASSWD, "getpwuid_r", __nss_compat_getpwuid_r, _nss_ldap_getpwuid_r },
@@ -156,3 +162,58 @@
 	h_errno = h_errnop;
 	return (status);
 }
+
+static int
+__gr_addgid(gid_t gid, gid_t *groups, int maxgrp, int *groupc)
+{
+	int	ret, dupc;
+
+	/* skip duplicates */
+	for (dupc = 0; dupc < MIN(maxgrp, *groupc); dupc++) {
+		if (groups[dupc] == gid)
+			return 1;
+	}
+
+	ret = 1;
+	if (*groupc < maxgrp)			/* add this gid */
+		groups[*groupc] = gid;
+	else
+		ret = 0;
+	(*groupc)++;
+	return ret;
+}
+
+static int __freebsd_getgroupmembership(void *retval, void *mdata, va_list ap)
+{
+	int err;
+	enum nss_status s;
+	const char *user 	= va_arg(ap, const char *);
+	gid_t group 		= va_arg(ap, gid_t);
+	gid_t *groups 		= va_arg(ap, gid_t *);
+	int limit 		= va_arg(ap, int);
+	int *size 		= va_arg(ap, int*);
+	gid_t *tmpgroups;
+	long int lstart, lsize;
+	int i;
+
+	tmpgroups = malloc(limit * sizeof(gid_t));
+	if (tmpgroups == NULL)
+		return NS_TRYAGAIN;
+
+	/* insert primary membership */
+	__gr_addgid(group, groups, limit, size);
+
+	lstart = 0;
+	lsize = limit;
+	s = _nss_ldap_initgroups_dyn(user, group, &lstart, &lsize,
+		&tmpgroups, 0, &err);
+	if (s == NSS_STATUS_SUCCESS) {
+		for (i = 0; i < lstart; i++)
+			 __gr_addgid(tmpgroups[i], groups, limit, size);
+		s = NSS_STATUS_NOTFOUND;
+	}
+
+	free(tmpgroups);
+
+	return __nss_compat_result(s, err);
+}


>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the freebsd-ports-bugs mailing list