2005-09-03 16:55:45 +00:00
/*
* Unix SMB / CIFS implementation .
* MS - RPC client library implementation ( SAMR pipe )
* Copyright ( C ) Chris Nicholls 2005.
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "libmsrpc.h"
# include "libmsrpc_internal.h"
/*used by cac_SamGetNamesFromRids*/
# define SAMR_RID_UNKNOWN 8
# define SAMR_ENUM_MAX_SIZE 0xffff
/*not sure what this is.. taken from rpcclient/cmd_samr.c*/
# define SAMR_LOOKUP_FLAGS 0x000003e8
int cac_SamConnect ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamConnect * op ) {
SMBCSRV * srv = NULL ;
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
POLICY_HND * sam_out = NULL ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | op - > in . access = = 0 | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
srv = cac_GetServer ( hnd ) ;
if ( ! srv ) {
hnd - > status = NT_STATUS_INVALID_CONNECTION ;
return CAC_FAILURE ;
}
/*initialize for samr pipe if we have to*/
if ( ! hnd - > _internal . pipes [ PI_SAMR ] ) {
2005-10-17 16:44:26 +00:00
if ( ! ( pipe_hnd = cli_rpc_pipe_open_noauth ( & srv - > cli , PI_SAMR , & ( hnd - > status ) ) ) ) {
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
hnd - > _internal . pipes [ PI_SAMR ] = True ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
2005-09-03 16:55:45 +00:00
sam_out = talloc ( mem_ctx , POLICY_HND ) ;
if ( ! sam_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
if ( hnd - > _internal . srv_level > = SRV_WIN_2K_SP3 ) {
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_connect4 ( pipe_hnd , mem_ctx , op - > in . access , sam_out ) ;
2005-09-03 16:55:45 +00:00
}
if ( hnd - > _internal . srv_level < SRV_WIN_2K_SP3 | | ! NT_STATUS_IS_OK ( hnd - > status ) ) {
/*if sam_connect4 failed, the use sam_connect and lower srv_level*/
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_connect ( pipe_hnd , mem_ctx , op - > in . access , sam_out ) ;
2005-09-03 16:55:45 +00:00
if ( NT_STATUS_IS_OK ( hnd - > status ) & & hnd - > _internal . srv_level > SRV_WIN_2K ) {
hnd - > _internal . srv_level = SRV_WIN_2K ;
}
}
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > out . sam = sam_out ;
return CAC_SUCCESS ;
}
int cac_SamClose ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , POLICY_HND * sam ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! sam | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_close ( pipe_hnd , mem_ctx , sam ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
/*this is an internal function. Due to a circular dependency, it must be prototyped in libmsrpc.h (which I don't want to do)
* cac_SamOpenDomain ( ) is the only function that calls it , so I just put the definition here
*/
/*attempts to find the sid of the domain we are connected to*/
DOM_SID * cac_get_domain_sid ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , uint32 des_access ) {
struct LsaOpenPolicy lop ;
struct LsaFetchSid fs ;
DOM_SID * sid ;
ZERO_STRUCT ( lop ) ;
ZERO_STRUCT ( fs ) ;
lop . in . access = des_access ;
lop . in . security_qos = True ;
if ( ! cac_LsaOpenPolicy ( hnd , mem_ctx , & lop ) )
return NULL ;
fs . in . pol = lop . out . pol ;
fs . in . info_class = CAC_DOMAIN_INFO ;
if ( ! cac_LsaFetchSid ( hnd , mem_ctx , & fs ) )
return NULL ;
cac_LsaClosePolicy ( hnd , mem_ctx , lop . out . pol ) ;
if ( ! fs . out . domain_sid )
return NULL ;
sid = talloc_memdup ( mem_ctx , & ( fs . out . domain_sid - > sid ) , sizeof ( DOM_SID ) ) ;
if ( ! sid ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
}
return sid ;
}
int cac_SamOpenDomain ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamOpenDomain * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
DOM_SID * sid_buf ;
POLICY_HND * sam_out ;
POLICY_HND * pol_out ;
struct SamLookupDomain sld ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | op - > in . access = = 0 | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
if ( ! op - > in . sam ) {
/*use cac_SamConnect() since it does the session setup*/
struct SamConnect sc ;
ZERO_STRUCT ( sc ) ;
sc . in . access = op - > in . access ;
if ( ! cac_SamConnect ( hnd , mem_ctx , & sc ) ) {
return CAC_FAILURE ;
}
sam_out = sc . out . sam ;
}
else {
sam_out = op - > in . sam ;
}
if ( ! op - > in . sid ) {
/*find the sid for the SAM's domain*/
/*try using cac_SamLookupDomain() first*/
ZERO_STRUCT ( sld ) ;
sld . in . sam = sam_out ;
sld . in . name = hnd - > domain ;
if ( cac_SamLookupDomain ( hnd , mem_ctx , & sld ) ) {
/*then we got the sid*/
sid_buf = sld . out . sid ;
}
else {
/*try to get it from the LSA*/
sid_buf = cac_get_domain_sid ( hnd , mem_ctx , op - > in . access ) ;
}
}
else {
/*we already have the sid for the domain we want*/
sid_buf = op - > in . sid ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
2005-09-03 16:55:45 +00:00
pol_out = talloc ( mem_ctx , POLICY_HND ) ;
if ( ! pol_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
/*now open the domain*/
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_open_domain ( pipe_hnd , mem_ctx , sam_out , op - > in . access , sid_buf , pol_out ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > out . sam = sam_out ;
op - > out . dom_hnd = pol_out ;
return CAC_SUCCESS ;
}
int cac_SamOpenUser ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamOpenUser * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
uint32 * rid_buf = NULL ;
uint32 num_rids = 0 ;
uint32 * rid_types = NULL ;
POLICY_HND * user_out = NULL ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . dom_hnd | | op - > in . access = = 0 | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
if ( op - > in . rid = = 0 & & op - > in . name = = NULL ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
if ( op - > in . rid = = 0 & & op - > in . name ) {
/*lookup the name and then set rid_buf*/
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_lookup_names ( pipe_hnd , mem_ctx , op - > in . dom_hnd , SAMR_LOOKUP_FLAGS , 1 , ( const char * * ) & op - > in . name ,
2005-09-03 16:55:45 +00:00
& num_rids , & rid_buf , & rid_types ) ;
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
if ( num_rids = = 0 | | rid_buf = = NULL | | rid_types [ 0 ] = = SAMR_RID_UNKNOWN ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
talloc_free ( rid_types ) ;
}
else {
rid_buf = & op - > in . rid ;
}
user_out = talloc ( mem_ctx , POLICY_HND ) ;
if ( ! user_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_open_user ( pipe_hnd , mem_ctx , op - > in . dom_hnd , op - > in . access , * rid_buf , user_out ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > out . user_hnd = user_out ;
return CAC_SUCCESS ;
}
int cac_SamCreateUser ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamCreateUser * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
POLICY_HND * user_out = NULL ;
uint32 rid_out ;
/**found in rpcclient/cmd_samr.c*/
uint32 unknown = 0xe005000b ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . dom_hnd | | ! op - > in . name | | op - > in . acb_mask = = 0 | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
user_out = talloc ( mem_ctx , POLICY_HND ) ;
if ( ! user_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_create_dom_user ( pipe_hnd , mem_ctx , op - > in . dom_hnd , op - > in . name , op - > in . acb_mask , unknown , user_out , & rid_out ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > out . user_hnd = user_out ;
op - > out . rid = rid_out ;
return CAC_SUCCESS ;
}
int cac_SamDeleteUser ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , POLICY_HND * user_hnd ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! user_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_delete_dom_user ( pipe_hnd , mem_ctx , user_hnd ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamEnumUsers ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamEnumUsers * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
uint32 resume_idx_out = 0 ;
char * * names_out = NULL ;
uint32 * rids_out = NULL ;
uint32 num_users_out = 0 ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . dom_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
/*this is a hack.. but is the only reliable way to know if everything has been enumerated*/
if ( op - > out . done = = True )
return CAC_FAILURE ;
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
resume_idx_out = op - > out . resume_idx ;
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_enum_dom_users ( pipe_hnd , mem_ctx , op - > in . dom_hnd , & resume_idx_out , op - > in . acb_mask , SAMR_ENUM_MAX_SIZE ,
2005-09-03 16:55:45 +00:00
& names_out , & rids_out , & num_users_out ) ;
if ( NT_STATUS_IS_OK ( hnd - > status ) )
op - > out . done = True ;
/*if there are no more entries, the operation will return NT_STATUS_OK.
* We want to return failure if no results were returned */
if ( ! NT_STATUS_IS_OK ( hnd - > status ) & & NT_STATUS_V ( hnd - > status ) ! = NT_STATUS_V ( STATUS_MORE_ENTRIES ) )
return CAC_FAILURE ;
op - > out . resume_idx = resume_idx_out ;
op - > out . num_users = num_users_out ;
op - > out . rids = rids_out ;
op - > out . names = names_out ;
return CAC_SUCCESS ;
}
int cac_SamGetNamesFromRids ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamGetNamesFromRids * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
uint32 num_names_out ;
char * * names_out ;
uint32 * name_types_out ;
uint32 i = 0 ;
CacLookupRidsRecord * map_out ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . dom_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
if ( ! op - > in . rids & & op - > in . num_rids ! = 0 ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
if ( op - > in . num_rids = = 0 ) {
/*nothing to do*/
op - > out . num_names = 0 ;
return CAC_SUCCESS ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_lookup_rids ( pipe_hnd , mem_ctx , op - > in . dom_hnd , op - > in . num_rids , op - > in . rids , & num_names_out , & names_out , & name_types_out ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) & & ! NT_STATUS_EQUAL ( hnd - > status , STATUS_SOME_UNMAPPED ) )
return CAC_FAILURE ;
map_out = TALLOC_ARRAY ( mem_ctx , CacLookupRidsRecord , num_names_out ) ;
if ( ! map_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
for ( i = 0 ; i < num_names_out ; i + + ) {
if ( name_types_out [ i ] = = SAMR_RID_UNKNOWN ) {
map_out [ i ] . found = False ;
map_out [ i ] . name = NULL ;
map_out [ i ] . type = 0 ;
}
else {
map_out [ i ] . found = True ;
map_out [ i ] . name = talloc_strdup ( mem_ctx , names_out [ i ] ) ;
map_out [ i ] . type = name_types_out [ i ] ;
}
map_out [ i ] . rid = op - > in . rids [ i ] ;
}
talloc_free ( names_out ) ;
talloc_free ( name_types_out ) ;
op - > out . num_names = num_names_out ;
op - > out . map = map_out ;
if ( NT_STATUS_EQUAL ( hnd - > status , STATUS_SOME_UNMAPPED ) )
return CAC_PARTIAL_SUCCESS ;
return CAC_SUCCESS ;
}
int cac_SamGetRidsFromNames ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamGetRidsFromNames * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
uint32 num_rids_out ;
uint32 * rids_out ;
uint32 * rid_types_out ;
uint32 i = 0 ;
CacLookupRidsRecord * map_out ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . dom_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
if ( ! op - > in . names & & op - > in . num_names ! = 0 ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
if ( op - > in . num_names = = 0 ) {
/*then we don't have to do anything*/
op - > out . num_rids = 0 ;
return CAC_SUCCESS ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_lookup_names ( pipe_hnd , mem_ctx , op - > in . dom_hnd , SAMR_LOOKUP_FLAGS , op - > in . num_names , ( const char * * ) op - > in . names ,
2005-09-03 16:55:45 +00:00
& num_rids_out , & rids_out , & rid_types_out ) ;
if ( ! NT_STATUS_IS_OK ( hnd - > status ) & & ! NT_STATUS_EQUAL ( hnd - > status , STATUS_SOME_UNMAPPED ) )
return CAC_FAILURE ;
map_out = TALLOC_ARRAY ( mem_ctx , CacLookupRidsRecord , num_rids_out ) ;
if ( ! map_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
for ( i = 0 ; i < num_rids_out ; i + + ) {
if ( rid_types_out [ i ] = = SAMR_RID_UNKNOWN ) {
map_out [ i ] . found = False ;
map_out [ i ] . rid = 0 ;
map_out [ i ] . type = 0 ;
}
else {
map_out [ i ] . found = True ;
map_out [ i ] . rid = rids_out [ i ] ;
map_out [ i ] . type = rid_types_out [ i ] ;
}
map_out [ i ] . name = talloc_strdup ( mem_ctx , op - > in . names [ i ] ) ;
}
op - > out . num_rids = num_rids_out ;
op - > out . map = map_out ;
talloc_free ( rids_out ) ;
talloc_free ( rid_types_out ) ;
if ( NT_STATUS_EQUAL ( hnd - > status , STATUS_SOME_UNMAPPED ) )
return CAC_PARTIAL_SUCCESS ;
return CAC_SUCCESS ;
}
int cac_SamGetGroupsForUser ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamGetGroupsForUser * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
DOM_GID * groups = NULL ;
uint32 num_groups_out = 0 ;
uint32 * rids_out = NULL ;
uint32 * attr_out = NULL ;
uint32 i ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . user_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_query_usergroups ( pipe_hnd , mem_ctx , op - > in . user_hnd , & num_groups_out , & groups ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
rids_out = talloc_array ( mem_ctx , uint32 , num_groups_out ) ;
if ( ! rids_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
attr_out = talloc_array ( mem_ctx , uint32 , num_groups_out ) ;
if ( ! attr_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
for ( i = 0 ; i < num_groups_out ; i + + ) {
rids_out [ i ] = groups [ i ] . g_rid ;
attr_out [ i ] = groups [ i ] . attr ;
}
talloc_free ( groups ) ;
op - > out . num_groups = num_groups_out ;
op - > out . rids = rids_out ;
op - > out . attributes = attr_out ;
return CAC_SUCCESS ;
}
int cac_SamOpenGroup ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamOpenGroup * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
POLICY_HND * group_hnd_out = NULL ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | op - > in . access = = 0 | | op - > in . rid = = 0 | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
group_hnd_out = talloc ( mem_ctx , POLICY_HND ) ;
if ( ! group_hnd_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_open_group ( pipe_hnd , mem_ctx , op - > in . dom_hnd , op - > in . access , op - > in . rid , group_hnd_out ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > out . group_hnd = group_hnd_out ;
return CAC_SUCCESS ;
}
int cac_SamCreateGroup ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamCreateGroup * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
POLICY_HND * group_hnd_out = NULL ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . name | | op - > in . name [ 0 ] = = ' \0 ' | | op - > in . access = = 0 | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
group_hnd_out = talloc ( mem_ctx , POLICY_HND ) ;
if ( ! group_hnd_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_create_dom_group ( pipe_hnd , mem_ctx , op - > in . dom_hnd , op - > in . name , op - > in . access , group_hnd_out ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > out . group_hnd = group_hnd_out ;
return CAC_SUCCESS ;
}
int cac_SamDeleteGroup ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , POLICY_HND * group_hnd ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! group_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_delete_dom_group ( pipe_hnd , mem_ctx , group_hnd ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamGetGroupMembers ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamGetGroupMembers * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
uint32 num_mem_out ;
uint32 * rids_out ;
uint32 * attr_out ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . group_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_query_groupmem ( pipe_hnd , mem_ctx , op - > in . group_hnd , & num_mem_out , & rids_out , & attr_out ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > out . num_members = num_mem_out ;
op - > out . rids = rids_out ;
op - > out . attributes = attr_out ;
return CAC_SUCCESS ;
}
int cac_SamAddGroupMember ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamAddGroupMember * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . group_hnd | | op - > in . rid = = 0 | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_add_groupmem ( pipe_hnd , mem_ctx , op - > in . group_hnd , op - > in . rid ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamRemoveGroupMember ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamRemoveGroupMember * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . group_hnd | | op - > in . rid = = 0 | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_del_groupmem ( pipe_hnd , mem_ctx , op - > in . group_hnd , op - > in . rid ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamClearGroupMembers ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , POLICY_HND * group_hnd ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
int result = CAC_SUCCESS ;
uint32 i = 0 ;
uint32 num_mem = 0 ;
uint32 * rid = NULL ;
uint32 * attr = NULL ;
NTSTATUS status ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! group_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_query_groupmem ( pipe_hnd , mem_ctx , group_hnd , & num_mem , & rid , & attr ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
/*try to delete the users one by one*/
for ( i = 0 ; i < num_mem & & NT_STATUS_IS_OK ( hnd - > status ) ; i + + ) {
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_del_groupmem ( pipe_hnd , mem_ctx , group_hnd , rid [ i ] ) ;
2005-09-03 16:55:45 +00:00
}
/*if not all members could be removed, then try to re-add the members that were already deleted*/
if ( ! NT_STATUS_IS_OK ( hnd - > status ) ) {
status = NT_STATUS_OK ;
for ( i - = 1 ; i > = 0 & & NT_STATUS_IS_OK ( status ) ; i - - ) {
2005-10-17 16:44:26 +00:00
status = rpccli_samr_add_groupmem ( pipe_hnd , mem_ctx , group_hnd , rid [ i ] ) ;
2005-09-03 16:55:45 +00:00
}
/*we return with the NTSTATUS error that we got when trying to delete users*/
if ( ! NT_STATUS_IS_OK ( status ) )
result = CAC_FAILURE ;
}
talloc_free ( attr ) ;
return result ;
}
int cac_SamSetGroupMembers ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamSetGroupMembers * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
uint32 i = 0 ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . group_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
/*use cac_SamClearGroupMembers() to clear them*/
if ( ! cac_SamClearGroupMembers ( hnd , mem_ctx , op - > in . group_hnd ) )
return CAC_FAILURE ; /*hnd->status is already set*/
for ( i = 0 ; i < op - > in . num_members & & NT_STATUS_IS_OK ( hnd - > status ) ; i + + ) {
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_add_groupmem ( pipe_hnd , mem_ctx , op - > in . group_hnd , op - > in . rids [ i ] ) ;
2005-09-03 16:55:45 +00:00
}
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamEnumGroups ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamEnumGroups * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
uint32 i = 0 ;
uint32 resume_idx_out = 0 ;
char * * names_out = NULL ;
char * * desc_out = NULL ;
uint32 * rids_out = NULL ;
uint32 num_groups_out = 0 ;
struct acct_info * acct_buf = NULL ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . dom_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
/*using this BOOL is the only reliable way to know that we are done*/
if ( op - > out . done = = True ) /*we return failure so the call will break out of a loop*/
return CAC_FAILURE ;
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
resume_idx_out = op - > out . resume_idx ;
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_enum_dom_groups ( pipe_hnd , mem_ctx , op - > in . dom_hnd , & resume_idx_out , SAMR_ENUM_MAX_SIZE ,
2005-09-03 16:55:45 +00:00
& acct_buf , & num_groups_out ) ;
if ( NT_STATUS_IS_OK ( hnd - > status ) ) {
op - > out . done = True ;
}
else if ( NT_STATUS_V ( hnd - > status ) ! = NT_STATUS_V ( STATUS_MORE_ENTRIES ) ) {
/*if there are no more entries, the operation will return NT_STATUS_OK.
* We want to return failure if no results were returned */
return CAC_FAILURE ;
}
names_out = talloc_array ( mem_ctx , char * , num_groups_out ) ;
if ( ! names_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
talloc_free ( acct_buf ) ;
return CAC_FAILURE ;
}
desc_out = talloc_array ( mem_ctx , char * , num_groups_out ) ;
if ( ! desc_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
talloc_free ( acct_buf ) ;
talloc_free ( names_out ) ;
return CAC_FAILURE ;
}
rids_out = talloc_array ( mem_ctx , uint32 , num_groups_out ) ;
if ( ! rids_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
talloc_free ( acct_buf ) ;
talloc_free ( names_out ) ;
talloc_free ( desc_out ) ;
return CAC_FAILURE ;
}
for ( i = 0 ; i < num_groups_out ; i + + ) {
names_out [ i ] = talloc_strdup ( mem_ctx , acct_buf [ i ] . acct_name ) ;
desc_out [ i ] = talloc_strdup ( mem_ctx , acct_buf [ i ] . acct_desc ) ;
rids_out [ i ] = acct_buf [ i ] . rid ;
if ( ! names_out [ i ] | | ! desc_out [ i ] ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
}
op - > out . resume_idx = resume_idx_out ;
op - > out . num_groups = num_groups_out ;
op - > out . rids = rids_out ;
op - > out . names = names_out ;
op - > out . descriptions = desc_out ;
return CAC_SUCCESS ;
}
int cac_SamEnumAliases ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamEnumAliases * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
uint32 i = 0 ;
uint32 resume_idx_out = 0 ;
char * * names_out = NULL ;
char * * desc_out = NULL ;
uint32 * rids_out = NULL ;
uint32 num_als_out = 0 ;
struct acct_info * acct_buf = NULL ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . dom_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
/*this is a hack.. but is the only reliable way to know if everything has been enumerated*/
if ( op - > out . done = = True ) {
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
resume_idx_out = op - > out . resume_idx ;
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_enum_als_groups ( pipe_hnd , mem_ctx , op - > in . dom_hnd , & resume_idx_out , SAMR_ENUM_MAX_SIZE ,
2005-09-03 16:55:45 +00:00
& acct_buf , & num_als_out ) ;
if ( NT_STATUS_IS_OK ( hnd - > status ) )
op - > out . done = True ;
/*if there are no more entries, the operation will return NT_STATUS_OK.
* We want to return failure if no results were returned */
if ( ! NT_STATUS_IS_OK ( hnd - > status ) & & NT_STATUS_V ( hnd - > status ) ! = NT_STATUS_V ( STATUS_MORE_ENTRIES ) )
return CAC_FAILURE ;
names_out = talloc_array ( mem_ctx , char * , num_als_out ) ;
if ( ! names_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
talloc_free ( acct_buf ) ;
return CAC_FAILURE ;
}
desc_out = talloc_array ( mem_ctx , char * , num_als_out ) ;
if ( ! desc_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
talloc_free ( acct_buf ) ;
talloc_free ( names_out ) ;
return CAC_FAILURE ;
}
rids_out = talloc_array ( mem_ctx , uint32 , num_als_out ) ;
if ( ! rids_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
talloc_free ( acct_buf ) ;
talloc_free ( names_out ) ;
talloc_free ( desc_out ) ;
return CAC_FAILURE ;
}
for ( i = 0 ; i < num_als_out ; i + + ) {
names_out [ i ] = talloc_strdup ( mem_ctx , acct_buf [ i ] . acct_name ) ;
desc_out [ i ] = talloc_strdup ( mem_ctx , acct_buf [ i ] . acct_desc ) ;
rids_out [ i ] = acct_buf [ i ] . rid ;
if ( ! names_out [ i ] | | ! desc_out [ i ] ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
}
op - > out . resume_idx = resume_idx_out ;
op - > out . num_aliases = num_als_out ;
op - > out . rids = rids_out ;
op - > out . names = names_out ;
op - > out . descriptions = desc_out ;
return CAC_SUCCESS ;
}
int cac_SamCreateAlias ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamCreateAlias * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
POLICY_HND * als_hnd_out = NULL ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . name | | op - > in . name [ 0 ] = = ' \0 ' | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
als_hnd_out = talloc ( mem_ctx , POLICY_HND ) ;
if ( ! als_hnd_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_create_dom_alias ( pipe_hnd , mem_ctx , op - > in . dom_hnd , op - > in . name , als_hnd_out ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > out . alias_hnd = als_hnd_out ;
return CAC_SUCCESS ;
}
int cac_SamOpenAlias ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamOpenAlias * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
POLICY_HND * als_hnd_out = NULL ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | op - > in . access = = 0 | | op - > in . rid = = 0 | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
als_hnd_out = talloc ( mem_ctx , POLICY_HND ) ;
if ( ! als_hnd_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_open_alias ( pipe_hnd , mem_ctx , op - > in . dom_hnd , op - > in . access , op - > in . rid , als_hnd_out ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > out . alias_hnd = als_hnd_out ;
return CAC_SUCCESS ;
}
int cac_SamDeleteAlias ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , POLICY_HND * alias_hnd ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! alias_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_delete_dom_alias ( pipe_hnd , mem_ctx , alias_hnd ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamAddAliasMember ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamAddAliasMember * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . alias_hnd | | ! op - > in . sid | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_add_aliasmem ( pipe_hnd , mem_ctx , op - > in . alias_hnd , op - > in . sid ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamRemoveAliasMember ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamRemoveAliasMember * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . alias_hnd | | ! op - > in . sid | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_del_aliasmem ( pipe_hnd , mem_ctx , op - > in . alias_hnd , op - > in . sid ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamGetAliasMembers ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamGetAliasMembers * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
uint32 num_mem_out ;
DOM_SID * sids_out ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . alias_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_query_aliasmem ( pipe_hnd , mem_ctx , op - > in . alias_hnd , & num_mem_out , & sids_out ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > out . num_members = num_mem_out ;
op - > out . sids = sids_out ;
return CAC_SUCCESS ;
}
int cac_SamClearAliasMembers ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , POLICY_HND * alias_hnd ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
int result = CAC_SUCCESS ;
uint32 i = 0 ;
uint32 num_mem = 0 ;
DOM_SID * sid = NULL ;
NTSTATUS status ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! alias_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_query_aliasmem ( pipe_hnd , mem_ctx , alias_hnd , & num_mem , & sid ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
/*try to delete the users one by one*/
for ( i = 0 ; i < num_mem & & NT_STATUS_IS_OK ( hnd - > status ) ; i + + ) {
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_del_aliasmem ( pipe_hnd , mem_ctx , alias_hnd , & sid [ i ] ) ;
2005-09-03 16:55:45 +00:00
}
/*if not all members could be removed, then try to re-add the members that were already deleted*/
if ( ! NT_STATUS_IS_OK ( hnd - > status ) ) {
status = NT_STATUS_OK ;
for ( i - = 1 ; i > = 0 & & NT_STATUS_IS_OK ( status ) ; i - - ) {
2005-10-17 16:44:26 +00:00
status = rpccli_samr_add_aliasmem ( pipe_hnd , mem_ctx , alias_hnd , & sid [ i ] ) ;
2005-09-03 16:55:45 +00:00
}
/*we return with the NTSTATUS error that we got when trying to delete users*/
if ( ! NT_STATUS_IS_OK ( status ) )
result = CAC_FAILURE ;
}
talloc_free ( sid ) ;
return result ;
}
int cac_SamSetAliasMembers ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamSetAliasMembers * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
uint32 i = 0 ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . alias_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
/*use cac_SamClearAliasMembers() to clear them*/
if ( ! cac_SamClearAliasMembers ( hnd , mem_ctx , op - > in . alias_hnd ) )
return CAC_FAILURE ; /*hnd->status is already set*/
for ( i = 0 ; i < op - > in . num_members & & NT_STATUS_IS_OK ( hnd - > status ) ; i + + ) {
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_add_aliasmem ( pipe_hnd , mem_ctx , op - > in . alias_hnd , & ( op - > in . sids [ i ] ) ) ;
2005-09-03 16:55:45 +00:00
}
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamUserChangePasswd ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamUserChangePasswd * op ) {
SMBCSRV * srv = NULL ;
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . username | | ! op - > in . password | | ! op - > in . new_password | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
srv = cac_GetServer ( hnd ) ;
if ( ! srv ) {
hnd - > status = NT_STATUS_INVALID_CONNECTION ;
return CAC_FAILURE ;
}
/*open a session on SAMR if we don't have one*/
if ( ! hnd - > _internal . pipes [ PI_SAMR ] ) {
2005-10-17 16:44:26 +00:00
if ( ! ( pipe_hnd = cli_rpc_pipe_open_noauth ( & srv - > cli , PI_SAMR , & ( hnd - > status ) ) ) ) {
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
hnd - > _internal . pipes [ PI_SAMR ] = True ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
2005-09-03 16:55:45 +00:00
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_chgpasswd_user ( pipe_hnd , mem_ctx , op - > in . username , op - > in . new_password , op - > in . password ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamEnableUser ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , POLICY_HND * user_hnd ) {
SMBCSRV * srv = NULL ;
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
SAM_USERINFO_CTR * ctr ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! user_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
srv = cac_GetServer ( hnd ) ;
if ( ! srv ) {
hnd - > status = NT_STATUS_INVALID_CONNECTION ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
2005-09-03 16:55:45 +00:00
/*info_level = 21 is the only level that I have found to work reliably. It would be nice if user_level = 10 worked.*/
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_query_userinfo ( pipe_hnd , mem_ctx , user_hnd , 0x10 , & ctr ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
/**check the ACB mask*/
if ( ( ctr - > info . id16 - > acb_info & ACB_DISABLED ) = = ACB_DISABLED ) {
/*toggle the disabled bit*/
ctr - > info . id16 - > acb_info ^ = ACB_DISABLED ;
}
else {
/*the user is already enabled so just return success*/
return CAC_SUCCESS ;
}
/*now set the userinfo*/
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_set_userinfo2 ( pipe_hnd , mem_ctx , user_hnd , 0x10 , & ( srv - > cli . user_session_key ) , ctr ) ;
2005-09-03 16:55:45 +00:00
/*this will only work properly if we use set_userinfo2 - fail if it is not supported*/
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamDisableUser ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , POLICY_HND * user_hnd ) {
SMBCSRV * srv = NULL ;
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
SAM_USERINFO_CTR * ctr ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! user_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
srv = cac_GetServer ( hnd ) ;
if ( ! srv ) {
hnd - > status = NT_STATUS_INVALID_CONNECTION ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
2005-09-03 16:55:45 +00:00
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_query_userinfo ( pipe_hnd , mem_ctx , user_hnd , 0x10 , & ctr ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
if ( ( ctr - > info . id16 - > acb_info & ACB_DISABLED ) = = ACB_DISABLED ) {
/*then the user is already disabled*/
return CAC_SUCCESS ;
}
/*toggle the disabled bit*/
ctr - > info . id16 - > acb_info ^ = ACB_DISABLED ;
/*this will only work properly if we use set_userinfo2*/
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_set_userinfo2 ( pipe_hnd , mem_ctx , user_hnd , 0x10 , & ( srv - > cli . user_session_key ) , ctr ) ;
2005-09-03 16:55:45 +00:00
/*this will only work properly if we use set_userinfo2 fail if it is not supported*/
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamSetPassword ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamSetPassword * op ) {
SMBCSRV * srv = NULL ;
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
SAM_USERINFO_CTR ctr ;
SAM_USER_INFO_24 info24 ;
uint8 pw [ 516 ] ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . user_hnd | | ! op - > in . password | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
srv = cac_GetServer ( hnd ) ;
if ( ! srv ) {
hnd - > status = NT_STATUS_INVALID_CONNECTION ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
2005-09-03 16:55:45 +00:00
ZERO_STRUCT ( ctr ) ;
ZERO_STRUCT ( info24 ) ;
encode_pw_buffer ( pw , op - > in . password , STR_UNICODE ) ;
init_sam_user_info24 ( & info24 , ( char * ) pw , 24 ) ;
ctr . switch_value = 24 ;
ctr . info . id24 = & info24 ;
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_set_userinfo ( pipe_hnd , mem_ctx , op - > in . user_hnd , 24 , & ( srv - > cli . user_session_key ) , & ctr ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamGetUserInfo ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamGetUserInfo * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
SAM_USERINFO_CTR * ctr ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . user_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_query_userinfo ( pipe_hnd , mem_ctx , op - > in . user_hnd , 21 , & ctr ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > out . info = cac_MakeUserInfo ( mem_ctx , ctr ) ;
if ( ! op - > out . info ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
return CAC_SUCCESS ;
}
int cac_SamSetUserInfo ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamSetUserInfo * op ) {
SMBCSRV * srv = NULL ;
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
SAM_USERINFO_CTR * ctr ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . user_hnd | | ! op - > in . info | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
ctr = cac_MakeUserInfoCtr ( mem_ctx , op - > in . info ) ;
if ( ! ctr ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
srv = cac_GetServer ( hnd ) ;
if ( ! srv ) {
hnd - > status = NT_STATUS_INVALID_CONNECTION ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
2005-09-03 16:55:45 +00:00
if ( hnd - > _internal . srv_level > = SRV_WIN_NT4 ) {
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_set_userinfo2 ( pipe_hnd , mem_ctx , op - > in . user_hnd , 21 , & ( srv - > cli . user_session_key ) , ctr ) ;
2005-09-03 16:55:45 +00:00
}
if ( hnd - > _internal . srv_level < SRV_WIN_NT4 | | ! NT_STATUS_IS_OK ( hnd - > status ) ) {
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_set_userinfo ( pipe_hnd , mem_ctx , op - > in . user_hnd , 21 , & ( srv - > cli . user_session_key ) , ctr ) ;
2005-09-03 16:55:45 +00:00
if ( NT_STATUS_IS_OK ( hnd - > status ) & & hnd - > _internal . srv_level > SRV_WIN_NT4 ) {
hnd - > _internal . srv_level = SRV_WIN_NT4 ;
}
}
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamGetUserInfoCtr ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamGetUserInfoCtr * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
SAM_USERINFO_CTR * ctr_out ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . user_hnd | | op - > in . info_class = = 0 | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_query_userinfo ( pipe_hnd , mem_ctx , op - > in . user_hnd , op - > in . info_class , & ctr_out ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > out . ctr = ctr_out ;
return CAC_SUCCESS ;
}
int cac_SamSetUserInfoCtr ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamSetUserInfoCtr * op ) {
SMBCSRV * srv = NULL ;
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . user_hnd | | ! op - > in . ctr | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
srv = cac_GetServer ( hnd ) ;
if ( ! srv ) {
hnd - > status = NT_STATUS_INVALID_CONNECTION ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
2005-09-03 16:55:45 +00:00
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_set_userinfo ( pipe_hnd , mem_ctx , op - > in . user_hnd , op - > in . ctr - > switch_value , & ( srv - > cli . user_session_key ) , op - > in . ctr ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamRenameUser ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamRenameUser * op ) {
SMBCSRV * srv = NULL ;
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
SAM_USERINFO_CTR ctr ;
SAM_USER_INFO_7 info7 ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . user_hnd | | ! op - > in . new_name | | op - > in . new_name [ 0 ] = = ' \0 ' | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
srv = cac_GetServer ( hnd ) ;
if ( ! srv ) {
hnd - > status = NT_STATUS_INVALID_CONNECTION ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
2005-09-03 16:55:45 +00:00
ZERO_STRUCT ( ctr ) ;
ZERO_STRUCT ( info7 ) ;
init_sam_user_info7 ( & info7 , op - > in . new_name ) ;
ctr . switch_value = 7 ;
ctr . info . id7 = & info7 ;
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_set_userinfo ( pipe_hnd , mem_ctx , op - > in . user_hnd , 7 , & ( srv - > cli . user_session_key ) , & ctr ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamGetGroupInfo ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamGetGroupInfo * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
GROUP_INFO_CTR * ctr ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . group_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
/*get a GROUP_INFO_1 structure*/
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_query_groupinfo ( pipe_hnd , mem_ctx , op - > in . group_hnd , 1 , & ctr ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > out . info = cac_MakeGroupInfo ( mem_ctx , ctr ) ;
if ( ! op - > out . info ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
return CAC_SUCCESS ;
}
int cac_SamSetGroupInfo ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamSetGroupInfo * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
GROUP_INFO_CTR * ctr = NULL ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . group_hnd | | ! op - > in . info | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
ctr = cac_MakeGroupInfoCtr ( mem_ctx , op - > in . info ) ;
if ( ! ctr ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_set_groupinfo ( pipe_hnd , mem_ctx , op - > in . group_hnd , ctr ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamRenameGroup ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamRenameGroup * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
GROUP_INFO_CTR ctr ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . group_hnd | | ! op - > in . new_name | | op - > in . new_name [ 0 ] = = ' \0 ' | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
ZERO_STRUCT ( ctr ) ;
init_samr_group_info2 ( & ctr . group . info2 , op - > in . new_name ) ;
ctr . switch_value1 = 2 ;
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_set_groupinfo ( pipe_hnd , mem_ctx , op - > in . group_hnd , & ctr ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamGetAliasInfo ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamGetAliasInfo * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
ALIAS_INFO_CTR ctr ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . alias_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
/*get a GROUP_INFO_1 structure*/
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_query_alias_info ( pipe_hnd , mem_ctx , op - > in . alias_hnd , 1 , & ctr ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > out . info = cac_MakeAliasInfo ( mem_ctx , ctr ) ;
if ( ! op - > out . info ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
return CAC_SUCCESS ;
}
int cac_SamSetAliasInfo ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamSetAliasInfo * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
ALIAS_INFO_CTR * ctr = NULL ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . alias_hnd | | ! op - > in . info | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
ctr = cac_MakeAliasInfoCtr ( mem_ctx , op - > in . info ) ;
if ( ! ctr ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_set_aliasinfo ( pipe_hnd , mem_ctx , op - > in . alias_hnd , ctr ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
return CAC_SUCCESS ;
}
int cac_SamGetDomainInfo ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamGetDomainInfo * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
SAM_UNK_CTR ctr ;
SAM_UNK_INFO_1 info1 ;
SAM_UNK_INFO_2 info2 ;
SAM_UNK_INFO_12 info12 ;
/*use this to keep track of a failed call*/
NTSTATUS status_buf = NT_STATUS_OK ;
uint16 fail_count = 0 ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . dom_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
/*first try with info 1*/
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_query_dom_info ( pipe_hnd , mem_ctx , op - > in . dom_hnd , 1 , & ctr ) ;
2005-09-03 16:55:45 +00:00
if ( NT_STATUS_IS_OK ( hnd - > status ) ) {
/*then we buffer the SAM_UNK_INFO_1 structure*/
info1 = ctr . info . inf1 ;
}
else {
/*then the call failed, store the status and ZERO out the info structure*/
ZERO_STRUCT ( info1 ) ;
status_buf = hnd - > status ;
fail_count + + ;
}
/*try again for the next one*/
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_query_dom_info ( pipe_hnd , mem_ctx , op - > in . dom_hnd , 2 , & ctr ) ;
2005-09-03 16:55:45 +00:00
if ( NT_STATUS_IS_OK ( hnd - > status ) ) {
/*store the info*/
info2 = ctr . info . inf2 ;
}
else {
/*ZERO out the structure and store the bad status*/
ZERO_STRUCT ( info2 ) ;
status_buf = hnd - > status ;
fail_count + + ;
}
/*once more*/
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_query_dom_info ( pipe_hnd , mem_ctx , op - > in . dom_hnd , 12 , & ctr ) ;
2005-09-03 16:55:45 +00:00
if ( NT_STATUS_IS_OK ( hnd - > status ) ) {
info12 = ctr . info . inf12 ;
}
else {
ZERO_STRUCT ( info12 ) ;
status_buf = hnd - > status ;
fail_count + + ;
}
/*return failure if all 3 calls failed*/
if ( fail_count = = 3 )
return CAC_FAILURE ;
op - > out . info = cac_MakeDomainInfo ( mem_ctx , & info1 , & info2 , & info12 ) ;
if ( ! op - > out . info ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
if ( fail_count > 0 ) {
hnd - > status = status_buf ;
return CAC_PARTIAL_SUCCESS ;
}
return CAC_SUCCESS ;
}
int cac_SamGetDomainInfoCtr ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamGetDomainInfoCtr * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
SAM_UNK_CTR * ctr_out ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . dom_hnd | | op - > in . info_class = = 0 | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
ctr_out = talloc ( mem_ctx , SAM_UNK_CTR ) ;
if ( ! ctr_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_query_dom_info ( pipe_hnd , mem_ctx , op - > in . dom_hnd , op - > in . info_class , ctr_out ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > out . info = ctr_out ;
return CAC_SUCCESS ;
}
int cac_SamGetDisplayInfo ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamGetDisplayInfo * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
SAM_DISPINFO_CTR ctr_out ;
uint32 max_entries_buf = 0 ;
uint32 max_size_buf = 0 ;
uint32 resume_idx_out ;
uint32 num_entries_out ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . dom_hnd | | op - > in . info_class = = 0 | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
if ( op - > out . done = = True ) /*this is done so we can use the function as a loop condition*/
return CAC_FAILURE ;
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
if ( op - > in . max_entries = = 0 | | op - > in . max_size = = 0 ) {
get_query_dispinfo_params ( op - > out . loop_count , & max_entries_buf , & max_size_buf ) ;
}
else {
max_entries_buf = op - > in . max_entries ;
max_size_buf = op - > in . max_size ;
}
resume_idx_out = op - > out . resume_idx ;
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_query_dispinfo ( pipe_hnd , mem_ctx , op - > in . dom_hnd , & resume_idx_out , op - > in . info_class ,
2005-09-03 16:55:45 +00:00
& num_entries_out , max_entries_buf , max_size_buf , & ctr_out ) ;
if ( ! NT_STATUS_IS_OK ( hnd - > status ) & & ! NT_STATUS_EQUAL ( hnd - > status , STATUS_MORE_ENTRIES ) ) {
/*be defensive, maybe they'll call again without zeroing the struct*/
op - > out . loop_count = 0 ;
op - > out . resume_idx = 0 ;
return CAC_FAILURE ;
}
if ( NT_STATUS_IS_OK ( hnd - > status ) ) {
/*we want to quit once the function is called next. so it can be used in a loop*/
op - > out . done = True ;
}
op - > out . resume_idx = resume_idx_out ;
op - > out . num_entries = num_entries_out ;
op - > out . ctr = ctr_out ;
op - > out . loop_count + + ;
return CAC_SUCCESS ;
}
int cac_SamLookupDomain ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamLookupDomain * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
DOM_SID * sid_out = NULL ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . sam | | ! op - > in . name | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
sid_out = talloc ( mem_ctx , DOM_SID ) ;
if ( ! sid_out ) {
hnd - > status = NT_STATUS_NO_MEMORY ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_lookup_domain ( pipe_hnd , mem_ctx , op - > in . sam , op - > in . name , sid_out ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > out . sid = sid_out ;
return CAC_SUCCESS ;
}
int cac_SamGetSecurityObject ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamGetSecurityObject * op ) {
2005-10-17 16:44:26 +00:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2005-09-03 16:55:45 +00:00
/*this number taken from rpcclient/cmd_samr.c, I think it is the only supported level*/
uint16 info_level = 4 ;
SEC_DESC_BUF * sec_out = NULL ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op - > in . pol | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
pipe_hnd = cac_GetPipe ( hnd , PI_SAMR ) ;
if ( ! pipe_hnd ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
2005-09-03 16:55:45 +00:00
return CAC_FAILURE ;
}
2005-10-17 16:44:26 +00:00
hnd - > status = rpccli_samr_query_sec_obj ( pipe_hnd , mem_ctx , op - > in . pol , info_level , mem_ctx , & sec_out ) ;
2005-09-03 16:55:45 +00:00
if ( ! NT_STATUS_IS_OK ( hnd - > status ) )
return CAC_FAILURE ;
op - > out . sec = sec_out ;
return CAC_SUCCESS ;
}
int cac_SamFlush ( CacServerHandle * hnd , TALLOC_CTX * mem_ctx , struct SamFlush * op ) {
struct SamOpenDomain od ;
if ( ! hnd )
return CAC_FAILURE ;
if ( ! hnd - > _internal . ctx | | ! hnd - > _internal . pipes [ PI_SAMR ] ) {
hnd - > status = NT_STATUS_INVALID_HANDLE ;
return CAC_FAILURE ;
}
if ( ! op | | ! op - > in . dom_hnd | | ! mem_ctx ) {
hnd - > status = NT_STATUS_INVALID_PARAMETER ;
return CAC_FAILURE ;
}
if ( ! cac_SamClose ( hnd , mem_ctx , op - > in . dom_hnd ) )
return CAC_FAILURE ;
ZERO_STRUCT ( od ) ;
od . in . access = ( op - > in . access ) ? op - > in . access : MAXIMUM_ALLOWED_ACCESS ;
od . in . sid = op - > in . sid ;
if ( ! cac_SamOpenDomain ( hnd , mem_ctx , & od ) )
return CAC_FAILURE ;
/*this function does not use an output parameter to make it as convenient as possible to use*/
* op - > in . dom_hnd = * od . out . dom_hnd ;
talloc_free ( od . out . dom_hnd ) ;
return CAC_SUCCESS ;
}