2004-05-03 18:58:08 +04:00
/*
Unix SMB / CIFS implementation .
endpoint server for the samr pipe
Copyright ( C ) Andrew Tridgell 2004
2004-12-29 02:05:48 +03:00
Copyright ( C ) Volker Lendecke 2004
2005-01-12 10:57:33 +03:00
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2004 - 2005
2004-05-03 18:58:08 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2004-11-01 13:30:34 +03:00
# include "librpc/gen_ndr/ndr_samr.h"
2004-11-02 10:42:47 +03:00
# include "rpc_server/dcerpc_server.h"
2004-05-04 10:11:47 +04:00
# include "rpc_server/common/common.h"
2004-05-24 09:35:59 +04:00
# include "rpc_server/samr/dcesrv_samr.h"
2004-11-02 03:24:21 +03:00
# include "system/time.h"
2004-11-16 12:00:52 +03:00
# include "lib/ldb/include/ldb.h"
2005-02-10 10:43:39 +03:00
# include "ads.h"
2004-05-06 11:32:51 +04:00
2004-05-03 18:58:08 +04:00
2004-12-26 21:02:18 +03:00
/*
This is a bad temporary hack until we have at least some kind of schema
support
*/
2005-02-10 08:09:35 +03:00
static char * ldb_hexstr ( TALLOC_CTX * mem_ctx , uint32_t val )
2004-12-26 21:02:18 +03:00
{
return talloc_asprintf ( mem_ctx , " 0x%.8x " , val ) ;
}
2004-05-03 18:58:08 +04:00
/*
samr_Connect
create a connection to the SAM database
*/
static NTSTATUS samr_Connect ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_Connect * r )
{
2004-05-10 16:37:06 +04:00
struct samr_connect_state * c_state ;
2004-05-03 18:58:08 +04:00
struct dcesrv_handle * handle ;
2004-09-21 07:51:38 +04:00
ZERO_STRUCTP ( r - > out . connect_handle ) ;
2004-05-03 18:58:08 +04:00
2005-01-27 10:08:20 +03:00
c_state = talloc ( dce_call - > conn , struct samr_connect_state ) ;
2004-05-10 16:37:06 +04:00
if ( ! c_state ) {
2004-05-03 18:58:08 +04:00
return NT_STATUS_NO_MEMORY ;
}
/* make sure the sam database is accessible */
2004-09-25 15:48:30 +04:00
c_state - > sam_ctx = samdb_connect ( c_state ) ;
2004-05-10 16:37:06 +04:00
if ( c_state - > sam_ctx = = NULL ) {
2004-09-08 04:00:56 +04:00
talloc_free ( c_state ) ;
2004-05-04 10:07:52 +04:00
return NT_STATUS_INVALID_SYSTEM_SERVICE ;
2004-05-03 18:58:08 +04:00
}
2005-01-10 15:15:26 +03:00
handle = dcesrv_handle_new ( dce_call - > context , SAMR_HANDLE_CONNECT ) ;
2004-05-03 18:58:08 +04:00
if ( ! handle ) {
2004-08-25 10:44:23 +04:00
talloc_free ( c_state ) ;
2004-05-03 18:58:08 +04:00
return NT_STATUS_NO_MEMORY ;
}
2005-01-10 15:15:26 +03:00
handle - > data = talloc_steal ( handle , c_state ) ;
2004-05-03 18:58:08 +04:00
2004-05-10 16:37:06 +04:00
c_state - > access_mask = r - > in . access_mask ;
2004-09-21 07:51:38 +04:00
* r - > out . connect_handle = handle - > wire_handle ;
2004-05-03 18:58:08 +04:00
return NT_STATUS_OK ;
}
/*
samr_Close
*/
static NTSTATUS samr_Close ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_Close * r )
{
2004-05-08 04:02:31 +04:00
struct dcesrv_handle * h ;
* r - > out . handle = * r - > in . handle ;
DCESRV_PULL_HANDLE ( h , r - > in . handle , DCESRV_HANDLE_ANY ) ;
2004-05-03 18:58:08 +04:00
2005-01-10 15:15:26 +03:00
talloc_free ( h ) ;
2004-05-03 18:58:08 +04:00
ZERO_STRUCTP ( r - > out . handle ) ;
return NT_STATUS_OK ;
}
/*
samr_SetSecurity
*/
static NTSTATUS samr_SetSecurity ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_SetSecurity * r )
{
2004-05-04 10:07:52 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_QuerySecurity
*/
static NTSTATUS samr_QuerySecurity ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_QuerySecurity * r )
{
2004-05-28 17:23:30 +04:00
struct dcesrv_handle * h ;
2004-11-20 03:29:04 +03:00
struct sec_desc_buf * sd ;
2004-05-28 17:23:30 +04:00
r - > out . sdbuf = NULL ;
DCESRV_PULL_HANDLE ( h , r - > in . handle , DCESRV_HANDLE_ANY ) ;
2005-01-27 10:08:20 +03:00
sd = talloc ( mem_ctx , struct sec_desc_buf ) ;
2004-05-28 17:23:30 +04:00
if ( sd = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
sd - > sd = samdb_default_security_descriptor ( mem_ctx ) ;
r - > out . sdbuf = sd ;
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_Shutdown
we refuse this operation completely . If a admin wants to shutdown samr
in Samba then they should use the samba admin tools to disable the samr pipe
*/
static NTSTATUS samr_Shutdown ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_Shutdown * r )
{
return NT_STATUS_ACCESS_DENIED ;
}
/*
samr_LookupDomain
this maps from a domain name to a SID
*/
static NTSTATUS samr_LookupDomain ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_LookupDomain * r )
{
2004-05-10 16:37:06 +04:00
struct samr_connect_state * c_state ;
2004-05-03 18:58:08 +04:00
struct dcesrv_handle * h ;
2005-06-24 04:18:20 +04:00
struct dom_sid * sid ;
2005-08-03 22:30:21 +04:00
const char * const dom_attrs [ ] = { " objectSid " , NULL } ;
const char * const ref_attrs [ ] = { " ncName " , NULL } ;
struct ldb_message * * dom_msgs ;
struct ldb_message * * ref_msgs ;
int ret ;
2004-05-08 04:02:31 +04:00
r - > out . sid = NULL ;
2004-05-04 10:07:52 +04:00
2004-09-21 07:51:38 +04:00
DCESRV_PULL_HANDLE ( h , r - > in . connect_handle , SAMR_HANDLE_CONNECT ) ;
2004-05-03 18:58:08 +04:00
2004-05-10 16:37:06 +04:00
c_state = h - > data ;
2004-05-06 16:42:42 +04:00
2005-02-13 03:26:43 +03:00
if ( r - > in . domain_name - > string = = NULL ) {
2004-05-04 10:07:52 +04:00
return NT_STATUS_INVALID_PARAMETER ;
2004-05-03 18:58:08 +04:00
}
2005-08-03 22:30:21 +04:00
if ( strcasecmp ( r - > in . domain_name - > string , " BUILTIN " ) = = 0 ) {
ret = gendb_search ( c_state - > sam_ctx ,
mem_ctx , NULL , & dom_msgs , dom_attrs ,
" (objectClass=builtinDomain) " ) ;
} else {
ret = gendb_search ( c_state - > sam_ctx ,
mem_ctx , NULL , & ref_msgs , ref_attrs ,
" (&(&(nETBIOSName=%s)(objectclass=crossRef))(ncName=*)) " ,
2005-06-24 04:18:20 +04:00
r - > in . domain_name - > string ) ;
2005-08-03 22:30:21 +04:00
if ( ret ! = 1 ) {
return NT_STATUS_NO_SUCH_DOMAIN ;
}
ret = gendb_search_dn ( c_state - > sam_ctx , mem_ctx ,
samdb_result_string ( ref_msgs [ 0 ] , " ncName " , NULL ) ,
& dom_msgs , dom_attrs ) ;
}
if ( ret ! = 1 ) {
return NT_STATUS_NO_SUCH_DOMAIN ;
}
sid = samdb_result_dom_sid ( mem_ctx , dom_msgs [ 0 ] ,
" objectSid " ) ;
2004-05-03 18:58:08 +04:00
if ( sid = = NULL ) {
2005-06-24 04:18:20 +04:00
return NT_STATUS_NO_SUCH_DOMAIN ;
2004-05-03 18:58:08 +04:00
}
r - > out . sid = sid ;
return NT_STATUS_OK ;
}
/*
samr_EnumDomains
list the domains in the SAM
*/
static NTSTATUS samr_EnumDomains ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_EnumDomains * r )
{
2004-05-10 16:37:06 +04:00
struct samr_connect_state * c_state ;
2004-05-03 18:58:08 +04:00
struct dcesrv_handle * h ;
struct samr_SamArray * array ;
int count , i , start_i ;
2005-08-03 22:30:21 +04:00
const char * const dom_attrs [ ] = { " cn " , NULL } ;
const char * const ref_attrs [ ] = { " nETBIOSName " , NULL } ;
struct ldb_message * * dom_msgs ;
struct ldb_message * * ref_msgs ;
2004-05-03 18:58:08 +04:00
* r - > out . resume_handle = 0 ;
r - > out . sam = NULL ;
r - > out . num_entries = 0 ;
2004-09-21 07:51:38 +04:00
DCESRV_PULL_HANDLE ( h , r - > in . connect_handle , SAMR_HANDLE_CONNECT ) ;
2004-05-08 04:02:31 +04:00
2004-05-10 16:37:06 +04:00
c_state = h - > data ;
2004-05-08 04:02:31 +04:00
2005-08-03 22:30:21 +04:00
count = gendb_search ( c_state - > sam_ctx ,
mem_ctx , NULL , & dom_msgs , dom_attrs ,
" (objectClass=domain) " ) ;
2004-05-03 18:58:08 +04:00
if ( count = = - 1 ) {
2004-07-05 11:24:14 +04:00
DEBUG ( 0 , ( " samdb: no domains found in EnumDomains \n " ) ) ;
2004-05-04 10:07:52 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2004-05-03 18:58:08 +04:00
}
* r - > out . resume_handle = count ;
start_i = * r - > in . resume_handle ;
if ( start_i > = count ) {
/* search past end of list is not an error for this call */
return NT_STATUS_OK ;
}
2005-01-27 10:08:20 +03:00
array = talloc ( mem_ctx , struct samr_SamArray ) ;
2004-05-03 18:58:08 +04:00
if ( array = = NULL ) {
2004-05-04 10:07:52 +04:00
return NT_STATUS_NO_MEMORY ;
2004-05-03 18:58:08 +04:00
}
array - > count = 0 ;
array - > entries = NULL ;
2005-01-27 10:08:20 +03:00
array - > entries = talloc_array ( mem_ctx , struct samr_SamEntry , count - start_i ) ;
2004-05-03 18:58:08 +04:00
if ( array - > entries = = NULL ) {
2004-05-04 10:07:52 +04:00
return NT_STATUS_NO_MEMORY ;
2004-05-03 18:58:08 +04:00
}
for ( i = 0 ; i < count - start_i ; i + + ) {
2005-08-03 22:30:21 +04:00
int ret ;
2004-05-03 18:58:08 +04:00
array - > entries [ i ] . idx = start_i + i ;
2005-08-03 22:30:21 +04:00
/* try and find the domain */
2005-08-03 23:58:58 +04:00
ret = gendb_search ( c_state - > sam_ctx , mem_ctx , NULL ,
& ref_msgs , ref_attrs ,
2005-08-03 22:30:21 +04:00
" (&(objectClass=crossRef)(ncName=%s)) " ,
2005-08-03 23:58:58 +04:00
dom_msgs [ i ] - > dn ) ;
2005-08-03 22:30:21 +04:00
if ( ret = = 1 ) {
array - > entries [ i ] . name . string = samdb_result_string ( ref_msgs [ 0 ] , " nETBIOSName " , NULL ) ;
} else {
2005-08-03 23:58:58 +04:00
array - > entries [ i ] . name . string = samdb_result_string ( dom_msgs [ i ] , " cn " , NULL ) ;
2005-08-03 22:30:21 +04:00
}
2004-05-03 18:58:08 +04:00
}
r - > out . sam = array ;
2004-05-20 11:49:34 +04:00
r - > out . num_entries = i ;
2004-05-03 18:58:08 +04:00
array - > count = r - > out . num_entries ;
return NT_STATUS_OK ;
}
/*
samr_OpenDomain
*/
static NTSTATUS samr_OpenDomain ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-04 11:53:06 +04:00
struct samr_OpenDomain * r )
2004-05-03 18:58:08 +04:00
{
2004-05-04 11:53:06 +04:00
struct dcesrv_handle * h_conn , * h_domain ;
2005-06-24 04:18:20 +04:00
const char * domain_name ;
2004-05-06 16:42:42 +04:00
struct samr_connect_state * c_state ;
2004-05-10 16:37:06 +04:00
struct samr_domain_state * d_state ;
2005-08-03 23:58:58 +04:00
const char * const dom_attrs [ ] = { " cn " , NULL } ;
2005-08-03 22:30:21 +04:00
const char * const ref_attrs [ ] = { " nETBIOSName " , NULL } ;
struct ldb_message * * dom_msgs ;
struct ldb_message * * ref_msgs ;
2004-05-08 04:02:31 +04:00
int ret ;
ZERO_STRUCTP ( r - > out . domain_handle ) ;
2004-05-04 11:53:06 +04:00
2004-09-21 07:51:38 +04:00
DCESRV_PULL_HANDLE ( h_conn , r - > in . connect_handle , SAMR_HANDLE_CONNECT ) ;
2004-05-04 11:53:06 +04:00
2004-05-06 16:42:42 +04:00
c_state = h_conn - > data ;
2004-05-08 04:02:31 +04:00
if ( r - > in . sid = = NULL ) {
return NT_STATUS_INVALID_PARAMETER ;
}
2005-03-23 04:30:43 +03:00
ret = gendb_search ( c_state - > sam_ctx ,
2005-08-03 22:30:21 +04:00
mem_ctx , NULL , & dom_msgs , dom_attrs ,
2005-08-03 23:58:58 +04:00
" (&(objectSid=%s)(&(objectclass=domain)(!(objectClass=builtinDomain)))) " ,
2005-06-24 04:18:20 +04:00
ldap_encode_ndr_dom_sid ( mem_ctx , r - > in . sid ) ) ;
2005-08-03 23:58:58 +04:00
if ( ret = = - 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
} else if ( ret = = 0 ) {
ret = gendb_search ( c_state - > sam_ctx ,
mem_ctx , NULL , & dom_msgs , dom_attrs ,
" (&(objectSid=%s)(objectClass=builtinDomain)) " ,
ldap_encode_ndr_dom_sid ( mem_ctx , r - > in . sid ) ) ;
if ( ret ! = 1 ) {
return NT_STATUS_NO_SUCH_DOMAIN ;
}
2005-08-03 22:30:21 +04:00
2005-08-03 23:58:58 +04:00
domain_name = ldb_msg_find_string ( dom_msgs [ 0 ] , " cn " , NULL ) ;
if ( domain_name = = NULL ) {
return NT_STATUS_NO_SUCH_DOMAIN ;
}
} else {
ret = gendb_search ( c_state - > sam_ctx ,
mem_ctx , NULL , & ref_msgs , ref_attrs ,
" (&(&(nETBIOSName=*)(objectclass=crossRef))(ncName=%s)) " ,
dom_msgs [ 0 ] - > dn ) ;
if ( ret ! = 1 ) {
return NT_STATUS_NO_SUCH_DOMAIN ;
}
domain_name = ldb_msg_find_string ( ref_msgs [ 0 ] , " nETBIOSName " , NULL ) ;
if ( domain_name = = NULL ) {
return NT_STATUS_NO_SUCH_DOMAIN ;
}
2004-05-04 11:53:06 +04:00
}
2005-01-27 10:08:20 +03:00
d_state = talloc ( c_state , struct samr_domain_state ) ;
2004-05-10 16:37:06 +04:00
if ( ! d_state ) {
2004-05-04 11:53:06 +04:00
return NT_STATUS_NO_MEMORY ;
}
2004-09-27 09:13:00 +04:00
d_state - > connect_state = talloc_reference ( d_state , c_state ) ;
2004-05-10 16:37:06 +04:00
d_state - > sam_ctx = c_state - > sam_ctx ;
2005-06-24 04:18:20 +04:00
d_state - > domain_sid = dom_sid_dup ( d_state , r - > in . sid ) ;
2004-08-25 10:44:23 +04:00
d_state - > domain_name = talloc_strdup ( d_state , domain_name ) ;
2005-08-03 22:30:21 +04:00
d_state - > domain_dn = talloc_strdup ( d_state , dom_msgs [ 0 ] - > dn ) ;
2004-05-10 16:37:06 +04:00
if ( ! d_state - > domain_sid | | ! d_state - > domain_name | | ! d_state - > domain_dn ) {
2004-08-25 10:44:23 +04:00
talloc_free ( d_state ) ;
2004-05-08 04:02:31 +04:00
return NT_STATUS_NO_MEMORY ;
}
2004-05-10 16:37:06 +04:00
d_state - > access_mask = r - > in . access_mask ;
2004-05-04 11:53:06 +04:00
2005-01-10 15:15:26 +03:00
h_domain = dcesrv_handle_new ( dce_call - > context , SAMR_HANDLE_DOMAIN ) ;
2004-05-04 11:53:06 +04:00
if ( ! h_domain ) {
2004-08-25 10:44:23 +04:00
talloc_free ( d_state ) ;
2004-05-04 11:53:06 +04:00
return NT_STATUS_NO_MEMORY ;
}
2004-09-27 09:13:00 +04:00
2005-01-10 15:15:26 +03:00
h_domain - > data = talloc_steal ( h_domain , d_state ) ;
2004-05-04 11:53:06 +04:00
* r - > out . domain_handle = h_domain - > wire_handle ;
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2004-12-30 20:01:49 +03:00
/*
return DomInfo1
*/
static NTSTATUS samr_info_DomInfo1 ( struct samr_domain_state * state ,
TALLOC_CTX * mem_ctx ,
struct samr_DomInfo1 * info )
{
const char * const attrs [ ] = { " minPwdLength " , " pwdHistoryLength " ,
" pwdProperties " , " maxPwdAge " ,
" minPwdAge " , NULL } ;
int ret ;
struct ldb_message * * res ;
2005-06-14 23:15:17 +04:00
ret = gendb_search_dn ( state - > sam_ctx , mem_ctx ,
state - > domain_dn , & res , attrs ) ;
2004-12-30 20:01:49 +03:00
if ( ret ! = 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
info - > min_password_length =
samdb_result_uint ( res [ 0 ] , " minPwdLength " , 0 ) ;
info - > password_history_length =
samdb_result_uint ( res [ 0 ] , " pwdHistoryLength " , 0 ) ;
info - > password_properties =
samdb_result_uint ( res [ 0 ] , " pwdProperties " , 0 ) ;
info - > max_password_age =
samdb_result_int64 ( res [ 0 ] , " maxPwdAge " , 0 ) ;
info - > min_password_age =
samdb_result_int64 ( res [ 0 ] , " minPwdAge " , 0 ) ;
return NT_STATUS_OK ;
}
2004-05-27 08:13:58 +04:00
/*
return DomInfo2
*/
static NTSTATUS samr_info_DomInfo2 ( struct samr_domain_state * state , TALLOC_CTX * mem_ctx ,
struct samr_DomInfo2 * info )
{
2005-08-03 22:30:21 +04:00
const char * const dom_attrs [ ] = { " comment " , NULL } ;
2004-05-27 08:13:58 +04:00
int ret ;
2005-08-03 22:30:21 +04:00
struct ldb_message * * dom_msgs ;
const char * domain_name ;
2005-06-14 23:15:17 +04:00
ret = gendb_search_dn ( state - > sam_ctx , mem_ctx ,
2005-08-03 22:30:21 +04:00
state - > domain_dn , & dom_msgs , dom_attrs ) ;
2004-05-27 08:13:58 +04:00
if ( ret ! = 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2005-08-03 23:58:58 +04:00
domain_name = state - > domain_name ;
2004-05-27 08:13:58 +04:00
/* where is this supposed to come from? is it settable? */
info - > force_logoff_time = 0x8000000000000000LL ;
2005-08-03 22:30:21 +04:00
info - > comment . string = samdb_result_string ( dom_msgs [ 0 ] , " comment " , NULL ) ;
info - > domain_name . string = domain_name ;
2004-05-27 08:13:58 +04:00
2004-11-13 16:45:41 +03:00
info - > primary . string = lp_netbios_name ( ) ;
2004-05-27 08:13:58 +04:00
info - > sequence_num = 0 ;
info - > role = ROLE_DOMAIN_PDC ;
info - > num_users = samdb_search_count ( state - > sam_ctx , mem_ctx , NULL , " (objectClass=user) " ) ;
info - > num_groups = samdb_search_count ( state - > sam_ctx , mem_ctx , NULL ,
" (&(objectClass=group)(sAMAccountType=%u)) " ,
ATYPE_GLOBAL_GROUP ) ;
info - > num_aliases = samdb_search_count ( state - > sam_ctx , mem_ctx , NULL ,
" (&(objectClass=group)(sAMAccountType=%u)) " ,
ATYPE_LOCAL_GROUP ) ;
return NT_STATUS_OK ;
}
2004-05-03 18:58:08 +04:00
2004-12-30 22:11:25 +03:00
/*
return DomInfo3
*/
static NTSTATUS samr_info_DomInfo3 ( struct samr_domain_state * state ,
TALLOC_CTX * mem_ctx ,
struct samr_DomInfo3 * info )
{
/* where is this supposed to come from? is it settable? */
info - > force_logoff_time = 0x8000000000000000LL ;
return NT_STATUS_OK ;
}
2004-05-03 18:58:08 +04:00
/*
samr_QueryDomainInfo
*/
static NTSTATUS samr_QueryDomainInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-27 08:13:58 +04:00
struct samr_QueryDomainInfo * r )
2004-05-03 18:58:08 +04:00
{
2004-05-27 08:13:58 +04:00
struct dcesrv_handle * h ;
struct samr_domain_state * d_state ;
r - > out . info = NULL ;
2004-09-21 07:51:38 +04:00
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
2004-05-27 08:13:58 +04:00
d_state = h - > data ;
2005-01-27 10:08:20 +03:00
r - > out . info = talloc ( mem_ctx , union samr_DomainInfo ) ;
2004-05-27 08:13:58 +04:00
if ( ! r - > out . info ) {
return NT_STATUS_NO_MEMORY ;
}
ZERO_STRUCTP ( r - > out . info ) ;
switch ( r - > in . level ) {
2004-12-30 20:01:49 +03:00
case 1 :
return samr_info_DomInfo1 ( d_state , mem_ctx ,
& r - > out . info - > info1 ) ;
2004-05-27 08:13:58 +04:00
case 2 :
return samr_info_DomInfo2 ( d_state , mem_ctx , & r - > out . info - > info2 ) ;
2004-12-30 22:11:25 +03:00
case 3 :
return samr_info_DomInfo3 ( d_state , mem_ctx ,
& r - > out . info - > info3 ) ;
2004-05-27 08:13:58 +04:00
}
return NT_STATUS_INVALID_INFO_CLASS ;
2004-05-03 18:58:08 +04:00
}
/*
samr_SetDomainInfo
*/
static NTSTATUS samr_SetDomainInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_SetDomainInfo * r )
{
2004-05-04 10:07:52 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_CreateDomainGroup
*/
static NTSTATUS samr_CreateDomainGroup ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-09 16:32:25 +04:00
struct samr_CreateDomainGroup * r )
2004-05-03 18:58:08 +04:00
{
2004-05-09 15:21:46 +04:00
struct samr_domain_state * d_state ;
2004-05-10 16:37:06 +04:00
struct samr_account_state * a_state ;
2004-05-09 15:21:46 +04:00
struct dcesrv_handle * h ;
const char * name ;
2005-01-02 10:51:13 +03:00
struct ldb_message * msg ;
2005-03-28 03:31:43 +04:00
struct dom_sid * sid ;
2005-06-24 04:18:20 +04:00
const char * groupname ;
2004-05-09 15:21:46 +04:00
struct dcesrv_handle * g_handle ;
int ret ;
ZERO_STRUCTP ( r - > out . group_handle ) ;
* r - > out . rid = 0 ;
2004-09-21 07:51:38 +04:00
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
2004-05-09 15:21:46 +04:00
d_state = h - > data ;
2004-11-13 16:45:41 +03:00
groupname = r - > in . name - > string ;
2004-05-09 15:21:46 +04:00
if ( groupname = = NULL ) {
return NT_STATUS_INVALID_PARAMETER ;
}
/* check if the group already exists */
2004-05-26 08:20:17 +04:00
name = samdb_search_string ( d_state - > sam_ctx , mem_ctx , NULL ,
2004-05-09 16:32:25 +04:00
" sAMAccountName " ,
2004-05-09 15:21:46 +04:00
" (&(sAMAccountName=%s)(objectclass=group)) " ,
groupname ) ;
if ( name ! = NULL ) {
return NT_STATUS_GROUP_EXISTS ;
}
2005-01-02 10:51:13 +03:00
msg = ldb_msg_new ( mem_ctx ) ;
if ( msg = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2004-05-09 15:21:46 +04:00
/* add core elements to the ldb_message for the user */
2005-01-02 10:51:13 +03:00
msg - > dn = talloc_asprintf ( mem_ctx , " CN=%s,CN=Users,%s " , groupname ,
d_state - > domain_dn ) ;
if ( ! msg - > dn ) {
2004-05-09 15:21:46 +04:00
return NT_STATUS_NO_MEMORY ;
}
2005-01-02 10:51:13 +03:00
samdb_msg_add_string ( d_state - > sam_ctx , mem_ctx , msg , " sAMAccountName " , groupname ) ;
samdb_msg_add_string ( d_state - > sam_ctx , mem_ctx , msg , " objectClass " , " group " ) ;
2004-05-09 15:21:46 +04:00
/* create the group */
2005-01-02 10:51:13 +03:00
ret = samdb_add ( d_state - > sam_ctx , mem_ctx , msg ) ;
2004-05-09 15:21:46 +04:00
if ( ret ! = 0 ) {
2005-01-02 10:51:13 +03:00
DEBUG ( 0 , ( " Failed to create group record %s \n " , msg - > dn ) ) ;
2004-05-09 15:21:46 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2005-01-27 10:08:20 +03:00
a_state = talloc ( d_state , struct samr_account_state ) ;
2004-05-10 16:37:06 +04:00
if ( ! a_state ) {
2004-05-09 15:21:46 +04:00
return NT_STATUS_NO_MEMORY ;
}
2004-05-10 16:37:06 +04:00
a_state - > sam_ctx = d_state - > sam_ctx ;
a_state - > access_mask = r - > in . access_mask ;
2004-09-27 09:13:00 +04:00
a_state - > domain_state = talloc_reference ( a_state , d_state ) ;
2005-01-02 10:51:13 +03:00
a_state - > account_dn = talloc_steal ( a_state , msg - > dn ) ;
2005-03-28 03:31:43 +04:00
2005-06-24 04:18:20 +04:00
/* retrieve the sid for the group just created */
sid = samdb_search_dom_sid ( d_state - > sam_ctx , a_state ,
2005-07-17 13:20:52 +04:00
msg - > dn , " objectSid " , " dn=%s " , msg - > dn ) ;
2005-06-24 04:18:20 +04:00
if ( sid = = NULL ) {
2005-03-28 03:31:43 +04:00
return NT_STATUS_UNSUCCESSFUL ;
}
2004-12-23 00:20:12 +03:00
a_state - > account_name = talloc_strdup ( a_state , groupname ) ;
2004-12-23 01:19:54 +03:00
if ( ! a_state - > account_name ) {
2004-05-09 15:21:46 +04:00
return NT_STATUS_NO_MEMORY ;
}
/* create the policy handle */
2005-01-10 15:15:26 +03:00
g_handle = dcesrv_handle_new ( dce_call - > context , SAMR_HANDLE_GROUP ) ;
2004-05-09 15:21:46 +04:00
if ( ! g_handle ) {
return NT_STATUS_NO_MEMORY ;
}
2005-01-10 15:15:26 +03:00
g_handle - > data = talloc_steal ( g_handle , a_state ) ;
2004-05-09 15:21:46 +04:00
* r - > out . group_handle = g_handle - > wire_handle ;
2005-03-28 03:31:43 +04:00
* r - > out . rid = sid - > sub_auths [ sid - > num_auths - 1 ] ;
2004-05-09 15:21:46 +04:00
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2004-12-28 10:57:31 +03:00
/*
comparison function for sorting SamEntry array
*/
static int compare_SamEntry ( struct samr_SamEntry * e1 , struct samr_SamEntry * e2 )
{
return e1 - > idx - e2 - > idx ;
}
2004-05-03 18:58:08 +04:00
/*
samr_EnumDomainGroups
*/
static NTSTATUS samr_EnumDomainGroups ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-06 11:32:51 +04:00
struct samr_EnumDomainGroups * r )
2004-05-03 18:58:08 +04:00
{
2004-12-28 10:57:31 +03:00
struct dcesrv_handle * h ;
struct samr_domain_state * d_state ;
struct ldb_message * * res ;
int ldb_cnt , count , i , first ;
struct samr_SamEntry * entries ;
const char * const attrs [ 3 ] = { " objectSid " , " sAMAccountName " , NULL } ;
* r - > out . resume_handle = 0 ;
r - > out . sam = NULL ;
r - > out . num_entries = 0 ;
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
d_state = h - > data ;
2004-12-30 20:01:49 +03:00
2004-12-28 10:57:31 +03:00
/* search for all domain groups in this domain. This could possibly be
cached and resumed based on resume_key */
2004-12-30 20:01:49 +03:00
ldb_cnt = samdb_search_domain ( d_state - > sam_ctx , mem_ctx ,
d_state - > domain_dn , & res , attrs ,
2005-06-24 04:18:20 +04:00
d_state - > domain_sid ,
2004-12-30 20:01:49 +03:00
" (&(grouptype=%s)(objectclass=group)) " ,
ldb_hexstr ( mem_ctx ,
GTYPE_SECURITY_GLOBAL_GROUP ) ) ;
2004-12-28 10:57:31 +03:00
if ( ldb_cnt = = - 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
if ( ldb_cnt = = 0 | | r - > in . max_size = = 0 ) {
return NT_STATUS_OK ;
}
/* convert to SamEntry format */
2005-01-27 10:08:20 +03:00
entries = talloc_array ( mem_ctx , struct samr_SamEntry , ldb_cnt ) ;
2004-12-28 10:57:31 +03:00
if ( ! entries ) {
return NT_STATUS_NO_MEMORY ;
}
count = 0 ;
for ( i = 0 ; i < ldb_cnt ; i + + ) {
2004-12-30 20:01:49 +03:00
struct dom_sid * group_sid ;
2004-12-28 10:57:31 +03:00
2004-12-30 20:01:49 +03:00
group_sid = samdb_result_dom_sid ( mem_ctx , res [ i ] ,
2004-12-28 10:57:31 +03:00
" objectSid " ) ;
2004-12-30 20:01:49 +03:00
if ( group_sid = = NULL )
2004-12-28 10:57:31 +03:00
continue ;
entries [ count ] . idx =
2004-12-30 20:01:49 +03:00
group_sid - > sub_auths [ group_sid - > num_auths - 1 ] ;
2004-12-28 10:57:31 +03:00
entries [ count ] . name . string =
samdb_result_string ( res [ i ] , " sAMAccountName " , " " ) ;
count + = 1 ;
}
/* sort the results by rid */
qsort ( entries , count , sizeof ( struct samr_SamEntry ) ,
( comparison_fn_t ) compare_SamEntry ) ;
/* find the first entry to return */
for ( first = 0 ;
first < count & & entries [ first ] . idx < = * r - > in . resume_handle ;
first + + ) ;
if ( first = = count ) {
return NT_STATUS_OK ;
}
/* return the rest, limit by max_size. Note that we
use the w2k3 element size value of 54 */
r - > out . num_entries = count - first ;
r - > out . num_entries = MIN ( r - > out . num_entries ,
1 + ( r - > in . max_size / SAMR_ENUM_USERS_MULTIPLIER ) ) ;
2005-01-27 10:08:20 +03:00
r - > out . sam = talloc ( mem_ctx , struct samr_SamArray ) ;
2004-12-28 10:57:31 +03:00
if ( ! r - > out . sam ) {
return NT_STATUS_NO_MEMORY ;
}
r - > out . sam - > entries = entries + first ;
r - > out . sam - > count = r - > out . num_entries ;
if ( r - > out . num_entries < count - first ) {
* r - > out . resume_handle = entries [ first + r - > out . num_entries - 1 ] . idx ;
return STATUS_MORE_ENTRIES ;
}
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2004-05-06 11:32:51 +04:00
/*
samr_CreateUser2
2004-05-08 04:02:31 +04:00
TODO : This should do some form of locking , especially around the rid allocation
2004-05-06 11:32:51 +04:00
*/
static NTSTATUS samr_CreateUser2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_CreateUser2 * r )
{
2004-05-06 16:42:42 +04:00
struct samr_domain_state * d_state ;
2004-05-10 16:37:06 +04:00
struct samr_account_state * a_state ;
2004-05-08 04:02:31 +04:00
struct dcesrv_handle * h ;
2004-05-06 16:42:42 +04:00
const char * name ;
2005-01-02 10:51:13 +03:00
struct ldb_message * msg ;
2005-03-28 03:31:43 +04:00
struct dom_sid * sid ;
2005-06-24 04:18:20 +04:00
const char * account_name ;
2004-05-08 04:02:31 +04:00
struct dcesrv_handle * u_handle ;
int ret ;
2005-07-12 14:59:12 +04:00
const char * container , * obj_class = NULL ;
char * cn_name ;
int cn_name_len ;
2004-05-08 04:02:31 +04:00
2004-09-21 07:51:38 +04:00
ZERO_STRUCTP ( r - > out . user_handle ) ;
2004-05-08 04:02:31 +04:00
* r - > out . access_granted = 0 ;
* r - > out . rid = 0 ;
2004-05-06 16:42:42 +04:00
2004-09-21 07:51:38 +04:00
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
2004-05-06 11:32:51 +04:00
2004-05-06 16:42:42 +04:00
d_state = h - > data ;
2004-11-13 16:45:41 +03:00
account_name = r - > in . account_name - > string ;
2004-05-08 04:02:31 +04:00
2004-06-05 07:22:10 +04:00
if ( account_name = = NULL ) {
2004-05-06 16:42:42 +04:00
return NT_STATUS_INVALID_PARAMETER ;
}
2004-05-06 11:32:51 +04:00
/* check if the user already exists */
2004-05-26 08:20:17 +04:00
name = samdb_search_string ( d_state - > sam_ctx , mem_ctx , NULL ,
2004-05-09 16:32:25 +04:00
" sAMAccountName " ,
2004-06-05 07:22:10 +04:00
" (&(sAMAccountName=%s)(objectclass=user)) " , account_name ) ;
2004-05-06 16:42:42 +04:00
if ( name ! = NULL ) {
return NT_STATUS_USER_EXISTS ;
}
2005-01-02 10:51:13 +03:00
msg = ldb_msg_new ( mem_ctx ) ;
if ( msg = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2004-05-08 04:02:31 +04:00
2005-07-12 14:59:12 +04:00
cn_name = talloc_strdup ( mem_ctx , account_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( cn_name ) ;
cn_name_len = strlen ( cn_name ) ;
2004-05-15 11:51:38 +04:00
/* This must be one of these values *only* */
if ( r - > in . acct_flags = = ACB_NORMAL ) {
container = " Users " ;
2005-07-12 14:59:12 +04:00
obj_class = " user " ;
2004-05-15 11:51:38 +04:00
} else if ( r - > in . acct_flags = = ACB_WSTRUST ) {
2005-07-12 14:59:12 +04:00
if ( cn_name [ cn_name_len - 1 ] ! = ' $ ' ) {
return NT_STATUS_FOOBAR ;
}
cn_name [ cn_name_len - 1 ] = ' \0 ' ;
2004-05-15 11:51:38 +04:00
container = " Computers " ;
2005-07-12 14:59:12 +04:00
obj_class = " computer " ;
2004-05-15 11:51:38 +04:00
} else if ( r - > in . acct_flags = = ACB_SVRTRUST ) {
2005-07-12 14:59:12 +04:00
if ( cn_name [ cn_name_len - 1 ] ! = ' $ ' ) {
return NT_STATUS_FOOBAR ;
}
cn_name [ cn_name_len - 1 ] = ' \0 ' ;
2004-12-21 14:49:36 +03:00
container = " Domain Controllers " ;
2005-07-12 14:59:12 +04:00
obj_class = " computer " ;
2004-05-15 11:51:38 +04:00
} else if ( r - > in . acct_flags = = ACB_DOMTRUST ) {
2004-12-21 14:49:36 +03:00
container = " Users " ;
2005-07-12 14:59:12 +04:00
obj_class = " user " ;
2004-05-15 11:51:38 +04:00
} else {
return NT_STATUS_INVALID_PARAMETER ;
2004-05-08 04:02:31 +04:00
}
2004-05-15 11:51:38 +04:00
2004-05-08 04:02:31 +04:00
/* add core elements to the ldb_message for the user */
2005-07-12 14:59:12 +04:00
msg - > dn = talloc_asprintf ( mem_ctx , " CN=%s,CN=%s,%s " , cn_name , container , d_state - > domain_dn ) ;
2005-01-02 10:51:13 +03:00
if ( ! msg - > dn ) {
2004-05-08 04:02:31 +04:00
return NT_STATUS_NO_MEMORY ;
}
2005-01-02 10:51:13 +03:00
samdb_msg_add_string ( d_state - > sam_ctx , mem_ctx , msg , " sAMAccountName " , account_name ) ;
2005-07-12 14:59:12 +04:00
samdb_msg_add_string ( d_state - > sam_ctx , mem_ctx , msg , " objectClass " , obj_class ) ;
2004-05-06 11:32:51 +04:00
/* create the user */
2005-01-02 10:51:13 +03:00
ret = samdb_add ( d_state - > sam_ctx , mem_ctx , msg ) ;
2004-05-08 04:02:31 +04:00
if ( ret ! = 0 ) {
2005-01-02 10:51:13 +03:00
DEBUG ( 0 , ( " Failed to create user record %s \n " , msg - > dn ) ) ;
2004-05-08 04:02:31 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2005-01-27 10:08:20 +03:00
a_state = talloc ( d_state , struct samr_account_state ) ;
2004-05-10 16:37:06 +04:00
if ( ! a_state ) {
2004-05-08 04:02:31 +04:00
return NT_STATUS_NO_MEMORY ;
}
2004-05-10 16:37:06 +04:00
a_state - > sam_ctx = d_state - > sam_ctx ;
a_state - > access_mask = r - > in . access_mask ;
2004-09-27 09:13:00 +04:00
a_state - > domain_state = talloc_reference ( a_state , d_state ) ;
2005-01-02 10:51:13 +03:00
a_state - > account_dn = talloc_steal ( a_state , msg - > dn ) ;
2005-03-28 03:31:43 +04:00
2005-07-27 04:23:09 +04:00
/* retrieve the sid for the user just created */
2005-06-24 04:18:20 +04:00
sid = samdb_search_dom_sid ( d_state - > sam_ctx , a_state ,
2005-07-17 13:20:52 +04:00
msg - > dn , " objectSid " , " dn=%s " , msg - > dn ) ;
2005-06-24 04:18:20 +04:00
if ( sid = = NULL ) {
2005-03-28 03:31:43 +04:00
return NT_STATUS_UNSUCCESSFUL ;
}
2004-12-23 01:19:54 +03:00
a_state - > account_name = talloc_strdup ( a_state , account_name ) ;
if ( ! a_state - > account_name ) {
2004-05-08 04:02:31 +04:00
return NT_STATUS_NO_MEMORY ;
}
/* create the policy handle */
2005-01-10 15:15:26 +03:00
u_handle = dcesrv_handle_new ( dce_call - > context , SAMR_HANDLE_USER ) ;
2004-05-08 04:02:31 +04:00
if ( ! u_handle ) {
return NT_STATUS_NO_MEMORY ;
}
2005-01-10 15:15:26 +03:00
u_handle - > data = talloc_steal ( u_handle , a_state ) ;
2004-05-08 04:02:31 +04:00
2004-09-21 07:51:38 +04:00
* r - > out . user_handle = u_handle - > wire_handle ;
2004-05-08 04:02:31 +04:00
* r - > out . access_granted = 0xf07ff ; /* TODO: fix access mask calculations */
2005-03-28 03:31:43 +04:00
* r - > out . rid = sid - > sub_auths [ sid - > num_auths - 1 ] ;
2004-05-08 04:02:31 +04:00
return NT_STATUS_OK ;
2004-05-06 11:32:51 +04:00
}
2004-05-03 18:58:08 +04:00
/*
samr_CreateUser
*/
static NTSTATUS samr_CreateUser ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-06 11:32:51 +04:00
struct samr_CreateUser * r )
2004-05-03 18:58:08 +04:00
{
2004-05-06 11:32:51 +04:00
struct samr_CreateUser2 r2 ;
2004-06-24 04:25:38 +04:00
uint32_t access_granted = 0 ;
2004-05-06 11:32:51 +04:00
/* a simple wrapper around samr_CreateUser2 works nicely */
2004-09-21 07:51:38 +04:00
r2 . in . domain_handle = r - > in . domain_handle ;
2004-06-05 07:22:10 +04:00
r2 . in . account_name = r - > in . account_name ;
2004-05-15 11:51:38 +04:00
r2 . in . acct_flags = ACB_NORMAL ;
2004-05-06 11:32:51 +04:00
r2 . in . access_mask = r - > in . access_mask ;
2004-09-21 07:51:38 +04:00
r2 . out . user_handle = r - > out . user_handle ;
2004-05-06 11:32:51 +04:00
r2 . out . access_granted = & access_granted ;
2004-05-08 04:02:31 +04:00
r2 . out . rid = r - > out . rid ;
2004-05-06 11:32:51 +04:00
return samr_CreateUser2 ( dce_call , mem_ctx , & r2 ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_EnumDomainUsers
*/
static NTSTATUS samr_EnumDomainUsers ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-08 18:42:45 +04:00
struct samr_EnumDomainUsers * r )
2004-05-03 18:58:08 +04:00
{
2004-05-08 18:42:45 +04:00
struct dcesrv_handle * h ;
2004-05-10 16:37:06 +04:00
struct samr_domain_state * d_state ;
2004-05-08 18:42:45 +04:00
struct ldb_message * * res ;
int count , i , first ;
struct samr_SamEntry * entries ;
const char * const attrs [ 3 ] = { " objectSid " , " sAMAccountName " , NULL } ;
* r - > out . resume_handle = 0 ;
r - > out . sam = NULL ;
r - > out . num_entries = 0 ;
2004-09-21 07:51:38 +04:00
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
2004-05-08 18:42:45 +04:00
2004-05-10 16:37:06 +04:00
d_state = h - > data ;
2004-05-08 18:42:45 +04:00
/* search for all users in this domain. This could possibly be cached and
resumed based on resume_key */
2005-03-23 04:30:43 +03:00
count = gendb_search ( d_state - > sam_ctx , mem_ctx , d_state - > domain_dn , & res , attrs ,
2004-05-08 18:42:45 +04:00
" objectclass=user " ) ;
if ( count = = - 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2004-05-09 04:42:09 +04:00
if ( count = = 0 | | r - > in . max_size = = 0 ) {
2004-05-08 18:42:45 +04:00
return NT_STATUS_OK ;
}
/* convert to SamEntry format */
2005-01-27 10:08:20 +03:00
entries = talloc_array ( mem_ctx , struct samr_SamEntry , count ) ;
2004-05-08 18:42:45 +04:00
if ( ! entries ) {
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < count ; i + + ) {
entries [ i ] . idx = samdb_result_rid_from_sid ( mem_ctx , res [ i ] , " objectSid " , 0 ) ;
2004-11-13 16:45:41 +03:00
entries [ i ] . name . string = samdb_result_string ( res [ i ] , " sAMAccountName " , " " ) ;
2004-05-08 18:42:45 +04:00
}
/* sort the results by rid */
qsort ( entries , count , sizeof ( struct samr_SamEntry ) ,
( comparison_fn_t ) compare_SamEntry ) ;
/* find the first entry to return */
for ( first = 0 ;
first < count & & entries [ first ] . idx < = * r - > in . resume_handle ;
first + + ) ;
if ( first = = count ) {
return NT_STATUS_OK ;
}
/* return the rest, limit by max_size. Note that we
use the w2k3 element size value of 54 */
r - > out . num_entries = count - first ;
2004-05-09 04:42:09 +04:00
r - > out . num_entries = MIN ( r - > out . num_entries ,
1 + ( r - > in . max_size / SAMR_ENUM_USERS_MULTIPLIER ) ) ;
2004-05-08 18:42:45 +04:00
2005-01-27 10:08:20 +03:00
r - > out . sam = talloc ( mem_ctx , struct samr_SamArray ) ;
2004-05-08 18:42:45 +04:00
if ( ! r - > out . sam ) {
return NT_STATUS_NO_MEMORY ;
}
r - > out . sam - > entries = entries + first ;
r - > out . sam - > count = r - > out . num_entries ;
if ( r - > out . num_entries < count - first ) {
* r - > out . resume_handle = entries [ first + r - > out . num_entries - 1 ] . idx ;
return STATUS_MORE_ENTRIES ;
}
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_CreateDomAlias
*/
static NTSTATUS samr_CreateDomAlias ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_CreateDomAlias * r )
{
2004-12-23 01:19:54 +03:00
struct samr_domain_state * d_state ;
struct samr_account_state * a_state ;
struct dcesrv_handle * h ;
2005-06-24 04:18:20 +04:00
const char * alias_name , * name ;
2005-01-02 10:51:13 +03:00
struct ldb_message * msg ;
2005-03-28 03:31:43 +04:00
struct dom_sid * sid ;
2004-12-23 01:19:54 +03:00
struct dcesrv_handle * a_handle ;
int ret ;
ZERO_STRUCTP ( r - > out . alias_handle ) ;
* r - > out . rid = 0 ;
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
d_state = h - > data ;
2005-04-13 10:26:43 +04:00
alias_name = r - > in . alias_name - > string ;
2004-12-23 01:19:54 +03:00
2005-04-13 10:26:43 +04:00
if ( alias_name = = NULL ) {
2004-12-23 01:19:54 +03:00
return NT_STATUS_INVALID_PARAMETER ;
}
/* Check if alias already exists */
name = samdb_search_string ( d_state - > sam_ctx , mem_ctx , NULL ,
" sAMAccountName " ,
2005-07-27 04:23:09 +04:00
" (sAMAccountName=%s)(objectclass=group)) " ,
2005-04-13 10:26:43 +04:00
alias_name ) ;
2004-12-23 01:19:54 +03:00
if ( name ! = NULL ) {
return NT_STATUS_ALIAS_EXISTS ;
}
2005-01-02 10:51:13 +03:00
msg = ldb_msg_new ( mem_ctx ) ;
if ( msg = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2004-12-23 01:19:54 +03:00
2004-12-28 01:20:17 +03:00
/* add core elements to the ldb_message for the alias */
2005-04-13 10:26:43 +04:00
msg - > dn = talloc_asprintf ( mem_ctx , " CN=%s,CN=Users,%s " , alias_name ,
2004-12-23 01:19:54 +03:00
d_state - > domain_dn ) ;
2005-01-02 10:51:13 +03:00
if ( ! msg - > dn ) {
2004-12-23 01:19:54 +03:00
return NT_STATUS_NO_MEMORY ;
}
2005-04-13 10:26:43 +04:00
samdb_msg_add_string ( d_state - > sam_ctx , mem_ctx , msg , " sAMAccountName " , alias_name ) ;
2005-01-02 10:51:13 +03:00
samdb_msg_add_string ( d_state - > sam_ctx , mem_ctx , msg , " objectClass " , " group " ) ;
2005-03-28 03:31:43 +04:00
samdb_msg_add_string ( d_state - > sam_ctx , mem_ctx , msg , " groupType " , " 0x80000004 " ) ;
2004-12-23 01:19:54 +03:00
/* create the alias */
2005-01-02 10:51:13 +03:00
ret = samdb_add ( d_state - > sam_ctx , mem_ctx , msg ) ;
2004-12-23 01:19:54 +03:00
if ( ret ! = 0 ) {
2005-01-02 10:51:13 +03:00
DEBUG ( 0 , ( " Failed to create alias record %s \n " , msg - > dn ) ) ;
2004-12-23 01:19:54 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2005-01-27 10:08:20 +03:00
a_state = talloc ( d_state , struct samr_account_state ) ;
2004-12-23 01:19:54 +03:00
if ( ! a_state ) {
return NT_STATUS_NO_MEMORY ;
}
a_state - > sam_ctx = d_state - > sam_ctx ;
a_state - > access_mask = r - > in . access_mask ;
a_state - > domain_state = talloc_reference ( a_state , d_state ) ;
2005-01-02 10:51:13 +03:00
a_state - > account_dn = talloc_steal ( a_state , msg - > dn ) ;
2005-03-28 03:31:43 +04:00
2005-06-24 04:18:20 +04:00
/* retrieve the sid for the alias just created */
sid = samdb_search_dom_sid ( d_state - > sam_ctx , a_state ,
2005-07-17 13:20:52 +04:00
msg - > dn , " objectSid " , " dn=%s " , msg - > dn ) ;
2005-03-28 03:31:43 +04:00
2005-04-13 10:26:43 +04:00
a_state - > account_name = talloc_strdup ( a_state , alias_name ) ;
2004-12-23 15:02:55 +03:00
if ( ! a_state - > account_name ) {
2004-12-23 01:19:54 +03:00
return NT_STATUS_NO_MEMORY ;
}
/* create the policy handle */
2005-01-10 15:15:26 +03:00
a_handle = dcesrv_handle_new ( dce_call - > context , SAMR_HANDLE_ALIAS ) ;
2004-12-23 01:19:54 +03:00
if ( a_handle = = NULL )
return NT_STATUS_NO_MEMORY ;
2005-01-10 15:15:26 +03:00
a_handle - > data = talloc_steal ( a_handle , a_state ) ;
2004-12-23 01:19:54 +03:00
* r - > out . alias_handle = a_handle - > wire_handle ;
2005-03-28 03:31:43 +04:00
* r - > out . rid = sid - > sub_auths [ sid - > num_auths - 1 ] ;
2004-12-23 01:19:54 +03:00
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_EnumDomainAliases
*/
static NTSTATUS samr_EnumDomainAliases ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_EnumDomainAliases * r )
{
2004-12-28 10:57:31 +03:00
struct dcesrv_handle * h ;
struct samr_domain_state * d_state ;
struct ldb_message * * res ;
int ldb_cnt , count , i , first ;
struct samr_SamEntry * entries ;
const char * const attrs [ 3 ] = { " objectSid " , " sAMAccountName " , NULL } ;
* r - > out . resume_handle = 0 ;
r - > out . sam = NULL ;
r - > out . num_entries = 0 ;
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
d_state = h - > data ;
2004-12-30 20:01:49 +03:00
2004-12-28 10:57:31 +03:00
/* search for all domain groups in this domain. This could possibly be
cached and resumed based on resume_key */
2004-12-30 20:01:49 +03:00
ldb_cnt = samdb_search_domain ( d_state - > sam_ctx , mem_ctx ,
d_state - > domain_dn ,
2005-06-24 04:18:20 +04:00
& res , attrs ,
d_state - > domain_sid ,
2004-12-30 20:01:49 +03:00
" (&(|(grouptype=%s)(grouptype=%s))) "
" (objectclass=group)) " ,
ldb_hexstr ( mem_ctx ,
GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ) ,
ldb_hexstr ( mem_ctx ,
GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ) ) ;
2004-12-28 10:57:31 +03:00
if ( ldb_cnt = = - 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
if ( ldb_cnt = = 0 ) {
return NT_STATUS_OK ;
}
/* convert to SamEntry format */
2005-01-27 10:08:20 +03:00
entries = talloc_array ( mem_ctx , struct samr_SamEntry , ldb_cnt ) ;
2004-12-28 10:57:31 +03:00
if ( ! entries ) {
return NT_STATUS_NO_MEMORY ;
}
count = 0 ;
for ( i = 0 ; i < ldb_cnt ; i + + ) {
struct dom_sid * alias_sid ;
alias_sid = samdb_result_dom_sid ( mem_ctx , res [ i ] ,
" objectSid " ) ;
if ( alias_sid = = NULL )
continue ;
entries [ count ] . idx =
alias_sid - > sub_auths [ alias_sid - > num_auths - 1 ] ;
entries [ count ] . name . string =
samdb_result_string ( res [ i ] , " sAMAccountName " , " " ) ;
count + = 1 ;
}
/* sort the results by rid */
qsort ( entries , count , sizeof ( struct samr_SamEntry ) ,
( comparison_fn_t ) compare_SamEntry ) ;
/* find the first entry to return */
for ( first = 0 ;
first < count & & entries [ first ] . idx < = * r - > in . resume_handle ;
first + + ) ;
if ( first = = count ) {
return NT_STATUS_OK ;
}
r - > out . num_entries = count - first ;
r - > out . num_entries = MIN ( r - > out . num_entries , 1000 ) ;
2005-01-27 10:08:20 +03:00
r - > out . sam = talloc ( mem_ctx , struct samr_SamArray ) ;
2004-12-28 10:57:31 +03:00
if ( ! r - > out . sam ) {
return NT_STATUS_NO_MEMORY ;
}
r - > out . sam - > entries = entries + first ;
r - > out . sam - > count = r - > out . num_entries ;
if ( r - > out . num_entries < count - first ) {
* r - > out . resume_handle =
entries [ first + r - > out . num_entries - 1 ] . idx ;
return STATUS_MORE_ENTRIES ;
}
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_GetAliasMembership
*/
static NTSTATUS samr_GetAliasMembership ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_GetAliasMembership * r )
{
2004-12-30 01:57:20 +03:00
struct dcesrv_handle * h ;
struct samr_domain_state * d_state ;
struct ldb_message * * res ;
int i , count = 0 ;
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
d_state = h - > data ;
if ( r - > in . sids - > num_sids > 0 ) {
const char * filter ;
const char * const attrs [ 2 ] = { " objectSid " , NULL } ;
filter = talloc_asprintf ( mem_ctx ,
" (&(|(grouptype=%s)(grouptype=%s)) "
" (objectclass=group)(| " ,
ldb_hexstr ( mem_ctx ,
GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ) ,
ldb_hexstr ( mem_ctx ,
GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ) ) ;
if ( filter = = NULL )
return NT_STATUS_NO_MEMORY ;
for ( i = 0 ; i < r - > in . sids - > num_sids ; i + + ) {
2005-06-24 04:18:20 +04:00
const char * memberdn ;
2004-12-30 01:57:20 +03:00
2005-06-24 04:18:20 +04:00
memberdn =
samdb_search_string ( d_state - > sam_ctx ,
mem_ctx , NULL , " dn " ,
" (objectSid=%s) " ,
ldap_encode_ndr_dom_sid ( mem_ctx ,
r - > in . sids - > sids [ i ] . sid ) ) ;
2004-12-30 01:57:20 +03:00
if ( memberdn = = NULL )
continue ;
filter = talloc_asprintf ( mem_ctx , " %s(member=%s) " ,
filter , memberdn ) ;
if ( filter = = NULL )
return NT_STATUS_NO_MEMORY ;
}
2004-12-30 20:01:49 +03:00
count = samdb_search_domain ( d_state - > sam_ctx , mem_ctx ,
d_state - > domain_dn , & res , attrs ,
2005-06-24 04:18:20 +04:00
d_state - > domain_sid , " %s)) " , filter ) ;
2004-12-30 01:57:20 +03:00
if ( count < 0 )
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
r - > out . rids - > count = 0 ;
2005-01-27 10:08:20 +03:00
r - > out . rids - > ids = talloc_array ( mem_ctx , uint32_t , count ) ;
2004-12-30 01:57:20 +03:00
if ( r - > out . rids - > ids = = NULL )
return NT_STATUS_NO_MEMORY ;
for ( i = 0 ; i < count ; i + + ) {
struct dom_sid * alias_sid ;
alias_sid = samdb_result_dom_sid ( mem_ctx , res [ i ] , " objectSid " ) ;
if ( alias_sid = = NULL ) {
DEBUG ( 0 , ( " Could not find objectSid \n " ) ) ;
continue ;
}
r - > out . rids - > ids [ r - > out . rids - > count ] =
alias_sid - > sub_auths [ alias_sid - > num_auths - 1 ] ;
r - > out . rids - > count + = 1 ;
}
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_LookupNames
*/
static NTSTATUS samr_LookupNames ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-08 04:02:31 +04:00
struct samr_LookupNames * r )
2004-05-03 18:58:08 +04:00
{
2004-05-08 04:02:31 +04:00
struct dcesrv_handle * h ;
2004-05-10 16:37:06 +04:00
struct samr_domain_state * d_state ;
2004-05-08 04:02:31 +04:00
int i ;
NTSTATUS status = NT_STATUS_OK ;
const char * const attrs [ ] = { " sAMAccountType " , " objectSid " , NULL } ;
int count ;
ZERO_STRUCT ( r - > out . rids ) ;
ZERO_STRUCT ( r - > out . types ) ;
2004-09-21 07:51:38 +04:00
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
2004-05-08 04:02:31 +04:00
2004-05-10 16:37:06 +04:00
d_state = h - > data ;
2004-05-08 04:02:31 +04:00
if ( r - > in . num_names = = 0 ) {
return NT_STATUS_OK ;
}
2005-01-27 10:08:20 +03:00
r - > out . rids . ids = talloc_array ( mem_ctx , uint32_t , r - > in . num_names ) ;
r - > out . types . ids = talloc_array ( mem_ctx , uint32_t , r - > in . num_names ) ;
2004-05-08 04:02:31 +04:00
if ( ! r - > out . rids . ids | | ! r - > out . types . ids ) {
return NT_STATUS_NO_MEMORY ;
}
r - > out . rids . count = r - > in . num_names ;
r - > out . types . count = r - > in . num_names ;
for ( i = 0 ; i < r - > in . num_names ; i + + ) {
struct ldb_message * * res ;
2005-06-24 04:18:20 +04:00
struct dom_sid * sid ;
2004-05-25 20:24:13 +04:00
uint32_t atype , rtype ;
2004-05-08 04:02:31 +04:00
r - > out . rids . ids [ i ] = 0 ;
r - > out . types . ids [ i ] = SID_NAME_UNKNOWN ;
2005-03-23 04:30:43 +03:00
count = gendb_search ( d_state - > sam_ctx , mem_ctx , d_state - > domain_dn , & res , attrs ,
2004-11-13 16:45:41 +03:00
" sAMAccountName=%s " , r - > in . names [ i ] . string ) ;
2004-05-08 04:02:31 +04:00
if ( count ! = 1 ) {
status = STATUS_SOME_UNMAPPED ;
continue ;
}
2005-06-24 04:18:20 +04:00
sid = samdb_result_dom_sid ( mem_ctx , res [ 0 ] , " objectSid " ) ;
2004-05-08 04:02:31 +04:00
if ( sid = = NULL ) {
status = STATUS_SOME_UNMAPPED ;
continue ;
}
2005-06-24 04:18:20 +04:00
2004-05-08 04:02:31 +04:00
atype = samdb_result_uint ( res [ 0 ] , " sAMAccountType " , 0 ) ;
if ( atype = = 0 ) {
status = STATUS_SOME_UNMAPPED ;
continue ;
}
2004-05-15 11:51:38 +04:00
rtype = samdb_atype_map ( atype ) ;
if ( rtype = = SID_NAME_UNKNOWN ) {
2004-05-08 04:02:31 +04:00
status = STATUS_SOME_UNMAPPED ;
continue ;
}
r - > out . rids . ids [ i ] = sid - > sub_auths [ sid - > num_auths - 1 ] ;
r - > out . types . ids [ i ] = rtype ;
}
return status ;
2004-05-03 18:58:08 +04:00
}
/*
samr_LookupRids
*/
static NTSTATUS samr_LookupRids ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_LookupRids * r )
{
2004-12-27 02:31:19 +03:00
struct dcesrv_handle * h ;
struct samr_domain_state * d_state ;
2005-03-28 03:31:43 +04:00
int i , total ;
2004-12-27 02:31:19 +03:00
NTSTATUS status = NT_STATUS_OK ;
2005-07-08 12:09:02 +04:00
struct lsa_String * names ;
2004-12-27 12:48:49 +03:00
uint32_t * ids ;
2004-12-27 02:31:19 +03:00
ZERO_STRUCT ( r - > out . names ) ;
ZERO_STRUCT ( r - > out . types ) ;
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
d_state = h - > data ;
if ( r - > in . num_rids = = 0 )
return NT_STATUS_OK ;
2005-07-08 12:09:02 +04:00
names = talloc_array ( mem_ctx , struct lsa_String , r - > in . num_rids ) ;
2005-01-27 10:08:20 +03:00
ids = talloc_array ( mem_ctx , uint32_t , r - > in . num_rids ) ;
2004-12-27 02:31:19 +03:00
2004-12-27 12:48:49 +03:00
if ( ( names = = NULL ) | | ( ids = = NULL ) )
2004-12-27 02:31:19 +03:00
return NT_STATUS_NO_MEMORY ;
2005-03-28 03:31:43 +04:00
total = 0 ;
2004-12-27 02:31:19 +03:00
for ( i = 0 ; i < r - > in . num_rids ; i + + ) {
struct ldb_message * * res ;
int count ;
const char * const attrs [ ] = { " sAMAccountType " ,
" sAMAccountName " , NULL } ;
uint32_t atype ;
2005-06-24 04:18:20 +04:00
struct dom_sid * sid ;
2004-12-27 02:31:19 +03:00
2004-12-27 12:48:49 +03:00
ids [ i ] = SID_NAME_UNKNOWN ;
2004-12-27 02:31:19 +03:00
2005-06-24 04:18:20 +04:00
sid = dom_sid_add_rid ( mem_ctx , d_state - > domain_sid , r - > in . rids [ i ] ) ;
if ( sid = = NULL ) {
names [ i ] . string = NULL ;
status = STATUS_SOME_UNMAPPED ;
continue ;
}
2005-03-23 04:30:43 +03:00
count = gendb_search ( d_state - > sam_ctx , mem_ctx ,
2004-12-27 02:31:19 +03:00
d_state - > domain_dn , & res , attrs ,
2005-06-24 04:18:20 +04:00
" (objectSid=%s) " ,
ldap_encode_ndr_dom_sid ( mem_ctx , sid ) ) ;
2004-12-27 02:31:19 +03:00
if ( count ! = 1 ) {
2005-03-28 03:31:43 +04:00
names [ i ] . string = NULL ;
2004-12-27 02:31:19 +03:00
status = STATUS_SOME_UNMAPPED ;
continue ;
}
2004-12-27 12:48:49 +03:00
names [ i ] . string = samdb_result_string ( res [ 0 ] , " sAMAccountName " ,
NULL ) ;
2005-03-28 03:31:43 +04:00
2004-12-27 02:31:19 +03:00
atype = samdb_result_uint ( res [ 0 ] , " sAMAccountType " , 0 ) ;
if ( atype = = 0 ) {
status = STATUS_SOME_UNMAPPED ;
continue ;
}
2004-12-27 12:48:49 +03:00
ids [ i ] = samdb_atype_map ( atype ) ;
2004-12-27 02:31:19 +03:00
2004-12-27 12:48:49 +03:00
if ( ids [ i ] = = SID_NAME_UNKNOWN ) {
2004-12-27 02:31:19 +03:00
status = STATUS_SOME_UNMAPPED ;
continue ;
}
}
2004-12-27 12:48:49 +03:00
r - > out . names . names = names ;
r - > out . names . count = r - > in . num_rids ;
r - > out . types . ids = ids ;
r - > out . types . count = r - > in . num_rids ;
2004-12-27 02:31:19 +03:00
return status ;
2004-05-03 18:58:08 +04:00
}
/*
samr_OpenGroup
*/
static NTSTATUS samr_OpenGroup ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_OpenGroup * r )
{
2004-05-09 19:39:12 +04:00
struct samr_domain_state * d_state ;
2004-05-10 16:37:06 +04:00
struct samr_account_state * a_state ;
2004-05-09 19:39:12 +04:00
struct dcesrv_handle * h ;
2005-06-24 04:18:20 +04:00
const char * groupname ;
struct dom_sid * sid ;
2004-05-09 19:39:12 +04:00
struct ldb_message * * msgs ;
struct dcesrv_handle * g_handle ;
const char * const attrs [ 2 ] = { " sAMAccountName " , NULL } ;
int ret ;
2004-09-21 07:51:38 +04:00
ZERO_STRUCTP ( r - > out . group_handle ) ;
2004-05-09 19:39:12 +04:00
2004-09-21 07:51:38 +04:00
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
2004-05-09 19:39:12 +04:00
d_state = h - > data ;
/* form the group SID */
2005-06-24 04:18:20 +04:00
sid = dom_sid_add_rid ( mem_ctx , d_state - > domain_sid , r - > in . rid ) ;
if ( ! sid ) {
2004-05-09 19:39:12 +04:00
return NT_STATUS_NO_MEMORY ;
}
/* search for the group record */
2005-03-23 04:30:43 +03:00
ret = gendb_search ( d_state - > sam_ctx ,
2004-05-10 16:37:06 +04:00
mem_ctx , d_state - > domain_dn , & msgs , attrs ,
2004-12-26 21:02:18 +03:00
" (&(objectSid=%s)(objectclass=group) "
" (grouptype=%s)) " ,
2005-06-24 04:18:20 +04:00
ldap_encode_ndr_dom_sid ( mem_ctx , sid ) ,
ldb_hexstr ( mem_ctx ,
GTYPE_SECURITY_GLOBAL_GROUP ) ) ;
2004-05-09 19:39:12 +04:00
if ( ret = = 0 ) {
return NT_STATUS_NO_SUCH_GROUP ;
}
if ( ret ! = 1 ) {
2005-06-24 04:18:20 +04:00
DEBUG ( 0 , ( " Found %d records matching sid %s \n " ,
ret , dom_sid_string ( mem_ctx , sid ) ) ) ;
2004-05-09 19:39:12 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
groupname = samdb_result_string ( msgs [ 0 ] , " sAMAccountName " , NULL ) ;
if ( groupname = = NULL ) {
2005-06-24 04:18:20 +04:00
DEBUG ( 0 , ( " sAMAccountName field missing for sid %s \n " ,
dom_sid_string ( mem_ctx , sid ) ) ) ;
2004-05-09 19:39:12 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2005-01-27 10:08:20 +03:00
a_state = talloc ( d_state , struct samr_account_state ) ;
2004-05-10 16:37:06 +04:00
if ( ! a_state ) {
2004-05-09 19:39:12 +04:00
return NT_STATUS_NO_MEMORY ;
}
2004-05-10 16:37:06 +04:00
a_state - > sam_ctx = d_state - > sam_ctx ;
a_state - > access_mask = r - > in . access_mask ;
2004-09-27 09:13:00 +04:00
a_state - > domain_state = talloc_reference ( a_state , d_state ) ;
2004-08-25 10:44:23 +04:00
a_state - > account_dn = talloc_steal ( a_state , msgs [ 0 ] - > dn ) ;
2005-06-24 04:18:20 +04:00
a_state - > account_sid = talloc_steal ( a_state , sid ) ;
2004-08-25 10:44:23 +04:00
a_state - > account_name = talloc_strdup ( a_state , groupname ) ;
2004-12-23 15:02:55 +03:00
if ( ! a_state - > account_name ) {
2004-05-09 19:39:12 +04:00
return NT_STATUS_NO_MEMORY ;
}
/* create the policy handle */
2005-01-10 15:15:26 +03:00
g_handle = dcesrv_handle_new ( dce_call - > context , SAMR_HANDLE_GROUP ) ;
2004-05-09 19:39:12 +04:00
if ( ! g_handle ) {
return NT_STATUS_NO_MEMORY ;
}
2005-01-10 15:15:26 +03:00
g_handle - > data = talloc_steal ( g_handle , a_state ) ;
2004-05-09 19:39:12 +04:00
2004-09-21 07:51:38 +04:00
* r - > out . group_handle = g_handle - > wire_handle ;
2004-05-09 19:39:12 +04:00
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2004-05-09 19:39:12 +04:00
/* these query macros make samr_Query[User|Group]Info a bit easier to read */
# define QUERY_STRING(msg, field, attr) \
r - > out . info - > field = samdb_result_string ( msg , attr , " " ) ;
# define QUERY_UINT(msg, field, attr) \
r - > out . info - > field = samdb_result_uint ( msg , attr , 0 ) ;
# define QUERY_RID(msg, field, attr) \
r - > out . info - > field = samdb_result_rid_from_sid ( mem_ctx , msg , attr , 0 ) ;
# define QUERY_NTTIME(msg, field, attr) \
r - > out . info - > field = samdb_result_nttime ( msg , attr , 0 ) ;
# define QUERY_APASSC(msg, field, attr) \
2004-06-05 07:22:10 +04:00
r - > out . info - > field = samdb_result_allow_password_change ( a_state - > sam_ctx , mem_ctx , \
2004-05-10 16:37:06 +04:00
a_state - > domain_state - > domain_dn , msg , attr ) ;
2004-05-09 19:39:12 +04:00
# define QUERY_FPASSC(msg, field, attr) \
2004-06-05 07:22:10 +04:00
r - > out . info - > field = samdb_result_force_password_change ( a_state - > sam_ctx , mem_ctx , \
2004-05-10 16:37:06 +04:00
a_state - > domain_state - > domain_dn , msg , attr ) ;
2004-05-09 19:39:12 +04:00
# define QUERY_LHOURS(msg, field, attr) \
r - > out . info - > field = samdb_result_logon_hours ( mem_ctx , msg , attr ) ;
# define QUERY_AFLAGS(msg, field, attr) \
r - > out . info - > field = samdb_result_acct_flags ( msg , attr ) ;
/* these are used to make the Set[User|Group]Info code easier to follow */
# define SET_STRING(mod, field, attr) do { \
if ( r - > in . info - > field = = NULL ) return NT_STATUS_INVALID_PARAMETER ; \
2004-05-10 16:37:06 +04:00
if ( samdb_msg_add_string ( a_state - > sam_ctx , mem_ctx , mod , attr , r - > in . info - > field ) ! = 0 ) { \
2004-05-09 19:39:12 +04:00
return NT_STATUS_NO_MEMORY ; \
} \
} while ( 0 )
# define SET_UINT(mod, field, attr) do { \
2004-05-10 16:37:06 +04:00
if ( samdb_msg_add_uint ( a_state - > sam_ctx , mem_ctx , mod , attr , r - > in . info - > field ) ! = 0 ) { \
2004-05-09 19:39:12 +04:00
return NT_STATUS_NO_MEMORY ; \
} \
} while ( 0 )
# define SET_AFLAGS(msg, field, attr) do { \
2004-05-10 16:37:06 +04:00
if ( samdb_msg_add_acct_flags ( a_state - > sam_ctx , mem_ctx , msg , attr , r - > in . info - > field ) ! = 0 ) { \
2004-05-09 19:39:12 +04:00
return NT_STATUS_NO_MEMORY ; \
} \
} while ( 0 )
# define SET_LHOURS(msg, field, attr) do { \
2004-11-02 05:57:18 +03:00
if ( samdb_msg_add_logon_hours ( a_state - > sam_ctx , mem_ctx , msg , attr , & r - > in . info - > field ) ! = 0 ) { \
2004-05-09 19:39:12 +04:00
return NT_STATUS_NO_MEMORY ; \
} \
} while ( 0 )
2004-05-03 18:58:08 +04:00
/*
samr_QueryGroupInfo
*/
static NTSTATUS samr_QueryGroupInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_QueryGroupInfo * r )
{
2004-05-09 19:39:12 +04:00
struct dcesrv_handle * h ;
2004-05-10 16:37:06 +04:00
struct samr_account_state * a_state ;
2004-05-09 19:39:12 +04:00
struct ldb_message * msg , * * res ;
const char * const attrs [ 4 ] = { " sAMAccountName " , " description " ,
" numMembers " , NULL } ;
int ret ;
r - > out . info = NULL ;
2004-09-21 07:51:38 +04:00
DCESRV_PULL_HANDLE ( h , r - > in . group_handle , SAMR_HANDLE_GROUP ) ;
2004-05-09 19:39:12 +04:00
2004-05-10 16:37:06 +04:00
a_state = h - > data ;
2004-05-09 19:39:12 +04:00
/* pull all the group attributes */
2005-06-14 23:15:17 +04:00
ret = gendb_search_dn ( a_state - > sam_ctx , mem_ctx ,
a_state - > account_dn , & res , attrs ) ;
2004-05-09 19:39:12 +04:00
if ( ret ! = 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
msg = res [ 0 ] ;
/* allocate the info structure */
2005-01-27 10:08:20 +03:00
r - > out . info = talloc ( mem_ctx , union samr_GroupInfo ) ;
2004-05-09 19:39:12 +04:00
if ( r - > out . info = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
ZERO_STRUCTP ( r - > out . info ) ;
/* Fill in the level */
switch ( r - > in . level ) {
2005-01-29 05:46:37 +03:00
case GROUPINFOALL :
2004-11-13 16:45:41 +03:00
QUERY_STRING ( msg , all . name . string , " sAMAccountName " ) ;
2004-11-17 16:39:37 +03:00
r - > out . info - > all . attributes = 7 ; /* Do like w2k3 */
2004-05-09 19:39:12 +04:00
QUERY_UINT ( msg , all . num_members , " numMembers " )
2004-11-13 16:45:41 +03:00
QUERY_STRING ( msg , all . description . string , " description " ) ;
2004-05-09 19:39:12 +04:00
break ;
2005-01-29 05:46:37 +03:00
case GROUPINFONAME :
2004-11-13 16:45:41 +03:00
QUERY_STRING ( msg , name . string , " sAMAccountName " ) ;
2004-05-09 19:39:12 +04:00
break ;
2005-01-29 05:46:37 +03:00
case GROUPINFOX :
2004-05-09 19:39:12 +04:00
r - > out . info - > unknown . unknown = 7 ;
break ;
2005-01-29 05:46:37 +03:00
case GROUPINFODESCRIPTION :
2004-11-13 16:45:41 +03:00
QUERY_STRING ( msg , description . string , " description " ) ;
2004-05-09 19:39:12 +04:00
break ;
default :
r - > out . info = NULL ;
return NT_STATUS_INVALID_INFO_CLASS ;
}
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_SetGroupInfo
*/
static NTSTATUS samr_SetGroupInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-01-02 10:51:13 +03:00
struct samr_SetGroupInfo * r )
2004-05-03 18:58:08 +04:00
{
2004-05-09 19:39:12 +04:00
struct dcesrv_handle * h ;
2004-05-10 16:37:06 +04:00
struct samr_account_state * a_state ;
2005-01-02 10:51:13 +03:00
struct ldb_message * msg ;
2004-05-22 04:53:57 +04:00
int ret ;
2004-05-09 19:39:12 +04:00
2004-09-21 07:51:38 +04:00
DCESRV_PULL_HANDLE ( h , r - > in . group_handle , SAMR_HANDLE_GROUP ) ;
2004-05-09 19:39:12 +04:00
2004-05-10 16:37:06 +04:00
a_state = h - > data ;
2004-05-09 19:39:12 +04:00
2005-01-02 10:51:13 +03:00
msg = ldb_msg_new ( mem_ctx ) ;
if ( msg = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
msg - > dn = talloc_strdup ( mem_ctx , a_state - > account_dn ) ;
if ( ! msg - > dn ) {
2004-05-09 19:39:12 +04:00
return NT_STATUS_NO_MEMORY ;
}
switch ( r - > in . level ) {
2005-01-29 05:46:37 +03:00
case GROUPINFODESCRIPTION :
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , description . string , " description " ) ;
2004-05-09 19:39:12 +04:00
break ;
2005-01-29 05:46:37 +03:00
case GROUPINFONAME :
2004-05-09 19:39:12 +04:00
/* On W2k3 this does not change the name, it changes the
* sAMAccountName attribute */
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , name . string , " sAMAccountName " ) ;
2004-05-09 19:39:12 +04:00
break ;
2005-01-29 05:46:37 +03:00
case GROUPINFOX :
2004-05-09 19:39:12 +04:00
/* This does not do anything obviously visible in W2k3 LDAP */
break ;
default :
return NT_STATUS_INVALID_INFO_CLASS ;
}
/* modify the samdb record */
2005-01-02 10:51:13 +03:00
ret = samdb_replace ( a_state - > sam_ctx , mem_ctx , msg ) ;
2004-05-09 19:39:12 +04:00
if ( ret ! = 0 ) {
/* we really need samdb.c to return NTSTATUS */
return NT_STATUS_UNSUCCESSFUL ;
}
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_AddGroupMember
*/
static NTSTATUS samr_AddGroupMember ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_AddGroupMember * r )
{
2004-12-26 21:02:18 +03:00
struct dcesrv_handle * h ;
struct samr_account_state * a_state ;
struct samr_domain_state * d_state ;
2005-01-02 10:51:13 +03:00
struct ldb_message * mod ;
2005-06-24 04:18:20 +04:00
struct dom_sid * membersid ;
2004-12-26 21:02:18 +03:00
const char * memberdn ;
struct ldb_message * * msgs ;
const char * const attrs [ 2 ] = { " dn " , NULL } ;
int ret ;
DCESRV_PULL_HANDLE ( h , r - > in . group_handle , SAMR_HANDLE_GROUP ) ;
a_state = h - > data ;
d_state = a_state - > domain_state ;
2005-06-24 04:18:20 +04:00
membersid = dom_sid_add_rid ( mem_ctx , d_state - > domain_sid , r - > in . rid ) ;
if ( membersid = = NULL )
2004-12-26 21:02:18 +03:00
return NT_STATUS_NO_MEMORY ;
/* In native mode, AD can also nest domain groups. Not sure yet
* whether this is also available via RPC . */
2005-03-23 04:30:43 +03:00
ret = gendb_search ( d_state - > sam_ctx , mem_ctx , d_state - > domain_dn ,
2004-12-26 21:02:18 +03:00
& msgs , attrs , " (&(objectSid=%s)(objectclass=user)) " ,
2005-06-24 04:18:20 +04:00
ldap_encode_ndr_dom_sid ( mem_ctx , membersid ) ) ;
2004-12-26 21:02:18 +03:00
if ( ret = = 0 )
return NT_STATUS_NO_SUCH_USER ;
if ( ret > 1 )
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
memberdn = samdb_result_string ( msgs [ 0 ] , " dn " , NULL ) ;
if ( memberdn = = NULL )
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2005-01-02 10:51:13 +03:00
mod = ldb_msg_new ( mem_ctx ) ;
if ( mod = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2004-12-26 21:02:18 +03:00
2005-01-02 10:51:13 +03:00
mod - > dn = talloc_reference ( mem_ctx , a_state - > account_dn ) ;
if ( samdb_msg_add_addval ( d_state - > sam_ctx , mem_ctx , mod , " member " ,
2004-12-26 21:02:18 +03:00
memberdn ) ! = 0 )
return NT_STATUS_UNSUCCESSFUL ;
2005-01-02 10:51:13 +03:00
if ( samdb_modify ( a_state - > sam_ctx , mem_ctx , mod ) ! = 0 )
2004-12-26 21:02:18 +03:00
return NT_STATUS_UNSUCCESSFUL ;
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_DeleteDomainGroup
*/
static NTSTATUS samr_DeleteDomainGroup ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_DeleteDomainGroup * r )
{
2004-05-09 19:39:12 +04:00
struct dcesrv_handle * h ;
2004-05-10 16:37:06 +04:00
struct samr_account_state * a_state ;
2004-05-09 19:39:12 +04:00
int ret ;
2004-09-21 07:51:38 +04:00
* r - > out . group_handle = * r - > in . group_handle ;
2004-05-09 19:39:12 +04:00
2004-09-21 07:51:38 +04:00
DCESRV_PULL_HANDLE ( h , r - > in . group_handle , SAMR_HANDLE_GROUP ) ;
2004-05-09 19:39:12 +04:00
2004-05-10 16:37:06 +04:00
a_state = h - > data ;
2004-05-09 19:39:12 +04:00
2004-05-10 16:37:06 +04:00
ret = samdb_delete ( a_state - > sam_ctx , mem_ctx , a_state - > account_dn ) ;
2004-05-09 19:39:12 +04:00
if ( ret ! = 0 ) {
return NT_STATUS_UNSUCCESSFUL ;
}
2004-09-21 07:51:38 +04:00
ZERO_STRUCTP ( r - > out . group_handle ) ;
2004-05-09 19:39:12 +04:00
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_DeleteGroupMember
*/
static NTSTATUS samr_DeleteGroupMember ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_DeleteGroupMember * r )
{
2004-12-26 21:02:18 +03:00
struct dcesrv_handle * h ;
struct samr_account_state * a_state ;
struct samr_domain_state * d_state ;
2005-01-02 10:51:13 +03:00
struct ldb_message * mod ;
2005-06-24 04:18:20 +04:00
struct dom_sid * membersid ;
2004-12-26 21:02:18 +03:00
const char * memberdn ;
struct ldb_message * * msgs ;
const char * const attrs [ 2 ] = { " dn " , NULL } ;
int ret ;
DCESRV_PULL_HANDLE ( h , r - > in . group_handle , SAMR_HANDLE_GROUP ) ;
a_state = h - > data ;
d_state = a_state - > domain_state ;
2005-06-24 04:18:20 +04:00
membersid = dom_sid_add_rid ( mem_ctx , d_state - > domain_sid , r - > in . rid ) ;
if ( membersid = = NULL )
2004-12-26 21:02:18 +03:00
return NT_STATUS_NO_MEMORY ;
/* In native mode, AD can also nest domain groups. Not sure yet
* whether this is also available via RPC . */
2005-03-23 04:30:43 +03:00
ret = gendb_search ( d_state - > sam_ctx , mem_ctx , d_state - > domain_dn ,
2004-12-26 21:02:18 +03:00
& msgs , attrs , " (&(objectSid=%s)(objectclass=user)) " ,
2005-06-24 04:18:20 +04:00
ldap_encode_ndr_dom_sid ( mem_ctx , membersid ) ) ;
2004-12-26 21:02:18 +03:00
if ( ret = = 0 )
return NT_STATUS_NO_SUCH_USER ;
if ( ret > 1 )
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
memberdn = samdb_result_string ( msgs [ 0 ] , " dn " , NULL ) ;
if ( memberdn = = NULL )
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2005-01-02 10:51:13 +03:00
mod = ldb_msg_new ( mem_ctx ) ;
if ( mod = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
mod - > dn = talloc_reference ( mem_ctx , a_state - > account_dn ) ;
2004-12-26 21:02:18 +03:00
2005-01-02 10:51:13 +03:00
if ( samdb_msg_add_delval ( d_state - > sam_ctx , mem_ctx , mod , " member " ,
2004-12-26 21:02:18 +03:00
memberdn ) ! = 0 )
return NT_STATUS_UNSUCCESSFUL ;
2005-01-02 10:51:13 +03:00
if ( samdb_modify ( a_state - > sam_ctx , mem_ctx , mod ) ! = 0 )
2004-12-26 21:02:18 +03:00
return NT_STATUS_UNSUCCESSFUL ;
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_QueryGroupMember
*/
static NTSTATUS samr_QueryGroupMember ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_QueryGroupMember * r )
{
2004-12-26 21:02:18 +03:00
struct dcesrv_handle * h ;
struct samr_account_state * a_state ;
struct ldb_message * * res ;
struct ldb_message_element * el ;
2005-05-01 12:05:17 +04:00
struct samr_RidTypeArray * array ;
2004-12-26 21:02:18 +03:00
const char * const attrs [ 2 ] = { " member " , NULL } ;
int ret ;
DCESRV_PULL_HANDLE ( h , r - > in . group_handle , SAMR_HANDLE_GROUP ) ;
a_state = h - > data ;
/* pull the member attribute */
2005-06-14 23:15:17 +04:00
ret = gendb_search_dn ( a_state - > sam_ctx , mem_ctx ,
a_state - > account_dn , & res , attrs ) ;
2004-12-26 21:02:18 +03:00
if ( ret ! = 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2005-05-01 12:05:17 +04:00
array = talloc ( mem_ctx , struct samr_RidTypeArray ) ;
2004-12-26 21:02:18 +03:00
if ( array = = NULL )
return NT_STATUS_NO_MEMORY ;
ZERO_STRUCTP ( array ) ;
el = ldb_msg_find_element ( res [ 0 ] , " member " ) ;
if ( el ! = NULL ) {
int i ;
array - > count = el - > num_values ;
2005-02-10 08:09:35 +03:00
array - > rids = talloc_array ( mem_ctx , uint32_t ,
2004-12-26 21:02:18 +03:00
el - > num_values ) ;
if ( array - > rids = = NULL )
return NT_STATUS_NO_MEMORY ;
2005-05-01 12:05:17 +04:00
array - > types = talloc_array ( mem_ctx , uint32_t ,
el - > num_values ) ;
if ( array - > types = = NULL )
2004-12-26 21:02:18 +03:00
return NT_STATUS_NO_MEMORY ;
for ( i = 0 ; i < el - > num_values ; i + + ) {
struct ldb_message * * res2 ;
const char * const attrs2 [ 2 ] = { " objectSid " , NULL } ;
2005-06-14 23:15:17 +04:00
ret = gendb_search_dn ( a_state - > sam_ctx , mem_ctx ,
( char * ) el - > values [ i ] . data ,
& res2 , attrs2 ) ;
2004-12-26 21:02:18 +03:00
if ( ret ! = 1 )
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
array - > rids [ i ] =
samdb_result_rid_from_sid ( mem_ctx , res2 [ 0 ] ,
" objectSid " , 0 ) ;
if ( array - > rids [ i ] = = 0 )
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2005-05-01 12:05:17 +04:00
array - > types [ i ] = 7 ; /* RID type of some kind, not sure what the value means. */
2004-12-26 21:02:18 +03:00
}
}
r - > out . rids = array ;
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_SetMemberAttributesOfGroup
*/
static NTSTATUS samr_SetMemberAttributesOfGroup ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_SetMemberAttributesOfGroup * r )
{
2004-05-04 10:07:52 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_OpenAlias
*/
static NTSTATUS samr_OpenAlias ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_OpenAlias * r )
{
2004-12-27 14:27:30 +03:00
struct samr_domain_state * d_state ;
struct samr_account_state * a_state ;
struct dcesrv_handle * h ;
2005-06-24 04:18:20 +04:00
const char * alias_name ;
struct dom_sid * sid ;
2004-12-27 14:27:30 +03:00
struct ldb_message * * msgs ;
struct dcesrv_handle * g_handle ;
const char * const attrs [ 2 ] = { " sAMAccountName " , NULL } ;
int ret ;
ZERO_STRUCTP ( r - > out . alias_handle ) ;
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
d_state = h - > data ;
/* form the alias SID */
2005-06-24 04:18:20 +04:00
sid = dom_sid_add_rid ( mem_ctx , d_state - > domain_sid , r - > in . rid ) ;
if ( sid = = NULL )
2004-12-27 14:27:30 +03:00
return NT_STATUS_NO_MEMORY ;
/* search for the group record */
2005-03-23 04:30:43 +03:00
ret = gendb_search ( d_state - > sam_ctx ,
2004-12-27 14:27:30 +03:00
mem_ctx , d_state - > domain_dn , & msgs , attrs ,
" (&(objectSid=%s)(objectclass=group) "
" (|(grouptype=%s)(grouptype=%s))) " ,
2005-06-24 04:18:20 +04:00
ldap_encode_ndr_dom_sid ( mem_ctx , sid ) ,
2004-12-28 10:57:31 +03:00
ldb_hexstr ( mem_ctx ,
GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ) ,
ldb_hexstr ( mem_ctx ,
GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ) ) ;
2004-12-27 14:27:30 +03:00
if ( ret = = 0 ) {
return NT_STATUS_NO_SUCH_ALIAS ;
}
if ( ret ! = 1 ) {
2005-06-24 04:18:20 +04:00
DEBUG ( 0 , ( " Found %d records matching sid %s \n " ,
ret , dom_sid_string ( mem_ctx , sid ) ) ) ;
2004-12-27 14:27:30 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2005-04-13 10:26:43 +04:00
alias_name = samdb_result_string ( msgs [ 0 ] , " sAMAccountName " , NULL ) ;
if ( alias_name = = NULL ) {
2005-06-24 04:18:20 +04:00
DEBUG ( 0 , ( " sAMAccountName field missing for sid %s \n " ,
dom_sid_string ( mem_ctx , sid ) ) ) ;
2004-12-27 14:27:30 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2005-01-27 10:08:20 +03:00
a_state = talloc ( d_state , struct samr_account_state ) ;
2004-12-27 14:27:30 +03:00
if ( ! a_state ) {
return NT_STATUS_NO_MEMORY ;
}
a_state - > sam_ctx = d_state - > sam_ctx ;
a_state - > access_mask = r - > in . access_mask ;
a_state - > domain_state = talloc_reference ( a_state , d_state ) ;
a_state - > account_dn = talloc_steal ( a_state , msgs [ 0 ] - > dn ) ;
2005-06-24 04:18:20 +04:00
a_state - > account_sid = talloc_steal ( a_state , sid ) ;
2005-04-13 10:26:43 +04:00
a_state - > account_name = talloc_strdup ( a_state , alias_name ) ;
2004-12-27 14:27:30 +03:00
if ( ! a_state - > account_name ) {
return NT_STATUS_NO_MEMORY ;
}
/* create the policy handle */
2005-01-10 15:15:26 +03:00
g_handle = dcesrv_handle_new ( dce_call - > context , SAMR_HANDLE_ALIAS ) ;
2004-12-27 14:27:30 +03:00
if ( ! g_handle ) {
return NT_STATUS_NO_MEMORY ;
}
2005-01-10 15:15:26 +03:00
g_handle - > data = talloc_steal ( g_handle , a_state ) ;
2004-12-27 14:27:30 +03:00
* r - > out . alias_handle = g_handle - > wire_handle ;
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_QueryAliasInfo
*/
static NTSTATUS samr_QueryAliasInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_QueryAliasInfo * r )
{
2004-12-27 14:27:30 +03:00
struct dcesrv_handle * h ;
struct samr_account_state * a_state ;
struct ldb_message * msg , * * res ;
const char * const attrs [ 4 ] = { " sAMAccountName " , " description " ,
" numMembers " , NULL } ;
int ret ;
r - > out . info = NULL ;
DCESRV_PULL_HANDLE ( h , r - > in . alias_handle , SAMR_HANDLE_ALIAS ) ;
a_state = h - > data ;
/* pull all the alias attributes */
2005-06-14 23:15:17 +04:00
ret = gendb_search_dn ( a_state - > sam_ctx , mem_ctx ,
a_state - > account_dn , & res , attrs ) ;
2004-12-27 14:27:30 +03:00
if ( ret ! = 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
msg = res [ 0 ] ;
/* allocate the info structure */
2005-01-27 10:08:20 +03:00
r - > out . info = talloc ( mem_ctx , union samr_AliasInfo ) ;
2004-12-27 14:27:30 +03:00
if ( r - > out . info = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
ZERO_STRUCTP ( r - > out . info ) ;
switch ( r - > in . level ) {
2005-01-29 05:46:37 +03:00
case ALIASINFOALL :
2004-12-27 14:27:30 +03:00
QUERY_STRING ( msg , all . name . string , " sAMAccountName " ) ;
QUERY_UINT ( msg , all . num_members , " numMembers " ) ;
QUERY_STRING ( msg , all . description . string , " description " ) ;
break ;
2005-01-29 05:46:37 +03:00
case ALIASINFONAME :
2004-12-27 14:27:30 +03:00
QUERY_STRING ( msg , name . string , " sAMAccountName " ) ;
break ;
2005-01-29 05:46:37 +03:00
case ALIASINFODESCRIPTION :
2004-12-27 14:27:30 +03:00
QUERY_STRING ( msg , description . string , " description " ) ;
break ;
default :
r - > out . info = NULL ;
return NT_STATUS_INVALID_INFO_CLASS ;
}
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_SetAliasInfo
*/
static NTSTATUS samr_SetAliasInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_SetAliasInfo * r )
{
2004-12-27 14:27:30 +03:00
struct dcesrv_handle * h ;
struct samr_account_state * a_state ;
2005-01-02 10:51:13 +03:00
struct ldb_message * msg ;
2004-12-27 14:27:30 +03:00
int ret ;
DCESRV_PULL_HANDLE ( h , r - > in . alias_handle , SAMR_HANDLE_ALIAS ) ;
a_state = h - > data ;
2005-01-02 10:51:13 +03:00
msg = ldb_msg_new ( mem_ctx ) ;
if ( msg = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
msg - > dn = talloc_strdup ( mem_ctx , a_state - > account_dn ) ;
if ( ! msg - > dn ) {
2004-12-27 14:27:30 +03:00
return NT_STATUS_NO_MEMORY ;
}
switch ( r - > in . level ) {
2005-01-29 05:46:37 +03:00
case ALIASINFODESCRIPTION :
2004-12-27 14:27:30 +03:00
SET_STRING ( msg , description . string , " description " ) ;
break ;
2005-01-29 05:46:37 +03:00
case ALIASINFONAME :
2004-12-27 14:27:30 +03:00
/* On W2k3 this does not change the name, it changes the
* sAMAccountName attribute */
SET_STRING ( msg , name . string , " sAMAccountName " ) ;
break ;
default :
return NT_STATUS_INVALID_INFO_CLASS ;
}
/* modify the samdb record */
2005-01-02 10:51:13 +03:00
ret = samdb_replace ( a_state - > sam_ctx , mem_ctx , msg ) ;
2004-12-27 14:27:30 +03:00
if ( ret ! = 0 ) {
/* we really need samdb.c to return NTSTATUS */
return NT_STATUS_UNSUCCESSFUL ;
}
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_DeleteDomAlias
*/
static NTSTATUS samr_DeleteDomAlias ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_DeleteDomAlias * r )
{
2005-03-28 03:31:43 +04:00
struct dcesrv_handle * h ;
struct samr_account_state * a_state ;
int ret ;
* r - > out . alias_handle = * r - > in . alias_handle ;
DCESRV_PULL_HANDLE ( h , r - > in . alias_handle , SAMR_HANDLE_ALIAS ) ;
a_state = h - > data ;
ret = samdb_delete ( a_state - > sam_ctx , mem_ctx , a_state - > account_dn ) ;
if ( ret ! = 0 ) {
return NT_STATUS_UNSUCCESSFUL ;
}
ZERO_STRUCTP ( r - > out . alias_handle ) ;
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_AddAliasMember
*/
static NTSTATUS samr_AddAliasMember ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_AddAliasMember * r )
{
2004-12-28 01:20:17 +03:00
struct dcesrv_handle * h ;
struct samr_account_state * a_state ;
struct samr_domain_state * d_state ;
2005-01-02 10:51:13 +03:00
struct ldb_message * mod ;
2004-12-28 01:20:17 +03:00
struct ldb_message * * msgs ;
const char * const attrs [ 2 ] = { " dn " , NULL } ;
const char * memberdn = NULL ;
int ret ;
DCESRV_PULL_HANDLE ( h , r - > in . alias_handle , SAMR_HANDLE_ALIAS ) ;
a_state = h - > data ;
d_state = a_state - > domain_state ;
2005-03-23 04:30:43 +03:00
ret = gendb_search ( d_state - > sam_ctx , mem_ctx , NULL ,
2005-06-24 04:18:20 +04:00
& msgs , attrs , " (objectsid=%s) " ,
ldap_encode_ndr_dom_sid ( mem_ctx , r - > in . sid ) ) ;
2004-12-28 01:20:17 +03:00
if ( ret = = 1 ) {
memberdn = ldb_msg_find_string ( msgs [ 0 ] , " dn " , NULL ) ;
} else if ( ret > 1 ) {
2005-06-24 04:18:20 +04:00
DEBUG ( 0 , ( " Found %d records matching sid %s \n " ,
ret , dom_sid_string ( mem_ctx , r - > in . sid ) ) ) ;
2004-12-28 01:20:17 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
} else if ( ret = = 0 ) {
2005-01-02 10:51:13 +03:00
struct ldb_message * msg ;
2005-07-21 12:34:54 +04:00
const char * basedn , * sidstr ;
2005-06-24 04:18:20 +04:00
sidstr = dom_sid_string ( mem_ctx , r - > in . sid ) ;
NT_STATUS_HAVE_NO_MEMORY ( sidstr ) ;
2004-12-28 01:20:17 +03:00
/* We might have to create a ForeignSecurityPrincipal, but
* only if it ' s not our own domain */
2005-06-24 04:18:20 +04:00
if ( dom_sid_in_domain ( d_state - > domain_sid , r - > in . sid ) )
2004-12-28 01:20:17 +03:00
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
2005-01-02 10:51:13 +03:00
msg = ldb_msg_new ( mem_ctx ) ;
if ( msg = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2004-12-28 01:20:17 +03:00
/* TODO: Hmmm. This feels wrong. How do I find the base dn to
* put the ForeignSecurityPrincipals ? d_state - > domain_dn does
* not work , this is wrong for the Builtin domain , there ' s no
* cn = For . . . , cn = Builtin , dc = { BASEDN } . - - vl
*/
basedn = samdb_search_string ( d_state - > sam_ctx , mem_ctx , NULL ,
" dn " ,
" (&(objectClass=container) "
" (cn=ForeignSecurityPrincipals)) " ) ;
if ( basedn = = NULL ) {
DEBUG ( 0 , ( " Failed to find DN for "
" ForeignSecurityPrincipal container \n " ) ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
/* add core elements to the ldb_message for the alias */
2005-01-02 10:51:13 +03:00
msg - > dn = talloc_asprintf ( mem_ctx , " CN=%s,%s " , sidstr , basedn ) ;
if ( msg - > dn = = NULL )
2004-12-28 01:20:17 +03:00
return NT_STATUS_NO_MEMORY ;
2005-01-02 10:51:13 +03:00
memberdn = msg - > dn ;
2004-12-28 01:20:17 +03:00
2005-01-02 10:51:13 +03:00
samdb_msg_add_string ( d_state - > sam_ctx , mem_ctx , msg ,
2004-12-28 01:20:17 +03:00
" objectClass " ,
" foreignSecurityPrincipal " ) ;
2005-07-27 04:23:09 +04:00
2004-12-28 01:20:17 +03:00
/* create the alias */
2005-01-02 10:51:13 +03:00
ret = samdb_add ( d_state - > sam_ctx , mem_ctx , msg ) ;
2004-12-28 01:20:17 +03:00
if ( ret ! = 0 ) {
DEBUG ( 0 , ( " Failed to create foreignSecurityPrincipal "
2005-01-02 10:51:13 +03:00
" record %s \n " , msg - > dn ) ) ;
2004-12-28 01:20:17 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
} else {
DEBUG ( 0 , ( " samdb_search returned %d \n " , ret ) ) ;
}
if ( memberdn = = NULL ) {
DEBUG ( 0 , ( " Could not find memberdn \n " ) ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2005-01-02 10:51:13 +03:00
mod = ldb_msg_new ( mem_ctx ) ;
if ( mod = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
mod - > dn = talloc_reference ( mem_ctx , a_state - > account_dn ) ;
2004-12-28 01:20:17 +03:00
2005-01-02 10:51:13 +03:00
if ( samdb_msg_add_addval ( d_state - > sam_ctx , mem_ctx , mod , " member " ,
2004-12-28 01:20:17 +03:00
memberdn ) ! = 0 )
return NT_STATUS_UNSUCCESSFUL ;
2005-01-02 10:51:13 +03:00
if ( samdb_modify ( a_state - > sam_ctx , mem_ctx , mod ) ! = 0 )
2004-12-28 01:20:17 +03:00
return NT_STATUS_UNSUCCESSFUL ;
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_DeleteAliasMember
*/
static NTSTATUS samr_DeleteAliasMember ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_DeleteAliasMember * r )
{
2004-12-28 01:20:17 +03:00
struct dcesrv_handle * h ;
struct samr_account_state * a_state ;
struct samr_domain_state * d_state ;
2005-01-02 10:51:13 +03:00
struct ldb_message * mod ;
2004-12-28 01:20:17 +03:00
const char * memberdn ;
DCESRV_PULL_HANDLE ( h , r - > in . alias_handle , SAMR_HANDLE_ALIAS ) ;
a_state = h - > data ;
d_state = a_state - > domain_state ;
memberdn = samdb_search_string ( d_state - > sam_ctx , mem_ctx , NULL ,
2005-06-24 04:18:20 +04:00
" dn " , " (objectSid=%s) " ,
ldap_encode_ndr_dom_sid ( mem_ctx , r - > in . sid ) ) ;
2004-12-28 01:20:17 +03:00
if ( memberdn = = NULL )
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
2005-01-02 10:51:13 +03:00
mod = ldb_msg_new ( mem_ctx ) ;
if ( mod = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
mod - > dn = talloc_reference ( mem_ctx , a_state - > account_dn ) ;
2004-12-28 01:20:17 +03:00
2005-01-02 10:51:13 +03:00
if ( samdb_msg_add_delval ( d_state - > sam_ctx , mem_ctx , mod , " member " ,
2004-12-28 01:20:17 +03:00
memberdn ) ! = 0 )
return NT_STATUS_UNSUCCESSFUL ;
2005-01-02 10:51:13 +03:00
if ( samdb_modify ( a_state - > sam_ctx , mem_ctx , mod ) ! = 0 )
2004-12-28 01:20:17 +03:00
return NT_STATUS_UNSUCCESSFUL ;
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_GetMembersInAlias
*/
static NTSTATUS samr_GetMembersInAlias ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_GetMembersInAlias * r )
{
2004-12-28 01:20:17 +03:00
struct dcesrv_handle * h ;
struct samr_account_state * a_state ;
struct samr_domain_state * d_state ;
struct ldb_message * * msgs ;
struct lsa_SidPtr * sids ;
struct ldb_message_element * el ;
const char * const attrs [ 2 ] = { " member " , NULL } ;
int ret ;
DCESRV_PULL_HANDLE ( h , r - > in . alias_handle , SAMR_HANDLE_ALIAS ) ;
a_state = h - > data ;
d_state = a_state - > domain_state ;
2005-06-14 23:15:17 +04:00
ret = gendb_search_dn ( d_state - > sam_ctx , mem_ctx ,
a_state - > account_dn , & msgs , attrs ) ;
2004-05-03 18:58:08 +04:00
2004-12-28 01:20:17 +03:00
if ( ret ! = 1 )
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2004-12-29 16:22:00 +03:00
r - > out . sids - > num_sids = 0 ;
r - > out . sids - > sids = NULL ;
2004-12-28 01:20:17 +03:00
el = ldb_msg_find_element ( msgs [ 0 ] , " member " ) ;
if ( el ! = NULL ) {
int i ;
2005-01-27 10:08:20 +03:00
sids = talloc_array ( mem_ctx , struct lsa_SidPtr ,
2004-12-28 01:20:17 +03:00
el - > num_values ) ;
if ( sids = = NULL )
return NT_STATUS_NO_MEMORY ;
for ( i = 0 ; i < el - > num_values ; i + + ) {
struct ldb_message * * msgs2 ;
const char * const attrs2 [ 2 ] = { " objectSid " , NULL } ;
2005-06-14 23:15:17 +04:00
ret = gendb_search_dn ( a_state - > sam_ctx , mem_ctx ,
( char * ) el - > values [ i ] . data ,
& msgs2 , attrs2 ) ;
2004-12-28 01:20:17 +03:00
if ( ret ! = 1 )
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
sids [ i ] . sid = samdb_result_dom_sid ( mem_ctx , msgs2 [ 0 ] ,
" objectSid " ) ;
if ( sids [ i ] . sid = = NULL )
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2004-12-29 16:22:00 +03:00
r - > out . sids - > num_sids = el - > num_values ;
r - > out . sids - > sids = sids ;
2004-12-28 01:20:17 +03:00
}
return NT_STATUS_OK ;
}
2004-05-03 18:58:08 +04:00
/*
samr_OpenUser
*/
static NTSTATUS samr_OpenUser ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-08 04:02:31 +04:00
struct samr_OpenUser * r )
2004-05-03 18:58:08 +04:00
{
2004-05-08 04:02:31 +04:00
struct samr_domain_state * d_state ;
2004-05-10 16:37:06 +04:00
struct samr_account_state * a_state ;
2004-05-08 04:02:31 +04:00
struct dcesrv_handle * h ;
2005-06-24 04:18:20 +04:00
const char * account_name ;
struct dom_sid * sid ;
2004-05-08 04:02:31 +04:00
struct ldb_message * * msgs ;
struct dcesrv_handle * u_handle ;
const char * const attrs [ 2 ] = { " sAMAccountName " , NULL } ;
int ret ;
2004-09-21 07:51:38 +04:00
ZERO_STRUCTP ( r - > out . user_handle ) ;
2004-05-08 04:02:31 +04:00
2004-09-21 07:51:38 +04:00
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
2004-05-08 04:02:31 +04:00
d_state = h - > data ;
/* form the users SID */
2005-06-24 04:18:20 +04:00
sid = dom_sid_add_rid ( mem_ctx , d_state - > domain_sid , r - > in . rid ) ;
if ( ! sid ) {
2004-05-08 04:02:31 +04:00
return NT_STATUS_NO_MEMORY ;
}
/* search for the user record */
2005-03-23 04:30:43 +03:00
ret = gendb_search ( d_state - > sam_ctx ,
2004-05-10 16:37:06 +04:00
mem_ctx , d_state - > domain_dn , & msgs , attrs ,
2004-05-08 04:02:31 +04:00
" (&(objectSid=%s)(objectclass=user)) " ,
2005-06-24 04:18:20 +04:00
ldap_encode_ndr_dom_sid ( mem_ctx , sid ) ) ;
2004-05-08 04:02:31 +04:00
if ( ret = = 0 ) {
return NT_STATUS_NO_SUCH_USER ;
}
if ( ret ! = 1 ) {
2005-06-24 04:18:20 +04:00
DEBUG ( 0 , ( " Found %d records matching sid %s \n " , ret ,
dom_sid_string ( mem_ctx , sid ) ) ) ;
2004-05-08 04:02:31 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2004-06-05 07:22:10 +04:00
account_name = samdb_result_string ( msgs [ 0 ] , " sAMAccountName " , NULL ) ;
if ( account_name = = NULL ) {
2005-06-24 04:18:20 +04:00
DEBUG ( 0 , ( " sAMAccountName field missing for sid %s \n " ,
dom_sid_string ( mem_ctx , sid ) ) ) ;
2004-05-08 04:02:31 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2005-01-27 10:08:20 +03:00
a_state = talloc ( mem_ctx , struct samr_account_state ) ;
2004-05-10 16:37:06 +04:00
if ( ! a_state ) {
2004-05-08 04:02:31 +04:00
return NT_STATUS_NO_MEMORY ;
}
2004-05-10 16:37:06 +04:00
a_state - > sam_ctx = d_state - > sam_ctx ;
a_state - > access_mask = r - > in . access_mask ;
2004-09-27 09:13:00 +04:00
a_state - > domain_state = talloc_reference ( a_state , d_state ) ;
2004-12-23 15:02:55 +03:00
a_state - > account_dn = talloc_steal ( a_state , msgs [ 0 ] - > dn ) ;
2005-06-24 04:18:20 +04:00
a_state - > account_sid = talloc_steal ( a_state , sid ) ;
2004-12-23 15:02:55 +03:00
a_state - > account_name = talloc_strdup ( a_state , account_name ) ;
if ( ! a_state - > account_name ) {
2004-05-08 04:02:31 +04:00
return NT_STATUS_NO_MEMORY ;
}
/* create the policy handle */
2005-01-10 15:15:26 +03:00
u_handle = dcesrv_handle_new ( dce_call - > context , SAMR_HANDLE_USER ) ;
2004-05-08 04:02:31 +04:00
if ( ! u_handle ) {
return NT_STATUS_NO_MEMORY ;
}
2005-01-10 15:15:26 +03:00
u_handle - > data = talloc_steal ( u_handle , a_state ) ;
2004-05-08 04:02:31 +04:00
2004-09-21 07:51:38 +04:00
* r - > out . user_handle = u_handle - > wire_handle ;
2004-05-08 04:02:31 +04:00
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_DeleteUser
*/
static NTSTATUS samr_DeleteUser ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-08 04:02:31 +04:00
struct samr_DeleteUser * r )
2004-05-03 18:58:08 +04:00
{
2004-05-08 04:02:31 +04:00
struct dcesrv_handle * h ;
2004-05-10 16:37:06 +04:00
struct samr_account_state * a_state ;
2004-05-08 04:02:31 +04:00
int ret ;
2004-09-21 07:51:38 +04:00
* r - > out . user_handle = * r - > in . user_handle ;
2004-05-08 04:02:31 +04:00
2004-09-21 07:51:38 +04:00
DCESRV_PULL_HANDLE ( h , r - > in . user_handle , SAMR_HANDLE_USER ) ;
2004-05-08 04:02:31 +04:00
2004-05-10 16:37:06 +04:00
a_state = h - > data ;
2004-05-08 04:02:31 +04:00
2004-05-10 16:37:06 +04:00
ret = samdb_delete ( a_state - > sam_ctx , mem_ctx , a_state - > account_dn ) ;
2004-05-08 04:02:31 +04:00
if ( ret ! = 0 ) {
return NT_STATUS_UNSUCCESSFUL ;
}
2004-09-21 07:51:38 +04:00
ZERO_STRUCTP ( r - > out . user_handle ) ;
2004-05-08 04:02:31 +04:00
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_QueryUserInfo
*/
static NTSTATUS samr_QueryUserInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-08 18:42:45 +04:00
struct samr_QueryUserInfo * r )
2004-05-03 18:58:08 +04:00
{
2004-05-08 18:42:45 +04:00
struct dcesrv_handle * h ;
2004-05-10 16:37:06 +04:00
struct samr_account_state * a_state ;
2004-05-08 18:42:45 +04:00
struct ldb_message * msg , * * res ;
int ret ;
r - > out . info = NULL ;
2004-09-21 07:51:38 +04:00
DCESRV_PULL_HANDLE ( h , r - > in . user_handle , SAMR_HANDLE_USER ) ;
2004-05-08 18:42:45 +04:00
2004-05-10 16:37:06 +04:00
a_state = h - > data ;
2004-05-08 18:42:45 +04:00
/* pull all the user attributes */
2005-06-14 23:15:17 +04:00
ret = gendb_search_dn ( a_state - > sam_ctx , mem_ctx ,
a_state - > account_dn , & res , NULL ) ;
2004-05-08 18:42:45 +04:00
if ( ret ! = 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
msg = res [ 0 ] ;
/* allocate the info structure */
2005-01-27 10:08:20 +03:00
r - > out . info = talloc ( mem_ctx , union samr_UserInfo ) ;
2004-05-08 18:42:45 +04:00
if ( r - > out . info = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
ZERO_STRUCTP ( r - > out . info ) ;
/* fill in the reply */
switch ( r - > in . level ) {
case 1 :
2004-11-13 16:45:41 +03:00
QUERY_STRING ( msg , info1 . account_name . string , " sAMAccountName " ) ;
QUERY_STRING ( msg , info1 . full_name . string , " displayName " ) ;
QUERY_UINT ( msg , info1 . primary_gid , " primaryGroupID " ) ;
QUERY_STRING ( msg , info1 . description . string , " description " ) ;
QUERY_STRING ( msg , info1 . comment . string , " comment " ) ;
2004-05-08 18:42:45 +04:00
break ;
case 2 :
2004-11-13 16:45:41 +03:00
QUERY_STRING ( msg , info2 . comment . string , " comment " ) ;
QUERY_UINT ( msg , info2 . country_code , " countryCode " ) ;
QUERY_UINT ( msg , info2 . code_page , " codePage " ) ;
2004-05-08 18:42:45 +04:00
break ;
case 3 :
2004-11-13 16:45:41 +03:00
QUERY_STRING ( msg , info3 . account_name . string , " sAMAccountName " ) ;
QUERY_STRING ( msg , info3 . full_name . string , " displayName " ) ;
QUERY_RID ( msg , info3 . rid , " objectSid " ) ;
QUERY_UINT ( msg , info3 . primary_gid , " primaryGroupID " ) ;
QUERY_STRING ( msg , info3 . home_directory . string , " homeDirectory " ) ;
QUERY_STRING ( msg , info3 . home_drive . string , " homeDrive " ) ;
QUERY_STRING ( msg , info3 . logon_script . string , " scriptPath " ) ;
QUERY_STRING ( msg , info3 . profile_path . string , " profilePath " ) ;
QUERY_STRING ( msg , info3 . workstations . string , " userWorkstations " ) ;
QUERY_NTTIME ( msg , info3 . last_logon , " lastLogon " ) ;
QUERY_NTTIME ( msg , info3 . last_logoff , " lastLogoff " ) ;
QUERY_NTTIME ( msg , info3 . last_password_change , " pwdLastSet " ) ;
QUERY_APASSC ( msg , info3 . allow_password_change , " pwdLastSet " ) ;
QUERY_FPASSC ( msg , info3 . force_password_change , " pwdLastSet " ) ;
QUERY_LHOURS ( msg , info3 . logon_hours , " logonHours " ) ;
QUERY_UINT ( msg , info3 . bad_password_count , " badPwdCount " ) ;
QUERY_UINT ( msg , info3 . logon_count , " logonCount " ) ;
QUERY_AFLAGS ( msg , info3 . acct_flags , " userAccountControl " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 4 :
2004-11-13 16:45:41 +03:00
QUERY_LHOURS ( msg , info4 . logon_hours , " logonHours " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 5 :
2004-11-13 16:45:41 +03:00
QUERY_STRING ( msg , info5 . account_name . string , " sAMAccountName " ) ;
QUERY_STRING ( msg , info5 . full_name . string , " displayName " ) ;
QUERY_RID ( msg , info5 . rid , " objectSid " ) ;
QUERY_UINT ( msg , info5 . primary_gid , " primaryGroupID " ) ;
QUERY_STRING ( msg , info5 . home_directory . string , " homeDirectory " ) ;
QUERY_STRING ( msg , info5 . home_drive . string , " homeDrive " ) ;
QUERY_STRING ( msg , info5 . logon_script . string , " scriptPath " ) ;
QUERY_STRING ( msg , info5 . profile_path . string , " profilePath " ) ;
QUERY_STRING ( msg , info5 . description . string , " description " ) ;
QUERY_STRING ( msg , info5 . workstations . string , " userWorkstations " ) ;
QUERY_NTTIME ( msg , info5 . last_logon , " lastLogon " ) ;
QUERY_NTTIME ( msg , info5 . last_logoff , " lastLogoff " ) ;
QUERY_LHOURS ( msg , info5 . logon_hours , " logonHours " ) ;
QUERY_UINT ( msg , info5 . bad_password_count , " badPwdCount " ) ;
QUERY_UINT ( msg , info5 . logon_count , " logonCount " ) ;
QUERY_NTTIME ( msg , info5 . last_password_change , " pwdLastSet " ) ;
QUERY_NTTIME ( msg , info5 . acct_expiry , " accountExpires " ) ;
QUERY_AFLAGS ( msg , info5 . acct_flags , " userAccountControl " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 6 :
2004-11-13 16:45:41 +03:00
QUERY_STRING ( msg , info6 . account_name . string , " sAMAccountName " ) ;
QUERY_STRING ( msg , info6 . full_name . string , " displayName " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 7 :
2004-11-13 16:45:41 +03:00
QUERY_STRING ( msg , info7 . account_name . string , " sAMAccountName " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 8 :
2004-11-13 16:45:41 +03:00
QUERY_STRING ( msg , info8 . full_name . string , " displayName " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 9 :
2004-11-13 16:45:41 +03:00
QUERY_UINT ( msg , info9 . primary_gid , " primaryGroupID " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 10 :
2004-11-13 16:45:41 +03:00
QUERY_STRING ( msg , info10 . home_directory . string , " homeDirectory " ) ;
QUERY_STRING ( msg , info10 . home_drive . string , " homeDrive " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 11 :
2004-11-13 16:45:41 +03:00
QUERY_STRING ( msg , info11 . logon_script . string , " scriptPath " ) ;
2004-05-08 18:42:45 +04:00
break ;
2004-05-09 13:39:47 +04:00
case 12 :
2004-11-13 16:45:41 +03:00
QUERY_STRING ( msg , info12 . profile_path . string , " profilePath " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 13 :
2004-11-13 16:45:41 +03:00
QUERY_STRING ( msg , info13 . description . string , " description " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 14 :
2004-11-13 16:45:41 +03:00
QUERY_STRING ( msg , info14 . workstations . string , " userWorkstations " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 16 :
2004-11-13 16:45:41 +03:00
QUERY_AFLAGS ( msg , info16 . acct_flags , " userAccountControl " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 17 :
2004-11-13 16:45:41 +03:00
QUERY_NTTIME ( msg , info17 . acct_expiry , " accountExpires " ) ;
2004-05-09 13:39:47 +04:00
case 20 :
2004-11-13 16:45:41 +03:00
QUERY_STRING ( msg , info20 . parameters . string , " userParameters " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 21 :
2004-11-13 16:45:41 +03:00
QUERY_NTTIME ( msg , info21 . last_logon , " lastLogon " ) ;
QUERY_NTTIME ( msg , info21 . last_logoff , " lastLogoff " ) ;
QUERY_NTTIME ( msg , info21 . last_password_change , " pwdLastSet " ) ;
QUERY_NTTIME ( msg , info21 . acct_expiry , " accountExpires " ) ;
2004-06-05 08:32:50 +04:00
QUERY_APASSC ( msg , info21 . allow_password_change , " pwdLastSet " ) ;
QUERY_FPASSC ( msg , info21 . force_password_change , " pwdLastSet " ) ;
2004-11-13 16:45:41 +03:00
QUERY_STRING ( msg , info21 . account_name . string , " sAMAccountName " ) ;
QUERY_STRING ( msg , info21 . full_name . string , " displayName " ) ;
QUERY_STRING ( msg , info21 . home_directory . string , " homeDirectory " ) ;
QUERY_STRING ( msg , info21 . home_drive . string , " homeDrive " ) ;
QUERY_STRING ( msg , info21 . logon_script . string , " scriptPath " ) ;
QUERY_STRING ( msg , info21 . profile_path . string , " profilePath " ) ;
QUERY_STRING ( msg , info21 . description . string , " description " ) ;
QUERY_STRING ( msg , info21 . workstations . string , " userWorkstations " ) ;
QUERY_STRING ( msg , info21 . comment . string , " comment " ) ;
QUERY_STRING ( msg , info21 . parameters . string , " userParameters " ) ;
QUERY_RID ( msg , info21 . rid , " objectSid " ) ;
QUERY_UINT ( msg , info21 . primary_gid , " primaryGroupID " ) ;
QUERY_AFLAGS ( msg , info21 . acct_flags , " userAccountControl " ) ;
2004-05-09 13:39:47 +04:00
r - > out . info - > info21 . fields_present = 0x00FFFFFF ;
2004-11-13 16:45:41 +03:00
QUERY_LHOURS ( msg , info21 . logon_hours , " logonHours " ) ;
QUERY_UINT ( msg , info21 . bad_password_count , " badPwdCount " ) ;
QUERY_UINT ( msg , info21 . logon_count , " logonCount " ) ;
QUERY_UINT ( msg , info21 . country_code , " countryCode " ) ;
QUERY_UINT ( msg , info21 . code_page , " codePage " ) ;
2004-05-09 13:39:47 +04:00
break ;
2004-05-08 18:42:45 +04:00
default :
r - > out . info = NULL ;
return NT_STATUS_INVALID_INFO_CLASS ;
}
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2004-05-09 13:39:47 +04:00
2004-05-03 18:58:08 +04:00
/*
samr_SetUserInfo
*/
static NTSTATUS samr_SetUserInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-08 18:42:45 +04:00
struct samr_SetUserInfo * r )
2004-05-03 18:58:08 +04:00
{
2004-05-08 18:42:45 +04:00
struct dcesrv_handle * h ;
2004-05-10 16:37:06 +04:00
struct samr_account_state * a_state ;
2005-01-02 10:51:13 +03:00
struct ldb_message * msg ;
2004-05-22 04:53:57 +04:00
int ret ;
2004-05-10 15:23:50 +04:00
NTSTATUS status = NT_STATUS_OK ;
2004-05-08 18:42:45 +04:00
2004-09-21 07:51:38 +04:00
DCESRV_PULL_HANDLE ( h , r - > in . user_handle , SAMR_HANDLE_USER ) ;
2004-05-08 18:42:45 +04:00
2004-05-10 16:37:06 +04:00
a_state = h - > data ;
2004-05-08 18:42:45 +04:00
2005-01-02 10:51:13 +03:00
msg = ldb_msg_new ( mem_ctx ) ;
if ( msg = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2005-01-11 16:59:18 +03:00
msg - > dn = talloc_reference ( mem_ctx , a_state - > account_dn ) ;
2005-01-02 10:51:13 +03:00
if ( ! msg - > dn ) {
2004-05-08 18:42:45 +04:00
return NT_STATUS_NO_MEMORY ;
}
switch ( r - > in . level ) {
case 2 :
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info2 . comment . string , " comment " ) ;
SET_UINT ( msg , info2 . country_code , " countryCode " ) ;
SET_UINT ( msg , info2 . code_page , " codePage " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 4 :
2004-11-13 16:45:41 +03:00
SET_LHOURS ( msg , info4 . logon_hours , " logonHours " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 6 :
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info6 . full_name . string , " displayName " ) ;
2004-05-09 13:39:47 +04:00
break ;
2005-03-13 09:43:34 +03:00
case 7 :
SET_STRING ( msg , info7 . account_name . string , " samAccountName " ) ;
break ;
2004-05-09 13:39:47 +04:00
case 8 :
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info8 . full_name . string , " displayName " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 9 :
2004-11-13 16:45:41 +03:00
SET_UINT ( msg , info9 . primary_gid , " primaryGroupID " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 10 :
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info10 . home_directory . string , " homeDirectory " ) ;
SET_STRING ( msg , info10 . home_drive . string , " homeDrive " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 11 :
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info11 . logon_script . string , " scriptPath " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 12 :
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info12 . profile_path . string , " profilePath " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 13 :
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info13 . description . string , " description " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 14 :
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info14 . workstations . string , " userWorkstations " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 16 :
2004-11-13 16:45:41 +03:00
SET_AFLAGS ( msg , info16 . acct_flags , " userAccountControl " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 20 :
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info20 . parameters . string , " userParameters " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 21 :
# define IFSET(bit) if (bit & r->in.info->info21.fields_present)
2005-03-13 09:43:34 +03:00
IFSET ( SAMR_FIELD_ACCOUNT_NAME )
SET_STRING ( msg , info21 . account_name . string , " samAccountName " ) ;
IFSET ( SAMR_FIELD_FULL_NAME )
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info21 . full_name . string , " displayName " ) ;
2004-05-10 15:23:50 +04:00
IFSET ( SAMR_FIELD_DESCRIPTION )
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info21 . description . string , " description " ) ;
2004-05-10 15:23:50 +04:00
IFSET ( SAMR_FIELD_COMMENT )
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info21 . comment . string , " comment " ) ;
2004-05-10 15:23:50 +04:00
IFSET ( SAMR_FIELD_LOGON_SCRIPT )
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info21 . logon_script . string , " scriptPath " ) ;
2004-06-05 08:32:50 +04:00
IFSET ( SAMR_FIELD_PROFILE_PATH )
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info21 . profile_path . string , " profilePath " ) ;
2005-03-18 07:25:10 +03:00
IFSET ( SAMR_FIELD_WORKSTATIONS )
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info21 . workstations . string , " userWorkstations " ) ;
2004-05-10 15:23:50 +04:00
IFSET ( SAMR_FIELD_LOGON_HOURS )
2004-11-13 16:45:41 +03:00
SET_LHOURS ( msg , info21 . logon_hours , " logonHours " ) ;
2004-10-20 06:12:52 +04:00
IFSET ( SAMR_FIELD_ACCT_FLAGS )
2004-11-13 16:45:41 +03:00
SET_AFLAGS ( msg , info21 . acct_flags , " userAccountControl " ) ;
IFSET ( SAMR_FIELD_PARAMETERS )
SET_STRING ( msg , info21 . parameters . string , " userParameters " ) ;
2004-05-10 15:23:50 +04:00
IFSET ( SAMR_FIELD_COUNTRY_CODE )
2004-11-13 16:45:41 +03:00
SET_UINT ( msg , info21 . country_code , " countryCode " ) ;
2004-05-10 15:23:50 +04:00
IFSET ( SAMR_FIELD_CODE_PAGE )
2004-11-13 16:45:41 +03:00
SET_UINT ( msg , info21 . code_page , " codePage " ) ;
2004-10-20 06:12:52 +04:00
/* Any reason the rest of these can't be set? */
2004-05-26 08:20:17 +04:00
# undef IFSET
break ;
case 23 :
# define IFSET(bit) if (bit & r->in.info->info23.info.fields_present)
2005-03-13 09:43:34 +03:00
IFSET ( SAMR_FIELD_ACCOUNT_NAME )
SET_STRING ( msg , info23 . info . account_name . string , " samAccountName " ) ;
IFSET ( SAMR_FIELD_FULL_NAME )
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info23 . info . full_name . string , " displayName " ) ;
2004-05-26 08:20:17 +04:00
IFSET ( SAMR_FIELD_DESCRIPTION )
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info23 . info . description . string , " description " ) ;
2004-05-26 08:20:17 +04:00
IFSET ( SAMR_FIELD_COMMENT )
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info23 . info . comment . string , " comment " ) ;
2004-05-26 08:20:17 +04:00
IFSET ( SAMR_FIELD_LOGON_SCRIPT )
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info23 . info . logon_script . string , " scriptPath " ) ;
2004-06-05 08:32:50 +04:00
IFSET ( SAMR_FIELD_PROFILE_PATH )
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info23 . info . profile_path . string , " profilePath " ) ;
2005-03-18 07:25:10 +03:00
IFSET ( SAMR_FIELD_WORKSTATIONS )
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info23 . info . workstations . string , " userWorkstations " ) ;
2004-05-26 08:20:17 +04:00
IFSET ( SAMR_FIELD_LOGON_HOURS )
2004-11-13 16:45:41 +03:00
SET_LHOURS ( msg , info23 . info . logon_hours , " logonHours " ) ;
2004-10-20 06:12:52 +04:00
IFSET ( SAMR_FIELD_ACCT_FLAGS )
2004-11-13 16:45:41 +03:00
SET_AFLAGS ( msg , info23 . info . acct_flags , " userAccountControl " ) ;
IFSET ( SAMR_FIELD_PARAMETERS )
SET_STRING ( msg , info23 . info . parameters . string , " userParameters " ) ;
2004-05-26 08:20:17 +04:00
IFSET ( SAMR_FIELD_COUNTRY_CODE )
2004-11-13 16:45:41 +03:00
SET_UINT ( msg , info23 . info . country_code , " countryCode " ) ;
2004-05-26 08:20:17 +04:00
IFSET ( SAMR_FIELD_CODE_PAGE )
2004-11-13 16:45:41 +03:00
SET_UINT ( msg , info23 . info . code_page , " codePage " ) ;
2004-05-26 08:20:17 +04:00
IFSET ( SAMR_FIELD_PASSWORD ) {
status = samr_set_password ( dce_call ,
a_state - > sam_ctx ,
a_state - > account_dn ,
a_state - > domain_state - > domain_dn ,
mem_ctx , msg ,
& r - > in . info - > info23 . password ) ;
2004-10-20 06:26:59 +04:00
} else IFSET ( SAMR_FIELD_PASSWORD2 ) {
status = samr_set_password ( dce_call ,
a_state - > sam_ctx ,
a_state - > account_dn ,
a_state - > domain_state - > domain_dn ,
mem_ctx , msg ,
& r - > in . info - > info23 . password ) ;
2004-05-26 08:20:17 +04:00
}
# undef IFSET
2004-05-08 18:42:45 +04:00
break ;
2004-05-10 15:23:50 +04:00
/* the set password levels are handled separately */
case 24 :
2004-05-25 17:57:39 +04:00
status = samr_set_password ( dce_call ,
a_state - > sam_ctx ,
2004-05-24 09:35:59 +04:00
a_state - > account_dn ,
a_state - > domain_state - > domain_dn ,
mem_ctx , msg ,
2004-05-10 15:23:50 +04:00
& r - > in . info - > info24 . password ) ;
break ;
2004-05-26 08:20:17 +04:00
case 25 :
# define IFSET(bit) if (bit & r->in.info->info25.info.fields_present)
2005-03-13 09:43:34 +03:00
IFSET ( SAMR_FIELD_ACCOUNT_NAME )
SET_STRING ( msg , info25 . info . account_name . string , " samAccountName " ) ;
IFSET ( SAMR_FIELD_FULL_NAME )
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info25 . info . full_name . string , " displayName " ) ;
2004-05-26 08:20:17 +04:00
IFSET ( SAMR_FIELD_DESCRIPTION )
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info25 . info . description . string , " description " ) ;
2004-05-26 08:20:17 +04:00
IFSET ( SAMR_FIELD_COMMENT )
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info25 . info . comment . string , " comment " ) ;
2004-05-26 08:20:17 +04:00
IFSET ( SAMR_FIELD_LOGON_SCRIPT )
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info25 . info . logon_script . string , " scriptPath " ) ;
2004-06-05 08:32:50 +04:00
IFSET ( SAMR_FIELD_PROFILE_PATH )
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info25 . info . profile_path . string , " profilePath " ) ;
2005-03-18 07:25:10 +03:00
IFSET ( SAMR_FIELD_WORKSTATIONS )
2004-11-13 16:45:41 +03:00
SET_STRING ( msg , info25 . info . workstations . string , " userWorkstations " ) ;
2004-05-26 08:20:17 +04:00
IFSET ( SAMR_FIELD_LOGON_HOURS )
2004-11-13 16:45:41 +03:00
SET_LHOURS ( msg , info25 . info . logon_hours , " logonHours " ) ;
2004-10-20 06:12:52 +04:00
IFSET ( SAMR_FIELD_ACCT_FLAGS )
2004-11-13 16:45:41 +03:00
SET_AFLAGS ( msg , info25 . info . acct_flags , " userAccountControl " ) ;
IFSET ( SAMR_FIELD_PARAMETERS )
SET_STRING ( msg , info25 . info . parameters . string , " userParameters " ) ;
2004-05-26 08:20:17 +04:00
IFSET ( SAMR_FIELD_COUNTRY_CODE )
2004-11-13 16:45:41 +03:00
SET_UINT ( msg , info25 . info . country_code , " countryCode " ) ;
2004-05-26 08:20:17 +04:00
IFSET ( SAMR_FIELD_CODE_PAGE )
2004-11-13 16:45:41 +03:00
SET_UINT ( msg , info25 . info . code_page , " codePage " ) ;
2004-05-26 08:20:17 +04:00
IFSET ( SAMR_FIELD_PASSWORD ) {
status = samr_set_password_ex ( dce_call ,
a_state - > sam_ctx ,
a_state - > account_dn ,
a_state - > domain_state - > domain_dn ,
mem_ctx , msg ,
& r - > in . info - > info25 . password ) ;
2004-10-20 06:26:59 +04:00
} else IFSET ( SAMR_FIELD_PASSWORD2 ) {
status = samr_set_password_ex ( dce_call ,
a_state - > sam_ctx ,
a_state - > account_dn ,
a_state - > domain_state - > domain_dn ,
mem_ctx , msg ,
& r - > in . info - > info25 . password ) ;
2004-05-26 08:20:17 +04:00
}
# undef IFSET
break ;
/* the set password levels are handled separately */
case 26 :
status = samr_set_password_ex ( dce_call ,
a_state - > sam_ctx ,
a_state - > account_dn ,
a_state - > domain_state - > domain_dn ,
mem_ctx , msg ,
& r - > in . info - > info26 . password ) ;
break ;
2004-05-10 15:23:50 +04:00
2004-05-08 18:42:45 +04:00
default :
/* many info classes are not valid for SetUserInfo */
return NT_STATUS_INVALID_INFO_CLASS ;
}
2004-05-10 15:23:50 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2004-05-08 18:42:45 +04:00
/* modify the samdb record */
2004-05-22 04:53:57 +04:00
ret = samdb_replace ( a_state - > sam_ctx , mem_ctx , msg ) ;
2004-05-08 18:42:45 +04:00
if ( ret ! = 0 ) {
/* we really need samdb.c to return NTSTATUS */
return NT_STATUS_UNSUCCESSFUL ;
}
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_GetGroupsForUser
*/
static NTSTATUS samr_GetGroupsForUser ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_GetGroupsForUser * r )
{
2004-12-30 01:57:20 +03:00
struct dcesrv_handle * h ;
struct samr_account_state * a_state ;
struct samr_domain_state * d_state ;
struct ldb_message * * res ;
const char * const attrs [ 2 ] = { " objectSid " , NULL } ;
2005-06-29 17:55:09 +04:00
struct samr_RidWithAttributeArray * array ;
2004-12-30 01:57:20 +03:00
int count ;
DCESRV_PULL_HANDLE ( h , r - > in . user_handle , SAMR_HANDLE_USER ) ;
a_state = h - > data ;
d_state = a_state - > domain_state ;
2004-12-30 20:01:49 +03:00
count = samdb_search_domain ( a_state - > sam_ctx , mem_ctx , NULL , & res ,
2005-06-24 04:18:20 +04:00
attrs , d_state - > domain_sid ,
2004-12-30 20:01:49 +03:00
" (&(member=%s)(grouptype=%s)(objectclass=group)) " ,
a_state - > account_dn ,
ldb_hexstr ( mem_ctx ,
GTYPE_SECURITY_GLOBAL_GROUP ) ) ;
2004-12-30 01:57:20 +03:00
if ( count < 0 )
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2005-06-29 17:55:09 +04:00
array = talloc ( mem_ctx , struct samr_RidWithAttributeArray ) ;
2004-12-30 01:57:20 +03:00
if ( array = = NULL )
return NT_STATUS_NO_MEMORY ;
array - > count = 0 ;
2005-05-01 12:05:17 +04:00
array - > rids = NULL ;
2004-12-30 01:57:20 +03:00
if ( count > 0 ) {
int i ;
2005-06-29 17:55:09 +04:00
array - > rids = talloc_array ( mem_ctx , struct samr_RidWithAttribute ,
2004-12-30 01:57:20 +03:00
count ) ;
2005-05-01 12:05:17 +04:00
if ( array - > rids = = NULL )
2004-12-30 01:57:20 +03:00
return NT_STATUS_NO_MEMORY ;
for ( i = 0 ; i < count ; i + + ) {
struct dom_sid * group_sid ;
group_sid = samdb_result_dom_sid ( mem_ctx , res [ i ] ,
" objectSid " ) ;
if ( group_sid = = NULL ) {
DEBUG ( 0 , ( " Couldn't find objectSid attrib \n " ) ) ;
continue ;
}
2005-05-01 12:05:17 +04:00
array - > rids [ array - > count ] . rid =
2004-12-30 01:57:20 +03:00
group_sid - > sub_auths [ group_sid - > num_auths - 1 ] ;
2005-06-29 17:55:09 +04:00
array - > rids [ array - > count ] . attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED ;
2004-12-30 01:57:20 +03:00
array - > count + = 1 ;
}
}
r - > out . rids = array ;
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_QueryDisplayInfo
*/
static NTSTATUS samr_QueryDisplayInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_QueryDisplayInfo * r )
{
2004-12-29 02:01:34 +03:00
struct dcesrv_handle * h ;
struct samr_domain_state * d_state ;
struct ldb_message * * res ;
int ldb_cnt , count , i ;
const char * const attrs [ 4 ] = { " objectSid " , " sAMAccountName " ,
" description " , NULL } ;
struct samr_DispEntryFull * entriesFull = NULL ;
struct samr_DispEntryAscii * entriesAscii = NULL ;
struct samr_DispEntryGeneral * entriesGeneral = NULL ;
const char * filter ;
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
d_state = h - > data ;
switch ( r - > in . level ) {
case 1 :
case 4 :
filter = talloc_asprintf ( mem_ctx , " (&(objectclass=user) "
" (sAMAccountType=%s)) " ,
ldb_hexstr ( mem_ctx ,
ATYPE_NORMAL_ACCOUNT ) ) ;
break ;
case 2 :
filter = talloc_asprintf ( mem_ctx , " (&(objectclass=user) "
" (sAMAccountType=%s)) " ,
ldb_hexstr ( mem_ctx ,
ATYPE_WORKSTATION_TRUST ) ) ;
break ;
case 3 :
case 5 :
filter = talloc_asprintf ( mem_ctx , " (&(grouptype=%s) "
" (objectclass=group)) " ,
ldb_hexstr ( mem_ctx , GTYPE_SECURITY_GLOBAL_GROUP ) ) ;
break ;
default :
return NT_STATUS_INVALID_INFO_CLASS ;
}
2004-12-30 20:01:49 +03:00
/* search for all requested objects in this domain. This could
possibly be cached and resumed based on resume_key */
ldb_cnt = samdb_search_domain ( d_state - > sam_ctx , mem_ctx ,
d_state - > domain_dn , & res , attrs ,
2005-06-24 04:18:20 +04:00
d_state - > domain_sid , " %s " , filter ) ;
2004-12-29 02:01:34 +03:00
if ( ldb_cnt = = - 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
if ( ldb_cnt = = 0 | | r - > in . max_entries = = 0 ) {
return NT_STATUS_OK ;
}
switch ( r - > in . level ) {
case 1 :
2005-01-27 10:08:20 +03:00
entriesGeneral = talloc_array ( mem_ctx ,
2004-12-29 02:01:34 +03:00
struct samr_DispEntryGeneral ,
ldb_cnt ) ;
break ;
case 2 :
case 3 :
2005-01-27 10:08:20 +03:00
entriesFull = talloc_array ( mem_ctx ,
2004-12-29 02:01:34 +03:00
struct samr_DispEntryFull ,
ldb_cnt ) ;
break ;
case 4 :
case 5 :
2005-01-27 10:08:20 +03:00
entriesAscii = talloc_array ( mem_ctx ,
2004-12-29 02:01:34 +03:00
struct samr_DispEntryAscii ,
ldb_cnt ) ;
break ;
}
if ( ( entriesGeneral = = NULL ) & & ( entriesFull = = NULL ) & &
( entriesAscii = = NULL ) )
return NT_STATUS_NO_MEMORY ;
count = 0 ;
for ( i = 0 ; i < ldb_cnt ; i + + ) {
struct dom_sid * objectsid ;
objectsid = samdb_result_dom_sid ( mem_ctx , res [ i ] ,
" objectSid " ) ;
if ( objectsid = = NULL )
continue ;
switch ( r - > in . level ) {
case 1 :
2005-06-12 15:03:15 +04:00
entriesGeneral [ count ] . idx = count + 1 ;
2004-12-29 02:01:34 +03:00
entriesGeneral [ count ] . rid =
objectsid - > sub_auths [ objectsid - > num_auths - 1 ] ;
entriesGeneral [ count ] . acct_flags =
samdb_result_acct_flags ( res [ i ] ,
" userAccountControl " ) ;
entriesGeneral [ count ] . account_name . string =
samdb_result_string ( res [ i ] ,
" sAMAccountName " , " " ) ;
entriesGeneral [ count ] . full_name . string =
samdb_result_string ( res [ i ] , " displayName " , " " ) ;
entriesGeneral [ count ] . description . string =
samdb_result_string ( res [ i ] , " description " , " " ) ;
break ;
case 2 :
case 3 :
2005-06-12 15:03:15 +04:00
entriesFull [ count ] . idx = count + 1 ;
2004-12-29 02:01:34 +03:00
entriesFull [ count ] . rid =
objectsid - > sub_auths [ objectsid - > num_auths - 1 ] ;
entriesFull [ count ] . acct_flags =
samdb_result_acct_flags ( res [ i ] ,
" userAccountControl " ) ;
if ( r - > in . level = = 3 ) {
/* We get a "7" here for groups */
entriesFull [ count ] . acct_flags = 7 ;
}
entriesFull [ count ] . account_name . string =
samdb_result_string ( res [ i ] , " sAMAccountName " ,
" " ) ;
entriesFull [ count ] . description . string =
samdb_result_string ( res [ i ] , " description " , " " ) ;
break ;
case 4 :
case 5 :
2005-06-12 15:03:15 +04:00
entriesAscii [ count ] . idx = count + 1 ;
2004-12-29 02:01:34 +03:00
entriesAscii [ count ] . account_name . string =
samdb_result_string ( res [ i ] , " sAMAccountName " ,
" " ) ;
break ;
}
count + = 1 ;
}
r - > out . total_size = count ;
if ( r - > in . start_idx > = count ) {
r - > out . returned_size = 0 ;
switch ( r - > in . level ) {
case 1 :
r - > out . info . info1 . count = r - > out . returned_size ;
r - > out . info . info1 . entries = NULL ;
break ;
case 2 :
r - > out . info . info2 . count = r - > out . returned_size ;
r - > out . info . info2 . entries = NULL ;
break ;
case 3 :
r - > out . info . info3 . count = r - > out . returned_size ;
r - > out . info . info3 . entries = NULL ;
break ;
case 4 :
r - > out . info . info4 . count = r - > out . returned_size ;
r - > out . info . info4 . entries = NULL ;
break ;
case 5 :
r - > out . info . info5 . count = r - > out . returned_size ;
r - > out . info . info5 . entries = NULL ;
break ;
}
} else {
r - > out . returned_size = MIN ( count - r - > in . start_idx ,
r - > in . max_entries ) ;
switch ( r - > in . level ) {
case 1 :
r - > out . info . info1 . count = r - > out . returned_size ;
r - > out . info . info1 . entries =
& ( entriesGeneral [ r - > in . start_idx ] ) ;
break ;
case 2 :
r - > out . info . info2 . count = r - > out . returned_size ;
r - > out . info . info2 . entries =
& ( entriesFull [ r - > in . start_idx ] ) ;
break ;
case 3 :
r - > out . info . info3 . count = r - > out . returned_size ;
r - > out . info . info3 . entries =
& ( entriesFull [ r - > in . start_idx ] ) ;
break ;
case 4 :
r - > out . info . info4 . count = r - > out . returned_size ;
r - > out . info . info4 . entries =
& ( entriesAscii [ r - > in . start_idx ] ) ;
break ;
case 5 :
r - > out . info . info5 . count = r - > out . returned_size ;
r - > out . info . info5 . entries =
& ( entriesAscii [ r - > in . start_idx ] ) ;
break ;
}
}
return ( r - > out . returned_size < ( count - r - > in . start_idx ) ) ?
STATUS_MORE_ENTRIES : NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_GetDisplayEnumerationIndex
*/
static NTSTATUS samr_GetDisplayEnumerationIndex ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_GetDisplayEnumerationIndex * r )
{
2004-05-04 10:07:52 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_TestPrivateFunctionsDomain
*/
static NTSTATUS samr_TestPrivateFunctionsDomain ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_TestPrivateFunctionsDomain * r )
{
2004-05-04 10:07:52 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_TestPrivateFunctionsUser
*/
static NTSTATUS samr_TestPrivateFunctionsUser ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_TestPrivateFunctionsUser * r )
{
2004-05-04 10:07:52 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_GetUserPwInfo
*/
static NTSTATUS samr_GetUserPwInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-09 16:32:25 +04:00
struct samr_GetUserPwInfo * r )
2004-05-03 18:58:08 +04:00
{
2004-05-09 16:32:25 +04:00
struct dcesrv_handle * h ;
2004-05-10 16:37:06 +04:00
struct samr_account_state * a_state ;
2004-05-09 16:32:25 +04:00
ZERO_STRUCT ( r - > out . info ) ;
2004-09-21 07:51:38 +04:00
DCESRV_PULL_HANDLE ( h , r - > in . user_handle , SAMR_HANDLE_USER ) ;
2004-05-09 16:32:25 +04:00
2004-05-10 16:37:06 +04:00
a_state = h - > data ;
2004-05-09 16:32:25 +04:00
2005-06-14 23:15:17 +04:00
r - > out . info . min_password_length = samdb_search_uint ( a_state - > sam_ctx , mem_ctx , 0 ,
2005-07-17 13:20:52 +04:00
a_state - > domain_state - > domain_dn , " minPwdLength " ,
" dn=%s " ,
a_state - > domain_state - > domain_dn ) ;
2005-06-14 23:15:17 +04:00
r - > out . info . password_properties = samdb_search_uint ( a_state - > sam_ctx , mem_ctx , 0 ,
2005-07-17 13:20:52 +04:00
a_state - > account_dn ,
" pwdProperties " ,
" dn=%s " , a_state - > account_dn ) ;
2004-05-09 16:32:25 +04:00
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_RemoveMemberFromForeignDomain
*/
static NTSTATUS samr_RemoveMemberFromForeignDomain ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_RemoveMemberFromForeignDomain * r )
{
2004-12-30 21:50:15 +03:00
struct dcesrv_handle * h ;
struct samr_domain_state * d_state ;
2005-06-24 04:18:20 +04:00
const char * memberdn ;
2004-12-30 21:50:15 +03:00
struct ldb_message * * res ;
const char * const attrs [ 3 ] = { " dn " , " objectSid " , NULL } ;
int i , count ;
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
d_state = h - > data ;
memberdn = samdb_search_string ( d_state - > sam_ctx , mem_ctx , NULL ,
2005-06-24 04:18:20 +04:00
" dn " , " (objectSid=%s) " ,
ldap_encode_ndr_dom_sid ( mem_ctx , r - > in . sid ) ) ;
2004-12-30 21:50:15 +03:00
if ( memberdn = = NULL )
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
/* TODO: Does this call only remove alias members, or does it do this
* for domain groups as well ? */
count = samdb_search_domain ( d_state - > sam_ctx , mem_ctx ,
d_state - > domain_dn , & res , attrs ,
2005-06-24 04:18:20 +04:00
d_state - > domain_sid ,
2004-12-30 21:50:15 +03:00
" (&(member=%s)(objectClass=group) "
" (|(groupType=%s)(groupType=%s))) " ,
memberdn ,
ldb_hexstr ( mem_ctx ,
GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ) ,
ldb_hexstr ( mem_ctx ,
GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ) ) ;
if ( count < 0 )
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
for ( i = 0 ; i < count ; i + + ) {
2005-01-02 10:51:13 +03:00
struct ldb_message * mod ;
2004-12-30 21:50:15 +03:00
2005-01-02 10:51:13 +03:00
mod = ldb_msg_new ( mem_ctx ) ;
if ( mod = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
mod - > dn = talloc_reference ( mod ,
samdb_result_string ( res [ i ] , " dn " ,
NULL ) ) ;
if ( mod - > dn = = NULL ) {
talloc_free ( mod ) ;
2004-12-30 21:50:15 +03:00
continue ;
2005-01-02 10:51:13 +03:00
}
2004-12-30 21:50:15 +03:00
2005-01-02 10:51:13 +03:00
if ( samdb_msg_add_delval ( d_state - > sam_ctx , mem_ctx , mod ,
2004-12-30 21:50:15 +03:00
" member " , memberdn ) ! = 0 )
return NT_STATUS_NO_MEMORY ;
2005-01-02 10:51:13 +03:00
if ( samdb_modify ( d_state - > sam_ctx , mem_ctx , mod ) ! = 0 )
2004-12-30 21:50:15 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2005-01-02 10:51:13 +03:00
talloc_free ( mod ) ;
2004-12-30 21:50:15 +03:00
}
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_QueryDomainInfo2
*/
static NTSTATUS samr_QueryDomainInfo2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_QueryDomainInfo2 * r )
{
2004-05-04 10:07:52 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_QueryUserInfo2
2004-05-09 13:39:47 +04:00
just an alias for samr_QueryUserInfo
2004-05-03 18:58:08 +04:00
*/
static NTSTATUS samr_QueryUserInfo2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-09 13:39:47 +04:00
struct samr_QueryUserInfo2 * r )
2004-05-03 18:58:08 +04:00
{
2004-05-09 13:39:47 +04:00
struct samr_QueryUserInfo r1 ;
NTSTATUS status ;
2005-01-03 02:31:12 +03:00
ZERO_STRUCT ( r1 . out ) ;
2004-09-21 07:51:38 +04:00
r1 . in . user_handle = r - > in . user_handle ;
2004-05-09 13:39:47 +04:00
r1 . in . level = r - > in . level ;
status = samr_QueryUserInfo ( dce_call , mem_ctx , & r1 ) ;
r - > out . info = r1 . out . info ;
return status ;
2004-05-03 18:58:08 +04:00
}
/*
samr_QueryDisplayInfo2
*/
static NTSTATUS samr_QueryDisplayInfo2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-01-03 02:31:12 +03:00
struct samr_QueryDisplayInfo2 * r )
2004-05-03 18:58:08 +04:00
{
2004-12-30 20:01:49 +03:00
struct samr_QueryDisplayInfo q ;
NTSTATUS result ;
q . in . domain_handle = r - > in . domain_handle ;
q . in . level = r - > in . level ;
q . in . start_idx = r - > in . start_idx ;
q . in . max_entries = r - > in . max_entries ;
q . in . buf_size = r - > in . buf_size ;
2005-01-03 02:31:12 +03:00
ZERO_STRUCT ( q . out ) ;
2004-12-30 20:01:49 +03:00
result = samr_QueryDisplayInfo ( dce_call , mem_ctx , & q ) ;
r - > out . total_size = q . out . total_size ;
r - > out . returned_size = q . out . returned_size ;
r - > out . info = q . out . info ;
return result ;
2004-05-03 18:58:08 +04:00
}
/*
samr_GetDisplayEnumerationIndex2
*/
static NTSTATUS samr_GetDisplayEnumerationIndex2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_GetDisplayEnumerationIndex2 * r )
{
2004-05-04 10:07:52 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_QueryDisplayInfo3
*/
static NTSTATUS samr_QueryDisplayInfo3 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_QueryDisplayInfo3 * r )
{
2004-05-04 10:07:52 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_AddMultipleMembersToAlias
*/
static NTSTATUS samr_AddMultipleMembersToAlias ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_AddMultipleMembersToAlias * r )
{
2004-05-04 10:07:52 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_RemoveMultipleMembersFromAlias
*/
static NTSTATUS samr_RemoveMultipleMembersFromAlias ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_RemoveMultipleMembersFromAlias * r )
{
2004-05-04 10:07:52 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_GetDomPwInfo
2004-05-04 11:53:06 +04:00
this fetches the default password properties for a domain
2004-05-26 11:32:30 +04:00
note that w2k3 completely ignores the domain name in this call , and
always returns the information for the servers primary domain
2004-05-03 18:58:08 +04:00
*/
static NTSTATUS samr_GetDomPwInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-04 11:53:06 +04:00
struct samr_GetDomPwInfo * r )
2004-05-03 18:58:08 +04:00
{
2004-05-04 11:53:06 +04:00
struct ldb_message * * msgs ;
int ret ;
2004-05-08 04:02:31 +04:00
const char * const attrs [ ] = { " minPwdLength " , " pwdProperties " , NULL } ;
2005-07-27 04:23:09 +04:00
struct ldb_context * sam_ctx ;
2004-05-04 11:53:06 +04:00
2004-06-05 00:36:44 +04:00
ZERO_STRUCT ( r - > out . info ) ;
2004-08-25 10:44:23 +04:00
sam_ctx = samdb_connect ( mem_ctx ) ;
2004-05-06 16:42:42 +04:00
if ( sam_ctx = = NULL ) {
return NT_STATUS_INVALID_SYSTEM_SERVICE ;
}
2005-03-23 04:30:43 +03:00
ret = gendb_search ( sam_ctx ,
2004-05-08 04:02:31 +04:00
mem_ctx , NULL , & msgs , attrs ,
2005-07-27 04:23:09 +04:00
" (&(!(objectClass=builtinDomain))(objectclass=domain)) " ) ;
2004-05-04 11:53:06 +04:00
if ( ret < = 0 ) {
return NT_STATUS_NO_SUCH_DOMAIN ;
}
if ( ret > 1 ) {
2005-04-25 16:46:18 +04:00
talloc_free ( msgs ) ;
2004-05-04 11:53:06 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2004-11-17 14:56:13 +03:00
r - > out . info . min_password_length = samdb_result_uint ( msgs [ 0 ] , " minPwdLength " , 0 ) ;
2004-05-04 11:53:06 +04:00
r - > out . info . password_properties = samdb_result_uint ( msgs [ 0 ] , " pwdProperties " , 1 ) ;
2005-04-25 16:46:18 +04:00
talloc_free ( msgs ) ;
2004-05-04 11:53:06 +04:00
2004-08-25 10:44:23 +04:00
talloc_free ( sam_ctx ) ;
2004-05-04 11:53:06 +04:00
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/*
samr_Connect2
*/
static NTSTATUS samr_Connect2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_Connect2 * r )
{
struct samr_Connect c ;
c . in . system_name = NULL ;
c . in . access_mask = r - > in . access_mask ;
2004-09-21 07:51:38 +04:00
c . out . connect_handle = r - > out . connect_handle ;
2004-05-03 18:58:08 +04:00
2004-05-04 10:07:52 +04:00
return samr_Connect ( dce_call , mem_ctx , & c ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_SetUserInfo2
2004-05-08 18:42:45 +04:00
just an alias for samr_SetUserInfo
2004-05-03 18:58:08 +04:00
*/
static NTSTATUS samr_SetUserInfo2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-08 18:42:45 +04:00
struct samr_SetUserInfo2 * r )
2004-05-03 18:58:08 +04:00
{
2004-05-08 18:42:45 +04:00
struct samr_SetUserInfo r2 ;
2004-09-21 07:51:38 +04:00
r2 . in . user_handle = r - > in . user_handle ;
2004-05-08 18:42:45 +04:00
r2 . in . level = r - > in . level ;
r2 . in . info = r - > in . info ;
return samr_SetUserInfo ( dce_call , mem_ctx , & r2 ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_SetBootKeyInformation
*/
static NTSTATUS samr_SetBootKeyInformation ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_SetBootKeyInformation * r )
{
2004-05-04 10:07:52 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_GetBootKeyInformation
*/
static NTSTATUS samr_GetBootKeyInformation ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_GetBootKeyInformation * r )
{
2004-05-04 10:07:52 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_Connect3
*/
static NTSTATUS samr_Connect3 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_Connect3 * r )
{
struct samr_Connect c ;
c . in . system_name = NULL ;
c . in . access_mask = r - > in . access_mask ;
2004-09-21 07:51:38 +04:00
c . out . connect_handle = r - > out . connect_handle ;
2004-05-03 18:58:08 +04:00
2004-05-04 10:07:52 +04:00
return samr_Connect ( dce_call , mem_ctx , & c ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_Connect4
*/
static NTSTATUS samr_Connect4 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_Connect4 * r )
{
struct samr_Connect c ;
c . in . system_name = NULL ;
c . in . access_mask = r - > in . access_mask ;
2004-09-21 07:51:38 +04:00
c . out . connect_handle = r - > out . connect_handle ;
2004-05-03 18:58:08 +04:00
2004-05-04 10:07:52 +04:00
return samr_Connect ( dce_call , mem_ctx , & c ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_Connect5
*/
static NTSTATUS samr_Connect5 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_Connect5 * r )
{
struct samr_Connect c ;
NTSTATUS status ;
c . in . system_name = NULL ;
c . in . access_mask = r - > in . access_mask ;
2004-09-21 07:51:38 +04:00
c . out . connect_handle = r - > out . connect_handle ;
2004-05-03 18:58:08 +04:00
status = samr_Connect ( dce_call , mem_ctx , & c ) ;
r - > out . info - > info1 . unknown1 = 3 ;
r - > out . info - > info1 . unknown2 = 0 ;
r - > out . level = r - > in . level ;
return status ;
}
/*
samr_RidToSid
*/
static NTSTATUS samr_RidToSid ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_RidToSid * r )
{
2004-05-04 10:07:52 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_SetDsrmPassword
*/
static NTSTATUS samr_SetDsrmPassword ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct samr_SetDsrmPassword * r )
{
2004-05-04 10:07:52 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2004-05-03 18:58:08 +04:00
}
/*
samr_ValidatePassword
*/
static NTSTATUS samr_ValidatePassword ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-24 09:35:59 +04:00
struct samr_ValidatePassword * r )
2004-05-03 18:58:08 +04:00
{
2004-05-04 10:07:52 +04:00
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
2004-05-03 18:58:08 +04:00
}
/* include the generated boilerplate */
# include "librpc/gen_ndr/ndr_samr_s.c"