2001-02-26 22:31:07 +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.
* 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 lsa server code. */
# include "includes.h"
extern DOM_SID global_sam_sid ;
extern fstring global_myworkgroup ;
extern pstring global_myname ;
2001-07-09 22:32:54 +04:00
extern PRIVS privs [ ] ;
struct lsa_info {
DOM_SID sid ;
uint32 access ;
} ;
/*******************************************************************
Function to free the per handle data .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void free_lsa_info ( void * ptr )
{
struct lsa_info * lsa = ( struct lsa_info * ) ptr ;
2001-09-17 14:26:23 +04:00
SAFE_FREE ( lsa ) ;
2001-07-09 22:32:54 +04:00
}
2001-02-26 22:31:07 +03:00
/***************************************************************************
Init dom_query
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void init_dom_query ( DOM_QUERY * d_q , char * dom_name , DOM_SID * dom_sid )
{
int domlen = ( dom_name ! = NULL ) ? strlen ( dom_name ) : 0 ;
/*
* I ' m not sure why this really odd combination of length
* values works , but it does appear to . I need to look at
* this * much * more closely - but at the moment leave alone
* until it ' s understood . This allows a W2k client to join
* a domain with both odd and even length names . . . JRA .
*/
d_q - > uni_dom_str_len = domlen ? ( ( domlen + 1 ) * 2 ) : 0 ;
d_q - > uni_dom_max_len = domlen * 2 ;
d_q - > buffer_dom_name = domlen ! = 0 ? 1 : 0 ; /* domain buffer pointer */
d_q - > buffer_dom_sid = dom_sid ! = NULL ? 1 : 0 ; /* domain sid pointer */
/* this string is supposed to be character short */
init_unistr2 ( & d_q - > uni_domain_name , dom_name , domlen ) ;
d_q - > uni_domain_name . uni_max_len + + ;
if ( dom_sid ! = NULL )
init_dom_sid2 ( & d_q - > dom_sid , dom_sid ) ;
}
/***************************************************************************
init_dom_ref - adds a domain if it ' s not already in , returns the index .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int init_dom_ref ( DOM_R_REF * ref , char * dom_name , DOM_SID * dom_sid )
{
int num = 0 ;
int len ;
if ( dom_name ! = NULL ) {
for ( num = 0 ; num < ref - > num_ref_doms_1 ; num + + ) {
fstring domname ;
2001-07-04 11:15:53 +04:00
rpcstr_pull ( domname , & ref - > ref_dom [ num ] . uni_dom_name , sizeof ( domname ) , - 1 , 0 ) ;
2001-02-26 22:31:07 +03:00
if ( strequal ( domname , dom_name ) )
return num ;
}
} else {
num = ref - > num_ref_doms_1 ;
}
if ( num > = MAX_REF_DOMAINS ) {
/* index not found, already at maximum domain limit */
return - 1 ;
}
ref - > num_ref_doms_1 = num + 1 ;
ref - > ptr_ref_dom = 1 ;
ref - > max_entries = MAX_REF_DOMAINS ;
ref - > num_ref_doms_2 = num + 1 ;
len = ( dom_name ! = NULL ) ? strlen ( dom_name ) : 0 ;
if ( dom_name ! = NULL & & len = = 0 )
len = 1 ;
init_uni_hdr ( & ref - > hdr_ref_dom [ num ] . hdr_dom_name , len ) ;
ref - > hdr_ref_dom [ num ] . ptr_dom_sid = dom_sid ! = NULL ? 1 : 0 ;
init_unistr2 ( & ref - > ref_dom [ num ] . uni_dom_name , dom_name , len ) ;
init_dom_sid2 ( & ref - > ref_dom [ num ] . ref_dom , dom_sid ) ;
return num ;
}
/***************************************************************************
init_lsa_rid2s
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void init_lsa_rid2s ( DOM_R_REF * ref , DOM_RID2 * rid2 ,
2001-05-08 05:26:28 +04:00
int num_entries , UNISTR2 * name ,
2001-03-13 04:44:05 +03:00
uint32 * mapped_count , BOOL endian )
2001-02-26 22:31:07 +03:00
{
int i ;
int total = 0 ;
* mapped_count = 0 ;
SMB_ASSERT ( num_entries < = MAX_LOOKUP_SIDS ) ;
for ( i = 0 ; i < num_entries ; i + + ) {
BOOL status = False ;
DOM_SID sid ;
uint32 rid = 0xffffffff ;
int dom_idx = - 1 ;
pstring full_name ;
fstring dom_name , user ;
enum SID_NAME_USE name_type = SID_NAME_UNKNOWN ;
/* Split name into domain and user component */
2001-07-09 22:32:54 +04:00
unistr2_to_ascii ( full_name , & name [ i ] , sizeof ( full_name ) ) ;
2001-02-26 22:31:07 +03:00
split_domain_name ( full_name , dom_name , user ) ;
/* Lookup name */
DEBUG ( 5 , ( " init_lsa_rid2s: looking up name %s \n " , full_name ) ) ;
status = lookup_name ( full_name , & sid , & name_type ) ;
DEBUG ( 5 , ( " init_lsa_rid2s: %s \n " , status ? " found " :
" not found " ) ) ;
if ( status ) {
sid_split_rid ( & sid , & rid ) ;
dom_idx = init_dom_ref ( ref , dom_name , & sid ) ;
( * mapped_count ) + + ;
} else {
dom_idx = - 1 ;
rid = 0xffffffff ;
name_type = SID_NAME_UNKNOWN ;
}
init_dom_rid2 ( & rid2 [ total ] , rid , name_type , dom_idx ) ;
total + + ;
}
}
/***************************************************************************
init_reply_lookup_names
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void init_reply_lookup_names ( LSA_R_LOOKUP_NAMES * r_l ,
DOM_R_REF * ref , uint32 num_entries ,
DOM_RID2 * rid2 , uint32 mapped_count )
{
r_l - > ptr_dom_ref = 1 ;
r_l - > dom_ref = ref ;
r_l - > num_entries = num_entries ;
r_l - > ptr_entries = 1 ;
r_l - > num_entries2 = num_entries ;
r_l - > dom_rid = rid2 ;
r_l - > mapped_count = mapped_count ;
if ( mapped_count = = 0 )
r_l - > status = NT_STATUS_NONE_MAPPED ;
else
2001-08-27 23:46:22 +04:00
r_l - > status = NT_STATUS_OK ;
2001-02-26 22:31:07 +03:00
}
/***************************************************************************
Init lsa_trans_names .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void init_lsa_trans_names ( TALLOC_CTX * ctx , DOM_R_REF * ref , LSA_TRANS_NAME_ENUM * trn ,
int num_entries , DOM_SID2 * sid ,
uint32 * mapped_count )
{
int i ;
int total = 0 ;
* mapped_count = 0 ;
/* Allocate memory for list of names */
if ( num_entries > 0 ) {
if ( ! ( trn - > name = ( LSA_TRANS_NAME * ) talloc ( ctx , sizeof ( LSA_TRANS_NAME ) *
num_entries ) ) ) {
DEBUG ( 0 , ( " init_lsa_trans_names(): out of memory \n " ) ) ;
return ;
}
if ( ! ( trn - > uni_name = ( UNISTR2 * ) talloc ( ctx , sizeof ( UNISTR2 ) *
num_entries ) ) ) {
DEBUG ( 0 , ( " init_lsa_trans_names(): out of memory \n " ) ) ;
return ;
}
}
for ( i = 0 ; i < num_entries ; i + + ) {
BOOL status = False ;
DOM_SID find_sid = sid [ i ] . sid ;
uint32 rid = 0xffffffff ;
int dom_idx = - 1 ;
fstring name , dom_name ;
enum SID_NAME_USE sid_name_use = ( enum SID_NAME_USE ) 0 ;
sid_to_string ( name , & find_sid ) ;
DEBUG ( 5 , ( " init_lsa_trans_names: looking up sid %s \n " , name ) ) ;
/* Lookup sid from winbindd */
memset ( dom_name , ' \0 ' , sizeof ( dom_name ) ) ;
memset ( name , ' \0 ' , sizeof ( name ) ) ;
status = lookup_sid ( & find_sid , dom_name , name , & sid_name_use ) ;
DEBUG ( 5 , ( " init_lsa_trans_names: %s \n " , status ? " found " :
" not found " ) ) ;
if ( ! status ) {
sid_name_use = SID_NAME_UNKNOWN ;
}
/* Store domain sid in ref array */
if ( find_sid . num_auths = = 5 ) {
sid_split_rid ( & find_sid , & rid ) ;
}
dom_idx = init_dom_ref ( ref , dom_name , & find_sid ) ;
DEBUG ( 10 , ( " init_lsa_trans_names: added user '%s \\ %s' to "
" referenced list. \n " , dom_name , name ) ) ;
( * mapped_count ) + + ;
init_lsa_trans_name ( & trn - > name [ total ] , & trn - > uni_name [ total ] ,
sid_name_use , name , dom_idx ) ;
total + + ;
}
trn - > num_entries = total ;
trn - > ptr_trans_names = 1 ;
trn - > num_entries2 = total ;
}
/***************************************************************************
Init_reply_lookup_sids .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void init_reply_lookup_sids ( LSA_R_LOOKUP_SIDS * r_l ,
DOM_R_REF * ref , LSA_TRANS_NAME_ENUM * names ,
uint32 mapped_count )
{
r_l - > ptr_dom_ref = 1 ;
r_l - > dom_ref = ref ;
r_l - > names = names ;
r_l - > mapped_count = mapped_count ;
if ( mapped_count = = 0 )
r_l - > status = NT_STATUS_NONE_MAPPED ;
else
2001-08-27 23:46:22 +04:00
r_l - > status = NT_STATUS_OK ;
2001-02-26 22:31:07 +03:00
}
/***************************************************************************
_lsa_open_policy2 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 21:52:23 +04:00
NTSTATUS _lsa_open_policy2 ( pipes_struct * p , LSA_Q_OPEN_POL2 * q_u , LSA_R_OPEN_POL2 * r_u )
2001-02-26 22:31:07 +03:00
{
/* lkclXXXX having decoded it, ignore all fields in the open policy! */
/* set up the LSA QUERY INFO response */
2001-03-11 03:32:10 +03:00
if ( ! create_policy_hnd ( p , & r_u - > pol , NULL , NULL ) )
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
2001-02-26 22:31:07 +03:00
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2001-02-26 22:31:07 +03:00
}
/***************************************************************************
_lsa_open_policy
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS _lsa_open_policy ( pipes_struct * p , LSA_Q_OPEN_POL * q_u , LSA_R_OPEN_POL * r_u )
2001-02-26 22:31:07 +03:00
{
/* lkclXXXX having decoded it, ignore all fields in the open policy! */
/* set up the LSA QUERY INFO response */
2001-03-11 03:32:10 +03:00
if ( ! create_policy_hnd ( p , & r_u - > pol , NULL , NULL ) )
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
2001-02-26 22:31:07 +03:00
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2001-02-26 22:31:07 +03:00
}
/***************************************************************************
_lsa_enum_trust_dom - this needs fixing to do more than return NULL ! JRA .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS _lsa_enum_trust_dom ( pipes_struct * p , LSA_Q_ENUM_TRUST_DOM * q_u , LSA_R_ENUM_TRUST_DOM * r_u )
2001-02-26 22:31:07 +03:00
{
uint32 enum_context = 0 ;
char * dom_name = NULL ;
DOM_SID * dom_sid = NULL ;
2001-03-11 03:32:10 +03:00
if ( ! find_policy_by_hnd ( p , & q_u - > pol , NULL ) )
return NT_STATUS_INVALID_HANDLE ;
2001-02-26 22:31:07 +03:00
/* set up the LSA QUERY INFO response */
2001-08-24 11:32:51 +04:00
init_r_enum_trust_dom ( p - > mem_ctx , r_u , enum_context , dom_name , dom_sid ,
2001-08-27 23:46:22 +04:00
dom_name ! = NULL ? NT_STATUS_OK : NT_STATUS_UNABLE_TO_FREE_VM ) ;
2001-02-26 22:31:07 +03:00
return r_u - > status ;
}
/***************************************************************************
2001-03-15 07:34:53 +03:00
_lsa_query_info . See the POLICY_INFOMATION_CLASS docs at msdn .
2001-02-26 22:31:07 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS _lsa_query_info ( pipes_struct * p , LSA_Q_QUERY_INFO * q_u , LSA_R_QUERY_INFO * r_u )
2001-02-26 22:31:07 +03:00
{
LSA_INFO_UNION * info = & r_u - > dom ;
DOM_SID domain_sid ;
char * name = NULL ;
DOM_SID * sid = NULL ;
2001-08-27 23:46:22 +04:00
r_u - > status = NT_STATUS_OK ;
2001-02-26 22:31:07 +03:00
2001-03-11 03:32:10 +03:00
if ( ! find_policy_by_hnd ( p , & q_u - > pol , NULL ) )
return NT_STATUS_INVALID_HANDLE ;
2001-02-26 22:31:07 +03:00
switch ( q_u - > info_class ) {
case 0x02 :
{
unsigned int i ;
/* fake info: We audit everything. ;) */
info - > id2 . auditing_enabled = 1 ;
info - > id2 . count1 = 7 ;
info - > id2 . count2 = 7 ;
if ( ( info - > id2 . auditsettings = ( uint32 * ) talloc ( p - > mem_ctx , 7 * sizeof ( uint32 ) ) ) = = NULL )
2001-08-27 23:46:22 +04:00
return NT_STATUS_NO_MEMORY ;
2001-02-26 22:31:07 +03:00
for ( i = 0 ; i < 7 ; i + + )
info - > id2 . auditsettings [ i ] = 3 ;
break ;
}
case 0x03 :
2001-04-22 03:06:59 +04:00
/* Request PolicyPrimaryDomainInformation. */
switch ( lp_server_role ( ) ) {
2001-02-26 22:31:07 +03:00
case ROLE_DOMAIN_PDC :
case ROLE_DOMAIN_BDC :
2001-07-04 11:15:53 +04:00
name = global_myworkgroup ;
2001-02-26 22:31:07 +03:00
sid = & global_sam_sid ;
break ;
case ROLE_DOMAIN_MEMBER :
2001-07-04 11:15:53 +04:00
name = global_myworkgroup ;
2001-04-22 03:06:59 +04:00
/* We need to return the Domain SID here. */
2001-07-04 11:15:53 +04:00
if ( secrets_fetch_domain_sid ( global_myworkgroup ,
2001-06-02 10:14:42 +04:00
& domain_sid ) )
sid = & domain_sid ;
2001-03-15 05:49:06 +03:00
else
2001-04-22 03:06:59 +04:00
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO ;
2001-02-26 22:31:07 +03:00
break ;
2001-03-15 06:08:22 +03:00
case ROLE_STANDALONE :
2001-07-04 11:15:53 +04:00
name = global_myworkgroup ;
2001-04-22 03:06:59 +04:00
sid = NULL ; /* Tell it we're not in a domain. */
2001-03-15 06:08:22 +03:00
break ;
2001-03-15 05:49:06 +03:00
default :
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO ;
2001-02-26 22:31:07 +03:00
}
init_dom_query ( & r_u - > dom . id3 , name , sid ) ;
break ;
case 0x05 :
2001-04-22 03:06:59 +04:00
/* Request PolicyAccountDomainInformation. */
switch ( lp_server_role ( ) ) {
2001-03-13 03:31:53 +03:00
case ROLE_DOMAIN_PDC :
case ROLE_DOMAIN_BDC :
2001-07-04 11:15:53 +04:00
name = global_myworkgroup ;
2001-03-13 03:31:53 +03:00
sid = & global_sam_sid ;
break ;
case ROLE_DOMAIN_MEMBER :
2001-07-04 11:15:53 +04:00
name = global_myworkgroup ;
2001-03-15 06:08:22 +03:00
sid = & global_sam_sid ;
break ;
2001-04-22 10:13:14 +04:00
case ROLE_STANDALONE :
2001-07-04 11:15:53 +04:00
name = global_myworkgroup ;
2001-05-03 00:32:17 +04:00
sid = & global_sam_sid ;
2001-04-22 10:13:14 +04:00
break ;
2001-03-15 05:49:06 +03:00
default :
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO ;
2001-03-13 03:31:53 +03:00
}
2001-02-26 22:31:07 +03:00
init_dom_query ( & r_u - > dom . id5 , name , sid ) ;
break ;
case 0x06 :
2001-04-22 03:06:59 +04:00
switch ( lp_server_role ( ) ) {
2001-02-26 22:31:07 +03:00
case ROLE_DOMAIN_BDC :
/*
* only a BDC is a backup controller
* of the domain , it controls .
*/
info - > id6 . server_role = 2 ;
break ;
default :
/*
* any other role is a primary
* of the domain , it controls .
*/
info - > id6 . server_role = 3 ;
break ;
}
break ;
default :
DEBUG ( 0 , ( " _lsa_query_info: unknown info level in Lsa Query: %d \n " , q_u - > info_class ) ) ;
r_u - > status = NT_STATUS_INVALID_INFO_CLASS ;
break ;
}
2001-08-27 23:46:22 +04:00
if ( NT_STATUS_IS_OK ( r_u - > status ) ) {
2001-02-26 22:31:07 +03:00
r_u - > undoc_buffer = 0x22000000 ; /* bizarre */
r_u - > info_class = q_u - > info_class ;
}
return r_u - > status ;
}
/***************************************************************************
_lsa_lookup_sids
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS _lsa_lookup_sids ( pipes_struct * p , LSA_Q_LOOKUP_SIDS * q_u , LSA_R_LOOKUP_SIDS * r_u )
2001-02-26 22:31:07 +03:00
{
DOM_SID2 * sid = q_u - > sids . sid ;
int num_entries = q_u - > sids . num_entries ;
2001-03-01 07:01:23 +03:00
DOM_R_REF * ref = NULL ;
LSA_TRANS_NAME_ENUM * names = NULL ;
2001-02-26 22:31:07 +03:00
uint32 mapped_count = 0 ;
2001-03-11 03:32:10 +03:00
if ( ! find_policy_by_hnd ( p , & q_u - > pol , NULL ) )
return NT_STATUS_INVALID_HANDLE ;
2001-03-01 07:01:23 +03:00
ref = ( DOM_R_REF * ) talloc_zero ( p - > mem_ctx , sizeof ( DOM_R_REF ) ) ;
names = ( LSA_TRANS_NAME_ENUM * ) talloc_zero ( p - > mem_ctx , sizeof ( LSA_TRANS_NAME_ENUM ) ) ;
if ( ! ref | | ! names )
return NT_STATUS_NO_MEMORY ;
2001-02-26 22:31:07 +03:00
/* set up the LSA Lookup SIDs response */
2001-03-01 07:01:23 +03:00
init_lsa_trans_names ( p - > mem_ctx , ref , names , num_entries , sid , & mapped_count ) ;
init_reply_lookup_sids ( r_u , ref , names , mapped_count ) ;
2001-02-26 22:31:07 +03:00
return r_u - > status ;
}
/***************************************************************************
lsa_reply_lookup_names
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS _lsa_lookup_names ( pipes_struct * p , LSA_Q_LOOKUP_NAMES * q_u , LSA_R_LOOKUP_NAMES * r_u )
2001-02-26 22:31:07 +03:00
{
UNISTR2 * names = q_u - > uni_name ;
int num_entries = q_u - > num_entries ;
2001-03-01 07:01:23 +03:00
DOM_R_REF * ref ;
DOM_RID2 * rids ;
2001-02-26 22:31:07 +03:00
uint32 mapped_count = 0 ;
2001-03-11 03:32:10 +03:00
if ( ! find_policy_by_hnd ( p , & q_u - > pol , NULL ) )
return NT_STATUS_INVALID_HANDLE ;
2001-03-01 07:01:23 +03:00
ref = ( DOM_R_REF * ) talloc_zero ( p - > mem_ctx , sizeof ( DOM_R_REF ) ) ;
rids = ( DOM_RID2 * ) talloc_zero ( p - > mem_ctx , sizeof ( DOM_RID2 ) * MAX_LOOKUP_SIDS ) ;
if ( ! ref | | ! rids )
return NT_STATUS_NO_MEMORY ;
2001-02-26 22:31:07 +03:00
/* set up the LSA Lookup RIDs response */
2001-03-13 04:44:05 +03:00
init_lsa_rid2s ( ref , rids , num_entries , names , & mapped_count , p - > endian ) ;
2001-03-01 07:01:23 +03:00
init_reply_lookup_names ( r_u , ref , num_entries , rids , mapped_count ) ;
2001-02-26 22:31:07 +03:00
return r_u - > status ;
}
/***************************************************************************
_lsa_close . Also weird - needs to check if lsa handle is correct . JRA .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS _lsa_close ( pipes_struct * p , LSA_Q_CLOSE * q_u , LSA_R_CLOSE * r_u )
2001-02-26 22:31:07 +03:00
{
2001-03-11 03:32:10 +03:00
if ( ! find_policy_by_hnd ( p , & q_u - > pol , NULL ) )
return NT_STATUS_INVALID_HANDLE ;
close_policy_hnd ( p , & q_u - > pol ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2001-02-26 22:31:07 +03:00
}
/***************************************************************************
" No more secrets Marty.... " : - ) .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS _lsa_open_secret ( pipes_struct * p , LSA_Q_OPEN_SECRET * q_u , LSA_R_OPEN_SECRET * r_u )
2001-02-26 22:31:07 +03:00
{
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
}
2001-06-30 03:12:55 +04:00
2001-07-09 22:32:54 +04:00
/***************************************************************************
_lsa_enum_privs .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS _lsa_enum_privs ( pipes_struct * p , LSA_Q_ENUM_PRIVS * q_u , LSA_R_ENUM_PRIVS * r_u )
2001-07-09 22:32:54 +04:00
{
uint32 i ;
uint32 enum_context = q_u - > enum_context ;
LSA_PRIV_ENTRY * entry ;
2001-11-23 02:50:16 +03:00
LSA_PRIV_ENTRY * entries = NULL ;
2001-07-09 22:32:54 +04:00
if ( ! find_policy_by_hnd ( p , & q_u - > pol , NULL ) )
return NT_STATUS_INVALID_HANDLE ;
if ( enum_context > = PRIV_ALL_INDEX )
2001-08-27 23:46:22 +04:00
return NT_STATUS_UNABLE_TO_FREE_VM ;
2001-07-09 22:32:54 +04:00
2001-11-23 02:50:16 +03:00
entries = ( LSA_PRIV_ENTRY * ) talloc_zero ( p - > mem_ctx , sizeof ( LSA_PRIV_ENTRY ) * ( PRIV_ALL_INDEX ) ) ;
2001-07-09 22:32:54 +04:00
if ( entries = = NULL )
return NT_STATUS_NO_MEMORY ;
entry = entries ;
2001-11-23 02:50:16 +03:00
DEBUG ( 10 , ( " _lsa_enum_privs: enum_context:%d total entries:%d \n " , enum_context , PRIV_ALL_INDEX ) ) ;
for ( i = 0 ; i < PRIV_ALL_INDEX ; i + + , entry + + ) {
if ( i < enum_context ) {
init_uni_hdr ( & entry - > hdr_name , 0 ) ;
init_unistr2 ( & entry - > name , NULL , 0 ) ;
entry - > luid_low = 0 ;
entry - > luid_high = 0 ;
} else {
init_uni_hdr ( & entry - > hdr_name , strlen ( privs [ i + 1 ] . priv ) ) ;
init_unistr2 ( & entry - > name , privs [ i + 1 ] . priv , strlen ( privs [ i + 1 ] . priv ) ) ;
entry - > luid_low = privs [ i + 1 ] . se_priv ;
entry - > luid_high = 1 ;
}
2001-07-09 22:32:54 +04:00
}
2001-11-23 02:50:16 +03:00
enum_context = PRIV_ALL_INDEX ;
init_lsa_r_enum_privs ( r_u , enum_context , PRIV_ALL_INDEX , entries ) ;
2001-07-09 22:32:54 +04:00
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2001-07-09 22:32:54 +04:00
}
/***************************************************************************
_lsa_priv_get_dispname .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS _lsa_priv_get_dispname ( pipes_struct * p , LSA_Q_PRIV_GET_DISPNAME * q_u , LSA_R_PRIV_GET_DISPNAME * r_u )
2001-07-09 22:32:54 +04:00
{
fstring name_asc ;
2001-11-22 20:19:59 +03:00
int i = 1 ;
2001-07-09 22:32:54 +04:00
if ( ! find_policy_by_hnd ( p , & q_u - > pol , NULL ) )
return NT_STATUS_INVALID_HANDLE ;
unistr2_to_ascii ( name_asc , & q_u - > name , sizeof ( name_asc ) ) ;
2001-11-22 20:19:59 +03:00
DEBUG ( 10 , ( " _lsa_priv_get_dispname: %s " , name_asc ) ) ;
2001-07-09 22:32:54 +04:00
2001-11-22 20:19:59 +03:00
while ( privs [ i ] . se_priv ! = SE_PRIV_ALL & & strcmp ( name_asc , privs [ i ] . priv ) )
i + + ;
if ( privs [ i ] . se_priv ! = SE_PRIV_ALL ) {
2001-11-23 02:50:16 +03:00
DEBUG ( 10 , ( " : %s \n " , privs [ i ] . description ) ) ;
2001-11-22 20:19:59 +03:00
init_uni_hdr ( & r_u - > hdr_desc , strlen ( privs [ i ] . description ) ) ;
init_unistr2 ( & r_u - > desc , privs [ i ] . description , strlen ( privs [ i ] . description ) ) ;
2001-07-09 22:32:54 +04:00
2001-11-22 20:19:59 +03:00
r_u - > ptr_info = 0xdeadbeef ;
r_u - > lang_id = q_u - > lang_id ;
return NT_STATUS_OK ;
} else {
DEBUG ( 10 , ( " : doesn't exist \n " ) ) ;
r_u - > ptr_info = 0 ;
return NT_STATUS_NO_SUCH_PRIVILEGE ;
}
2001-07-09 22:32:54 +04:00
}
/***************************************************************************
_lsa_enum_accounts .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS _lsa_enum_accounts ( pipes_struct * p , LSA_Q_ENUM_ACCOUNTS * q_u , LSA_R_ENUM_ACCOUNTS * r_u )
2001-07-09 22:32:54 +04:00
{
GROUP_MAP * map = NULL ;
int num_entries = 0 ;
LSA_SID_ENUM * sids = & r_u - > sids ;
int i = 0 , j = 0 ;
if ( ! find_policy_by_hnd ( p , & q_u - > pol , NULL ) )
return NT_STATUS_INVALID_HANDLE ;
/* get the list of mapped groups (domain, local, builtin) */
if ( ! enum_group_mapping ( SID_NAME_UNKNOWN , & map , & num_entries , ENUM_ONLY_MAPPED ) )
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2001-07-09 22:32:54 +04:00
sids - > ptr_sid = ( uint32 * ) talloc_zero ( p - > mem_ctx , ( num_entries - q_u - > enum_context ) * sizeof ( uint32 ) ) ;
sids - > sid = ( DOM_SID2 * ) talloc_zero ( p - > mem_ctx , ( num_entries - q_u - > enum_context ) * sizeof ( DOM_SID2 ) ) ;
if ( sids - > ptr_sid = = NULL | | sids - > sid = = NULL ) {
2001-09-17 14:26:23 +04:00
SAFE_FREE ( map ) ;
2001-07-09 22:32:54 +04:00
return NT_STATUS_NO_MEMORY ;
}
for ( i = q_u - > enum_context , j = 0 ; i < num_entries ; i + + ) {
init_dom_sid2 ( & ( * sids ) . sid [ j ] , & map [ i ] . sid ) ;
( * sids ) . ptr_sid [ j ] = 1 ;
j + + ;
}
2001-09-17 14:26:23 +04:00
SAFE_FREE ( map ) ;
2001-07-09 22:32:54 +04:00
init_lsa_r_enum_accounts ( r_u , j ) ;
2001-08-27 23:46:22 +04:00
return NT_STATUS_OK ;
2001-07-09 22:32:54 +04:00
}
2001-08-27 23:46:22 +04:00
NTSTATUS _lsa_unk_get_connuser ( pipes_struct * p , LSA_Q_UNK_GET_CONNUSER * q_u , LSA_R_UNK_GET_CONNUSER * r_u )
2001-06-30 03:12:55 +04:00
{
fstring username , domname ;
int ulen , dlen ;
user_struct * vuser = get_valid_user_struct ( p - > vuid ) ;
if ( vuser = = NULL )
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO ;
fstrcpy ( username , vuser - > user . smb_name ) ;
fstrcpy ( domname , vuser - > user . domain ) ;
2001-10-10 00:54:56 +04:00
ulen = strlen ( username ) + 1 ;
dlen = strlen ( domname ) + 1 ;
2001-06-30 03:12:55 +04:00
init_uni_hdr ( & r_u - > hdr_user_name , ulen ) ;
r_u - > ptr_user_name = 1 ;
init_unistr2 ( & r_u - > uni2_user_name , username , ulen ) ;
r_u - > unk1 = 1 ;
init_uni_hdr ( & r_u - > hdr_dom_name , dlen ) ;
r_u - > ptr_dom_name = 1 ;
init_unistr2 ( & r_u - > uni2_dom_name , domname , dlen ) ;
2001-08-27 23:46:22 +04:00
r_u - > status = NT_STATUS_OK ;
2001-06-30 03:12:55 +04:00
return r_u - > status ;
}
2001-07-09 22:32:54 +04:00
/***************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS _lsa_open_account ( pipes_struct * p , LSA_Q_OPENACCOUNT * q_u , LSA_R_OPENACCOUNT * r_u )
2001-07-09 22:32:54 +04:00
{
struct lsa_info * info ;
2001-08-27 23:46:22 +04:00
r_u - > status = NT_STATUS_OK ;
2001-07-09 22:32:54 +04:00
/* find the connection policy handle. */
if ( ! find_policy_by_hnd ( p , & q_u - > pol , NULL ) )
return NT_STATUS_INVALID_HANDLE ;
/* associate the user/group SID with the (unique) handle. */
if ( ( info = ( struct lsa_info * ) malloc ( sizeof ( struct lsa_info ) ) ) = = NULL )
return NT_STATUS_NO_MEMORY ;
ZERO_STRUCTP ( info ) ;
info - > sid = q_u - > sid . sid ;
info - > access = q_u - > access ;
/* get a (unique) handle. open a policy on it. */
if ( ! create_policy_hnd ( p , & r_u - > pol , free_lsa_info , ( void * ) info ) )
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
return r_u - > status ;
}
/***************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS _lsa_enum_privsaccount ( pipes_struct * p , LSA_Q_ENUMPRIVSACCOUNT * q_u , LSA_R_ENUMPRIVSACCOUNT * r_u )
2001-07-09 22:32:54 +04:00
{
struct lsa_info * info = NULL ;
GROUP_MAP map ;
uint32 count = 0 ;
int i = 0 ;
LUID_ATTR * set = NULL ;
2001-08-27 23:46:22 +04:00
r_u - > status = NT_STATUS_OK ;
2001-07-09 22:32:54 +04:00
/* find the connection policy handle. */
if ( ! find_policy_by_hnd ( p , & q_u - > pol , ( void * * ) & info ) )
return NT_STATUS_INVALID_HANDLE ;
if ( ! get_group_map_from_sid ( info - > sid , & map ) )
return NT_STATUS_NO_SUCH_GROUP ;
for ( i = 1 ; privs [ i ] . se_priv ! = SE_PRIV_ALL ; i + + ) {
if ( ( map . privilege & privs [ i ] . se_priv ) = = privs [ i ] . se_priv ) {
set = ( LUID_ATTR * ) talloc_realloc ( p - > mem_ctx , set , ( count + 1 ) * sizeof ( LUID_ATTR ) ) ;
2001-10-04 01:10:29 +04:00
if ( set = = NULL ) return NT_STATUS_NO_MEMORY ;
2001-07-09 22:32:54 +04:00
set [ count ] . luid . low = privs [ i ] . se_priv ;
set [ count ] . luid . high = 1 ;
set [ count ] . attr = 0 ;
count + + ;
}
}
init_lsa_r_enum_privsaccount ( r_u , set , count , 0 ) ;
return r_u - > status ;
}
/***************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-08-27 23:46:22 +04:00
NTSTATUS _lsa_getsystemaccount ( pipes_struct * p , LSA_Q_GETSYSTEMACCOUNT * q_u , LSA_R_GETSYSTEMACCOUNT * r_u )
2001-07-09 22:32:54 +04:00
{
2001-08-27 23:46:22 +04:00
r_u - > status = NT_STATUS_OK ;
2001-07-09 22:32:54 +04:00
/* find the connection policy handle. */
if ( ! find_policy_by_hnd ( p , & q_u - > pol , NULL ) )
return NT_STATUS_INVALID_HANDLE ;
r_u - > access = 3 ;
return r_u - > status ;
}