2000-05-09 15:43:00 +04:00
/*
Unix SMB / Netbios implementation .
2001-11-28 01:39:57 +03:00
Version 2.2
2000-05-09 15:43:00 +04:00
2001-05-07 08:32:40 +04:00
Winbind daemon - user related functions
2000-05-09 15:43:00 +04:00
Copyright ( C ) Tim Potter 2000
2001-11-28 01:39:57 +03:00
Copyright ( C ) Jeremy Allison 2001.
2000-05-09 15:43:00 +04: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 "winbindd.h"
/* Fill a pwent structure with information we have obtained */
2002-01-20 04:24:59 +03:00
static BOOL winbindd_fill_pwent ( char * dom_name , char * user_name ,
2001-05-07 08:32:40 +04:00
uint32 user_rid , uint32 group_rid ,
2001-11-27 23:57:14 +03:00
char * full_name , struct winbindd_pw * pw )
2000-05-09 15:43:00 +04:00
{
2001-05-08 09:58:03 +04:00
extern userdom_struct current_user_info ;
2002-01-20 04:24:59 +03:00
fstring output_username ;
2001-05-07 08:32:40 +04:00
pstring homedir ;
2002-01-20 04:24:59 +03:00
if ( ! pw | | ! dom_name | | ! user_name )
2001-05-07 08:32:40 +04:00
return False ;
/* Resolve the uid number */
2002-01-20 04:24:59 +03:00
if ( ! winbindd_idmap_get_uid_from_rid ( dom_name , user_rid ,
2001-05-07 08:32:40 +04:00
& pw - > pw_uid ) ) {
DEBUG ( 1 , ( " error getting user id for rid %d \n " , user_rid ) ) ;
return False ;
}
/* Resolve the gid number */
2002-01-20 04:24:59 +03:00
if ( ! winbindd_idmap_get_gid_from_rid ( dom_name , group_rid ,
2001-05-07 08:32:40 +04:00
& pw - > pw_gid ) ) {
DEBUG ( 1 , ( " error getting group id for rid %d \n " , group_rid ) ) ;
return False ;
}
/* Username */
2002-01-20 04:24:59 +03:00
fill_domain_username ( output_username , dom_name , user_name ) ;
safe_strcpy ( pw - > pw_name , output_username , sizeof ( pw - > pw_name ) - 1 ) ;
2001-05-07 08:32:40 +04:00
/* Full name (gecos) */
safe_strcpy ( pw - > pw_gecos , full_name , sizeof ( pw - > pw_gecos ) - 1 ) ;
2001-10-29 07:50:17 +03:00
2001-05-07 08:32:40 +04:00
/* Home directory and shell - use template config parameters. The
defaults are / tmp for the home directory and / bin / false for
shell . */
2001-05-08 09:58:03 +04:00
/* The substitution of %U and %D in the 'template homedir' is done
by lp_string ( ) calling standard_sub_basic ( ) . */
2001-05-07 08:32:40 +04:00
2002-01-20 04:24:59 +03:00
fstrcpy ( current_user_info . smb_name , user_name ) ;
fstrcpy ( current_user_info . domain , dom_name ) ;
2001-05-07 08:32:40 +04:00
2001-05-08 09:58:03 +04:00
pstrcpy ( homedir , lp_template_homedir ( ) ) ;
2001-05-07 08:32:40 +04:00
safe_strcpy ( pw - > pw_dir , homedir , sizeof ( pw - > pw_dir ) - 1 ) ;
safe_strcpy ( pw - > pw_shell , lp_template_shell ( ) ,
sizeof ( pw - > pw_shell ) - 1 ) ;
/* Password - set to "x" as we can't generate anything useful here.
2002-01-20 04:24:59 +03:00
Authentication can be done using the pam_winbind module . */
2001-05-07 08:32:40 +04:00
safe_strcpy ( pw - > pw_passwd , " x " , sizeof ( pw - > pw_passwd ) - 1 ) ;
return True ;
2000-05-09 15:43:00 +04:00
}
2001-12-10 04:05:50 +03:00
/* Return a password structure from a username. */
2000-05-09 15:43:00 +04:00
2002-01-10 09:20:03 +03:00
enum winbindd_result winbindd_getpwnam ( struct winbindd_cli_state * state )
2000-05-09 15:43:00 +04:00
{
2001-12-04 09:17:39 +03:00
uint32 user_rid ;
WINBIND_USERINFO user_info ;
2001-05-07 08:32:40 +04:00
DOM_SID user_sid ;
2001-12-04 09:17:39 +03:00
NTSTATUS status ;
2002-01-20 04:24:59 +03:00
fstring name_domain , name_user ;
2001-09-05 11:55:54 +04:00
enum SID_NAME_USE name_type ;
2001-11-21 12:59:15 +03:00
struct winbindd_domain * domain ;
TALLOC_CTX * mem_ctx ;
2001-05-07 08:32:40 +04:00
DEBUG ( 3 , ( " [%5d]: getpwnam %s \n " , state - > pid ,
state - > request . data . username ) ) ;
/* Parse domain and username */
2001-12-05 07:17:39 +03:00
if ( ! parse_domain_user ( state - > request . data . username , name_domain ,
2002-01-20 04:24:59 +03:00
name_user ) )
2001-05-07 08:32:40 +04:00
return WINBINDD_ERROR ;
2001-11-21 12:59:15 +03:00
if ( ( domain = find_domain_from_name ( name_domain ) ) = = NULL ) {
2002-01-10 09:20:03 +03:00
DEBUG ( 5 , ( " no such domain: %s \n " , name_domain ) ) ;
2001-11-21 12:59:15 +03:00
return WINBINDD_ERROR ;
}
2001-05-07 08:32:40 +04:00
2001-10-10 02:55:00 +04:00
/* Get rid and name type from name */
2001-05-07 08:32:40 +04:00
2002-01-26 12:55:38 +03:00
if ( ! winbindd_lookup_sid_by_name ( domain , name_user , & user_sid , & name_type ) ) {
2001-05-07 08:32:40 +04:00
DEBUG ( 1 , ( " user '%s' does not exist \n " , name_user ) ) ;
return WINBINDD_ERROR ;
}
if ( name_type ! = SID_NAME_USER ) {
DEBUG ( 1 , ( " name '%s' is not a user name: %d \n " , name_user ,
name_type ) ) ;
return WINBINDD_ERROR ;
}
/* Get some user info. Split the user rid from the sid obtained
from the winbind_lookup_by_name ( ) call and use it in a
winbind_lookup_userinfo ( ) */
2000-05-09 15:43:00 +04:00
2002-01-20 04:24:59 +03:00
if ( ! ( mem_ctx = talloc_init_named ( " winbindd_getpwnam([%s] \\ [%s]) " ,
name_domain , name_user ) ) ) {
2001-11-27 09:28:06 +03:00
DEBUG ( 1 , ( " out of memory \n " ) ) ;
return WINBINDD_ERROR ;
}
2001-10-29 07:50:17 +03:00
2001-05-07 08:32:40 +04:00
sid_split_rid ( & user_sid , & user_rid ) ;
2001-12-04 09:17:39 +03:00
2002-01-10 09:20:03 +03:00
status = domain - > methods - > query_user ( domain , mem_ctx , user_rid ,
& user_info ) ;
2001-12-04 09:17:39 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2002-01-20 04:24:59 +03:00
DEBUG ( 1 , ( " error getting user info for user '[%s] \\ [%s]' \n " ,
name_domain , name_user ) ) ;
2001-12-04 09:17:39 +03:00
talloc_destroy ( mem_ctx ) ;
2001-05-07 08:32:40 +04:00
return WINBINDD_ERROR ;
}
2000-05-09 15:43:00 +04:00
2001-12-04 09:17:39 +03:00
/* Now take all this information and fill in a passwd structure */
2002-01-20 04:24:59 +03:00
if ( ! winbindd_fill_pwent ( name_domain , name_user ,
2002-01-10 09:20:03 +03:00
user_rid , user_info . group_rid ,
user_info . full_name ,
2001-05-07 08:32:40 +04:00
& state - > response . data . pw ) ) {
2001-12-04 09:17:39 +03:00
talloc_destroy ( mem_ctx ) ;
2001-05-07 08:32:40 +04:00
return WINBINDD_ERROR ;
}
2001-12-04 09:17:39 +03:00
talloc_destroy ( mem_ctx ) ;
2001-05-07 08:32:40 +04:00
return WINBINDD_OK ;
2000-05-09 15:43:00 +04:00
}
/* Return a password structure given a uid number */
2002-01-10 09:20:03 +03:00
enum winbindd_result winbindd_getpwuid ( struct winbindd_cli_state * state )
2000-05-09 15:43:00 +04:00
{
2001-05-07 08:32:40 +04:00
DOM_SID user_sid ;
struct winbindd_domain * domain ;
2001-12-04 09:17:39 +03:00
uint32 user_rid ;
2002-01-20 04:24:59 +03:00
fstring dom_name ;
2001-12-04 09:17:39 +03:00
fstring user_name ;
2001-05-07 08:32:40 +04:00
enum SID_NAME_USE name_type ;
2001-12-04 09:17:39 +03:00
WINBIND_USERINFO user_info ;
2001-05-07 08:32:40 +04:00
gid_t gid ;
2001-11-27 23:57:14 +03:00
TALLOC_CTX * mem_ctx ;
2001-12-04 09:17:39 +03:00
NTSTATUS status ;
2001-05-07 08:32:40 +04:00
/* Bug out if the uid isn't in the winbind range */
if ( ( state - > request . data . uid < server_state . uid_low ) | |
2001-10-19 05:46:43 +04:00
( state - > request . data . uid > server_state . uid_high ) )
2001-05-07 08:32:40 +04:00
return WINBINDD_ERROR ;
DEBUG ( 3 , ( " [%5d]: getpwuid %d \n " , state - > pid ,
state - > request . data . uid ) ) ;
/* Get rid from uid */
if ( ! winbindd_idmap_get_rid_from_uid ( state - > request . data . uid ,
& user_rid , & domain ) ) {
2002-01-10 09:20:03 +03:00
DEBUG ( 1 , ( " could not convert uid %d to rid \n " ,
2001-05-07 08:32:40 +04:00
state - > request . data . uid ) ) ;
return WINBINDD_ERROR ;
}
/* Get name and name type from rid */
sid_copy ( & user_sid , & domain - > sid ) ;
sid_append_rid ( & user_sid , user_rid ) ;
2002-01-20 04:24:59 +03:00
if ( ! winbindd_lookup_name_by_sid ( & user_sid , dom_name , user_name , & name_type ) ) {
2001-05-07 08:32:40 +04:00
fstring temp ;
sid_to_string ( temp , & user_sid ) ;
2002-01-10 09:20:03 +03:00
DEBUG ( 1 , ( " could not lookup sid %s \n " , temp ) ) ;
2001-05-07 08:32:40 +04:00
return WINBINDD_ERROR ;
}
/* Get some user info */
2002-01-10 09:20:03 +03:00
if ( ! ( mem_ctx = talloc_init_named ( " winbind_getpwuid(%d) " ,
state - > request . data . uid ) ) ) {
2001-11-27 09:28:06 +03:00
DEBUG ( 1 , ( " out of memory \n " ) ) ;
return WINBINDD_ERROR ;
}
2001-10-29 07:50:17 +03:00
2002-01-10 09:20:03 +03:00
status = domain - > methods - > query_user ( domain , mem_ctx , user_rid ,
& user_info ) ;
2001-12-04 09:17:39 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2002-01-10 09:20:03 +03:00
DEBUG ( 1 , ( " error getting user info for user '%s' \n " ,
user_name ) ) ;
2002-01-20 04:24:59 +03:00
talloc_destroy ( mem_ctx ) ;
2001-05-07 08:32:40 +04:00
return WINBINDD_ERROR ;
}
/* Resolve gid number */
2001-12-04 09:17:39 +03:00
if ( ! winbindd_idmap_get_gid_from_rid ( domain - > name , user_info . group_rid , & gid ) ) {
2001-05-07 08:32:40 +04:00
DEBUG ( 1 , ( " error getting group id for user %s \n " , user_name ) ) ;
2002-01-20 04:24:59 +03:00
talloc_destroy ( mem_ctx ) ;
2001-05-07 08:32:40 +04:00
return WINBINDD_ERROR ;
}
/* Fill in password structure */
2001-12-04 09:17:39 +03:00
if ( ! winbindd_fill_pwent ( domain - > name , user_name , user_rid , user_info . group_rid ,
user_info . full_name , & state - > response . data . pw ) ) {
2002-01-20 04:24:59 +03:00
talloc_destroy ( mem_ctx ) ;
2001-05-07 08:32:40 +04:00
return WINBINDD_ERROR ;
2001-11-27 23:57:14 +03:00
}
2001-05-07 08:32:40 +04:00
2001-12-04 09:17:39 +03:00
talloc_destroy ( mem_ctx ) ;
2001-05-07 08:32:40 +04:00
return WINBINDD_OK ;
2000-05-09 15:43:00 +04:00
}
/*
* set / get / endpwent functions
*/
/* Rewind file pointer for ntdom passwd database */
enum winbindd_result winbindd_setpwent ( struct winbindd_cli_state * state )
{
2002-01-10 09:20:03 +03:00
struct winbindd_domain * domain ;
2001-10-08 04:34:14 +04:00
2001-11-27 23:57:14 +03:00
DEBUG ( 3 , ( " [%5d]: setpwent \n " , state - > pid ) ) ;
2001-10-08 04:34:14 +04:00
2001-11-27 23:57:14 +03:00
/* Check user has enabled this */
2001-10-08 04:34:14 +04:00
2001-11-27 23:57:14 +03:00
if ( ! lp_winbind_enum_users ( ) )
return WINBINDD_ERROR ;
2001-10-08 04:34:14 +04:00
2001-11-27 23:57:14 +03:00
/* Free old static data if it exists */
2001-10-08 04:34:14 +04:00
2001-11-27 23:57:14 +03:00
if ( state - > getpwent_state ! = NULL ) {
free_getent_state ( state - > getpwent_state ) ;
state - > getpwent_state = NULL ;
}
2001-10-08 04:34:14 +04:00
2001-11-27 23:57:14 +03:00
/* Create sam pipes for each domain we know about */
2001-10-08 04:34:14 +04:00
2002-01-11 08:33:45 +03:00
for ( domain = domain_list ( ) ; domain ! = NULL ; domain = domain - > next ) {
2001-11-27 23:57:14 +03:00
struct getent_state * domain_state ;
2001-10-08 04:34:14 +04:00
2001-11-27 23:57:14 +03:00
/*
* Skip domains other than WINBINDD_DOMAIN environment
* variable .
*/
2001-10-08 04:34:14 +04:00
2001-11-27 23:57:14 +03:00
if ( ( strcmp ( state - > request . domain , " " ) ! = 0 ) & &
2002-01-10 09:20:03 +03:00
! check_domain_env ( state - > request . domain ,
domain - > name ) )
2001-11-27 23:57:14 +03:00
continue ;
2001-10-08 04:34:14 +04:00
2001-11-27 23:57:14 +03:00
/* Create a state record for this domain */
2001-10-08 04:34:14 +04:00
2002-01-10 09:20:03 +03:00
if ( ( domain_state = ( struct getent_state * )
malloc ( sizeof ( struct getent_state ) ) ) = = NULL )
2001-11-27 23:57:14 +03:00
return WINBINDD_ERROR ;
2001-10-08 04:34:14 +04:00
2001-11-27 23:57:14 +03:00
ZERO_STRUCTP ( domain_state ) ;
2001-10-19 05:46:43 +04:00
2002-01-11 08:33:45 +03:00
fstrcpy ( domain_state - > domain_name , domain - > name ) ;
2001-10-08 04:34:14 +04:00
2001-11-27 23:57:14 +03:00
/* Add to list of open domains */
2001-10-08 04:34:14 +04:00
2001-11-27 23:57:14 +03:00
DLIST_ADD ( state - > getpwent_state , domain_state ) ;
}
2001-10-08 04:34:14 +04:00
2001-11-27 23:57:14 +03:00
return WINBINDD_OK ;
2000-05-09 15:43:00 +04:00
}
/* Close file pointer to ntdom passwd database */
enum winbindd_result winbindd_endpwent ( struct winbindd_cli_state * state )
{
2001-11-27 23:57:14 +03:00
DEBUG ( 3 , ( " [%5d]: endpwent \n " , state - > pid ) ) ;
2000-05-09 15:43:00 +04:00
2001-11-27 23:57:14 +03:00
free_getent_state ( state - > getpwent_state ) ;
state - > getpwent_state = NULL ;
2001-10-08 04:34:14 +04:00
2001-11-27 23:57:14 +03:00
return WINBINDD_OK ;
2000-05-09 15:43:00 +04:00
}
2001-05-07 08:32:40 +04:00
/* Get partial list of domain users for a domain. We fill in the sam_entries,
and num_sam_entries fields with domain user information . The dispinfo_ndx
field is incremented to the index of the next user to fetch . Return True if
some users were returned , False otherwise . */
# define MAX_FETCH_SAM_ENTRIES 100
static BOOL get_sam_user_entries ( struct getent_state * ent )
{
2001-09-04 11:13:01 +04:00
NTSTATUS status ;
uint32 num_entries ;
2001-12-03 14:32:55 +03:00
WINBIND_USERINFO * info ;
2001-05-07 08:32:40 +04:00
struct getpwent_user * name_list = NULL ;
2001-11-27 23:57:14 +03:00
BOOL result = False ;
TALLOC_CTX * mem_ctx ;
2002-01-11 08:33:45 +03:00
struct winbindd_domain * domain ;
2001-12-01 15:31:43 +03:00
struct winbindd_methods * methods ;
2001-12-11 03:03:58 +03:00
int i ;
2001-05-07 08:32:40 +04:00
2001-12-11 03:03:58 +03:00
if ( ent - > num_sam_entries )
2001-05-07 08:32:40 +04:00
return False ;
2002-01-10 09:20:03 +03:00
if ( ! ( mem_ctx = talloc_init_named ( " get_sam_user_entries(%s) " ,
2002-01-11 08:33:45 +03:00
ent - > domain_name ) ) )
2001-11-27 23:57:14 +03:00
return False ;
2001-10-19 12:22:52 +04:00
2002-01-11 08:33:45 +03:00
if ( ! ( domain = find_domain_from_name ( ent - > domain_name ) ) ) {
DEBUG ( 3 , ( " no such domain %s in get_sam_user_entries \n " ,
ent - > domain_name ) ) ;
return False ;
}
methods = domain - > methods ;
2001-05-07 08:32:40 +04:00
/* Free any existing user info */
2001-09-17 08:52:45 +04:00
SAFE_FREE ( ent - > sam_entries ) ;
ent - > num_sam_entries = 0 ;
2001-12-03 14:32:55 +03:00
/* Call query_user_list to get a list of usernames and user rids */
2002-01-11 08:33:45 +03:00
2001-12-11 03:03:58 +03:00
num_entries = 0 ;
2001-05-07 08:32:40 +04:00
2002-01-11 08:33:45 +03:00
status = methods - > query_user_list ( domain , mem_ctx , & num_entries ,
& info ) ;
2001-05-07 08:32:40 +04:00
2001-12-11 03:03:58 +03:00
if ( num_entries ) {
struct getpwent_user * tnl ;
tnl = ( struct getpwent_user * ) Realloc ( name_list ,
sizeof ( struct getpwent_user ) *
( ent - > num_sam_entries +
num_entries ) ) ;
if ( ! tnl ) {
2002-01-10 09:20:03 +03:00
DEBUG ( 0 , ( " get_sam_user_entries realloc failed. \n " ) ) ;
2001-12-11 03:03:58 +03:00
SAFE_FREE ( name_list ) ;
goto done ;
} else
name_list = tnl ;
}
2001-05-07 08:32:40 +04:00
2001-12-11 03:03:58 +03:00
for ( i = 0 ; i < num_entries ; i + + ) {
/* Store account name and gecos */
if ( ! info [ i ] . acct_name ) {
fstrcpy ( name_list [ ent - > num_sam_entries + i ] . name , " " ) ;
} else {
fstrcpy ( name_list [ ent - > num_sam_entries + i ] . name ,
info [ i ] . acct_name ) ;
}
if ( ! info [ i ] . full_name ) {
fstrcpy ( name_list [ ent - > num_sam_entries + i ] . gecos , " " ) ;
} else {
fstrcpy ( name_list [ ent - > num_sam_entries + i ] . gecos ,
info [ i ] . full_name ) ;
2001-05-07 08:32:40 +04:00
}
2001-12-11 03:03:58 +03:00
/* User and group ids */
name_list [ ent - > num_sam_entries + i ] . user_rid = info [ i ] . user_rid ;
name_list [ ent - > num_sam_entries + i ] . group_rid = info [ i ] . group_rid ;
}
ent - > num_sam_entries + = num_entries ;
2001-05-07 08:32:40 +04:00
/* Fill in remaining fields */
ent - > sam_entries = name_list ;
ent - > sam_entry_index = 0 ;
2001-10-19 12:22:52 +04:00
result = ent - > num_sam_entries > 0 ;
done :
2001-05-07 08:32:40 +04:00
2001-11-27 23:57:14 +03:00
talloc_destroy ( mem_ctx ) ;
return result ;
2001-05-07 08:32:40 +04:00
}
2000-05-09 15:43:00 +04:00
/* Fetch next passwd entry from ntdom database */
2001-05-07 08:32:40 +04:00
# define MAX_GETPWENT_USERS 500
2000-05-09 15:43:00 +04:00
enum winbindd_result winbindd_getpwent ( struct winbindd_cli_state * state )
{
2001-05-07 08:32:40 +04:00
struct getent_state * ent ;
struct winbindd_pw * user_list ;
int num_users , user_list_ndx = 0 , i ;
2000-05-09 15:43:00 +04:00
2001-05-07 08:32:40 +04:00
DEBUG ( 3 , ( " [%5d]: getpwent \n " , state - > pid ) ) ;
2000-05-09 15:43:00 +04:00
2001-05-07 08:32:40 +04:00
/* Check user has enabled this */
2000-05-09 15:43:00 +04:00
2001-10-08 04:34:14 +04:00
if ( ! lp_winbind_enum_users ( ) )
2001-05-07 08:32:40 +04:00
return WINBINDD_ERROR ;
2000-05-09 15:43:00 +04:00
2001-05-07 08:32:40 +04:00
/* Allocate space for returning a chunk of users */
2000-05-09 15:43:00 +04:00
2001-05-07 08:32:40 +04:00
num_users = MIN ( MAX_GETPWENT_USERS , state - > request . data . num_entries ) ;
if ( ( state - > response . extra_data =
2001-10-08 04:34:14 +04:00
malloc ( num_users * sizeof ( struct winbindd_pw ) ) ) = = NULL )
2001-05-07 08:32:40 +04:00
return WINBINDD_ERROR ;
2000-05-09 15:43:00 +04:00
2001-05-07 08:32:40 +04:00
memset ( state - > response . extra_data , 0 , num_users *
sizeof ( struct winbindd_pw ) ) ;
2000-05-09 15:43:00 +04:00
2001-05-07 08:32:40 +04:00
user_list = ( struct winbindd_pw * ) state - > response . extra_data ;
2001-10-08 04:34:14 +04:00
if ( ! ( ent = state - > getpwent_state ) )
2001-05-07 08:32:40 +04:00
return WINBINDD_ERROR ;
2000-05-09 15:43:00 +04:00
2001-05-07 08:32:40 +04:00
/* Start sending back users */
2000-05-09 15:43:00 +04:00
2001-05-07 08:32:40 +04:00
for ( i = 0 ; i < num_users ; i + + ) {
struct getpwent_user * name_list = NULL ;
fstring domain_user_name ;
uint32 result ;
2000-05-09 15:43:00 +04:00
2001-05-07 08:32:40 +04:00
/* Do we need to fetch another chunk of users? */
2000-05-09 15:43:00 +04:00
2001-05-07 08:32:40 +04:00
if ( ent - > num_sam_entries = = ent - > sam_entry_index ) {
2000-05-09 15:43:00 +04:00
2001-05-07 08:32:40 +04:00
while ( ent & & ! get_sam_user_entries ( ent ) ) {
struct getent_state * next_ent ;
2000-05-09 15:43:00 +04:00
2001-05-07 08:32:40 +04:00
/* Free state information for this domain */
2000-05-09 15:43:00 +04:00
2001-09-17 08:52:45 +04:00
SAFE_FREE ( ent - > sam_entries ) ;
2000-05-09 15:43:00 +04:00
2001-05-07 08:32:40 +04:00
next_ent = ent - > next ;
DLIST_REMOVE ( state - > getpwent_state , ent ) ;
2001-09-17 08:52:45 +04:00
SAFE_FREE ( ent ) ;
2001-05-07 08:32:40 +04:00
ent = next_ent ;
}
/* No more domains */
2001-10-08 04:34:14 +04:00
if ( ! ent )
2001-11-27 09:28:06 +03:00
break ;
2001-05-07 08:32:40 +04:00
}
name_list = ent - > sam_entries ;
/* Skip machine accounts */
if ( name_list [ ent - > sam_entry_index ] .
name [ strlen ( name_list [ ent - > sam_entry_index ] . name ) - 1 ]
= = ' $ ' ) {
ent - > sam_entry_index + + ;
continue ;
}
/* Lookup user info */
result = winbindd_fill_pwent (
2002-01-11 08:33:45 +03:00
ent - > domain_name ,
2002-01-20 04:24:59 +03:00
name_list [ ent - > sam_entry_index ] . name ,
2001-05-07 08:32:40 +04:00
name_list [ ent - > sam_entry_index ] . user_rid ,
name_list [ ent - > sam_entry_index ] . group_rid ,
name_list [ ent - > sam_entry_index ] . gecos ,
& user_list [ user_list_ndx ] ) ;
ent - > sam_entry_index + + ;
/* Add user to return list */
if ( result ) {
user_list_ndx + + ;
state - > response . data . num_entries + + ;
state - > response . length + =
sizeof ( struct winbindd_pw ) ;
2001-10-08 04:34:14 +04:00
} else
2001-05-07 08:32:40 +04:00
DEBUG ( 1 , ( " could not lookup domain user %s \n " ,
domain_user_name ) ) ;
}
/* Out of domains */
return ( user_list_ndx > 0 ) ? WINBINDD_OK : WINBINDD_ERROR ;
}
2000-05-09 15:43:00 +04:00
2001-05-07 08:32:40 +04:00
/* List domain users without mapping to unix ids */
enum winbindd_result winbindd_list_users ( struct winbindd_cli_state * state )
{
2001-08-18 23:43:28 +04:00
struct winbindd_domain * domain ;
2001-12-03 14:32:55 +03:00
WINBIND_USERINFO * info ;
2001-08-18 23:43:28 +04:00
uint32 num_entries = 0 , total_entries = 0 ;
2001-08-12 21:30:01 +04:00
char * ted , * extra_data = NULL ;
2001-05-07 08:32:40 +04:00
int extra_data_len = 0 ;
2001-11-27 09:28:06 +03:00
TALLOC_CTX * mem_ctx ;
enum winbindd_result rv = WINBINDD_ERROR ;
2001-05-07 08:32:40 +04:00
DEBUG ( 3 , ( " [%5d]: list users \n " , state - > pid ) ) ;
2002-01-10 09:20:03 +03:00
if ( ! ( mem_ctx = talloc_init_named ( " winbindd_list_users " ) ) )
2001-11-27 09:28:06 +03:00
return WINBINDD_ERROR ;
2001-10-19 05:46:43 +04:00
2001-08-18 23:43:28 +04:00
/* Enumerate over trusted domains */
2001-05-07 08:32:40 +04:00
2002-01-11 08:33:45 +03:00
for ( domain = domain_list ( ) ; domain ; domain = domain - > next ) {
2001-09-04 11:13:01 +04:00
NTSTATUS status ;
2001-12-01 15:31:43 +03:00
struct winbindd_methods * methods ;
2001-12-11 03:03:58 +03:00
int i ;
2001-05-07 08:32:40 +04:00
/* Skip domains other than WINBINDD_DOMAIN environment
variable */
if ( ( strcmp ( state - > request . domain , " " ) ! = 0 ) & &
2001-10-19 05:46:43 +04:00
! check_domain_env ( state - > request . domain , domain - > name ) )
2001-05-07 08:32:40 +04:00
continue ;
2001-12-01 15:31:43 +03:00
methods = domain - > methods ;
2001-08-18 23:43:28 +04:00
/* Query display info */
2001-12-11 03:03:58 +03:00
status = methods - > query_user_list ( domain , mem_ctx ,
& num_entries , & info ) ;
2001-05-07 08:32:40 +04:00
2001-12-11 03:03:58 +03:00
if ( num_entries = = 0 )
continue ;
2001-05-07 08:32:40 +04:00
2001-12-11 03:03:58 +03:00
/* Allocate some memory for extra data */
total_entries + = num_entries ;
2001-05-07 08:32:40 +04:00
2001-12-11 03:03:58 +03:00
ted = Realloc ( extra_data , sizeof ( fstring ) * total_entries ) ;
2001-05-07 08:32:40 +04:00
2001-12-11 03:03:58 +03:00
if ( ! ted ) {
2002-01-10 09:20:03 +03:00
DEBUG ( 0 , ( " failed to enlarge buffer! \n " ) ) ;
2001-12-11 03:03:58 +03:00
SAFE_FREE ( extra_data ) ;
goto done ;
} else
extra_data = ted ;
2001-05-07 08:32:40 +04:00
2001-12-11 03:03:58 +03:00
/* Pack user list into extra data fields */
for ( i = 0 ; i < num_entries ; i + + ) {
fstring acct_name , name ;
if ( ! info [ i ] . acct_name ) {
fstrcpy ( acct_name , " " ) ;
} else {
fstrcpy ( acct_name , info [ i ] . acct_name ) ;
}
2002-01-18 05:37:55 +03:00
fill_domain_username ( name , domain - > name , acct_name ) ;
2001-05-07 08:32:40 +04:00
/* Append to extra data */
2001-12-11 03:03:58 +03:00
memcpy ( & extra_data [ extra_data_len ] , name ,
strlen ( name ) ) ;
extra_data_len + = strlen ( name ) ;
extra_data [ extra_data_len + + ] = ' , ' ;
}
2000-05-09 15:43:00 +04:00
}
2001-05-07 08:32:40 +04:00
/* Assign extra_data fields in response structure */
if ( extra_data ) {
extra_data [ extra_data_len - 1 ] = ' \0 ' ;
state - > response . extra_data = extra_data ;
state - > response . length + = extra_data_len ;
}
/* No domains responded but that's still OK so don't return an
error . */
2000-05-09 15:43:00 +04:00
2001-10-19 05:46:43 +04:00
rv = WINBINDD_OK ;
done :
2001-11-27 09:28:06 +03:00
talloc_destroy ( mem_ctx ) ;
return rv ;
2000-05-09 15:43:00 +04:00
}