ports/152982: [patch] net/nss_ldap, ignore option nss_initgroups_ignoreusers
Konstantin Menshikov
kmenshikov at peterhost.ru
Fri Dec 10 11:00:21 UTC 2010
>Number: 152982
>Category: ports
>Synopsis: [patch] net/nss_ldap, ignore option nss_initgroups_ignoreusers
>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 11:00:17 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 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 Freebsd for authentication on LDAP server 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". Call function getgrouplist() for user nobody or run "id nobody".
Look ldap server logs (you see lookup for get list of group),
also you can add to /etc/make.conf CFLAGS+=-DDEBUG, rebuld nss_ldap and look 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