2008-12-16 11:30:16 +03:00
/*
2003-11-27 08:11:14 +03:00
Unix SMB / CIFS implementation .
2008-12-16 11:30:16 +03:00
AIX loadable authentication module , providing identification
2003-11-27 08:11:14 +03:00
routines against Samba winbind / Windows NT Domain
Copyright ( C ) Aaron Collins 2003
2014-10-19 17:48:45 +04:00
Copyright ( C ) Timur I . Bakeyev 2013
2008-12-16 11:30:16 +03:00
2003-11-27 08:11:14 +03:00
This library is free software ; you can redistribute it and / or
2007-07-10 08:04:46 +04:00
modify it under the terms of the GNU Lesser General Public
2003-11-27 08:11:14 +03:00
License as published by the Free Software Foundation ; either
2007-07-10 06:31:50 +04:00
version 3 of the License , or ( at your option ) any later version .
2008-12-16 11:30:16 +03:00
2003-11-27 08:11:14 +03:00
This library is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Library General Public License for more details .
2008-12-16 11:30:16 +03:00
2007-07-10 08:04:46 +04:00
You should have received a copy of the GNU Lesser General Public License
2007-07-10 06:31:50 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2003-11-27 08:11:14 +03:00
*/
# include "winbind_client.h"
/* Make sure that the module gets registered needed by freebsd 5.1 */
extern enum nss_status _nss_winbind_getgrent_r ( struct group * , char * , size_t ,
int * ) ;
extern enum nss_status _nss_winbind_getgrnam_r ( const char * , struct group * ,
char * , size_t , int * ) ;
extern enum nss_status _nss_winbind_getgrgid_r ( gid_t gid , struct group * , char * ,
size_t , int * ) ;
extern enum nss_status _nss_winbind_setgrent ( void ) ;
extern enum nss_status _nss_winbind_endgrent ( void ) ;
2014-10-19 17:48:45 +04:00
extern enum nss_status _nss_winbind_initgroups_dyn ( char * , gid_t , long int * ,
long int * , gid_t * * , long int , int * ) ;
2003-11-27 08:11:14 +03:00
extern enum nss_status _nss_winbind_getpwent_r ( struct passwd * , char * , size_t ,
int * ) ;
extern enum nss_status _nss_winbind_getpwnam_r ( const char * , struct passwd * ,
char * , size_t , int * ) ;
extern enum nss_status _nss_winbind_getpwuid_r ( gid_t gid , struct passwd * , char * ,
size_t , int * ) ;
extern enum nss_status _nss_winbind_setpwent ( void ) ;
extern enum nss_status _nss_winbind_endpwent ( void ) ;
2014-10-19 17:48:45 +04:00
ns_mtab * nss_module_register ( const char * , unsigned int * , nss_module_unregister_fn * ) ;
2003-11-27 08:11:14 +03:00
NSS_METHOD_PROTOTYPE ( __nss_compat_getgrnam_r ) ;
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 ( __nss_compat_getpwnam_r ) ;
NSS_METHOD_PROTOTYPE ( __nss_compat_getpwuid_r ) ;
NSS_METHOD_PROTOTYPE ( __nss_compat_getpwent_r ) ;
NSS_METHOD_PROTOTYPE ( __nss_compat_setpwent ) ;
NSS_METHOD_PROTOTYPE ( __nss_compat_endpwent ) ;
2014-10-19 17:48:45 +04:00
NSS_METHOD_PROTOTYPE ( __nss_compat_endpwent ) ;
NSS_METHOD_PROTOTYPE ( __freebsd_getgroupmembership ) ;
2003-11-27 08:11:14 +03:00
static ns_mtab methods [ ] = {
{ NSDB_GROUP , " getgrnam_r " , __nss_compat_getgrnam_r , _nss_winbind_getgrnam_r } ,
{ NSDB_GROUP , " getgrgid_r " , __nss_compat_getgrgid_r , _nss_winbind_getgrgid_r } ,
{ NSDB_GROUP , " getgrent_r " , __nss_compat_getgrent_r , _nss_winbind_getgrent_r } ,
2011-04-18 16:48:47 +04:00
{ NSDB_GROUP , " setgrent " , __nss_compat_setgrent , _nss_winbind_setgrent } ,
{ NSDB_GROUP , " endgrent " , __nss_compat_endgrent , _nss_winbind_endgrent } ,
2014-10-19 17:48:45 +04:00
{ NSDB_GROUP , " getgroupmembership " , __freebsd_getgroupmembership , NULL } ,
2003-11-27 08:11:14 +03:00
{ NSDB_PASSWD , " getpwnam_r " , __nss_compat_getpwnam_r , _nss_winbind_getpwnam_r } ,
{ NSDB_PASSWD , " getpwuid_r " , __nss_compat_getpwuid_r , _nss_winbind_getpwuid_r } ,
{ NSDB_PASSWD , " getpwent_r " , __nss_compat_getpwent_r , _nss_winbind_getpwent_r } ,
2011-04-18 16:48:47 +04:00
{ NSDB_PASSWD , " setpwent " , __nss_compat_setpwent , _nss_winbind_setpwent } ,
{ NSDB_PASSWD , " endpwent " , __nss_compat_endpwent , _nss_winbind_endpwent } ,
2003-11-27 08:11:14 +03:00
} ;
2014-10-19 17:48:45 +04:00
/* Taken from libc */
static int
gr_addgid ( gid_t gid , gid_t * groups , int maxgrp , int * grpcnt )
{
int ret , dupc ;
/* skip duplicates */
for ( dupc = 0 ; dupc < MIN ( maxgrp , * grpcnt ) ; dupc + + ) {
if ( groups [ dupc ] = = gid )
return 1 ;
}
ret = 1 ;
if ( * grpcnt < maxgrp ) /* add this gid */
groups [ * grpcnt ] = gid ;
else
ret = 0 ;
( * grpcnt ) + + ;
return ret ;
}
/*
rv = _nsdispatch ( NULL , dtab , NSDB_GROUP , " getgroupmembership " ,
defaultsrc , uname , agroup , groups , maxgrp , grpcnt ) ;
*/
int
__freebsd_getgroupmembership ( void * retval , void * mdata , va_list ap )
{
const char * uname = va_arg ( ap , const char * ) ;
gid_t group = 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 * ) ;
NSS_STATUS ret ;
long int lcount , lsize ;
int i , errnop ;
gid_t * tmpgroups ;
/* Can be realloc() inside _nss_winbind_initgroups_dyn() */
if ( ( tmpgroups = calloc ( maxgrp , sizeof ( gid_t ) ) ) = = NULL ) {
errno = ENOMEM ;
return NS_TRYAGAIN ;
}
lcount = 0 ;
lsize = maxgrp ;
/* insert primary membership(possibly already there) */
gr_addgid ( group , groups , maxgrp , groupc ) ;
/* Don't limit number of groups, we want to know total size */
ret = _nss_winbind_initgroups_dyn ( uname , group , & lcount , & lsize ,
& tmpgroups , 0 , & errnop ) ;
if ( ret = = NSS_STATUS_SUCCESS ) {
/* lcount potentially can be bigger than maxgrp, so would groupc */
for ( i = 0 ; i < lcount ; i + + )
gr_addgid ( tmpgroups [ i ] , groups , maxgrp , groupc ) ;
}
free ( tmpgroups ) ;
/* Let following nsswitch backend(s) add more groups(?) */
return NSS_STATUS_NOTFOUND ;
}
2003-11-27 08:11:14 +03:00
ns_mtab *
nss_module_register ( const char * source , unsigned int * mtabsize ,
nss_module_unregister_fn * unreg )
{
* mtabsize = sizeof ( methods ) / sizeof ( methods [ 0 ] ) ;
* unreg = NULL ;
return ( methods ) ;
}