diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2011-10-12 20:07:03 +0000 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2011-10-12 20:07:03 +0000 |
commit | 446ca5155c191b097aea2820813a94fd088617d3 (patch) | |
tree | 0b467ddb54a30cdfd4a857e32f3e52aada18abc4 | |
parent | 0f28775b8105e1da4688487644788e3617b5e9db (diff) |
implement group membership NSS function by Tom Judge (taken from FreeBSD PR 154000)
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-pam-ldapd@1553 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | nss/bsdnss.c | 63 |
2 files changed, 60 insertions, 4 deletions
@@ -114,3 +114,4 @@ Jakub Hrozek <jhrozek@redhat.com> Andreas B. Mundt <andi.mundt@web.de> Paul Gevers <paul@climbing.nl> Jeroen Schot <schot@A-Eskwadraat.nl> +Tom Judge <tom@tomjudge.com> diff --git a/nss/bsdnss.c b/nss/bsdnss.c index da862a5..cbf290d 100644 --- a/nss/bsdnss.c +++ b/nss/bsdnss.c @@ -7,6 +7,7 @@ Copyright (C) 2006 Artem Kazakov Copyright (C) 2009 Alexander V. Chernikov Copyright (C) 2011 Arthur de Jong + Copyright (C) 2011 Tom Judge This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -29,12 +30,10 @@ #include <errno.h> #include <sys/param.h> #include <netinet/in.h> -#include <pwd.h> -#include <grp.h> -#include <nss.h> -#include <netdb.h> #include "prototypes.h" +#include "common.h" +#include "compat/attrs.h" #define BUFFER_SIZE 1024 @@ -43,6 +42,7 @@ NSS_METHOD_PROTOTYPE(__nss_compat_getgrgid_r); NSS_METHOD_PROTOTYPE(__nss_compat_getgrent_r); NSS_METHOD_PROTOTYPE(__nss_compat_setgrent); NSS_METHOD_PROTOTYPE(__nss_compat_endgrent); +NSS_METHOD_PROTOTYPE(__freebsd_getgroupmembership); NSS_METHOD_PROTOTYPE(__nss_compat_getpwnam_r); NSS_METHOD_PROTOTYPE(__nss_compat_getpwuid_r); @@ -60,6 +60,7 @@ static ns_mtab methods[]={ { 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 }, @@ -146,6 +147,60 @@ int __nss_compat_gethostbyaddr(void *retval,void *mdata,va_list ap) return (status); } +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; + nss_status_t s; + gid_t group; + gid_t *tmpgroups; + size_t bufsize; + const char *user; + gid_t *groups; + gid_t agroup; + int maxgrp,*grpcnt; + int i,rv,ret_errno; + long int lstart,lsize; + user=va_arg(ap,const char *); + group=va_arg(ap,gid_t); + groups=va_arg(ap,gid_t *); + maxgrp=va_arg(ap,int); + grpcnt=va_arg(ap,int *); + tmpgroups=malloc(maxgrp*sizeof(gid_t)); + if (tmpgroups==NULL) + return NSS_STATUS_UNAVAIL; + /* insert primary membership */ + __gr_addgid(group,groups,maxgrp,grpcnt); + lstart=0; + lsize=maxgrp; + 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,maxgrp,grpcnt) + s=NSS_STATUS_NOTFOUND; + } + free(tmpgroups); + return __nss_compat_result(s,0); +} + ns_mtab *nss_module_register(const char *source,unsigned int *mtabsize, nss_module_unregister_fn *unreg) { |