2001-05-29 07:34:01 +00:00
/*
2002-01-30 06:08:46 +00:00
Unix SMB / CIFS implementation .
2001-05-29 07:34:01 +00:00
Samba utility functions
Copyright ( C ) Simo Sorce 2001
2001-12-14 21:51:09 +00:00
Copyright ( C ) Jeremy Allison 2001
2001-05-29 07:34:01 +00:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program 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 General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2001-06-11 22:06:11 +00:00
2001-05-29 07:34:01 +00:00
/****************************************************************
Returns a single linked list of group entries .
Use grent_free ( ) to free it after use .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-05-31 14:41:53 +00:00
2001-05-29 07:34:01 +00:00
struct sys_grent * getgrent_list ( void )
{
struct sys_grent * glist ;
struct sys_grent * gent ;
struct group * grp ;
gent = ( struct sys_grent * ) malloc ( sizeof ( struct sys_grent ) ) ;
if ( gent = = NULL ) {
DEBUG ( 0 , ( " Out of memory in getgrent_list! \n " ) ) ;
return NULL ;
}
2001-06-11 22:06:11 +00:00
memset ( gent , ' \0 ' , sizeof ( struct sys_grent ) ) ;
2001-05-29 07:34:01 +00:00
glist = gent ;
setgrent ( ) ;
grp = getgrent ( ) ;
2001-06-11 22:06:11 +00:00
if ( grp = = NULL ) {
endgrent ( ) ;
2001-09-17 02:19:44 +00:00
SAFE_FREE ( glist ) ;
2001-06-11 22:06:11 +00:00
return NULL ;
}
2001-05-31 14:41:53 +00:00
while ( grp ! = NULL ) {
2001-05-29 07:34:01 +00:00
int i , num ;
2001-05-31 14:41:53 +00:00
if ( grp - > gr_name ) {
if ( ( gent - > gr_name = strdup ( grp - > gr_name ) ) = = NULL )
goto err ;
}
if ( grp - > gr_passwd ) {
if ( ( gent - > gr_passwd = strdup ( grp - > gr_passwd ) ) = = NULL )
goto err ;
}
2001-05-29 07:34:01 +00:00
gent - > gr_gid = grp - > gr_gid ;
/* number of strings in gr_mem */
2001-05-31 14:41:53 +00:00
for ( num = 0 ; grp - > gr_mem [ num ] ; num + + )
;
2001-05-29 07:34:01 +00:00
/* alloc space for gr_mem string pointers */
2001-06-11 22:06:11 +00:00
if ( ( gent - > gr_mem = ( char * * ) malloc ( ( num + 1 ) * sizeof ( char * ) ) ) = = NULL )
2001-05-31 14:41:53 +00:00
goto err ;
2001-06-11 22:06:11 +00:00
memset ( gent - > gr_mem , ' \0 ' , ( num + 1 ) * sizeof ( char * ) ) ;
2001-05-31 14:41:53 +00:00
for ( i = 0 ; i < num ; i + + ) {
if ( ( gent - > gr_mem [ i ] = strdup ( grp - > gr_mem [ i ] ) ) = = NULL )
goto err ;
2001-05-29 07:34:01 +00:00
}
gent - > gr_mem [ num ] = NULL ;
grp = getgrent ( ) ;
2001-05-31 14:41:53 +00:00
if ( grp ) {
2001-05-29 07:34:01 +00:00
gent - > next = ( struct sys_grent * ) malloc ( sizeof ( struct sys_grent ) ) ;
2001-05-31 14:41:53 +00:00
if ( gent - > next = = NULL )
goto err ;
2001-05-29 07:34:01 +00:00
gent = gent - > next ;
2001-06-11 22:06:11 +00:00
memset ( gent , ' \0 ' , sizeof ( struct sys_grent ) ) ;
2001-05-29 07:34:01 +00:00
}
}
endgrent ( ) ;
return glist ;
2001-05-31 14:41:53 +00:00
err :
endgrent ( ) ;
DEBUG ( 0 , ( " Out of memory in getgrent_list! \n " ) ) ;
grent_free ( glist ) ;
return NULL ;
2001-05-29 07:34:01 +00:00
}
/****************************************************************
Free the single linked list of group entries made by
getgrent_list ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-05-31 14:41:53 +00:00
2001-05-29 07:34:01 +00:00
void grent_free ( struct sys_grent * glist )
{
2001-05-31 14:41:53 +00:00
while ( glist ) {
2001-06-11 22:06:11 +00:00
struct sys_grent * prev ;
2001-05-29 07:34:01 +00:00
2001-09-17 02:19:44 +00:00
SAFE_FREE ( glist - > gr_name ) ;
SAFE_FREE ( glist - > gr_passwd ) ;
2001-05-31 14:41:53 +00:00
if ( glist - > gr_mem ) {
2001-06-11 22:06:11 +00:00
int i ;
for ( i = 0 ; glist - > gr_mem [ i ] ; i + + )
2001-09-17 02:19:44 +00:00
SAFE_FREE ( glist - > gr_mem [ i ] ) ;
SAFE_FREE ( glist - > gr_mem ) ;
2001-05-29 07:34:01 +00:00
}
2001-06-11 22:06:11 +00:00
prev = glist ;
glist = glist - > next ;
2001-09-17 02:19:44 +00:00
SAFE_FREE ( prev ) ;
2001-05-29 07:34:01 +00:00
}
}
/****************************************************************
Returns a single linked list of passwd entries .
Use pwent_free ( ) to free it after use .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-05-31 14:41:53 +00:00
2001-05-29 07:34:01 +00:00
struct sys_pwent * getpwent_list ( void )
{
struct sys_pwent * plist ;
struct sys_pwent * pent ;
struct passwd * pwd ;
pent = ( struct sys_pwent * ) malloc ( sizeof ( struct sys_pwent ) ) ;
if ( pent = = NULL ) {
DEBUG ( 0 , ( " Out of memory in getpwent_list! \n " ) ) ;
return NULL ;
}
plist = pent ;
setpwent ( ) ;
pwd = getpwent ( ) ;
2001-05-31 14:41:53 +00:00
while ( pwd ! = NULL ) {
memset ( pent , ' \0 ' , sizeof ( struct sys_pwent ) ) ;
if ( pwd - > pw_name ) {
if ( ( pent - > pw_name = strdup ( pwd - > pw_name ) ) = = NULL )
goto err ;
}
if ( pwd - > pw_passwd ) {
if ( ( pent - > pw_passwd = strdup ( pwd - > pw_passwd ) ) = = NULL )
goto err ;
}
2001-05-29 07:34:01 +00:00
pent - > pw_uid = pwd - > pw_uid ;
pent - > pw_gid = pwd - > pw_gid ;
2001-05-31 14:41:53 +00:00
if ( pwd - > pw_gecos ) {
if ( ( pent - > pw_name = strdup ( pwd - > pw_gecos ) ) = = NULL )
goto err ;
}
if ( pwd - > pw_dir ) {
if ( ( pent - > pw_name = strdup ( pwd - > pw_dir ) ) = = NULL )
goto err ;
}
if ( pwd - > pw_shell ) {
if ( ( pent - > pw_name = strdup ( pwd - > pw_shell ) ) = = NULL )
goto err ;
}
2001-05-29 07:34:01 +00:00
pwd = getpwent ( ) ;
2001-05-31 14:41:53 +00:00
if ( pwd ) {
2001-05-29 07:34:01 +00:00
pent - > next = ( struct sys_pwent * ) malloc ( sizeof ( struct sys_pwent ) ) ;
2001-05-31 14:41:53 +00:00
if ( pent - > next = = NULL )
goto err ;
2001-05-29 07:34:01 +00:00
pent = pent - > next ;
}
}
endpwent ( ) ;
return plist ;
2001-05-31 14:41:53 +00:00
err :
endpwent ( ) ;
DEBUG ( 0 , ( " Out of memory in getpwent_list! \n " ) ) ;
pwent_free ( plist ) ;
return NULL ;
2001-05-29 07:34:01 +00:00
}
/****************************************************************
Free the single linked list of passwd entries made by
getpwent_list ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-05-31 14:41:53 +00:00
2001-05-29 07:34:01 +00:00
void pwent_free ( struct sys_pwent * plist )
{
2001-05-31 14:41:53 +00:00
while ( plist ) {
2001-06-11 22:06:11 +00:00
struct sys_pwent * prev ;
2001-05-29 07:34:01 +00:00
2001-09-17 02:19:44 +00:00
SAFE_FREE ( plist - > pw_name ) ;
SAFE_FREE ( plist - > pw_passwd ) ;
SAFE_FREE ( plist - > pw_gecos ) ;
SAFE_FREE ( plist - > pw_dir ) ;
SAFE_FREE ( plist - > pw_shell ) ;
2001-05-29 07:34:01 +00:00
2001-06-11 22:06:11 +00:00
prev = plist ;
plist = plist - > next ;
2001-09-17 02:19:44 +00:00
SAFE_FREE ( prev ) ;
2001-05-29 07:34:01 +00:00
}
}
2001-12-14 21:51:09 +00:00
/****************************************************************
Add the individual group users onto the list .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static struct sys_userlist * add_members_to_userlist ( struct sys_userlist * list_head , const struct group * grp )
{
size_t num_users , i ;
/* Count the number of users. */
for ( num_users = 0 ; grp - > gr_mem [ num_users ] ; num_users + + )
;
for ( i = 0 ; i < num_users ; i + + ) {
struct sys_userlist * entry = ( struct sys_userlist * ) malloc ( sizeof ( * entry ) ) ;
if ( entry = = NULL ) {
free_userlist ( list_head ) ;
return NULL ;
}
2003-04-14 02:24:16 +00:00
entry - > unix_name = ( char * ) strdup ( grp - > gr_mem [ i ] ) ;
2001-12-14 21:51:09 +00:00
if ( entry - > unix_name = = NULL ) {
SAFE_FREE ( entry ) ;
free_userlist ( list_head ) ;
return NULL ;
}
DLIST_ADD ( list_head , entry ) ;
}
return list_head ;
}
/****************************************************************
Get the list of UNIX users in a group .
We have to enumerate the / etc / group file as some UNIX getgrnam ( )
calls won ' t do that for us ( notably Tru64 UNIX ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct sys_userlist * get_users_in_group ( const char * gname )
{
struct sys_userlist * list_head = NULL ;
struct group * gptr ;
2002-01-27 12:12:22 +00:00
fstring domain ;
fstring groupname ;
DOM_SID sid ;
enum SID_NAME_USE name_type ;
2002-07-15 10:35:28 +00:00
/* No point using winbind if we can't split it in the
first place */
if ( split_domain_and_name ( gname , domain , groupname ) ) {
/*
* If we ' re doing this via winbindd , don ' t do the
* entire group list enumeration as we know this is
* pointless ( and slow ) .
*/
if ( winbind_lookup_name ( domain , groupname , & sid , & name_type )
& & name_type = = SID_NAME_DOM_GRP ) {
if ( ( gptr = ( struct group * ) getgrnam ( gname ) ) = = NULL )
return NULL ;
return add_members_to_userlist ( list_head , gptr ) ;
}
2001-12-14 21:51:09 +00:00
}
2002-07-15 10:35:28 +00:00
2003-02-18 04:48:32 +00:00
# if !defined(BROKEN_GETGRNAM)
if ( ( gptr = ( struct group * ) getgrnam ( gname ) ) = = NULL )
return NULL ;
return add_members_to_userlist ( list_head , gptr ) ;
# else
/* BROKEN_GETGRNAM - True64 */
2001-12-14 21:51:09 +00:00
setgrent ( ) ;
while ( ( gptr = getgrent ( ) ) ! = NULL ) {
if ( strequal ( gname , gptr - > gr_name ) ) {
list_head = add_members_to_userlist ( list_head , gptr ) ;
if ( list_head = = NULL )
return NULL ;
}
}
endgrent ( ) ;
return list_head ;
2003-02-18 04:48:32 +00:00
# endif
2001-12-14 21:51:09 +00:00
}
/****************************************************************
Free list allocated above .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void free_userlist ( struct sys_userlist * list_head )
{
while ( list_head ) {
struct sys_userlist * old_head = list_head ;
DLIST_REMOVE ( list_head , list_head ) ;
SAFE_FREE ( old_head - > unix_name ) ;
SAFE_FREE ( old_head ) ;
}
}