--- ../../../work.orig/samba-3.0.25a/source/nsswitch/winbind_nss_freebsd.c Mon Jul 30 19:30:33 2007 +++ nsswitch/winbind_nss_freebsd.c Tue Jul 31 18:10:52 2007 @@ -55,6 +55,9 @@ NSS_METHOD_PROTOTYPE(__nss_compat_getpwent_r); NSS_METHOD_PROTOTYPE(__nss_compat_setpwent); NSS_METHOD_PROTOTYPE(__nss_compat_endpwent); +NSS_METHOD_PROTOTYPE(__nss_compat_endpwent); + +NSS_METHOD_PROTOTYPE(netbsdwinbind_getgroupmembership); static ns_mtab methods[] = { { NSDB_GROUP, "getgrnam_r", __nss_compat_getgrnam_r, _nss_winbind_getgrnam_r }, @@ -62,6 +65,7 @@ { NSDB_GROUP, "getgrent_r", __nss_compat_getgrent_r, _nss_winbind_getgrent_r }, { NSDB_GROUP, "endgrent", __nss_compat_setgrent, _nss_winbind_setgrent }, { NSDB_GROUP, "setgrent", __nss_compat_endgrent, _nss_winbind_endgrent }, +{ NSDB_GROUP, "getgroupmembership", netbsdwinbind_getgroupmembership, NULL }, { NSDB_PASSWD, "getpwnam_r", __nss_compat_getpwnam_r, _nss_winbind_getpwnam_r }, { NSDB_PASSWD, "getpwuid_r", __nss_compat_getpwuid_r, _nss_winbind_getpwuid_r }, @@ -79,3 +83,51 @@ *unreg = NULL; return (methods); } + +/* Copied from winbind_nss_netbsd.c */ +int +netbsdwinbind_getgroupmembership(void *nsrv, void *nscb, va_list ap) +{ + int *result = va_arg(ap, int *); + const char *uname = va_arg(ap, const char *); + gid_t agroup = va_arg(ap, gid_t); + gid_t *groups = va_arg(ap, gid_t *); + int maxgrp = va_arg(ap, int); + int *groupc = va_arg(ap, int *); + + struct winbindd_request request; + struct winbindd_response response; + gid_t *wblistv; + int wblistc, i, isdup, dupc; + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + strncpy(request.data.username, uname, + sizeof(request.data.username) - 1); + i = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response); + if (i != NSS_STATUS_SUCCESS) + return NS_NOTFOUND; + wblistv = (gid_t *)response.extra_data.data; + wblistc = response.data.num_entries; + + for (i = 0; i < wblistc; i++) { /* add winbind gids */ + isdup = 0; /* skip duplicates */ + for (dupc = 0; dupc < MIN(maxgrp, *groupc); dupc++) { + if (groups[dupc] == wblistv[i]) { + isdup = 1; + break; + } + } + if (isdup) + continue; + if (*groupc < maxgrp) /* add this gid */ + groups[*groupc] = wblistv[i]; + else + *result = -1; + (*groupc)++; + } + SAFE_FREE(wblistv); + return NS_NOTFOUND; +} + +