2001-02-27 21:22:39 +03:00
/*
* Unix SMB / Netbios implementation .
* Version 1.9 .
* RPC Pipe client / server routines
* Copyright ( C ) Andrew Tridgell 1992 - 1997 ,
* Copyright ( C ) Luke Kenneth Casson Leighton 1996 - 1997 ,
* Copyright ( C ) Paul Ashton 1997.
2001-03-23 03:50:31 +03:00
* Copyright ( C ) Marc Jacobsen 1999.
2001-02-27 21:22:39 +03:00
* Copyright ( C ) Jeremy Allison 2001.
*
* 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 .
*/
/*
* This is the implementation of the SAMR code .
*/
# include "includes.h"
extern int DEBUGLEVEL ;
extern fstring global_myworkgroup ;
extern pstring global_myname ;
extern DOM_SID global_sam_sid ;
2001-03-23 03:50:31 +03:00
extern DOM_SID global_sid_Builtin ;
2001-02-27 21:22:39 +03:00
extern rid_name domain_group_rids [ ] ;
extern rid_name domain_alias_rids [ ] ;
extern rid_name builtin_alias_rids [ ] ;
2001-03-11 03:32:10 +03:00
struct samr_info {
/* for use by the \PIPE\samr policy */
DOM_SID sid ;
uint32 status ; /* some sort of flag. best to record it. comes from opnum 0x39 */
} ;
/*******************************************************************
Function to free the per handle data .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void free_samr_info ( void * ptr )
{
struct samr_info * samr = ( struct samr_info * ) ptr ;
safe_free ( samr ) ;
}
2001-03-13 03:32:43 +03:00
/*******************************************************************
Ensure password info is never given out . Paranioa . . . JRA .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void samr_clear_passwd_fields ( SAM_USER_INFO_21 * pass , int num_entries )
{
int i ;
if ( ! pass )
return ;
for ( i = 0 ; i < num_entries ; i + + ) {
memset ( & pass [ i ] . lm_pwd , ' \0 ' , sizeof ( pass [ i ] . lm_pwd ) ) ;
memset ( & pass [ i ] . nt_pwd , ' \0 ' , sizeof ( pass [ i ] . nt_pwd ) ) ;
}
}
2001-05-04 19:44:27 +04:00
static void samr_clear_sam_passwd ( SAM_ACCOUNT * sam_pass )
2001-03-13 03:32:43 +03:00
{
if ( ! sam_pass )
return ;
2001-05-09 21:57:08 +04:00
if ( sam_pass - > lm_pw ) memset ( sam_pass - > lm_pw , ' \0 ' , 16 ) ;
if ( sam_pass - > nt_pw ) memset ( sam_pass - > nt_pw , ' \0 ' , 16 ) ;
2001-03-13 03:32:43 +03:00
}
2001-02-27 21:22:39 +03:00
/*******************************************************************
This next function should be replaced with something that
dynamically returns the correct user info . . . . . JRA .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL get_sampwd_entries ( SAM_USER_INFO_21 * pw_buf , int start_idx ,
int * total_entries , int * num_entries ,
int max_num_entries , uint16 acb_mask )
{
2001-05-04 19:44:27 +04:00
SAM_ACCOUNT * pwd = NULL ;
BOOL ret ;
( * num_entries ) = 0 ;
( * total_entries ) = 0 ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
if ( pw_buf = = NULL )
return False ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
pdb_init_sam ( & pwd ) ;
2001-02-27 21:22:39 +03:00
2001-03-11 03:32:10 +03:00
if ( ! pdb_setsampwent ( False ) ) {
2001-05-04 19:44:27 +04:00
DEBUG ( 0 , ( " get_sampwd_entries: Unable to open passdb. \n " ) ) ;
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
2001-05-04 19:44:27 +04:00
return False ;
}
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
while ( ( ( ret = pdb_getsampwent ( pwd ) ) ! = False ) & & ( * num_entries ) < max_num_entries ) {
2001-02-27 21:22:39 +03:00
int user_name_len ;
if ( start_idx > 0 ) {
/* skip the requested number of entries.
not very efficient , but hey . . .
*/
start_idx - - ;
continue ;
}
2001-03-11 03:32:10 +03:00
user_name_len = strlen ( pdb_get_username ( pwd ) ) + 1 ;
init_unistr2 ( & pw_buf [ ( * num_entries ) ] . uni_user_name , pdb_get_username ( pwd ) , user_name_len ) ;
2001-02-27 21:22:39 +03:00
init_uni_hdr ( & pw_buf [ ( * num_entries ) ] . hdr_user_name , user_name_len ) ;
pw_buf [ ( * num_entries ) ] . user_rid = pwd - > user_rid ;
memset ( ( char * ) pw_buf [ ( * num_entries ) ] . nt_pwd , ' \0 ' , 16 ) ;
/* Now check if the NT compatible password is available. */
2001-03-11 03:32:10 +03:00
if ( pdb_get_nt_passwd ( pwd ) )
memcpy ( pw_buf [ ( * num_entries ) ] . nt_pwd , pdb_get_nt_passwd ( pwd ) , 16 ) ;
2001-02-27 21:22:39 +03:00
2001-03-11 03:32:10 +03:00
pw_buf [ ( * num_entries ) ] . acb_info = pdb_get_acct_ctrl ( pwd ) ;
2001-02-27 21:22:39 +03:00
DEBUG ( 5 , ( " entry idx: %d user %s, rid 0x%x, acb %x " ,
2001-03-11 03:32:10 +03:00
( * num_entries ) , pdb_get_username ( pwd ) , pdb_get_user_rid ( pwd ) , pdb_get_acct_ctrl ( pwd ) ) ) ;
2001-02-27 21:22:39 +03:00
if ( acb_mask = = 0 | | ( pwd - > acct_ctrl & acb_mask ) ) {
DEBUG ( 5 , ( " acb_mask %x accepts \n " , acb_mask ) ) ;
( * num_entries ) + + ;
}
else
DEBUG ( 5 , ( " acb_mask %x rejects \n " , acb_mask ) ) ;
( * total_entries ) + + ;
}
2001-05-04 19:44:27 +04:00
pdb_endsampwent ( ) ;
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
return ( * num_entries ) > 0 ;
2001-02-27 21:22:39 +03:00
}
static BOOL jf_get_sampwd_entries ( SAM_USER_INFO_21 * pw_buf , int start_idx ,
2001-03-11 03:32:10 +03:00
int * total_entries , uint32 * num_entries ,
2001-02-27 21:22:39 +03:00
int max_num_entries , uint16 acb_mask )
{
2001-05-04 19:44:27 +04:00
SAM_ACCOUNT * pwd = NULL ;
2001-02-27 21:22:39 +03:00
* num_entries = 0 ;
* total_entries = 0 ;
if ( pw_buf = = NULL )
return False ;
2001-05-04 19:44:27 +04:00
DEBUG ( 10 , ( " jf_get_sampwd_entries: start index:%d, max entries:%d, mask:%d \n " ,
start_idx , max_num_entries , acb_mask ) ) ;
2001-02-27 21:22:39 +03:00
2001-03-11 03:32:10 +03:00
if ( ! pdb_setsampwent ( False ) ) {
2001-05-04 19:44:27 +04:00
DEBUG ( 0 , ( " jf_get_sampwd_entries: Unable to open passdb. \n " ) ) ;
return False ;
}
pdb_init_sam ( & pwd ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
while ( ( pdb_getsampwent ( pwd ) ! = False ) & & ( * num_entries ) < max_num_entries ) {
2001-02-27 21:22:39 +03:00
int user_name_len ;
int full_name_len ;
2001-03-11 03:32:10 +03:00
if ( acb_mask ! = 0 & & ! ( pdb_get_acct_ctrl ( pwd ) & acb_mask ) )
2001-02-27 21:22:39 +03:00
continue ;
if ( start_idx > 0 ) {
/* skip the requested number of entries.
not very efficient , but hey . . .
*/
start_idx - - ;
continue ;
}
ZERO_STRUCTP ( & pw_buf [ ( * num_entries ) ] ) ;
2001-03-11 03:32:10 +03:00
user_name_len = strlen ( pdb_get_username ( pwd ) ) ;
init_unistr2 ( & pw_buf [ ( * num_entries ) ] . uni_user_name , pdb_get_username ( pwd ) , user_name_len ) ;
2001-02-27 21:22:39 +03:00
init_uni_hdr ( & pw_buf [ ( * num_entries ) ] . hdr_user_name , user_name_len ) ;
2001-03-11 03:32:10 +03:00
full_name_len = strlen ( pdb_get_fullname ( pwd ) ) ;
init_unistr2 ( & pw_buf [ ( * num_entries ) ] . uni_full_name , pdb_get_fullname ( pwd ) , full_name_len ) ;
2001-02-27 21:22:39 +03:00
init_uni_hdr ( & pw_buf [ ( * num_entries ) ] . hdr_full_name , full_name_len ) ;
2001-03-11 03:32:10 +03:00
pw_buf [ ( * num_entries ) ] . user_rid = pdb_get_user_rid ( pwd ) ;
2001-02-27 21:22:39 +03:00
memset ( ( char * ) pw_buf [ ( * num_entries ) ] . nt_pwd , ' \0 ' , 16 ) ;
/* Now check if the NT compatible password is available. */
2001-05-04 19:44:27 +04:00
if ( pdb_get_nt_passwd ( pwd ) )
memcpy ( pw_buf [ ( * num_entries ) ] . nt_pwd , pdb_get_nt_passwd ( pwd ) , 16 ) ;
2001-02-27 21:22:39 +03:00
2001-03-11 03:32:10 +03:00
pw_buf [ ( * num_entries ) ] . acb_info = pdb_get_acct_ctrl ( pwd ) ;
2001-02-27 21:22:39 +03:00
2001-03-11 03:32:10 +03:00
DEBUG ( 5 , ( " entry idx: %d user %s, rid 0x%x, acb %x \n " , ( * num_entries ) ,
pdb_get_username ( pwd ) , pdb_get_user_rid ( pwd ) , pdb_get_acct_ctrl ( pwd ) ) ) ;
2001-05-04 19:44:27 +04:00
2001-02-27 21:22:39 +03:00
( * num_entries ) + + ;
2001-05-08 20:33:18 +04:00
pdb_reset_sam ( pwd ) ;
2001-02-27 21:22:39 +03:00
}
2001-05-04 19:44:27 +04:00
pdb_endsampwent ( ) ;
2001-02-27 21:22:39 +03:00
* total_entries = * num_entries ;
2001-05-04 19:44:27 +04:00
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
2001-05-04 19:44:27 +04:00
2001-02-27 21:22:39 +03:00
return True ;
}
/*******************************************************************
This function uses the username map file and tries to map a UNIX
user name to an DOS name . ( Sort of the reverse of the
map_username ( ) function . ) Since more than one DOS name can map
to the UNIX name , to reverse the mapping you have to specify
which corresponding DOS name you want ; that ' s where the name_idx
parameter comes in . Returns the string requested or NULL if it
fails or can ' t complete the request for any reason . This doesn ' t
handle group names ( starting with ' @ ' ) or names starting with
' + ' or ' & ' . If they are encountered , they are skipped .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static char * unmap_unixname ( char * unix_user_name , int name_idx )
{
char * mapfile = lp_username_map ( ) ;
char * * lines ;
static pstring tok ;
int i ;
if ( ! * unix_user_name ) return NULL ;
if ( ! * mapfile ) return NULL ;
lines = file_lines_load ( mapfile , NULL , False ) ;
if ( ! lines ) {
DEBUG ( 0 , ( " unmap_unixname: can't open username map %s \n " , mapfile ) ) ;
return NULL ;
}
DEBUG ( 5 , ( " unmap_unixname: scanning username map %s, index: %d \n " , mapfile , name_idx ) ) ;
for ( i = 0 ; lines [ i ] ; i + + ) {
char * unixname = lines [ i ] ;
char * dosname = strchr ( unixname , ' = ' ) ;
if ( ! dosname )
continue ;
* dosname + + = 0 ;
while ( isspace ( * unixname ) )
unixname + + ;
if ( ' ! ' = = * unixname ) {
unixname + + ;
while ( * unixname & & isspace ( * unixname ) )
unixname + + ;
}
if ( ! * unixname | | strchr ( " #; " , * unixname ) )
continue ;
if ( strncmp ( unixname , unix_user_name , strlen ( unix_user_name ) ) )
continue ;
/* We have matched the UNIX user name */
while ( next_token ( & dosname , tok , LIST_SEP , sizeof ( tok ) ) ) {
if ( ! strchr ( " @&+ " , * tok ) ) {
name_idx - - ;
if ( name_idx < 0 ) {
break ;
}
}
}
if ( name_idx > = 0 ) {
DEBUG ( 0 , ( " unmap_unixname: index too high - not that many DOS names \n " ) ) ;
file_lines_free ( lines ) ;
return NULL ;
} else {
file_lines_free ( lines ) ;
return tok ;
}
}
DEBUG ( 0 , ( " unmap_unixname: Couldn't find the UNIX user name \n " ) ) ;
file_lines_free ( lines ) ;
return NULL ;
}
/*******************************************************************
This function sets up a list of users taken from the list of
users that UNIX knows about , as well as all the user names that
Samba maps to a valid UNIX user name . ( This should work with
/ etc / passwd or NIS . )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL get_passwd_entries ( SAM_USER_INFO_21 * pw_buf ,
int start_idx ,
int * total_entries , int * num_entries ,
int max_num_entries ,
uint16 acb_mask )
{
static struct passwd * pwd = NULL ;
static uint32 pw_rid ;
static BOOL orig_done = False ;
static int current_idx = 0 ;
static int mapped_idx = 0 ;
char * sep ;
DEBUG ( 5 , ( " get_passwd_entries: retrieving a list of UNIX users \n " ) ) ;
( * num_entries ) = 0 ;
( * total_entries ) = 0 ;
/* Skip all this stuff if we're in appliance mode */
if ( lp_hide_local_users ( ) ) goto done ;
if ( pw_buf = = NULL ) return False ;
if ( current_idx = = 0 ) {
sys_setpwent ( ) ;
}
/* These two cases are inefficient, but should be called very rarely */
/* they are the cases where the starting index isn't picking up */
/* where we left off last time. It is efficient when it starts over */
/* at zero though. */
if ( start_idx > current_idx ) {
/* We aren't far enough; advance to start_idx */
while ( current_idx < = start_idx ) {
char * unmap_name ;
if ( ! orig_done ) {
if ( ( pwd = sys_getpwent ( ) ) = = NULL ) break ;
current_idx + + ;
orig_done = True ;
}
while ( ( ( unmap_name = unmap_unixname ( pwd - > pw_name , mapped_idx ) ) ! = NULL ) & &
( current_idx < start_idx ) ) {
current_idx + + ;
mapped_idx + + ;
}
if ( unmap_name = = NULL ) {
orig_done = False ;
mapped_idx = 0 ;
}
}
} else if ( start_idx < current_idx ) {
/* We are already too far; start over and advance to start_idx */
sys_endpwent ( ) ;
sys_setpwent ( ) ;
current_idx = 0 ;
mapped_idx = 0 ;
orig_done = False ;
while ( current_idx < start_idx ) {
char * unmap_name ;
if ( ! orig_done ) {
if ( ( pwd = sys_getpwent ( ) ) = = NULL ) break ;
current_idx + + ;
orig_done = True ;
}
while ( ( ( unmap_name = unmap_unixname ( pwd - > pw_name , mapped_idx ) ) ! = NULL ) & &
( current_idx < start_idx ) ) {
current_idx + + ;
mapped_idx + + ;
}
if ( unmap_name = = NULL ) {
orig_done = False ;
mapped_idx = 0 ;
}
}
}
sep = lp_winbind_separator ( ) ;
/* now current_idx == start_idx */
while ( ( * num_entries ) < max_num_entries ) {
int user_name_len ;
char * unmap_name ;
/* This does the original UNIX user itself */
if ( ! orig_done ) {
if ( ( pwd = sys_getpwent ( ) ) = = NULL ) break ;
/* Don't enumerate winbind users as they are not local */
if ( strchr ( pwd - > pw_name , * sep ) ! = NULL ) {
continue ;
}
user_name_len = strlen ( pwd - > pw_name ) ;
/* skip the trust account stored in the /etc/passwd file */
if ( pwd - > pw_name [ user_name_len - 1 ] = = ' $ ' )
continue ;
pw_rid = pdb_uid_to_user_rid ( pwd - > pw_uid ) ;
ZERO_STRUCTP ( & pw_buf [ ( * num_entries ) ] ) ;
init_unistr2 ( & pw_buf [ ( * num_entries ) ] . uni_user_name , pwd - > pw_name , user_name_len ) ;
init_uni_hdr ( & pw_buf [ ( * num_entries ) ] . hdr_user_name , user_name_len ) ;
pw_buf [ ( * num_entries ) ] . user_rid = pw_rid ;
memset ( ( char * ) pw_buf [ ( * num_entries ) ] . nt_pwd , ' \0 ' , 16 ) ;
pw_buf [ ( * num_entries ) ] . acb_info = ACB_NORMAL ;
DEBUG ( 5 , ( " get_passwd_entries: entry idx %d user %s, rid 0x%x \n " , ( * num_entries ) , pwd - > pw_name , pw_rid ) ) ;
( * num_entries ) + + ;
( * total_entries ) + + ;
current_idx + + ;
orig_done = True ;
}
/* This does all the user names that map to the UNIX user */
while ( ( ( unmap_name = unmap_unixname ( pwd - > pw_name , mapped_idx ) ) ! = NULL ) & &
( * num_entries < max_num_entries ) ) {
user_name_len = strlen ( unmap_name ) ;
ZERO_STRUCTP ( & pw_buf [ ( * num_entries ) ] ) ;
init_unistr2 ( & pw_buf [ ( * num_entries ) ] . uni_user_name , unmap_name , user_name_len ) ;
init_uni_hdr ( & pw_buf [ ( * num_entries ) ] . hdr_user_name , user_name_len ) ;
pw_buf [ ( * num_entries ) ] . user_rid = pw_rid ;
memset ( ( char * ) pw_buf [ ( * num_entries ) ] . nt_pwd , ' \0 ' , 16 ) ;
pw_buf [ ( * num_entries ) ] . acb_info = ACB_NORMAL ;
DEBUG ( 5 , ( " get_passwd_entries: entry idx %d user %s, rid 0x%x \n " , ( * num_entries ) , pwd - > pw_name , pw_rid ) ) ;
( * num_entries ) + + ;
( * total_entries ) + + ;
current_idx + + ;
mapped_idx + + ;
}
if ( unmap_name = = NULL ) {
/* done with 'aliases', go on to next UNIX user */
orig_done = False ;
mapped_idx = 0 ;
}
}
if ( pwd = = NULL ) {
/* totally done, reset everything */
sys_endpwent ( ) ;
current_idx = 0 ;
mapped_idx = 0 ;
}
done :
return ( * num_entries ) > 0 ;
}
/*******************************************************************
_samr_close_hnd
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_close_hnd ( pipes_struct * p , SAMR_Q_CLOSE_HND * q_u , SAMR_R_CLOSE_HND * r_u )
{
r_u - > status = NT_STATUS_NOPROBLEMO ;
/* close the policy handle */
2001-03-11 03:32:10 +03:00
if ( ! close_policy_hnd ( p , & q_u - > pol ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_OBJECT_NAME_INVALID ;
DEBUG ( 5 , ( " samr_reply_close_hnd: %d \n " , __LINE__ ) ) ;
return r_u - > status ;
}
/*******************************************************************
samr_reply_open_domain
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_open_domain ( pipes_struct * p , SAMR_Q_OPEN_DOMAIN * q_u , SAMR_R_OPEN_DOMAIN * r_u )
{
2001-03-11 03:32:10 +03:00
struct samr_info * info ;
2001-02-27 21:22:39 +03:00
r_u - > status = NT_STATUS_NOPROBLEMO ;
/* find the connection policy handle. */
2001-03-11 03:32:10 +03:00
if ( ! find_policy_by_hnd ( p , & q_u - > pol , NULL ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_INVALID_HANDLE ;
/* associate the domain SID with the (unique) handle. */
2001-03-11 03:32:10 +03:00
if ( ( info = ( struct samr_info * ) malloc ( sizeof ( struct samr_info ) ) ) = = NULL )
return NT_STATUS_NO_MEMORY ;
ZERO_STRUCTP ( info ) ;
info - > sid = q_u - > dom_sid . sid ;
/* get a (unique) handle. open a policy on it. */
if ( ! create_policy_hnd ( p , & r_u - > domain_pol , free_samr_info , ( void * ) info ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
DEBUG ( 5 , ( " samr_open_domain: %d \n " , __LINE__ ) ) ;
return r_u - > status ;
}
2001-03-11 03:32:10 +03:00
static uint32 get_lsa_policy_samr_rid ( struct samr_info * info )
{
if ( ! info ) {
DEBUG ( 3 , ( " Error getting policy \n " ) ) ;
return 0xffffffff ;
}
return info - > sid . sub_auths [ info - > sid . num_auths - 1 ] ;
}
2001-02-27 21:22:39 +03:00
/*******************************************************************
_samr_get_usrdom_pwinfo
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_get_usrdom_pwinfo ( pipes_struct * p , SAMR_Q_GET_USRDOM_PWINFO * q_u , SAMR_R_GET_USRDOM_PWINFO * r_u )
{
2001-03-11 03:32:10 +03:00
struct samr_info * info = NULL ;
2001-02-27 21:22:39 +03:00
r_u - > status = NT_STATUS_NOPROBLEMO ;
/* find the policy handle. open a policy on it. */
2001-03-11 03:32:10 +03:00
if ( ! find_policy_by_hnd ( p , & q_u - > user_pol , ( void * * ) & info ) ) {
2001-02-27 21:22:39 +03:00
return NT_STATUS_INVALID_HANDLE ;
}
/* find the user's rid */
2001-03-11 03:32:10 +03:00
if ( get_lsa_policy_samr_rid ( info ) = = 0xffffffff ) {
2001-02-27 21:22:39 +03:00
return NT_STATUS_OBJECT_TYPE_MISMATCH ;
}
init_samr_r_get_usrdom_pwinfo ( r_u , NT_STATUS_NOPROBLEMO ) ;
DEBUG ( 5 , ( " _samr_get_usrdom_pwinfo: %d \n " , __LINE__ ) ) ;
return r_u - > status ;
}
/*******************************************************************
samr_make_usr_obj_sd
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static uint32 samr_make_usr_obj_sd ( TALLOC_CTX * ctx , SEC_DESC_BUF * * buf , DOM_SID * usr_sid )
{
extern DOM_SID global_sid_World ;
DOM_SID adm_sid ;
DOM_SID act_sid ;
SEC_ACE ace [ 4 ] ;
SEC_ACCESS mask ;
SEC_ACL * psa = NULL ;
SEC_DESC * psd = NULL ;
size_t sd_size ;
sid_copy ( & adm_sid , & global_sid_Builtin ) ;
sid_append_rid ( & adm_sid , BUILTIN_ALIAS_RID_ADMINS ) ;
sid_copy ( & act_sid , & global_sid_Builtin ) ;
sid_append_rid ( & act_sid , BUILTIN_ALIAS_RID_ACCOUNT_OPS ) ;
init_sec_access ( & mask , 0x2035b ) ;
init_sec_ace ( & ace [ 0 ] , & global_sid_World , SEC_ACE_TYPE_ACCESS_ALLOWED , mask , 0 ) ;
init_sec_access ( & mask , 0xf07ff ) ;
init_sec_ace ( & ace [ 1 ] , & adm_sid , SEC_ACE_TYPE_ACCESS_ALLOWED , mask , 0 ) ;
init_sec_ace ( & ace [ 2 ] , & act_sid , SEC_ACE_TYPE_ACCESS_ALLOWED , mask , 0 ) ;
init_sec_access ( & mask , 0x20044 ) ;
init_sec_ace ( & ace [ 3 ] , usr_sid , SEC_ACE_TYPE_ACCESS_ALLOWED , mask , 0 ) ;
if ( ( psa = make_sec_acl ( ctx , NT4_ACL_REVISION , 4 , ace ) ) = = NULL )
return NT_STATUS_NO_MEMORY ;
if ( ( psd = make_sec_desc ( ctx , SEC_DESC_REVISION , NULL , NULL , NULL , psa , & sd_size ) ) = = NULL )
return NT_STATUS_NO_MEMORY ;
if ( ( * buf = make_sec_desc_buf ( ctx , sd_size , psd ) ) = = NULL )
return NT_STATUS_NO_MEMORY ;
return NT_STATUS_NOPROBLEMO ;
}
2001-03-11 03:32:10 +03:00
static BOOL get_lsa_policy_samr_sid ( pipes_struct * p , POLICY_HND * pol , DOM_SID * sid )
{
struct samr_info * info = NULL ;
/* find the policy handle. open a policy on it. */
if ( ! find_policy_by_hnd ( p , pol , ( void * * ) & info ) )
return False ;
if ( ! info )
return False ;
* sid = info - > sid ;
return True ;
}
2001-02-27 21:22:39 +03:00
/*******************************************************************
_samr_query_sec_obj
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_query_sec_obj ( pipes_struct * p , SAMR_Q_QUERY_SEC_OBJ * q_u , SAMR_R_QUERY_SEC_OBJ * r_u )
{
DOM_SID pol_sid ;
r_u - > status = NT_STATUS_NOPROBLEMO ;
/* Get the SID. */
2001-03-11 03:32:10 +03:00
if ( ! get_lsa_policy_samr_sid ( p , & q_u - > user_pol , & pol_sid ) )
return NT_STATUS_INVALID_HANDLE ;
2001-02-27 21:22:39 +03:00
r_u - > status = samr_make_usr_obj_sd ( p - > mem_ctx , & r_u - > buf , & pol_sid ) ;
if ( r_u - > status = = NT_STATUS_NOPROBLEMO )
r_u - > ptr = 1 ;
return r_u - > status ;
}
/*******************************************************************
makes a SAM_ENTRY / UNISTR2 * structure from a user list .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void make_user_sam_entry_list ( TALLOC_CTX * ctx , SAM_ENTRY * * sam_pp , UNISTR2 * * uni_name_pp ,
uint32 num_sam_entries , SAM_USER_INFO_21 * pass )
{
uint32 i ;
SAM_ENTRY * sam ;
UNISTR2 * uni_name ;
* sam_pp = NULL ;
* uni_name_pp = NULL ;
if ( num_sam_entries = = 0 )
return ;
sam = ( SAM_ENTRY * ) talloc ( ctx , sizeof ( SAM_ENTRY ) * num_sam_entries ) ;
uni_name = ( UNISTR2 * ) talloc ( ctx , sizeof ( UNISTR2 ) * num_sam_entries ) ;
if ( sam = = NULL | | uni_name = = NULL ) {
DEBUG ( 0 , ( " NULL pointers in SAMR_R_QUERY_DISPINFO \n " ) ) ;
return ;
}
for ( i = 0 ; i < num_sam_entries ; i + + ) {
int len = pass [ i ] . uni_user_name . uni_str_len ;
init_sam_entry ( & sam [ i ] , len , pass [ i ] . user_rid ) ;
copy_unistr2 ( & uni_name [ i ] , & pass [ i ] . uni_user_name ) ;
}
* sam_pp = sam ;
* uni_name_pp = uni_name ;
}
/*******************************************************************
samr_reply_enum_dom_users
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_enum_dom_users ( pipes_struct * p , SAMR_Q_ENUM_DOM_USERS * q_u , SAMR_R_ENUM_DOM_USERS * r_u )
{
SAM_USER_INFO_21 pass [ MAX_SAM_ENTRIES ] ;
int num_entries = 0 ;
int total_entries = 0 ;
BOOL ret ;
r_u - > status = NT_STATUS_NOPROBLEMO ;
/* find the policy handle. open a policy on it. */
2001-03-11 03:32:10 +03:00
if ( ! find_policy_by_hnd ( p , & q_u - > pol , NULL ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_INVALID_HANDLE ;
DEBUG ( 5 , ( " _samr_enum_dom_users: %d \n " , __LINE__ ) ) ;
become_root ( ) ;
ret = get_sampwd_entries ( pass , q_u - > start_idx , & total_entries , & num_entries ,
MAX_SAM_ENTRIES , q_u - > acb_mask ) ;
unbecome_root ( ) ;
if ( ! ret )
return NT_STATUS_ACCESS_DENIED ;
2001-03-13 03:32:43 +03:00
samr_clear_passwd_fields ( pass , num_entries ) ;
2001-02-27 21:22:39 +03:00
/*
* Note from JRA . total_entries is not being used here . Currently if there is a
* large user base then it looks like NT will enumerate until get_sampwd_entries
* returns False due to num_entries being zero . This will cause an access denied
* return . I don ' t think this is right and needs further investigation . Note that
* this is also the same in the TNG code ( I don ' t think that has been tested with
* a very large user list as MAX_SAM_ENTRIES is set to 600 ) .
*
* I also think that one of the ' num_entries ' return parameters is probably
* the " max entries " parameter - but in the TNG code they ' re all currently set to the same
* value ( again I think this is wrong ) .
*/
make_user_sam_entry_list ( p - > mem_ctx , & r_u - > sam , & r_u - > uni_acct_name , num_entries , pass ) ;
init_samr_r_enum_dom_users ( r_u , q_u - > start_idx + num_entries , num_entries ) ;
DEBUG ( 5 , ( " _samr_enum_dom_users: %d \n " , __LINE__ ) ) ;
return r_u - > status ;
}
/*******************************************************************
makes a SAM_ENTRY / UNISTR2 * structure from a group list .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void make_group_sam_entry_list ( TALLOC_CTX * ctx , SAM_ENTRY * * sam_pp , UNISTR2 * * uni_name_pp ,
uint32 num_sam_entries , DOMAIN_GRP * grp )
{
uint32 i ;
SAM_ENTRY * sam ;
UNISTR2 * uni_name ;
* sam_pp = NULL ;
* uni_name_pp = NULL ;
if ( num_sam_entries = = 0 )
return ;
sam = ( SAM_ENTRY * ) talloc ( ctx , sizeof ( SAM_ENTRY ) * num_sam_entries ) ;
uni_name = ( UNISTR2 * ) talloc ( ctx , sizeof ( UNISTR2 ) * num_sam_entries ) ;
if ( sam = = NULL | | uni_name = = NULL ) {
DEBUG ( 0 , ( " NULL pointers in SAMR_R_QUERY_DISPINFO \n " ) ) ;
return ;
}
for ( i = 0 ; i < num_sam_entries ; i + + ) {
/*
* JRA . I think this should include the null . TNG does not .
*/
int len = strlen ( grp [ i ] . name ) + 1 ;
init_sam_entry ( & sam [ i ] , len , grp [ i ] . rid ) ;
init_unistr2 ( & uni_name [ i ] , grp [ i ] . name , len ) ;
}
* sam_pp = sam ;
* uni_name_pp = uni_name ;
}
/*******************************************************************
Get the group entries - similar to get_sampwd_entries ( ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-05-04 19:44:27 +04:00
static BOOL get_group_alias_entries ( DOMAIN_GRP * * d_grp , DOM_SID * sid , uint32 start_idx ,
2001-02-27 21:22:39 +03:00
uint32 * p_num_entries , uint32 max_entries )
{
fstring sid_str ;
uint32 num_entries = 0 ;
2001-05-04 19:44:27 +04:00
int i ;
GROUP_MAP smap ;
GROUP_MAP * map ;
2001-02-27 21:22:39 +03:00
sid_to_string ( sid_str , sid ) ;
2001-05-04 19:44:27 +04:00
DEBUG ( 5 , ( " get_group_alias_entries: enumerating aliases on SID: %s \n " , sid_str ) ) ;
2001-02-27 21:22:39 +03:00
* p_num_entries = 0 ;
/* well-known aliases */
2001-05-04 19:44:27 +04:00
if ( sid_equal ( sid , & global_sid_Builtin ) & & ! lp_hide_local_users ( ) ) {
enum_group_mapping ( SID_NAME_WKN_GRP , & map , & num_entries , ENUM_ONLY_MAPPED ) ;
* d_grp = ( DOMAIN_GRP * ) malloc ( num_entries * sizeof ( DOMAIN_GRP ) ) ;
if ( * d_grp = = NULL )
return NT_STATUS_NO_MEMORY ;
for ( i = 0 ; i < num_entries & & i < max_entries ; i + + ) {
fstrcpy ( ( * d_grp ) [ i ] . name , map [ i + start_idx ] . nt_name ) ;
sid_split_rid ( & map [ i ] . sid , & ( * d_grp ) [ i ] . rid ) ;
2001-02-27 21:22:39 +03:00
}
2001-05-04 19:44:27 +04:00
safe_free ( map ) ;
} else if ( sid_equal ( sid , & global_sam_sid ) & & ! lp_hide_local_users ( ) ) {
2001-02-27 21:22:39 +03:00
char * sep ;
struct group * grp ;
2001-05-04 19:44:27 +04:00
2001-02-27 21:22:39 +03:00
sep = lp_winbind_separator ( ) ;
/* local aliases */
/* we return the UNIX groups here. This seems to be the right */
/* thing to do, since NT member servers return their local */
/* groups in the same situation. */
setgrent ( ) ;
while ( num_entries < max_entries & & ( ( grp = getgrent ( ) ) ! = NULL ) ) {
uint32 trid ;
2001-05-04 19:44:27 +04:00
if ( ! get_group_from_gid ( grp - > gr_gid , & smap ) )
continue ;
if ( smap . sid_name_use ! = SID_NAME_ALIAS )
continue ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
sid_split_rid ( & smap . sid , & trid ) ;
2001-03-23 05:14:08 +03:00
2001-02-27 21:22:39 +03:00
/* Don't return winbind groups as they are not local! */
2001-05-04 19:44:27 +04:00
if ( strchr ( smap . nt_name , * sep ) ! = NULL ) {
DEBUG ( 10 , ( " get_group_alias_entries: not returing %s, not local. \n " , smap . nt_name ) ) ;
2001-02-27 21:22:39 +03:00
continue ;
2001-03-23 05:14:08 +03:00
}
/* Don't return user private groups... */
2001-05-04 19:44:27 +04:00
if ( Get_Pwnam ( smap . nt_name , False ) ! = 0 ) {
DEBUG ( 10 , ( " get_group_alias_entries: not returing %s, clashes with user. \n " , smap . nt_name ) ) ;
continue ;
2001-03-23 05:14:08 +03:00
}
2001-02-27 21:22:39 +03:00
for ( i = 0 ; i < num_entries ; i + + )
2001-05-04 19:44:27 +04:00
if ( ( * d_grp ) [ i ] . rid = = trid ) break ;
2001-02-27 21:22:39 +03:00
if ( i < num_entries )
continue ; /* rid was there, dup! */
/* JRA - added this for large group db enumeration... */
if ( start_idx > 0 ) {
/* skip the requested number of entries.
not very efficient , but hey . . .
*/
start_idx - - ;
continue ;
}
2001-05-04 19:44:27 +04:00
* d_grp = Realloc ( * d_grp , ( num_entries + 1 ) * sizeof ( DOMAIN_GRP ) ) ;
if ( * d_grp = = NULL )
return NT_STATUS_NO_MEMORY ;
fstrcpy ( ( * d_grp ) [ num_entries ] . name , smap . nt_name ) ;
( * d_grp ) [ num_entries ] . rid = trid ;
2001-02-27 21:22:39 +03:00
num_entries + + ;
}
endgrent ( ) ;
}
* p_num_entries = num_entries ;
return True ;
}
/*******************************************************************
Get the group entries - similar to get_sampwd_entries ( ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-05-04 19:44:27 +04:00
static BOOL get_group_domain_entries ( DOMAIN_GRP * * d_grp , DOM_SID * sid , uint32 start_idx ,
2001-02-27 21:22:39 +03:00
uint32 * p_num_entries , uint32 max_entries )
{
2001-05-04 19:44:27 +04:00
GROUP_MAP * map = NULL ;
int i ;
2001-02-27 21:22:39 +03:00
uint32 num_entries = 0 ;
* p_num_entries = 0 ;
2001-05-04 19:44:27 +04:00
enum_group_mapping ( SID_NAME_DOM_GRP , & map , & num_entries , ENUM_ONLY_MAPPED ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
* d_grp = ( DOMAIN_GRP * ) malloc ( num_entries * sizeof ( DOMAIN_GRP ) ) ;
if ( * d_grp = = NULL )
return False ;
for ( i = 0 ; i < num_entries ; i + + ) {
fstrcpy ( ( * d_grp ) [ i ] . name , map [ i ] . nt_name ) ;
fstrcpy ( ( * d_grp ) [ i ] . comment , map [ i ] . comment ) ;
sid_split_rid ( & map [ i ] . sid , & ( * d_grp ) [ i ] . rid ) ;
( * d_grp ) [ i ] . attr = SID_NAME_DOM_GRP ;
}
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
safe_free ( map ) ;
2001-02-27 21:22:39 +03:00
* p_num_entries = num_entries ;
return True ;
}
/*******************************************************************
samr_reply_enum_dom_groups
Only reply with one group - domain admins . This must be fixed for
a real PDC . JRA .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_enum_dom_groups ( pipes_struct * p , SAMR_Q_ENUM_DOM_GROUPS * q_u , SAMR_R_ENUM_DOM_GROUPS * r_u )
{
2001-05-04 19:44:27 +04:00
DOMAIN_GRP * grp = NULL ;
2001-03-11 03:32:10 +03:00
uint32 num_entries ;
2001-02-27 21:22:39 +03:00
DOM_SID sid ;
r_u - > status = NT_STATUS_NOPROBLEMO ;
2001-03-11 03:32:10 +03:00
if ( ! get_lsa_policy_samr_sid ( p , & q_u - > pol , & sid ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_INVALID_HANDLE ;
DEBUG ( 5 , ( " samr_reply_enum_dom_groups: %d \n " , __LINE__ ) ) ;
2001-05-04 19:44:27 +04:00
/* the domain group array is being allocated in the function below */
get_group_domain_entries ( & grp , & sid , q_u - > start_idx , & num_entries , MAX_SAM_ENTRIES ) ;
2001-02-27 21:22:39 +03:00
make_group_sam_entry_list ( p - > mem_ctx , & r_u - > sam , & r_u - > uni_grp_name , num_entries , grp ) ;
2001-05-04 19:44:27 +04:00
safe_free ( grp ) ;
2001-02-27 21:22:39 +03:00
init_samr_r_enum_dom_groups ( r_u , q_u - > start_idx , num_entries ) ;
DEBUG ( 5 , ( " samr_enum_dom_groups: %d \n " , __LINE__ ) ) ;
return r_u - > status ;
}
/*******************************************************************
samr_reply_enum_dom_aliases
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_enum_dom_aliases ( pipes_struct * p , SAMR_Q_ENUM_DOM_ALIASES * q_u , SAMR_R_ENUM_DOM_ALIASES * r_u )
{
2001-05-04 19:44:27 +04:00
DOMAIN_GRP * grp = NULL ;
2001-03-11 03:32:10 +03:00
uint32 num_entries = 0 ;
2001-02-27 21:22:39 +03:00
fstring sid_str ;
DOM_SID sid ;
r_u - > status = NT_STATUS_NOPROBLEMO ;
2001-03-11 03:32:10 +03:00
if ( ! get_lsa_policy_samr_sid ( p , & q_u - > pol , & sid ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_INVALID_HANDLE ;
sid_to_string ( sid_str , & sid ) ;
DEBUG ( 5 , ( " samr_reply_enum_dom_aliases: sid %s \n " , sid_str ) ) ;
2001-05-04 19:44:27 +04:00
if ( ! get_group_alias_entries ( & grp , & sid , q_u - > start_idx , & num_entries , MAX_SAM_ENTRIES ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_ACCESS_DENIED ;
make_group_sam_entry_list ( p - > mem_ctx , & r_u - > sam , & r_u - > uni_grp_name , num_entries , grp ) ;
2001-05-04 19:44:27 +04:00
safe_free ( grp ) ;
2001-02-27 21:22:39 +03:00
init_samr_r_enum_dom_aliases ( r_u , q_u - > start_idx , num_entries ) ;
DEBUG ( 5 , ( " samr_enum_dom_aliases: %d \n " , __LINE__ ) ) ;
return r_u - > status ;
}
/*******************************************************************
samr_reply_query_dispinfo
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_query_dispinfo ( pipes_struct * p , SAMR_Q_QUERY_DISPINFO * q_u , SAMR_R_QUERY_DISPINFO * r_u )
{
SAM_USER_INFO_21 pass [ MAX_SAM_ENTRIES ] ;
2001-05-04 19:44:27 +04:00
DOMAIN_GRP * grps = NULL ;
2001-02-27 21:22:39 +03:00
uint16 acb_mask = ACB_NORMAL ;
2001-05-04 19:44:27 +04:00
uint32 num_entries = 0 ;
int orig_num_entries = 0 ;
int total_entries = 0 ;
uint32 data_size = 0 ;
2001-02-27 21:22:39 +03:00
DOM_SID sid ;
BOOL ret ;
SAM_DISPINFO_CTR * ctr ;
DEBUG ( 5 , ( " samr_reply_query_dispinfo: %d \n " , __LINE__ ) ) ;
r_u - > status = NT_STATUS_NOPROBLEMO ;
2001-03-11 03:32:10 +03:00
if ( ! get_lsa_policy_samr_sid ( p , & q_u - > domain_pol , & sid ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_INVALID_HANDLE ;
/* decide how many entries to get depending on the max_entries
and max_size passed by client */
if ( q_u - > max_entries > MAX_SAM_ENTRIES )
q_u - > max_entries = MAX_SAM_ENTRIES ;
/* Get what we need from the password database */
switch ( q_u - > switch_level ) {
case 0x2 :
acb_mask = ACB_WSTRUST ;
/* Fall through */
case 0x1 :
case 0x4 :
become_root ( ) ;
#if 0
ret = get_passwd_entries ( pass , q_u - > start_idx , & total_entries , & num_entries ,
MAX_SAM_ENTRIES , acb_mask ) ;
# endif
#if 0
/*
* Which should we use here ? JRA .
*/
ret = get_sampwd_entries ( pass , q_u - > start_idx , & total_entries , & num_entries ,
MAX_SAM_ENTRIES , acb_mask ) ;
# endif
# if 1
ret = jf_get_sampwd_entries ( pass , q_u - > start_idx , & total_entries , & num_entries ,
MAX_SAM_ENTRIES , acb_mask ) ;
# endif
unbecome_root ( ) ;
if ( ! ret ) {
DEBUG ( 5 , ( " get_sampwd_entries: failed \n " ) ) ;
return NT_STATUS_ACCESS_DENIED ;
}
break ;
case 0x3 :
case 0x5 :
2001-05-04 19:44:27 +04:00
ret = get_group_domain_entries ( & grps , & sid , q_u - > start_idx , & num_entries , MAX_SAM_ENTRIES ) ;
2001-02-27 21:22:39 +03:00
if ( ! ret )
return NT_STATUS_ACCESS_DENIED ;
break ;
default :
DEBUG ( 0 , ( " _samr_query_dispinfo: Unknown info level (%u) \n " , ( unsigned int ) q_u - > switch_level ) ) ;
return NT_STATUS_INVALID_INFO_CLASS ;
}
if ( num_entries > q_u - > max_entries )
num_entries = q_u - > max_entries ;
if ( num_entries > MAX_SAM_ENTRIES ) {
num_entries = MAX_SAM_ENTRIES ;
DEBUG ( 5 , ( " limiting number of entries to %d \n " , num_entries ) ) ;
}
2001-03-13 03:32:43 +03:00
/* Ensure password info is never given out here. PARANOIA... JRA */
samr_clear_passwd_fields ( pass , num_entries ) ;
2001-02-27 21:22:39 +03:00
data_size = q_u - > max_size ;
orig_num_entries = num_entries ;
ctr = ( SAM_DISPINFO_CTR * ) talloc ( p - > mem_ctx , sizeof ( SAM_DISPINFO_CTR ) ) ;
/* Now create reply structure */
switch ( q_u - > switch_level ) {
case 0x1 :
ctr - > sam . info1 = ( SAM_DISPINFO_1 * ) talloc ( p - > mem_ctx , num_entries * sizeof ( SAM_DISPINFO_1 ) ) ;
init_sam_dispinfo_1 ( ctr - > sam . info1 , & num_entries , & data_size , q_u - > start_idx , pass ) ;
break ;
case 0x2 :
ctr - > sam . info2 = ( SAM_DISPINFO_2 * ) talloc ( p - > mem_ctx , num_entries * sizeof ( SAM_DISPINFO_2 ) ) ;
init_sam_dispinfo_2 ( ctr - > sam . info2 , & num_entries , & data_size , q_u - > start_idx , pass ) ;
break ;
case 0x3 :
ctr - > sam . info3 = ( SAM_DISPINFO_3 * ) talloc ( p - > mem_ctx , num_entries * sizeof ( SAM_DISPINFO_3 ) ) ;
init_sam_dispinfo_3 ( ctr - > sam . info3 , & num_entries , & data_size , q_u - > start_idx , grps ) ;
2001-05-04 19:44:27 +04:00
safe_free ( grps ) ;
2001-02-27 21:22:39 +03:00
break ;
case 0x4 :
ctr - > sam . info4 = ( SAM_DISPINFO_4 * ) talloc ( p - > mem_ctx , num_entries * sizeof ( SAM_DISPINFO_4 ) ) ;
init_sam_dispinfo_4 ( ctr - > sam . info4 , & num_entries , & data_size , q_u - > start_idx , pass ) ;
break ;
case 0x5 :
ctr - > sam . info5 = ( SAM_DISPINFO_5 * ) talloc ( p - > mem_ctx , num_entries * sizeof ( SAM_DISPINFO_5 ) ) ;
init_sam_dispinfo_5 ( ctr - > sam . info5 , & num_entries , & data_size , q_u - > start_idx , grps ) ;
2001-05-04 19:44:27 +04:00
safe_free ( grps ) ;
2001-02-27 21:22:39 +03:00
break ;
default :
ctr - > sam . info = NULL ;
return NT_STATUS_INVALID_INFO_CLASS ;
}
DEBUG ( 5 , ( " _samr_query_dispinfo: %d \n " , __LINE__ ) ) ;
init_samr_r_query_dispinfo ( r_u , num_entries , data_size , q_u - > switch_level , ctr , r_u - > status ) ;
if ( num_entries < orig_num_entries ) {
return STATUS_MORE_ENTRIES ;
}
return r_u - > status ;
}
/*******************************************************************
samr_reply_query_aliasinfo
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_query_aliasinfo ( pipes_struct * p , SAMR_Q_QUERY_ALIASINFO * q_u , SAMR_R_QUERY_ALIASINFO * r_u )
{
fstring alias_desc = " Local Unix group " ;
fstring alias = " " ;
enum SID_NAME_USE type ;
uint32 alias_rid ;
2001-03-11 03:32:10 +03:00
struct samr_info * info = NULL ;
2001-02-27 21:22:39 +03:00
r_u - > status = NT_STATUS_NOPROBLEMO ;
DEBUG ( 5 , ( " _samr_query_aliasinfo: %d \n " , __LINE__ ) ) ;
/* find the policy handle. open a policy on it. */
2001-03-11 03:32:10 +03:00
if ( ! find_policy_by_hnd ( p , & q_u - > pol , ( void * * ) & info ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_INVALID_HANDLE ;
2001-03-11 03:32:10 +03:00
alias_rid = get_lsa_policy_samr_rid ( info ) ;
2001-02-27 21:22:39 +03:00
if ( alias_rid = = 0xffffffff )
return NT_STATUS_NO_SUCH_ALIAS ;
if ( ! local_lookup_rid ( alias_rid , alias , & type ) )
2001-03-11 03:32:10 +03:00
return NT_STATUS_NO_SUCH_ALIAS ;
2001-02-27 21:22:39 +03:00
switch ( q_u - > switch_level ) {
case 3 :
r_u - > ptr = 1 ;
r_u - > ctr . switch_value1 = 3 ;
init_samr_alias_info3 ( & r_u - > ctr . alias . info3 , alias_desc ) ;
break ;
default :
return NT_STATUS_INVALID_INFO_CLASS ;
}
DEBUG ( 5 , ( " _samr_query_aliasinfo: %d \n " , __LINE__ ) ) ;
return r_u - > status ;
}
#if 0
/*******************************************************************
samr_reply_lookup_ids
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_lookup_ids ( pipes_struct * p , SAMR_Q_LOOKUP_IDS * q_u , SAMR_R_LOOKUP_IDS * r_u )
{
uint32 rid [ MAX_SAM_ENTRIES ] ;
int num_rids = q_u - > num_sids1 ;
r_u - > status = NT_STATUS_NOPROBLEMO ;
DEBUG ( 5 , ( " _samr_lookup_ids: %d \n " , __LINE__ ) ) ;
if ( num_rids > MAX_SAM_ENTRIES ) {
num_rids = MAX_SAM_ENTRIES ;
DEBUG ( 5 , ( " _samr_lookup_ids: truncating entries to %d \n " , num_rids ) ) ;
}
#if 0
int i ;
SMB_ASSERT_ARRAY ( q_u - > uni_user_name , num_rids ) ;
for ( i = 0 ; i < num_rids & & status = = 0 ; i + + )
{
struct sam_passwd * sam_pass ;
fstring user_name ;
fstrcpy ( user_name , unistrn2 ( q_u - > uni_user_name [ i ] . buffer ,
q_u - > uni_user_name [ i ] . uni_str_len ) ) ;
/* find the user account */
become_root ( ) ;
sam_pass = get_smb21pwd_entry ( user_name , 0 ) ;
unbecome_root ( ) ;
if ( sam_pass = = NULL )
{
status = 0xC0000000 | NT_STATUS_NO_SUCH_USER ;
rid [ i ] = 0 ;
}
else
{
rid [ i ] = sam_pass - > user_rid ;
}
}
# endif
num_rids = 1 ;
rid [ 0 ] = BUILTIN_ALIAS_RID_USERS ;
init_samr_r_lookup_ids ( & r_u , num_rids , rid , NT_STATUS_NOPROBLEMO ) ;
DEBUG ( 5 , ( " _samr_lookup_ids: %d \n " , __LINE__ ) ) ;
return r_u - > status ;
}
# endif
/*******************************************************************
_samr_lookup_names
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_lookup_names ( pipes_struct * p , SAMR_Q_LOOKUP_NAMES * q_u , SAMR_R_LOOKUP_NAMES * r_u )
{
uint32 rid [ MAX_SAM_ENTRIES ] ;
enum SID_NAME_USE type [ MAX_SAM_ENTRIES ] ;
int i ;
int num_rids = q_u - > num_names1 ;
DOM_SID pol_sid ;
r_u - > status = NT_STATUS_NOPROBLEMO ;
DEBUG ( 5 , ( " _samr_lookup_names: %d \n " , __LINE__ ) ) ;
ZERO_ARRAY ( rid ) ;
ZERO_ARRAY ( type ) ;
2001-03-11 03:32:10 +03:00
if ( ! get_lsa_policy_samr_sid ( p , & q_u - > pol , & pol_sid ) ) {
2001-02-27 21:22:39 +03:00
init_samr_r_lookup_names ( p - > mem_ctx , r_u , 0 , NULL , NULL , NT_STATUS_OBJECT_TYPE_MISMATCH ) ;
return r_u - > status ;
}
if ( num_rids > MAX_SAM_ENTRIES ) {
num_rids = MAX_SAM_ENTRIES ;
DEBUG ( 5 , ( " _samr_lookup_names: truncating entries to %d \n " , num_rids ) ) ;
}
SMB_ASSERT_ARRAY ( q_u - > uni_name , num_rids ) ;
for ( i = 0 ; i < num_rids ; i + + ) {
fstring name ;
r_u - > status = NT_STATUS_NONE_MAPPED ;
rid [ i ] = 0xffffffff ;
type [ i ] = SID_NAME_UNKNOWN ;
2001-03-15 03:49:13 +03:00
fstrcpy ( name , dos_unistrn2 ( q_u - > uni_name [ i ] . buffer , q_u - > uni_name [ i ] . uni_str_len ) ) ;
2001-02-27 21:22:39 +03:00
if ( sid_equal ( & pol_sid , & global_sam_sid ) ) {
DOM_SID sid ;
if ( local_lookup_name ( global_myname , name , & sid , & type [ i ] ) ) {
sid_split_rid ( & sid , & rid [ i ] ) ;
r_u - > status = NT_STATUS_NOPROBLEMO ;
}
}
}
2001-03-11 03:32:10 +03:00
init_samr_r_lookup_names ( p - > mem_ctx , r_u , num_rids , rid , ( uint32 * ) type , r_u - > status ) ;
2001-02-27 21:22:39 +03:00
DEBUG ( 5 , ( " _samr_lookup_names: %d \n " , __LINE__ ) ) ;
return r_u - > status ;
}
/*******************************************************************
_samr_chgpasswd_user
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_chgpasswd_user ( pipes_struct * p , SAMR_Q_CHGPASSWD_USER * q_u , SAMR_R_CHGPASSWD_USER * r_u )
{
fstring user_name ;
fstring wks ;
DEBUG ( 5 , ( " _samr_chgpasswd_user: %d \n " , __LINE__ ) ) ;
r_u - > status = NT_STATUS_NOPROBLEMO ;
2001-03-15 03:49:13 +03:00
fstrcpy ( user_name , dos_unistrn2 ( q_u - > uni_user_name . buffer , q_u - > uni_user_name . uni_str_len ) ) ;
fstrcpy ( wks , dos_unistrn2 ( q_u - > uni_dest_host . buffer , q_u - > uni_dest_host . uni_str_len ) ) ;
2001-02-27 21:22:39 +03:00
DEBUG ( 5 , ( " samr_chgpasswd_user: user: %s wks: %s \n " , user_name , wks ) ) ;
2001-04-16 02:29:36 +04:00
/*
* Pass the user through the NT - > unix user mapping
* function .
*/
( void ) map_username ( user_name ) ;
/*
* Do any UNIX username case mangling .
*/
( void ) Get_Pwnam ( user_name , True ) ;
2001-02-27 21:22:39 +03:00
if ( ! pass_oem_change ( user_name , q_u - > lm_newpass . pass , q_u - > lm_oldhash . hash ,
q_u - > nt_newpass . pass , q_u - > nt_oldhash . hash ) )
r_u - > status = NT_STATUS_WRONG_PASSWORD ;
init_samr_r_chgpasswd_user ( r_u , r_u - > status ) ;
DEBUG ( 5 , ( " _samr_chgpasswd_user: %d \n " , __LINE__ ) ) ;
return r_u - > status ;
}
/*******************************************************************
makes a SAMR_R_LOOKUP_RIDS structure .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL make_samr_lookup_rids ( TALLOC_CTX * ctx , uint32 num_names , fstring names [ ] ,
UNIHDR * * pp_hdr_name , UNISTR2 * * pp_uni_name )
{
uint32 i ;
2001-03-23 03:50:31 +03:00
UNIHDR * hdr_name = NULL ;
UNISTR2 * uni_name = NULL ;
2001-02-27 21:22:39 +03:00
* pp_uni_name = NULL ;
* pp_hdr_name = NULL ;
if ( num_names ! = 0 ) {
hdr_name = ( UNIHDR * ) talloc ( ctx , sizeof ( UNIHDR ) * num_names ) ;
if ( hdr_name = = NULL )
return False ;
uni_name = ( UNISTR2 * ) talloc ( ctx , sizeof ( UNISTR2 ) * num_names ) ;
if ( uni_name = = NULL )
return False ;
}
for ( i = 0 ; i < num_names ; i + + ) {
int len = names [ i ] ! = NULL ? strlen ( names [ i ] ) : 0 ;
DEBUG ( 10 , ( " names[%d]:%s \n " , i , names [ i ] ) ) ;
init_uni_hdr ( & hdr_name [ i ] , len ) ;
init_unistr2 ( & uni_name [ i ] , names [ i ] , len ) ;
}
* pp_uni_name = uni_name ;
* pp_hdr_name = hdr_name ;
return True ;
}
/*******************************************************************
_samr_lookup_rids
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_lookup_rids ( pipes_struct * p , SAMR_Q_LOOKUP_RIDS * q_u , SAMR_R_LOOKUP_RIDS * r_u )
{
fstring group_names [ MAX_SAM_ENTRIES ] ;
uint32 group_attrs [ MAX_SAM_ENTRIES ] ;
UNIHDR * hdr_name = NULL ;
UNISTR2 * uni_name = NULL ;
DOM_SID pol_sid ;
int num_rids = q_u - > num_rids1 ;
int i ;
r_u - > status = NT_STATUS_NOPROBLEMO ;
DEBUG ( 5 , ( " _samr_lookup_rids: %d \n " , __LINE__ ) ) ;
/* find the policy handle. open a policy on it. */
2001-03-11 03:32:10 +03:00
if ( ! get_lsa_policy_samr_sid ( p , & q_u - > pol , & pol_sid ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_INVALID_HANDLE ;
if ( num_rids > MAX_SAM_ENTRIES ) {
num_rids = MAX_SAM_ENTRIES ;
DEBUG ( 5 , ( " _samr_lookup_rids: truncating entries to %d \n " , num_rids ) ) ;
}
r_u - > status = NT_STATUS_NONE_MAPPED ;
for ( i = 0 ; i < num_rids ; i + + ) {
fstring tmpname ;
fstring domname ;
DOM_SID sid ;
enum SID_NAME_USE type ;
group_attrs [ i ] = SID_NAME_UNKNOWN ;
* group_names [ i ] = ' \0 ' ;
if ( sid_equal ( & pol_sid , & global_sam_sid ) ) {
sid_copy ( & sid , & pol_sid ) ;
sid_append_rid ( & sid , q_u - > rid [ i ] ) ;
if ( lookup_sid ( & sid , domname , tmpname , & type ) ) {
r_u - > status = NT_STATUS_NOPROBLEMO ;
group_attrs [ i ] = ( uint32 ) type ;
fstrcpy ( group_names [ i ] , tmpname ) ;
}
}
}
if ( ! make_samr_lookup_rids ( p - > mem_ctx , num_rids , group_names , & hdr_name , & uni_name ) )
return NT_STATUS_NO_MEMORY ;
init_samr_r_lookup_rids ( r_u , num_rids , hdr_name , uni_name , group_attrs ) ;
DEBUG ( 5 , ( " _samr_lookup_rids: %d \n " , __LINE__ ) ) ;
return r_u - > status ;
}
/*******************************************************************
2001-03-13 03:32:43 +03:00
_api_samr_open_user . Safe - gives out no passwd info .
2001-02-27 21:22:39 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _api_samr_open_user ( pipes_struct * p , SAMR_Q_OPEN_USER * q_u , SAMR_R_OPEN_USER * r_u )
{
2001-05-04 19:44:27 +04:00
SAM_ACCOUNT * sampass = NULL ;
DOM_SID sid ;
POLICY_HND domain_pol = q_u - > domain_pol ;
uint32 user_rid = q_u - > user_rid ;
POLICY_HND * user_pol = & r_u - > user_pol ;
2001-03-11 03:32:10 +03:00
struct samr_info * info = NULL ;
2001-05-04 19:44:27 +04:00
BOOL ret ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
r_u - > status = NT_STATUS_NO_PROBLEMO ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
/* find the domain policy handle. */
if ( ! find_policy_by_hnd ( p , & domain_pol , NULL ) )
return NT_STATUS_INVALID_HANDLE ;
2001-02-27 21:22:39 +03:00
2001-05-08 20:33:18 +04:00
pdb_init_sam ( & sampass ) ;
2001-05-04 19:44:27 +04:00
become_root ( ) ;
ret = pdb_getsampwrid ( sampass , user_rid ) ;
unbecome_root ( ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
/* check that the RID exists in our domain. */
if ( ret = = False ) {
2001-05-07 18:04:46 +04:00
pdb_free_sam ( sampass ) ;
2001-05-04 19:44:27 +04:00
return NT_STATUS_NO_SUCH_USER ;
}
2001-02-27 21:22:39 +03:00
2001-03-13 03:32:43 +03:00
samr_clear_sam_passwd ( sampass ) ;
2001-05-07 18:04:46 +04:00
pdb_free_sam ( sampass ) ;
2001-03-13 03:32:43 +03:00
2001-05-04 19:44:27 +04:00
/* Get the domain SID stored in the domain policy */
if ( ! get_lsa_policy_samr_sid ( p , & domain_pol , & sid ) )
return NT_STATUS_INVALID_HANDLE ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
/* append the user's RID to it */
if ( ! sid_append_rid ( & sid , user_rid ) )
return NT_STATUS_NO_SUCH_USER ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
/* associate the user's SID with the new handle. */
if ( ( info = ( struct samr_info * ) malloc ( sizeof ( struct samr_info ) ) ) = = NULL )
return NT_STATUS_NO_MEMORY ;
2001-03-11 03:32:10 +03:00
2001-05-04 19:44:27 +04:00
ZERO_STRUCTP ( info ) ;
info - > sid = sid ;
2001-03-11 03:32:10 +03:00
2001-05-04 19:44:27 +04:00
/* get a (unique) handle. open a policy on it. */
if ( ! create_policy_hnd ( p , user_pol , free_samr_info , ( void * ) info ) )
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
return r_u - > status ;
2001-02-27 21:22:39 +03:00
}
/*************************************************************************
2001-03-13 03:32:43 +03:00
get_user_info_10 . Safe . Only gives out acb bits .
2001-02-27 21:22:39 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL get_user_info_10 ( SAM_USER_INFO_10 * id10 , uint32 user_rid )
{
2001-05-04 19:44:27 +04:00
SAM_ACCOUNT * smbpass = NULL ;
BOOL ret ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
if ( ! pdb_rid_is_user ( user_rid ) ) {
DEBUG ( 4 , ( " RID 0x%x is not a user RID \n " , user_rid ) ) ;
return False ;
}
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
pdb_init_sam ( & smbpass ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
become_root ( ) ;
ret = pdb_getsampwrid ( smbpass , user_rid ) ;
unbecome_root ( ) ;
if ( ret = = False ) {
DEBUG ( 4 , ( " User 0x%x not found \n " , user_rid ) ) ;
2001-05-07 18:04:46 +04:00
pdb_free_sam ( smbpass ) ;
2001-05-04 19:44:27 +04:00
return False ;
}
DEBUG ( 3 , ( " User:[%s] \n " , pdb_get_username ( smbpass ) ) ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
init_sam_user_info10 ( id10 , pdb_get_acct_ctrl ( smbpass ) ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
samr_clear_sam_passwd ( smbpass ) ;
2001-05-07 18:04:46 +04:00
pdb_free_sam ( smbpass ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
return True ;
2001-02-27 21:22:39 +03:00
}
/*************************************************************************
2001-03-13 03:32:43 +03:00
get_user_info_12 . OK - this is the killer as it gives out password info .
Ensure that this is only allowed on an encrypted connection with a root
user . JRA .
2001-02-27 21:22:39 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-13 03:32:43 +03:00
static uint32 get_user_info_12 ( pipes_struct * p , SAM_USER_INFO_12 * id12 , uint32 user_rid )
2001-02-27 21:22:39 +03:00
{
2001-05-04 19:44:27 +04:00
SAM_ACCOUNT * smbpass = NULL ;
BOOL ret ;
2001-02-27 21:22:39 +03:00
2001-03-13 03:32:43 +03:00
if ( ! p - > ntlmssp_auth_validated )
return NT_STATUS_ACCESS_DENIED ;
if ( ! ( p - > ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN ) | | ! ( p - > ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL ) )
return NT_STATUS_ACCESS_DENIED ;
/*
* Do * NOT * do become_root ( ) / unbecome_root ( ) here ! JRA .
*/
2001-05-04 19:44:27 +04:00
pdb_init_sam ( & smbpass ) ;
2001-03-13 03:32:43 +03:00
2001-05-04 19:44:27 +04:00
ret = pdb_getsampwrid ( smbpass , user_rid ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
if ( ret = = False ) {
2001-02-27 21:22:39 +03:00
DEBUG ( 4 , ( " User 0x%x not found \n " , user_rid ) ) ;
2001-05-07 18:04:46 +04:00
pdb_free_sam ( smbpass ) ;
2001-03-13 03:32:43 +03:00
return ( geteuid ( ) = = ( uid_t ) 0 ) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED ;
2001-02-27 21:22:39 +03:00
}
2001-05-04 19:44:27 +04:00
DEBUG ( 3 , ( " User:[%s] 0x%x \n " , pdb_get_username ( smbpass ) , pdb_get_acct_ctrl ( smbpass ) ) ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
if ( pdb_get_acct_ctrl ( smbpass ) & ACB_DISABLED ) {
2001-05-07 18:04:46 +04:00
pdb_free_sam ( smbpass ) ;
2001-05-04 19:44:27 +04:00
return NT_STATUS_ACCOUNT_DISABLED ;
}
2001-02-27 21:22:39 +03:00
2001-03-11 03:32:10 +03:00
init_sam_user_info12 ( id12 , pdb_get_lanman_passwd ( smbpass ) , pdb_get_nt_passwd ( smbpass ) ) ;
2001-05-04 19:44:27 +04:00
2001-05-07 18:04:46 +04:00
pdb_free_sam ( smbpass ) ;
2001-02-27 21:22:39 +03:00
2001-03-13 03:32:43 +03:00
return NT_STATUS_NOPROBLEMO ;
2001-02-27 21:22:39 +03:00
}
/*************************************************************************
get_user_info_21
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL get_user_info_21 ( SAM_USER_INFO_21 * id21 , uint32 user_rid )
{
2001-05-04 19:44:27 +04:00
SAM_ACCOUNT * sampass = NULL ;
BOOL ret ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
if ( ! pdb_rid_is_user ( user_rid ) ) {
DEBUG ( 4 , ( " RID 0x%x is not a user RID \n " , user_rid ) ) ;
return False ;
}
2001-02-27 21:22:39 +03:00
2001-05-08 20:33:18 +04:00
pdb_init_sam ( & sampass ) ;
2001-05-04 19:44:27 +04:00
become_root ( ) ;
ret = pdb_getsampwrid ( sampass , user_rid ) ;
unbecome_root ( ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
if ( ret = = False ) {
DEBUG ( 4 , ( " User 0x%x not found \n " , user_rid ) ) ;
2001-05-07 18:04:46 +04:00
pdb_free_sam ( sampass ) ;
2001-05-04 19:44:27 +04:00
return False ;
}
2001-02-27 21:22:39 +03:00
2001-03-13 03:32:43 +03:00
samr_clear_sam_passwd ( sampass ) ;
2001-05-04 19:44:27 +04:00
DEBUG ( 3 , ( " User:[%s] \n " , pdb_get_username ( sampass ) ) ) ;
2001-03-11 03:32:10 +03:00
init_sam_user_info21A ( id21 , sampass ) ;
2001-05-04 19:44:27 +04:00
2001-05-07 18:04:46 +04:00
pdb_free_sam ( sampass ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
return True ;
2001-02-27 21:22:39 +03:00
}
/*******************************************************************
_samr_query_userinfo
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_query_userinfo ( pipes_struct * p , SAMR_Q_QUERY_USERINFO * q_u , SAMR_R_QUERY_USERINFO * r_u )
{
SAM_USERINFO_CTR * ctr ;
uint32 rid = 0 ;
2001-03-11 03:32:10 +03:00
struct samr_info * info = NULL ;
2001-02-27 21:22:39 +03:00
r_u - > status = NT_STATUS_NO_PROBLEMO ;
/* search for the handle */
2001-03-11 03:32:10 +03:00
if ( ! find_policy_by_hnd ( p , & q_u - > pol , ( void * * ) & info ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_INVALID_HANDLE ;
/* find the user's rid */
2001-03-11 03:32:10 +03:00
if ( ( rid = get_lsa_policy_samr_rid ( info ) ) = = 0xffffffff )
2001-02-27 21:22:39 +03:00
return NT_STATUS_OBJECT_TYPE_MISMATCH ;
DEBUG ( 5 , ( " _samr_query_userinfo: rid:0x%x \n " , rid ) ) ;
ctr = ( SAM_USERINFO_CTR * ) talloc ( p - > mem_ctx , sizeof ( SAM_USERINFO_CTR ) ) ;
if ( ! ctr )
return NT_STATUS_NO_MEMORY ;
ZERO_STRUCTP ( ctr ) ;
/* ok! user info levels (lots: see MSDEV help), off we go... */
ctr - > switch_value = q_u - > switch_value ;
switch ( q_u - > switch_value ) {
case 0x10 :
ctr - > info . id10 = ( SAM_USER_INFO_10 * ) talloc ( p - > mem_ctx , sizeof ( SAM_USER_INFO_10 ) ) ;
if ( ctr - > info . id10 = = NULL )
return NT_STATUS_NO_MEMORY ;
if ( ! get_user_info_10 ( ctr - > info . id10 , rid ) )
return NT_STATUS_NO_SUCH_USER ;
break ;
#if 0
/* whoops - got this wrong. i think. or don't understand what's happening. */
case 0x11 :
{
NTTIME expire ;
info = ( void * ) & id11 ;
expire . low = 0xffffffff ;
expire . high = 0x7fffffff ;
ctr - > info . id = ( SAM_USER_INFO_11 * ) talloc ( p - > mem_ctx ,
sizeof
( * ctr - >
info .
id11 ) ) ;
init_sam_user_info11 ( ctr - > info . id11 , & expire ,
" BROOKFIELDS$ " , /* name */
0x03ef , /* user rid */
0x201 , /* group rid */
0x0080 ) ; /* acb info */
break ;
}
# endif
case 0x12 :
ctr - > info . id12 = ( SAM_USER_INFO_12 * ) talloc ( p - > mem_ctx , sizeof ( SAM_USER_INFO_12 ) ) ;
if ( ctr - > info . id12 = = NULL )
return NT_STATUS_NO_MEMORY ;
2001-03-13 03:32:43 +03:00
if ( ( r_u - > status = get_user_info_12 ( p , ctr - > info . id12 , rid ) ) ! = NT_STATUS_NOPROBLEMO )
return r_u - > status ;
2001-02-27 21:22:39 +03:00
break ;
case 21 :
ctr - > info . id21 = ( SAM_USER_INFO_21 * ) talloc ( p - > mem_ctx , sizeof ( SAM_USER_INFO_21 ) ) ;
if ( ctr - > info . id21 = = NULL )
return NT_STATUS_NO_MEMORY ;
if ( ! get_user_info_21 ( ctr - > info . id21 , rid ) )
return NT_STATUS_NO_SUCH_USER ;
break ;
default :
return NT_STATUS_INVALID_INFO_CLASS ;
}
init_samr_r_query_userinfo ( r_u , ctr , r_u - > status ) ;
DEBUG ( 5 , ( " _samr_query_userinfo: %d \n " , __LINE__ ) ) ;
return r_u - > status ;
}
/*******************************************************************
samr_reply_query_usergroups
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_query_usergroups ( pipes_struct * p , SAMR_Q_QUERY_USERGROUPS * q_u , SAMR_R_QUERY_USERGROUPS * r_u )
{
2001-05-04 19:44:27 +04:00
struct sam_passwd * sam_pass = NULL ;
DOM_GID * gids = NULL ;
int num_groups = 0 ;
pstring groups ;
uint32 rid ;
2001-03-11 03:32:10 +03:00
struct samr_info * info = NULL ;
2001-05-04 19:44:27 +04:00
BOOL ret ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
r_u - > status = NT_STATUS_NO_PROBLEMO ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
DEBUG ( 5 , ( " _samr_query_usergroups: %d \n " , __LINE__ ) ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
/* find the policy handle. open a policy on it. */
if ( ! find_policy_by_hnd ( p , & q_u - > pol , ( void * * ) & info ) )
return NT_STATUS_INVALID_HANDLE ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
/* find the user's rid */
if ( ( rid = get_lsa_policy_samr_rid ( info ) ) = = 0xffffffff )
return NT_STATUS_OBJECT_TYPE_MISMATCH ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
pdb_init_sam ( & sam_pass ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
become_root ( ) ;
ret = pdb_getsampwrid ( sam_pass , rid ) ;
unbecome_root ( ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
if ( ret = = False ) {
samr_clear_sam_passwd ( sam_pass ) ;
return NT_STATUS_NO_SUCH_USER ;
}
2001-03-13 03:32:43 +03:00
2001-05-04 19:44:27 +04:00
get_domain_user_groups ( groups , pdb_get_username ( sam_pass ) ) ;
gids = NULL ;
num_groups = make_dom_gids ( p - > mem_ctx , groups , & gids ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
/* construct the response. lkclXXXX: gids are not copied! */
init_samr_r_query_usergroups ( r_u , num_groups , gids , r_u - > status ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
DEBUG ( 5 , ( " _samr_query_usergroups: %d \n " , __LINE__ ) ) ;
samr_clear_sam_passwd ( sam_pass ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
return r_u - > status ;
2001-02-27 21:22:39 +03:00
}
/*******************************************************************
_samr_query_dom_info
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_query_dom_info ( pipes_struct * p , SAMR_Q_QUERY_DOMAIN_INFO * q_u , SAMR_R_QUERY_DOMAIN_INFO * r_u )
{
SAM_UNK_CTR * ctr ;
if ( ( ctr = ( SAM_UNK_CTR * ) talloc ( p - > mem_ctx , sizeof ( SAM_UNK_CTR ) ) ) = = NULL )
return NT_STATUS_NO_MEMORY ;
ZERO_STRUCTP ( ctr ) ;
r_u - > status = NT_STATUS_NO_PROBLEMO ;
DEBUG ( 5 , ( " _samr_query_dom_info: %d \n " , __LINE__ ) ) ;
/* find the policy handle. open a policy on it. */
2001-03-11 03:32:10 +03:00
if ( ! find_policy_by_hnd ( p , & q_u - > domain_pol , NULL ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_INVALID_HANDLE ;
switch ( q_u - > switch_value ) {
case 0x01 :
init_unk_info1 ( & ctr - > info . inf1 ) ;
break ;
case 0x02 :
/* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
init_unk_info2 ( & ctr - > info . inf2 , global_myworkgroup , global_myname , ( uint32 ) time ( NULL ) ) ;
break ;
case 0x03 :
init_unk_info3 ( & ctr - > info . inf3 ) ;
break ;
case 0x06 :
init_unk_info6 ( & ctr - > info . inf6 ) ;
break ;
case 0x07 :
init_unk_info7 ( & ctr - > info . inf7 ) ;
break ;
case 0x0c :
init_unk_info12 ( & ctr - > info . inf12 ) ;
break ;
default :
return NT_STATUS_INVALID_INFO_CLASS ;
}
init_samr_r_query_dom_info ( r_u , q_u - > switch_value , ctr , NT_STATUS_NOPROBLEMO ) ;
DEBUG ( 5 , ( " _samr_query_dom_info: %d \n " , __LINE__ ) ) ;
return r_u - > status ;
}
/*******************************************************************
_api_samr_create_user
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _api_samr_create_user ( pipes_struct * p , SAMR_Q_CREATE_USER * q_u , SAMR_R_CREATE_USER * r_u )
{
2001-05-04 19:44:27 +04:00
SAM_ACCOUNT * sam_pass = NULL ;
fstring mach_acct ;
pstring err_str ;
pstring msg_str ;
int local_flags = 0 ;
DOM_SID sid ;
pstring add_script ;
POLICY_HND dom_pol = q_u - > domain_pol ;
UNISTR2 user_account = q_u - > uni_name ;
uint16 acb_info = q_u - > acb_info ;
POLICY_HND * user_pol = & r_u - > user_pol ;
2001-03-11 03:32:10 +03:00
struct samr_info * info = NULL ;
2001-05-04 19:44:27 +04:00
BOOL ret ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
/* find the policy handle. open a policy on it. */
if ( ! find_policy_by_hnd ( p , & dom_pol , NULL ) )
return NT_STATUS_INVALID_HANDLE ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
/* find the machine account: tell the caller if it exists.
lkclXXXX i have * no * idea if this is a problem or not
or even if you are supposed to construct a different
reply if the account already exists . . .
*/
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
fstrcpy ( mach_acct , dos_unistrn2 ( user_account . buffer , user_account . uni_str_len ) ) ;
strlower ( mach_acct ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
pdb_init_sam ( & sam_pass ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
become_root ( ) ;
ret = pdb_getsampwnam ( sam_pass , mach_acct ) ;
unbecome_root ( ) ;
if ( ret = = True ) {
/* machine account exists: say so */
2001-05-07 18:04:46 +04:00
pdb_free_sam ( sam_pass ) ;
2001-05-04 19:44:27 +04:00
return NT_STATUS_USER_EXISTS ;
}
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
local_flags = LOCAL_ADD_USER | LOCAL_DISABLE_USER | LOCAL_SET_NO_PASSWORD ;
local_flags | = ( acb_info & ACB_WSTRUST ) ? LOCAL_TRUST_ACCOUNT : 0 ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
/*
* NB . VERY IMPORTANT ! This call must be done as the current pipe user ,
* * NOT * surrounded by a become_root ( ) / unbecome_root ( ) call . This ensures
* that only people with write access to the smbpasswd file will be able
* to create a user . JRA .
*/
2001-03-11 03:32:10 +03:00
2001-05-04 19:44:27 +04:00
/*
* add the user in the / etc / passwd file or the unix authority system .
* We don ' t check if the smb_create_user ( ) function succed or not for 2 reasons :
* a ) local_password_change ( ) checks for us if the / etc / passwd account really exists
* b ) smb_create_user ( ) would return an error if the account already exists
* and as it could return an error also if it can ' t create the account , it would be tricky .
*
* So we go the easy way , only check after if the account exists .
* JFM ( 2 / 3 / 2001 ) , to clear any possible bad understanding ( - :
*/
2001-03-11 03:32:10 +03:00
2001-05-04 19:44:27 +04:00
pstrcpy ( add_script , lp_adduser_script ( ) ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
if ( * add_script )
smb_create_user ( mach_acct , NULL ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
/* add the user in the smbpasswd file or the Samba authority database */
if ( ! local_password_change ( mach_acct , local_flags , NULL , err_str ,
sizeof ( err_str ) , msg_str , sizeof ( msg_str ) ) ) {
DEBUG ( 0 , ( " %s \n " , err_str ) ) ;
close_policy_hnd ( p , user_pol ) ;
2001-05-07 18:04:46 +04:00
pdb_free_sam ( sam_pass ) ;
2001-05-04 19:44:27 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
become_root ( ) ;
ret = pdb_getsampwnam ( sam_pass , mach_acct ) ;
unbecome_root ( ) ;
if ( ret = = False ) {
/* account doesn't exist: say so */
close_policy_hnd ( p , user_pol ) ;
2001-05-07 18:04:46 +04:00
pdb_free_sam ( sam_pass ) ;
2001-05-04 19:44:27 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
/* Get the domain SID stored in the domain policy */
if ( ! get_lsa_policy_samr_sid ( p , & dom_pol , & sid ) ) {
close_policy_hnd ( p , user_pol ) ;
2001-05-07 18:04:46 +04:00
pdb_free_sam ( sam_pass ) ;
2001-05-04 19:44:27 +04:00
return NT_STATUS_INVALID_HANDLE ;
}
/* append the user's RID to it */
if ( ! sid_append_rid ( & sid , pdb_get_user_rid ( sam_pass ) ) ) {
close_policy_hnd ( p , user_pol ) ;
2001-05-07 18:04:46 +04:00
pdb_free_sam ( sam_pass ) ;
2001-05-04 19:44:27 +04:00
return NT_STATUS_NO_SUCH_USER ;
}
/* associate the user's SID with the new handle. */
if ( ( info = ( struct samr_info * ) malloc ( sizeof ( struct samr_info ) ) ) = = NULL ) {
2001-05-07 18:04:46 +04:00
pdb_free_sam ( sam_pass ) ;
2001-05-04 19:44:27 +04:00
return NT_STATUS_NO_MEMORY ;
}
ZERO_STRUCTP ( info ) ;
info - > sid = sid ;
/* get a (unique) handle. open a policy on it. */
if ( ! create_policy_hnd ( p , user_pol , free_samr_info , ( void * ) info ) ) {
2001-05-07 18:04:46 +04:00
pdb_free_sam ( sam_pass ) ;
2001-05-04 19:44:27 +04:00
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
r_u - > user_rid = sam_pass - > user_rid ;
r_u - > unknown_0 = 0x000703ff ;
2001-05-07 18:04:46 +04:00
pdb_free_sam ( sam_pass ) ;
2001-05-04 19:44:27 +04:00
return NT_STATUS_NO_PROBLEMO ;
2001-02-27 21:22:39 +03:00
}
/*******************************************************************
samr_reply_connect_anon
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_connect_anon ( pipes_struct * p , SAMR_Q_CONNECT_ANON * q_u , SAMR_R_CONNECT_ANON * r_u )
{
2001-03-11 03:32:10 +03:00
struct samr_info * info = NULL ;
2001-02-27 21:22:39 +03:00
/* set up the SAMR connect_anon response */
r_u - > status = NT_STATUS_NO_PROBLEMO ;
2001-03-11 03:32:10 +03:00
/* associate the user's SID with the new handle. */
if ( ( info = ( struct samr_info * ) malloc ( sizeof ( struct samr_info ) ) ) = = NULL )
return NT_STATUS_NO_MEMORY ;
ZERO_STRUCTP ( info ) ;
info - > status = q_u - > unknown_0 ;
2001-02-27 21:22:39 +03:00
2001-03-11 03:32:10 +03:00
/* get a (unique) handle. open a policy on it. */
if ( ! create_policy_hnd ( p , & r_u - > connect_pol , free_samr_info , ( void * ) info ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
return r_u - > status ;
}
/*******************************************************************
samr_reply_connect
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_connect ( pipes_struct * p , SAMR_Q_CONNECT * q_u , SAMR_R_CONNECT * r_u )
{
2001-03-11 03:32:10 +03:00
struct samr_info * info = NULL ;
2001-02-27 21:22:39 +03:00
DEBUG ( 5 , ( " _samr_connect: %d \n " , __LINE__ ) ) ;
r_u - > status = NT_STATUS_NO_PROBLEMO ;
2001-03-11 03:32:10 +03:00
/* associate the user's SID with the new handle. */
if ( ( info = ( struct samr_info * ) malloc ( sizeof ( struct samr_info ) ) ) = = NULL )
return NT_STATUS_NO_MEMORY ;
ZERO_STRUCTP ( info ) ;
info - > status = q_u - > access_mask ;
2001-02-27 21:22:39 +03:00
2001-03-11 03:32:10 +03:00
/* get a (unique) handle. open a policy on it. */
if ( ! create_policy_hnd ( p , & r_u - > connect_pol , free_samr_info , ( void * ) info ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
DEBUG ( 5 , ( " _samr_connect: %d \n " , __LINE__ ) ) ;
return r_u - > status ;
}
/**********************************************************************
api_samr_lookup_domain
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_lookup_domain ( pipes_struct * p , SAMR_Q_LOOKUP_DOMAIN * q_u , SAMR_R_LOOKUP_DOMAIN * r_u )
{
r_u - > status = NT_STATUS_NO_PROBLEMO ;
2001-03-11 03:32:10 +03:00
if ( ! find_policy_by_hnd ( p , & q_u - > connect_pol , NULL ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_INVALID_HANDLE ;
/* assume the domain name sent is our global_myname and
send global_sam_sid */
init_samr_r_lookup_domain ( r_u , & global_sam_sid , r_u - > status ) ;
return r_u - > status ;
}
/******************************************************************
makes a SAMR_R_ENUM_DOMAINS structure .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL make_enum_domains ( TALLOC_CTX * ctx , SAM_ENTRY * * pp_sam ,
UNISTR2 * * pp_uni_name , uint32 num_sam_entries , fstring doms [ ] )
{
uint32 i ;
SAM_ENTRY * sam ;
UNISTR2 * uni_name ;
DEBUG ( 5 , ( " make_enum_domains \n " ) ) ;
* pp_sam = NULL ;
* pp_uni_name = NULL ;
if ( num_sam_entries = = 0 )
return True ;
sam = ( SAM_ENTRY * ) talloc ( ctx , sizeof ( SAM_ENTRY ) * num_sam_entries ) ;
uni_name = ( UNISTR2 * ) talloc ( ctx , sizeof ( UNISTR2 ) * num_sam_entries ) ;
if ( sam = = NULL | | uni_name = = NULL )
return False ;
for ( i = 0 ; i < num_sam_entries ; i + + ) {
int len = doms [ i ] ! = NULL ? strlen ( doms [ i ] ) : 0 ;
init_sam_entry ( & sam [ i ] , len , 0 ) ;
init_unistr2 ( & uni_name [ i ] , doms [ i ] , len ) ;
}
* pp_sam = sam ;
* pp_uni_name = uni_name ;
return True ;
}
/**********************************************************************
api_samr_enum_domains
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_enum_domains ( pipes_struct * p , SAMR_Q_ENUM_DOMAINS * q_u , SAMR_R_ENUM_DOMAINS * r_u )
{
uint32 num_entries = 2 ;
fstring dom [ 2 ] ;
r_u - > status = NT_STATUS_NO_PROBLEMO ;
fstrcpy ( dom [ 0 ] , global_myworkgroup ) ;
fstrcpy ( dom [ 1 ] , " Builtin " ) ;
if ( ! make_enum_domains ( p - > mem_ctx , & r_u - > sam , & r_u - > uni_dom_name , num_entries , dom ) )
return NT_STATUS_NO_MEMORY ;
init_samr_r_enum_domains ( r_u , q_u - > start_idx + num_entries , num_entries ) ;
return r_u - > status ;
}
/*******************************************************************
api_samr_open_alias
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _api_samr_open_alias ( pipes_struct * p , SAMR_Q_OPEN_ALIAS * q_u , SAMR_R_OPEN_ALIAS * r_u )
{
DOM_SID sid ;
POLICY_HND domain_pol = q_u - > dom_pol ;
uint32 alias_rid = q_u - > rid_alias ;
POLICY_HND * alias_pol = & r_u - > pol ;
2001-03-11 03:32:10 +03:00
struct samr_info * info = NULL ;
2001-02-27 21:22:39 +03:00
r_u - > status = NT_STATUS_NO_PROBLEMO ;
/* get the domain policy. */
2001-03-11 03:32:10 +03:00
if ( ! find_policy_by_hnd ( p , & domain_pol , NULL ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_INVALID_HANDLE ;
/* Get the domain SID stored in the domain policy */
2001-03-11 03:32:10 +03:00
if ( ! get_lsa_policy_samr_sid ( p , & domain_pol , & sid ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_INVALID_HANDLE ;
2001-03-11 03:32:10 +03:00
/* append the alias' RID to it */
if ( ! sid_append_rid ( & sid , alias_rid ) )
return NT_STATUS_NO_SUCH_USER ;
2001-02-27 21:22:39 +03:00
/*
* we should check if the rid really exist ! ! !
* JFM .
*/
2001-03-11 03:32:10 +03:00
/* associate the user's SID with the new handle. */
if ( ( info = ( struct samr_info * ) malloc ( sizeof ( struct samr_info ) ) ) = = NULL )
return NT_STATUS_NO_MEMORY ;
2001-02-27 21:22:39 +03:00
2001-03-11 03:32:10 +03:00
ZERO_STRUCTP ( info ) ;
info - > sid = sid ;
2001-02-27 21:22:39 +03:00
2001-03-11 03:32:10 +03:00
/* get a (unique) handle. open a policy on it. */
if ( ! create_policy_hnd ( p , alias_pol , free_samr_info , ( void * ) info ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
return r_u - > status ;
}
/*******************************************************************
set_user_info_10
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL set_user_info_10 ( const SAM_USER_INFO_10 * id10 , uint32 rid )
{
2001-05-04 19:44:27 +04:00
SAM_ACCOUNT * pwd = NULL ;
BOOL ret ;
pdb_init_sam ( & pwd ) ;
ret = pdb_getsampwrid ( pwd , rid ) ;
if ( ret = = False ) {
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
2001-05-04 19:44:27 +04:00
return False ;
}
2001-02-27 21:22:39 +03:00
if ( id10 = = NULL ) {
DEBUG ( 5 , ( " set_user_info_10: NULL id10 \n " ) ) ;
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
2001-02-27 21:22:39 +03:00
return False ;
}
2001-03-11 03:32:10 +03:00
pdb_set_acct_ctrl ( pwd , id10 - > acb_info ) ;
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
if ( ! pdb_update_sam_account ( pwd , True ) ) {
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
2001-02-27 21:22:39 +03:00
return False ;
2001-05-04 19:44:27 +04:00
}
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
2001-02-27 21:22:39 +03:00
return True ;
}
/*******************************************************************
set_user_info_12
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL set_user_info_12 ( SAM_USER_INFO_12 * id12 , uint32 rid )
{
2001-05-04 19:44:27 +04:00
SAM_ACCOUNT * pwd = NULL ;
pdb_init_sam ( & pwd ) ;
if ( ! pdb_getsampwrid ( pwd , rid ) ) {
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
2001-02-27 21:22:39 +03:00
return False ;
2001-05-04 19:44:27 +04:00
}
2001-02-27 21:22:39 +03:00
if ( id12 = = NULL ) {
DEBUG ( 2 , ( " set_user_info_12: id12 is NULL \n " ) ) ;
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
2001-02-27 21:22:39 +03:00
return False ;
}
2001-03-11 03:32:10 +03:00
pdb_set_lanman_passwd ( pwd , id12 - > lm_pwd ) ;
pdb_set_nt_passwd ( pwd , id12 - > nt_pwd ) ;
2001-05-04 19:44:27 +04:00
if ( ! pdb_update_sam_account ( pwd , True ) ) {
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
2001-02-27 21:22:39 +03:00
return False ;
2001-05-04 19:44:27 +04:00
}
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
2001-02-27 21:22:39 +03:00
return True ;
}
/*******************************************************************
set_user_info_21
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-03-11 03:32:10 +03:00
static BOOL set_user_info_21 ( SAM_USER_INFO_21 * id21 , uint32 rid )
2001-02-27 21:22:39 +03:00
{
2001-05-04 19:44:27 +04:00
SAM_ACCOUNT * pwd = NULL ;
SAM_ACCOUNT * new_pwd = NULL ;
2001-03-11 03:32:10 +03:00
2001-02-27 21:22:39 +03:00
if ( id21 = = NULL ) {
DEBUG ( 5 , ( " set_user_info_21: NULL id21 \n " ) ) ;
return False ;
}
2001-03-11 03:32:10 +03:00
2001-05-04 19:44:27 +04:00
pdb_init_sam ( & pwd ) ;
pdb_init_sam ( & new_pwd ) ;
if ( ! pdb_getsampwrid ( pwd , rid ) ) {
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
pdb_free_sam ( new_pwd ) ;
2001-02-27 21:22:39 +03:00
return False ;
2001-05-04 19:44:27 +04:00
}
2001-03-11 03:32:10 +03:00
/* we make a copy so that we can modify stuff */
2001-05-04 19:44:27 +04:00
copy_sam_passwd ( new_pwd , pwd ) ;
copy_id21_to_sam_passwd ( new_pwd , id21 ) ;
2001-03-11 03:32:10 +03:00
/*
* The funny part about the previous two calls is
* that pwd still has the password hashes from the
* passdb entry . These have not been updated from
* id21 . I don ' t know if they need to be set . - - jerry
*/
/* write the change out */
2001-05-04 19:44:27 +04:00
if ( ! pdb_update_sam_account ( new_pwd , True ) ) {
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
pdb_free_sam ( new_pwd ) ;
2001-02-27 21:22:39 +03:00
return False ;
2001-05-04 19:44:27 +04:00
}
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
pdb_free_sam ( new_pwd ) ;
2001-05-04 19:44:27 +04:00
2001-02-27 21:22:39 +03:00
return True ;
}
/*******************************************************************
set_user_info_23
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL set_user_info_23 ( SAM_USER_INFO_23 * id23 , uint32 rid )
{
2001-05-04 19:44:27 +04:00
SAM_ACCOUNT * pwd = NULL ;
SAM_ACCOUNT * new_pwd = NULL ;
uint8 nt_hash [ 16 ] ;
uint8 lm_hash [ 16 ] ;
pstring buf ;
uint32 len ;
2001-03-11 03:32:10 +03:00
uint16 acct_ctrl ;
2001-05-04 19:44:27 +04:00
if ( id23 = = NULL ) {
DEBUG ( 5 , ( " set_user_info_23: NULL id23 \n " ) ) ;
return False ;
}
2001-03-11 03:32:10 +03:00
2001-05-04 19:44:27 +04:00
pdb_init_sam ( & pwd ) ;
pdb_init_sam ( & new_pwd ) ;
2001-03-11 03:32:10 +03:00
2001-05-11 00:05:06 +04:00
if ( ! pdb_getsampwrid ( pwd , rid ) ) {
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
pdb_free_sam ( new_pwd ) ;
2001-05-04 19:44:27 +04:00
return False ;
}
2001-02-27 21:22:39 +03:00
2001-05-04 19:44:27 +04:00
acct_ctrl = pdb_get_acct_ctrl ( pwd ) ;
copy_sam_passwd ( new_pwd , pwd ) ;
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
2001-05-04 19:44:27 +04:00
copy_id23_to_sam_passwd ( new_pwd , id23 ) ;
2001-03-11 03:32:10 +03:00
2001-05-04 19:44:27 +04:00
if ( ! decode_pw_buffer ( ( char * ) id23 - > pass , buf , 256 , & len , nt_hash , lm_hash ) ) {
2001-05-07 18:04:46 +04:00
pdb_free_sam ( new_pwd ) ;
2001-05-04 19:44:27 +04:00
return False ;
}
2001-04-22 06:54:04 +04:00
2001-05-04 19:44:27 +04:00
pdb_set_lanman_passwd ( new_pwd , lm_hash ) ;
pdb_set_nt_passwd ( new_pwd , nt_hash ) ;
2001-03-11 03:32:10 +03:00
2001-02-27 21:22:39 +03:00
/* if it's a trust account, don't update /etc/passwd */
2001-03-11 03:32:10 +03:00
if ( ( ( acct_ctrl & ACB_DOMTRUST ) = = ACB_DOMTRUST ) | |
( ( acct_ctrl & ACB_WSTRUST ) = = ACB_WSTRUST ) | |
( ( acct_ctrl & ACB_SVRTRUST ) = = ACB_SVRTRUST ) ) {
2001-02-27 21:22:39 +03:00
DEBUG ( 5 , ( " Changing trust account password, not updating /etc/passwd \n " ) ) ;
2001-03-11 03:32:10 +03:00
} else {
2001-02-27 21:22:39 +03:00
/* update the UNIX password */
if ( lp_unix_password_sync ( ) )
2001-05-04 19:44:27 +04:00
if ( ! chgpasswd ( pdb_get_username ( new_pwd ) , " " , buf , True ) ) {
2001-05-07 18:04:46 +04:00
pdb_free_sam ( new_pwd ) ;
2001-02-27 21:22:39 +03:00
return False ;
2001-05-04 19:44:27 +04:00
}
2001-02-27 21:22:39 +03:00
}
2001-03-11 03:32:10 +03:00
2001-05-04 19:44:27 +04:00
memset ( buf , 0 , sizeof ( buf ) ) ;
2001-03-11 03:32:10 +03:00
2001-05-04 19:44:27 +04:00
if ( ! pdb_update_sam_account ( new_pwd , True ) ) {
2001-05-07 18:04:46 +04:00
pdb_free_sam ( new_pwd ) ;
2001-05-04 19:44:27 +04:00
return False ;
}
2001-03-11 03:32:10 +03:00
2001-05-07 18:04:46 +04:00
pdb_free_sam ( new_pwd ) ;
2001-05-04 19:44:27 +04:00
return True ;
2001-02-27 21:22:39 +03:00
}
/*******************************************************************
set_user_info_24
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL set_user_info_24 ( SAM_USER_INFO_24 * id24 , uint32 rid )
{
2001-05-04 19:44:27 +04:00
SAM_ACCOUNT * pwd = NULL ;
2001-03-11 03:32:10 +03:00
uchar nt_hash [ 16 ] ;
uchar lm_hash [ 16 ] ;
2001-02-27 21:22:39 +03:00
uint32 len ;
pstring buf ;
2001-03-11 03:32:10 +03:00
uint16 acct_ctrl ;
2001-05-04 19:44:27 +04:00
pdb_init_sam ( & pwd ) ;
2001-03-11 03:32:10 +03:00
2001-05-04 19:44:27 +04:00
if ( ! pdb_getsampwrid ( pwd , rid ) ) {
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
2001-05-04 19:44:27 +04:00
return False ;
}
2001-03-11 03:32:10 +03:00
acct_ctrl = pdb_get_acct_ctrl ( pwd ) ;
2001-02-27 21:22:39 +03:00
2001-03-11 03:32:10 +03:00
memset ( buf , 0 , sizeof ( buf ) ) ;
2001-05-04 19:44:27 +04:00
if ( ! decode_pw_buffer ( ( char * ) id24 - > pass , buf , 256 , & len , nt_hash , lm_hash ) ) {
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
2001-02-27 21:22:39 +03:00
return False ;
2001-05-04 19:44:27 +04:00
}
2001-03-11 03:32:10 +03:00
pdb_set_lanman_passwd ( pwd , lm_hash ) ;
pdb_set_nt_passwd ( pwd , nt_hash ) ;
2001-02-27 21:22:39 +03:00
/* if it's a trust account, don't update /etc/passwd */
2001-03-11 03:32:10 +03:00
if ( ( ( acct_ctrl & ACB_DOMTRUST ) = = ACB_DOMTRUST ) | |
( ( acct_ctrl & ACB_WSTRUST ) = = ACB_WSTRUST ) | |
( ( acct_ctrl & ACB_SVRTRUST ) = = ACB_SVRTRUST ) ) {
2001-02-27 21:22:39 +03:00
DEBUG ( 5 , ( " Changing trust account password, not updating /etc/passwd \n " ) ) ;
} else {
/* update the UNIX password */
2001-03-11 03:32:10 +03:00
if ( lp_unix_password_sync ( ) )
2001-05-04 19:44:27 +04:00
if ( ! chgpasswd ( pdb_get_username ( pwd ) , " " , buf , True ) ) {
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
2001-02-27 21:22:39 +03:00
return False ;
2001-05-04 19:44:27 +04:00
}
2001-02-27 21:22:39 +03:00
}
2001-03-11 03:32:10 +03:00
2001-05-04 19:44:27 +04:00
memset ( buf , 0 , sizeof ( buf ) ) ;
2001-03-11 03:32:10 +03:00
2001-05-04 19:44:27 +04:00
DEBUG ( 0 , ( " set_user_info_24: pdb_update_sam_account() \n " ) ) ;
2001-03-11 03:32:10 +03:00
2001-05-04 19:44:27 +04:00
/* update the SAMBA password */
if ( ! pdb_update_sam_account ( pwd , True ) ) {
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
2001-05-04 19:44:27 +04:00
return False ;
}
2001-05-07 18:04:46 +04:00
pdb_free_sam ( pwd ) ;
2001-05-04 19:44:27 +04:00
return True ;
2001-02-27 21:22:39 +03:00
}
/*******************************************************************
samr_reply_set_userinfo
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_set_userinfo ( pipes_struct * p , SAMR_Q_SET_USERINFO * q_u , SAMR_R_SET_USERINFO * r_u )
{
uint32 rid = 0x0 ;
DOM_SID sid ;
struct current_user user ;
2001-05-04 19:44:27 +04:00
SAM_ACCOUNT * sam_pass = NULL ;
2001-02-27 21:22:39 +03:00
unsigned char sess_key [ 16 ] ;
POLICY_HND * pol = & q_u - > pol ;
uint16 switch_value = q_u - > switch_value ;
SAM_USERINFO_CTR * ctr = q_u - > ctr ;
2001-05-04 19:44:27 +04:00
BOOL ret ;
2001-02-27 21:22:39 +03:00
DEBUG ( 5 , ( " _samr_set_userinfo: %d \n " , __LINE__ ) ) ;
r_u - > status = NT_STATUS_NOPROBLEMO ;
if ( p - > ntlmssp_auth_validated ) {
memcpy ( & user , & p - > pipe_user , sizeof ( user ) ) ;
} else {
extern struct current_user current_user ;
memcpy ( & user , & current_user , sizeof ( user ) ) ;
}
/* find the policy handle. open a policy on it. */
2001-03-11 03:32:10 +03:00
if ( ! get_lsa_policy_samr_sid ( p , pol , & sid ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_INVALID_HANDLE ;
sid_split_rid ( & sid , & rid ) ;
DEBUG ( 5 , ( " _samr_set_userinfo: rid:0x%x, level:%d \n " , rid , switch_value ) ) ;
if ( ctr = = NULL ) {
DEBUG ( 5 , ( " _samr_set_userinfo: NULL info level \n " ) ) ;
return NT_STATUS_INVALID_INFO_CLASS ;
}
2001-05-04 19:44:27 +04:00
pdb_init_sam ( & sam_pass ) ;
2001-02-27 21:22:39 +03:00
/*
* We need the NT hash of the user who is changing the user ' s password .
* This NT hash is used to generate a " user session key "
* This " user session key " is in turn used to encrypt / decrypt the user ' s password .
*/
become_root ( ) ;
2001-05-04 19:44:27 +04:00
ret = pdb_getsampwuid ( sam_pass , user . uid ) ;
2001-02-27 21:22:39 +03:00
unbecome_root ( ) ;
2001-05-04 19:44:27 +04:00
if ( ret = = False ) {
2001-02-27 21:22:39 +03:00
DEBUG ( 0 , ( " _samr_set_userinfo: Unable to get smbpasswd entry for uid %u \n " , ( unsigned int ) user . uid ) ) ;
2001-05-07 18:04:46 +04:00
pdb_free_sam ( sam_pass ) ;
2001-02-27 21:22:39 +03:00
return NT_STATUS_ACCESS_DENIED ;
}
memset ( sess_key , ' \0 ' , 16 ) ;
2001-03-11 03:32:10 +03:00
mdfour ( sess_key , pdb_get_nt_passwd ( sam_pass ) , 16 ) ;
2001-02-27 21:22:39 +03:00
2001-05-07 18:04:46 +04:00
pdb_free_sam ( sam_pass ) ;
2001-05-04 19:44:27 +04:00
2001-02-27 21:22:39 +03:00
/* ok! user info levels (lots: see MSDEV help), off we go... */
switch ( switch_value ) {
case 0x12 :
if ( ! set_user_info_12 ( ctr - > info . id12 , rid ) )
return NT_STATUS_ACCESS_DENIED ;
break ;
case 24 :
SamOEMhash ( ctr - > info . id24 - > pass , sess_key , 1 ) ;
if ( ! set_user_info_24 ( ctr - > info . id24 , rid ) )
return NT_STATUS_ACCESS_DENIED ;
break ;
case 23 :
SamOEMhash ( ctr - > info . id23 - > pass , sess_key , 1 ) ;
if ( ! set_user_info_23 ( ctr - > info . id23 , rid ) )
return NT_STATUS_ACCESS_DENIED ;
break ;
default :
return NT_STATUS_INVALID_INFO_CLASS ;
}
return r_u - > status ;
}
/*******************************************************************
samr_reply_set_userinfo2
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_set_userinfo2 ( pipes_struct * p , SAMR_Q_SET_USERINFO2 * q_u , SAMR_R_SET_USERINFO2 * r_u )
{
DOM_SID sid ;
uint32 rid = 0x0 ;
2001-03-11 03:32:10 +03:00
SAM_USERINFO_CTR * ctr = q_u - > ctr ;
2001-02-27 21:22:39 +03:00
POLICY_HND * pol = & q_u - > pol ;
uint16 switch_value = q_u - > switch_value ;
DEBUG ( 5 , ( " samr_reply_set_userinfo2: %d \n " , __LINE__ ) ) ;
r_u - > status = NT_STATUS_NOPROBLEMO ;
/* find the policy handle. open a policy on it. */
2001-03-11 03:32:10 +03:00
if ( ! get_lsa_policy_samr_sid ( p , pol , & sid ) )
2001-02-27 21:22:39 +03:00
return NT_STATUS_INVALID_HANDLE ;
sid_split_rid ( & sid , & rid ) ;
DEBUG ( 5 , ( " samr_reply_set_userinfo2: rid:0x%x \n " , rid ) ) ;
if ( ctr = = NULL ) {
DEBUG ( 5 , ( " samr_reply_set_userinfo2: NULL info level \n " ) ) ;
return NT_STATUS_INVALID_INFO_CLASS ;
}
2001-03-11 03:32:10 +03:00
switch_value = ctr - > switch_value ;
2001-02-27 21:22:39 +03:00
/* ok! user info levels (lots: see MSDEV help), off we go... */
switch ( switch_value ) {
case 21 :
if ( ! set_user_info_21 ( ctr - > info . id21 , rid ) )
return NT_STATUS_ACCESS_DENIED ;
break ;
case 16 :
if ( ! set_user_info_10 ( ctr - > info . id10 , rid ) )
return NT_STATUS_ACCESS_DENIED ;
break ;
2001-03-13 22:21:51 +03:00
case 18 :
/* Used by AS/U JRA. */
if ( ! set_user_info_12 ( ctr - > info . id12 , rid ) )
return NT_STATUS_ACCESS_DENIED ;
break ;
2001-02-27 21:22:39 +03:00
default :
return NT_STATUS_INVALID_INFO_CLASS ;
}
return r_u - > status ;
}
/*********************************************************************
_samr_query_aliasmem
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_query_useraliases ( pipes_struct * p , SAMR_Q_QUERY_USERALIASES * q_u , SAMR_R_QUERY_USERALIASES * r_u )
{
2001-03-23 03:50:31 +03:00
uint32 * rid = NULL ;
int num_rids ;
num_rids = 1 ;
rid = ( uint32 * ) talloc ( p - > mem_ctx , num_rids * sizeof ( uint32 ) ) ;
if ( rid = = NULL )
return NT_STATUS_NO_MEMORY ;
/* until i see a real useraliases query, we fack one up */
rid [ 0 ] = BUILTIN_ALIAS_RID_USERS ;
init_samr_r_query_useraliases ( r_u , num_rids , rid , NT_STATUS_NO_PROBLEMO ) ;
return NT_STATUS_NO_PROBLEMO ;
2001-02-27 21:22:39 +03:00
}
/*********************************************************************
_samr_query_aliasmem
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_query_aliasmem ( pipes_struct * p , SAMR_Q_QUERY_ALIASMEM * q_u , SAMR_R_QUERY_ALIASMEM * r_u )
{
2001-03-23 03:50:31 +03:00
int i ;
GROUP_MAP map ;
int num_uids = 0 ;
DOM_SID2 * sid ;
uid_t * uid = NULL ;
DOM_SID alias_sid ;
DOM_SID als_sid ;
uint32 alias_rid ;
fstring alias_sid_str ;
DOM_SID temp_sid ;
/* find the policy handle. open a policy on it. */
if ( ! get_lsa_policy_samr_sid ( p , & q_u - > alias_pol , & alias_sid ) )
return NT_STATUS_INVALID_HANDLE ;
sid_copy ( & als_sid , & alias_sid ) ;
sid_to_string ( alias_sid_str , & alias_sid ) ;
sid_split_rid ( & alias_sid , & alias_rid ) ;
DEBUG ( 10 , ( " sid is %s \n " , alias_sid_str ) ) ;
if ( sid_equal ( & alias_sid , & global_sid_Builtin ) ) {
DEBUG ( 10 , ( " lookup on Builtin SID (S-1-5-32) \n " ) ) ;
if ( ! get_builtin_group_from_sid ( als_sid , & map ) )
return NT_STATUS_NO_SUCH_ALIAS ;
} else {
if ( sid_equal ( & alias_sid , & global_sam_sid ) ) {
DEBUG ( 10 , ( " lookup on Server SID \n " ) ) ;
if ( ! get_local_group_from_sid ( als_sid , & map ) )
return NT_STATUS_NO_SUCH_ALIAS ;
}
}
if ( ! get_uid_list_of_group ( map . gid , & uid , & num_uids ) )
return NT_STATUS_NO_SUCH_ALIAS ;
DEBUG ( 10 , ( " sid is %s \n " , alias_sid_str ) ) ;
sid = ( DOM_SID2 * ) talloc ( p - > mem_ctx , sizeof ( DOM_SID2 ) * num_uids ) ;
2001-05-08 20:33:18 +04:00
if ( num_uids ! = 0 & & sid = = NULL )
return NT_STATUS_NO_MEMORY ;
2001-03-23 03:50:31 +03:00
for ( i = 0 ; i < num_uids ; i + + ) {
sid_copy ( & temp_sid , & global_sam_sid ) ;
sid_append_rid ( & temp_sid , pdb_uid_to_user_rid ( uid [ i ] ) ) ;
init_dom_sid2 ( & sid [ i ] , & temp_sid ) ;
}
DEBUG ( 10 , ( " sid is %s \n " , alias_sid_str ) ) ;
init_samr_r_query_aliasmem ( r_u , num_uids , sid , NT_STATUS_NO_PROBLEMO ) ;
return NT_STATUS_NOPROBLEMO ;
2001-02-27 21:22:39 +03:00
}
/*********************************************************************
_samr_query_groupmem
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_query_groupmem ( pipes_struct * p , SAMR_Q_QUERY_GROUPMEM * q_u , SAMR_R_QUERY_GROUPMEM * r_u )
{
2001-03-23 03:50:31 +03:00
int num_uids = 0 ;
int i ;
DOM_SID group_sid ;
uint32 group_rid ;
fstring group_sid_str ;
uid_t * uid = NULL ;
GROUP_MAP map ;
uint32 * rid = NULL ;
uint32 * attr = NULL ;
/* find the policy handle. open a policy on it. */
if ( ! get_lsa_policy_samr_sid ( p , & q_u - > group_pol , & group_sid ) )
return NT_STATUS_INVALID_HANDLE ;
/* todo: change to use sid_compare_front */
sid_split_rid ( & group_sid , & group_rid ) ;
sid_to_string ( group_sid_str , & group_sid ) ;
DEBUG ( 10 , ( " sid is %s \n " , group_sid_str ) ) ;
/* can we get a query for an SID outside our domain ? */
if ( ! sid_equal ( & group_sid , & global_sam_sid ) )
return NT_STATUS_NO_SUCH_GROUP ;
sid_append_rid ( & group_sid , group_rid ) ;
DEBUG ( 10 , ( " lookup on Domain SID \n " ) ) ;
if ( ! get_domain_group_from_sid ( group_sid , & map ) )
return NT_STATUS_NO_SUCH_GROUP ;
if ( ! get_uid_list_of_group ( map . gid , & uid , & num_uids ) )
return NT_STATUS_NO_SUCH_GROUP ;
rid = talloc ( p - > mem_ctx , sizeof ( uint32 ) * num_uids ) ;
attr = talloc ( p - > mem_ctx , sizeof ( uint32 ) * num_uids ) ;
2001-05-08 20:33:18 +04:00
if ( num_uids ! = 0 & & ( rid = = NULL | | attr = = NULL ) )
2001-03-23 03:50:31 +03:00
return NT_STATUS_NO_MEMORY ;
for ( i = 0 ; i < num_uids ; i + + ) {
rid [ i ] = pdb_uid_to_user_rid ( uid [ i ] ) ;
attr [ i ] = SID_NAME_USER ;
}
init_samr_r_query_groupmem ( r_u , num_uids , rid , attr , NT_STATUS_NOPROBLEMO ) ;
return NT_STATUS_NOPROBLEMO ;
2001-02-27 21:22:39 +03:00
}
/*********************************************************************
_samr_add_aliasmem
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_add_aliasmem ( pipes_struct * p , SAMR_Q_ADD_ALIASMEM * q_u , SAMR_R_ADD_ALIASMEM * r_u )
{
2001-03-23 03:50:31 +03:00
DOM_SID alias_sid ;
fstring alias_sid_str ;
uid_t uid ;
struct passwd * pwd ;
struct group * grp ;
fstring grp_name ;
uint32 rid ;
GROUP_MAP map ;
/* Find the policy handle. Open a policy on it. */
if ( ! get_lsa_policy_samr_sid ( p , & q_u - > alias_pol , & alias_sid ) )
return NT_STATUS_INVALID_HANDLE ;
sid_to_string ( alias_sid_str , & alias_sid ) ;
DEBUG ( 10 , ( " sid is %s \n " , alias_sid_str ) ) ;
if ( sid_compare ( & alias_sid , & global_sam_sid ) > 0 ) {
DEBUG ( 10 , ( " adding member on Server SID \n " ) ) ;
if ( ! get_local_group_from_sid ( alias_sid , & map ) )
return NT_STATUS_NO_SUCH_ALIAS ;
} else {
if ( sid_compare ( & alias_sid , & global_sid_Builtin ) > 0 ) {
DEBUG ( 10 , ( " adding member on BUILTIN SID \n " ) ) ;
if ( ! get_builtin_group_from_sid ( alias_sid , & map ) )
return NT_STATUS_NO_SUCH_ALIAS ;
} else
return NT_STATUS_NO_SUCH_ALIAS ;
}
sid_split_rid ( & q_u - > sid . sid , & rid ) ;
uid = pdb_user_rid_to_uid ( rid ) ;
if ( ( pwd = getpwuid ( uid ) ) = = NULL )
return NT_STATUS_NO_SUCH_USER ;
if ( ( grp = getgrgid ( map . gid ) ) = = NULL )
return NT_STATUS_NO_SUCH_ALIAS ;
/* we need to copy the name otherwise it's overloaded in user_in_group_list */
fstrcpy ( grp_name , grp - > gr_name ) ;
/* if the user is already in the group */
if ( user_in_group_list ( pwd - > pw_name , grp_name ) )
return NT_STATUS_MEMBER_IN_ALIAS ;
/*
* ok , the group exist , the user exist , the user is not in the group ,
* we can ( finally ) add it to the group !
*/
smb_add_user_group ( grp_name , pwd - > pw_name ) ;
/* check if the user has been added then ... */
if ( ! user_in_group_list ( pwd - > pw_name , grp_name ) )
return NT_STATUS_MEMBER_NOT_IN_ALIAS ; /* don't know what to reply else */
return NT_STATUS_NOPROBLEMO ;
2001-02-27 21:22:39 +03:00
}
/*********************************************************************
_samr_del_aliasmem
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_del_aliasmem ( pipes_struct * p , SAMR_Q_DEL_ALIASMEM * q_u , SAMR_R_DEL_ALIASMEM * r_u )
{
DEBUG ( 0 , ( " _samr_del_aliasmem: Not yet implemented. \n " ) ) ;
return False ;
}
/*********************************************************************
_samr_add_groupmem
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_add_groupmem ( pipes_struct * p , SAMR_Q_ADD_GROUPMEM * q_u , SAMR_R_ADD_GROUPMEM * r_u )
{
2001-03-23 03:50:31 +03:00
DOM_SID group_sid ;
fstring group_sid_str ;
struct passwd * pwd ;
struct group * grp ;
fstring grp_name ;
GROUP_MAP map ;
/* Find the policy handle. Open a policy on it. */
if ( ! get_lsa_policy_samr_sid ( p , & q_u - > pol , & group_sid ) )
return NT_STATUS_INVALID_HANDLE ;
sid_to_string ( group_sid_str , & group_sid ) ;
DEBUG ( 10 , ( " sid is %s \n " , group_sid_str ) ) ;
if ( sid_compare ( & group_sid , & global_sam_sid ) < = 0 )
return NT_STATUS_NO_SUCH_GROUP ;
DEBUG ( 10 , ( " lookup on Domain SID \n " ) ) ;
if ( ! get_domain_group_from_sid ( group_sid , & map ) )
return NT_STATUS_NO_SUCH_GROUP ;
if ( ( pwd = getpwuid ( pdb_user_rid_to_uid ( q_u - > rid ) ) ) = = NULL )
return NT_STATUS_NO_SUCH_USER ;
if ( ( grp = getgrgid ( map . gid ) ) = = NULL )
return NT_STATUS_NO_SUCH_GROUP ;
/* we need to copy the name otherwise it's overloaded in user_in_group_list */
fstrcpy ( grp_name , grp - > gr_name ) ;
/* if the user is already in the group */
if ( user_in_group_list ( pwd - > pw_name , grp_name ) )
return NT_STATUS_MEMBER_IN_GROUP ;
/*
* ok , the group exist , the user exist , the user is not in the group ,
*
* we can ( finally ) add it to the group !
*/
smb_add_user_group ( grp_name , pwd - > pw_name ) ;
/* check if the user has been added then ... */
if ( ! user_in_group_list ( pwd - > pw_name , grp_name ) )
return NT_STATUS_MEMBER_NOT_IN_GROUP ; /* don't know what to reply else */
return NT_STATUS_NOPROBLEMO ;
2001-02-27 21:22:39 +03:00
}
/*********************************************************************
_samr_del_groupmem
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_del_groupmem ( pipes_struct * p , SAMR_Q_DEL_GROUPMEM * q_u , SAMR_R_DEL_GROUPMEM * r_u )
{
DEBUG ( 0 , ( " _samr_del_groupmem: Not yet implemented. \n " ) ) ;
return False ;
}
/*********************************************************************
_samr_delete_dom_user
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_delete_dom_user ( pipes_struct * p , SAMR_Q_DELETE_DOM_USER * q_u , SAMR_R_DELETE_DOM_USER * r_u )
{
DEBUG ( 0 , ( " _samr_delete_dom_user: Not yet implemented. \n " ) ) ;
return False ;
}
/*********************************************************************
_samr_delete_dom_group
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_delete_dom_group ( pipes_struct * p , SAMR_Q_DELETE_DOM_GROUP * q_u , SAMR_R_DELETE_DOM_GROUP * r_u )
{
DEBUG ( 0 , ( " _samr_delete_dom_group: Not yet implemented. \n " ) ) ;
return False ;
}
/*********************************************************************
_samr_delete_dom_alias
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_delete_dom_alias ( pipes_struct * p , SAMR_Q_DELETE_DOM_ALIAS * q_u , SAMR_R_DELETE_DOM_ALIAS * r_u )
{
DEBUG ( 0 , ( " _samr_delete_dom_alias: Not yet implemented. \n " ) ) ;
return False ;
}
/*********************************************************************
_samr_create_dom_group
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_create_dom_group ( pipes_struct * p , SAMR_Q_CREATE_DOM_GROUP * q_u , SAMR_R_CREATE_DOM_GROUP * r_u )
{
2001-03-23 03:50:31 +03:00
DOM_SID dom_sid ;
DOM_SID info_sid ;
fstring name ;
fstring sid_string ;
struct group * grp ;
struct samr_info * info ;
/* Find the policy handle. Open a policy on it. */
if ( ! get_lsa_policy_samr_sid ( p , & q_u - > pol , & dom_sid ) )
return NT_STATUS_INVALID_HANDLE ;
if ( ! sid_equal ( & dom_sid , & global_sam_sid ) )
return NT_STATUS_ACCESS_DENIED ;
/* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
unistr2_to_ascii ( name , & q_u - > uni_acct_desc , sizeof ( name ) - 1 ) ;
/* check if group already exist */
if ( ( grp = getgrnam ( name ) ) ! = NULL )
return NT_STATUS_GROUP_EXISTS ;
/* we can create the UNIX group */
smb_create_group ( name ) ;
/* check if the group has been successfully created */
if ( ( grp = getgrnam ( name ) ) = = NULL )
return NT_STATUS_ACCESS_DENIED ;
r_u - > rid = pdb_gid_to_group_rid ( grp - > gr_gid ) ;
/* add the group to the mapping table */
if ( ! add_initial_entry ( grp - > gr_gid , sid_string , SID_NAME_DOM_GRP , name , NULL , SE_PRIV_NONE ) )
return NT_STATUS_ACCESS_DENIED ;
if ( ( info = ( struct samr_info * ) malloc ( sizeof ( struct samr_info ) ) ) = = NULL )
return NT_STATUS_NO_MEMORY ;
ZERO_STRUCTP ( info ) ;
sid_copy ( & info_sid , & global_sam_sid ) ;
sid_append_rid ( & info - > sid , r_u - > rid ) ;
sid_to_string ( sid_string , & info - > sid ) ;
/* get a (unique) handle. open a policy on it. */
if ( ! create_policy_hnd ( p , & r_u - > pol , free_samr_info , ( void * ) info ) )
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
return NT_STATUS_NOPROBLEMO ;
2001-02-27 21:22:39 +03:00
}
/*********************************************************************
_samr_create_dom_alias
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_create_dom_alias ( pipes_struct * p , SAMR_Q_CREATE_DOM_ALIAS * q_u , SAMR_R_CREATE_DOM_ALIAS * r_u )
{
2001-03-23 03:50:31 +03:00
DOM_SID dom_sid ;
fstring name ;
fstring sid_string ;
struct group * grp ;
struct samr_info * info ;
/* Find the policy handle. Open a policy on it. */
if ( ! get_lsa_policy_samr_sid ( p , & q_u - > dom_pol , & dom_sid ) )
return NT_STATUS_INVALID_HANDLE ;
if ( ! sid_equal ( & dom_sid , & global_sam_sid ) )
return NT_STATUS_ACCESS_DENIED ;
/* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
unistr2_to_ascii ( name , & q_u - > uni_acct_desc , sizeof ( name ) - 1 ) ;
/* check if group already exists */
if ( ( grp = getgrnam ( name ) ) ! = NULL )
return NT_STATUS_GROUP_EXISTS ;
/* we can create the UNIX group */
smb_create_group ( name ) ;
/* check if the group has been successfully created */
if ( ( grp = getgrnam ( name ) ) = = NULL )
return NT_STATUS_ACCESS_DENIED ;
r_u - > rid = pdb_gid_to_group_rid ( grp - > gr_gid ) ;
if ( ( info = ( struct samr_info * ) malloc ( sizeof ( struct samr_info ) ) ) = = NULL )
return NT_STATUS_NO_MEMORY ;
ZERO_STRUCTP ( info ) ;
sid_copy ( & info - > sid , & global_sam_sid ) ;
sid_append_rid ( & info - > sid , r_u - > rid ) ;
sid_to_string ( sid_string , & info - > sid ) ;
2001-05-08 20:33:18 +04:00
/* add the group to the mapping table */
if ( ! add_initial_entry ( grp - > gr_gid , sid_string , SID_NAME_ALIAS , name , NULL , SE_PRIV_NONE ) )
return NT_STATUS_ACCESS_DENIED ;
2001-03-23 03:50:31 +03:00
/* get a (unique) handle. open a policy on it. */
if ( ! create_policy_hnd ( p , & r_u - > alias_pol , free_samr_info , ( void * ) info ) )
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
return NT_STATUS_NOPROBLEMO ;
2001-02-27 21:22:39 +03:00
}
/*********************************************************************
_samr_query_groupinfo
2001-03-23 03:50:31 +03:00
sends the name / comment pair of a domain group
level 1 send also the number of users of that group
2001-02-27 21:22:39 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_query_groupinfo ( pipes_struct * p , SAMR_Q_QUERY_GROUPINFO * q_u , SAMR_R_QUERY_GROUPINFO * r_u )
{
2001-03-23 03:50:31 +03:00
DOM_SID group_sid ;
GROUP_MAP map ;
2001-05-08 20:33:18 +04:00
uid_t * uid = NULL ;
2001-03-23 03:50:31 +03:00
int num_uids = 0 ;
GROUP_INFO_CTR * ctr ;
if ( ! get_lsa_policy_samr_sid ( p , & q_u - > pol , & group_sid ) )
return NT_STATUS_INVALID_HANDLE ;
if ( ! get_domain_group_from_sid ( group_sid , & map ) )
return NT_STATUS_INVALID_HANDLE ;
ctr = ( GROUP_INFO_CTR * ) talloc ( p - > mem_ctx , sizeof ( GROUP_INFO_CTR ) ) ;
if ( ctr = = NULL )
return NT_STATUS_NO_MEMORY ;
switch ( q_u - > switch_level ) {
case 1 :
ctr - > switch_value1 = 1 ;
if ( ! get_uid_list_of_group ( map . gid , & uid , & num_uids ) )
return NT_STATUS_NO_SUCH_GROUP ;
init_samr_group_info1 ( & ctr - > group . info1 , map . nt_name , map . comment , num_uids ) ;
safe_free ( uid ) ;
break ;
case 4 :
ctr - > switch_value1 = 4 ;
init_samr_group_info4 ( & ctr - > group . info4 , map . comment ) ;
break ;
default :
return NT_STATUS_INVALID_INFO_CLASS ;
}
init_samr_r_query_groupinfo ( r_u , ctr , NT_STATUS_NO_PROBLEMO ) ;
return NT_STATUS_NO_PROBLEMO ;
2001-02-27 21:22:39 +03:00
}
/*********************************************************************
_samr_set_groupinfo
2001-03-23 03:50:31 +03:00
update a domain group ' s comment .
2001-02-27 21:22:39 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_set_groupinfo ( pipes_struct * p , SAMR_Q_SET_GROUPINFO * q_u , SAMR_R_SET_GROUPINFO * r_u )
{
2001-03-23 03:50:31 +03:00
DOM_SID group_sid ;
GROUP_MAP map ;
GROUP_INFO_CTR * ctr ;
if ( ! get_lsa_policy_samr_sid ( p , & q_u - > pol , & group_sid ) )
return NT_STATUS_INVALID_HANDLE ;
if ( ! get_domain_group_from_sid ( group_sid , & map ) )
return NT_STATUS_NO_SUCH_GROUP ;
ctr = q_u - > ctr ;
switch ( ctr - > switch_value1 ) {
case 1 :
unistr2_to_ascii ( map . comment , & ( ctr - > group . info1 . uni_acct_desc ) , sizeof ( map . comment ) - 1 ) ;
break ;
case 4 :
unistr2_to_ascii ( map . comment , & ( ctr - > group . info4 . uni_acct_desc ) , sizeof ( map . comment ) - 1 ) ;
2001-05-08 20:33:18 +04:00
break ;
default :
return NT_STATUS_INVALID_INFO_CLASS ;
}
if ( ! add_mapping_entry ( & map , TDB_REPLACE ) )
return NT_STATUS_NO_SUCH_GROUP ;
return NT_STATUS_NO_PROBLEMO ;
}
/*********************************************************************
_samr_set_groupinfo
update a domain group ' s comment .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_set_aliasinfo ( pipes_struct * p , SAMR_Q_SET_ALIASINFO * q_u , SAMR_R_SET_ALIASINFO * r_u )
{
DOM_SID group_sid ;
GROUP_MAP map ;
ALIAS_INFO_CTR * ctr ;
if ( ! get_lsa_policy_samr_sid ( p , & q_u - > alias_pol , & group_sid ) )
return NT_STATUS_INVALID_HANDLE ;
if ( ! get_local_group_from_sid ( group_sid , & map ) )
return NT_STATUS_NO_SUCH_GROUP ;
ctr = & q_u - > ctr ;
switch ( ctr - > switch_value1 ) {
case 3 :
unistr2_to_ascii ( map . comment , & ( ctr - > alias . info3 . uni_acct_desc ) , sizeof ( map . comment ) - 1 ) ;
2001-03-23 03:50:31 +03:00
break ;
default :
return NT_STATUS_INVALID_INFO_CLASS ;
}
if ( ! add_mapping_entry ( & map , TDB_REPLACE ) )
return NT_STATUS_NO_SUCH_GROUP ;
return NT_STATUS_NO_PROBLEMO ;
2001-02-27 21:22:39 +03:00
}
/*********************************************************************
_samr_get_dom_pwinfo
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_get_dom_pwinfo ( pipes_struct * p , SAMR_Q_GET_DOM_PWINFO * q_u , SAMR_R_GET_DOM_PWINFO * r_u )
{
2001-03-13 03:32:43 +03:00
/* Actually, returning zeros here works quite well :-). */
return NT_STATUS_NOPROBLEMO ;
2001-02-27 21:22:39 +03:00
}
/*********************************************************************
_samr_open_group
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_open_group ( pipes_struct * p , SAMR_Q_OPEN_GROUP * q_u , SAMR_R_OPEN_GROUP * r_u )
{
2001-03-23 03:50:31 +03:00
DOM_SID sid ;
GROUP_MAP map ;
struct samr_info * info ;
fstring sid_string ;
if ( ! get_lsa_policy_samr_sid ( p , & q_u - > domain_pol , & sid ) )
return NT_STATUS_INVALID_HANDLE ;
/* this should not be hard-coded like this */
if ( ! sid_equal ( & sid , & global_sam_sid ) )
return NT_STATUS_ACCESS_DENIED ;
if ( ( info = ( struct samr_info * ) malloc ( sizeof ( struct samr_info ) ) ) = = NULL )
return NT_STATUS_NO_MEMORY ;
ZERO_STRUCTP ( info ) ;
sid_copy ( & info - > sid , & global_sam_sid ) ;
sid_append_rid ( & info - > sid , q_u - > rid_group ) ;
sid_to_string ( sid_string , & info - > sid ) ;
DEBUG ( 10 , ( " Opening SID: %s \n " , sid_string ) ) ;
/* check if that group really exists */
if ( ! get_domain_group_from_sid ( info - > sid , & map ) )
return NT_STATUS_NO_SUCH_USER ;
/* get a (unique) handle. open a policy on it. */
if ( ! create_policy_hnd ( p , & r_u - > pol , free_samr_info , ( void * ) info ) )
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
return NT_STATUS_NO_PROBLEMO ;
2001-02-27 21:22:39 +03:00
}
/*********************************************************************
_samr_unknown_2d
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32 _samr_unknown_2d ( pipes_struct * p , SAMR_Q_UNKNOWN_2D * q_u , SAMR_R_UNKNOWN_2D * r_u )
{
DEBUG ( 0 , ( " _samr_unknown_2d: Not yet implemented. \n " ) ) ;
return False ;
}