2010-10-29 12:55:07 +04:00
/*
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
2009-08-18 00:34:08 +04:00
Copyright ( C ) Matthias Dieter Wallnöfer 2009
2010-10-29 12:55:07 +04:00
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
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2004-05-03 18:58:08 +04:00
( at your option ) any later version .
2010-10-29 12:55:07 +04:00
2004-05-03 18:58:08 +04:00
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 .
2010-10-29 12:55:07 +04:00
2004-05-03 18:58:08 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2004-05-03 18:58:08 +04:00
*/
# 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"
2011-02-10 06:12:51 +03:00
# include <ldb.h>
# include <ldb_errors.h>
2009-06-12 16:27:19 +04:00
# include "../libds/common/flags.h"
2005-12-28 18:38:36 +03:00
# include "dsdb/samdb/samdb.h"
2010-05-21 02:14:53 +04:00
# include "dsdb/common/util.h"
2007-12-06 23:39:49 +03:00
# include "libcli/ldap/ldap_ndr.h"
2006-04-02 16:02:01 +04:00
# include "libcli/security/security.h"
2006-03-07 02:28:18 +03:00
# include "rpc_server/samr/proto.h"
2010-10-17 16:27:18 +04:00
# include "../lib/util/util_ldb.h"
2007-09-08 16:42:09 +04:00
# include "param/param.h"
2010-02-13 05:00:55 +03:00
# include "lib/util/tsort.h"
2011-02-24 03:23:53 +03:00
# include "libds/common/flag_mapping.h"
2004-05-06 11:32:51 +04:00
2015-08-07 10:50:30 +03:00
# define DCESRV_INTERFACE_SAMR_BIND(call, iface) \
dcesrv_interface_samr_bind ( call , iface )
static NTSTATUS dcesrv_interface_samr_bind ( struct dcesrv_call_state * dce_call ,
const struct dcesrv_interface * iface )
{
return dcesrv_interface_bind_reject_connect ( dce_call , iface ) ;
}
2008-11-10 13:26:43 +03:00
/* these query macros make samr_Query[User|Group|Alias]Info a bit easier to read */
2006-07-04 06:46:24 +04:00
# define QUERY_STRING(msg, field, attr) \
2010-10-14 11:41:42 +04:00
info - > field . string = ldb_msg_find_attr_as_string ( msg , attr , " " ) ;
2006-07-04 06:46:24 +04:00
# define QUERY_UINT(msg, field, attr) \
2010-10-14 11:41:42 +04:00
info - > field = ldb_msg_find_attr_as_uint ( msg , attr , 0 ) ;
2006-07-04 06:46:24 +04:00
# define QUERY_RID(msg, field, attr) \
2008-11-10 13:26:43 +03:00
info - > field = samdb_result_rid_from_sid ( mem_ctx , msg , attr , 0 ) ;
2007-09-06 08:01:52 +04:00
# define QUERY_UINT64(msg, field, attr) \
2010-10-14 11:41:42 +04:00
info - > field = ldb_msg_find_attr_as_uint64 ( msg , attr , 0 ) ;
2006-07-04 06:46:24 +04:00
# define QUERY_APASSC(msg, field, attr) \
2008-11-10 13:26:43 +03:00
info - > field = samdb_result_allow_password_change ( sam_ctx , mem_ctx , \
a_state - > domain_state - > domain_dn , msg , attr ) ;
2014-03-26 02:32:05 +04:00
# define QUERY_BPWDCT(msg, field, attr) \
info - > field = samdb_result_effective_badPwdCount ( sam_ctx , mem_ctx , \
a_state - > domain_state - > domain_dn , msg ) ;
2006-07-04 06:46:24 +04:00
# define QUERY_LHOURS(msg, field, attr) \
2008-11-10 13:26:43 +03:00
info - > field = samdb_result_logon_hours ( mem_ctx , msg , attr ) ;
2006-07-04 06:46:24 +04:00
# define QUERY_AFLAGS(msg, field, attr) \
2013-10-29 08:30:18 +04:00
info - > field = samdb_result_acct_flags ( msg , attr ) ;
2006-07-04 06:46:24 +04:00
/* these are used to make the Set[User|Group]Info code easier to follow */
2007-07-27 06:07:17 +04:00
# define SET_STRING(msg, field, attr) do { \
struct ldb_message_element * set_el ; \
if ( r - > in . info - > field . string = = NULL ) return NT_STATUS_INVALID_PARAMETER ; \
if ( r - > in . info - > field . string [ 0 ] = = ' \0 ' ) { \
2010-06-22 00:19:21 +04:00
if ( ldb_msg_add_empty ( msg , attr , LDB_FLAG_MOD_DELETE , NULL ) ! = LDB_SUCCESS ) { \
2007-07-27 06:07:17 +04:00
return NT_STATUS_NO_MEMORY ; \
} \
} \
2010-06-22 00:19:21 +04:00
if ( ldb_msg_add_string ( msg , attr , r - > in . info - > field . string ) ! = LDB_SUCCESS ) { \
2007-07-27 06:07:17 +04:00
return NT_STATUS_NO_MEMORY ; \
} \
set_el = ldb_msg_find_element ( msg , attr ) ; \
set_el - > flags = LDB_FLAG_MOD_REPLACE ; \
2006-07-04 06:46:24 +04:00
} while ( 0 )
2007-07-27 06:07:17 +04:00
# define SET_UINT(msg, field, attr) do { \
struct ldb_message_element * set_el ; \
2010-06-22 00:19:21 +04:00
if ( samdb_msg_add_uint ( sam_ctx , mem_ctx , msg , attr , r - > in . info - > field ) ! = LDB_SUCCESS ) { \
2007-07-27 06:07:17 +04:00
return NT_STATUS_NO_MEMORY ; \
} \
set_el = ldb_msg_find_element ( msg , attr ) ; \
set_el - > flags = LDB_FLAG_MOD_REPLACE ; \
2010-10-29 12:55:07 +04:00
} while ( 0 )
2007-07-27 06:07:17 +04:00
# define SET_INT64(msg, field, attr) do { \
struct ldb_message_element * set_el ; \
2010-06-22 00:19:21 +04:00
if ( samdb_msg_add_int64 ( sam_ctx , mem_ctx , msg , attr , r - > in . info - > field ) ! = LDB_SUCCESS ) { \
2007-07-27 06:07:17 +04:00
return NT_STATUS_NO_MEMORY ; \
} \
set_el = ldb_msg_find_element ( msg , attr ) ; \
set_el - > flags = LDB_FLAG_MOD_REPLACE ; \
2010-10-29 12:55:07 +04:00
} while ( 0 )
2007-07-27 06:07:17 +04:00
# define SET_UINT64(msg, field, attr) do { \
struct ldb_message_element * set_el ; \
2010-06-22 00:19:21 +04:00
if ( samdb_msg_add_uint64 ( sam_ctx , mem_ctx , msg , attr , r - > in . info - > field ) ! = LDB_SUCCESS ) { \
2007-07-27 06:07:17 +04:00
return NT_STATUS_NO_MEMORY ; \
} \
set_el = ldb_msg_find_element ( msg , attr ) ; \
set_el - > flags = LDB_FLAG_MOD_REPLACE ; \
2010-10-29 12:55:07 +04:00
} while ( 0 )
2008-02-28 02:05:32 +03:00
2010-10-29 12:55:07 +04:00
/* Set account flags, discarding flags that cannot be set with SAMR */
2007-07-27 06:07:17 +04:00
# define SET_AFLAGS(msg, field, attr) do { \
struct ldb_message_element * set_el ; \
2014-03-25 10:12:04 +04:00
if ( samdb_msg_add_acct_flags ( sam_ctx , mem_ctx , msg , attr , r - > in . info - > field ) ! = 0 ) { \
2007-07-27 06:07:17 +04:00
return NT_STATUS_NO_MEMORY ; \
} \
set_el = ldb_msg_find_element ( msg , attr ) ; \
set_el - > flags = LDB_FLAG_MOD_REPLACE ; \
2010-10-29 12:55:07 +04:00
} while ( 0 )
2007-07-27 06:07:17 +04:00
# define SET_LHOURS(msg, field, attr) do { \
struct ldb_message_element * set_el ; \
2010-06-22 00:19:21 +04:00
if ( samdb_msg_add_logon_hours ( sam_ctx , mem_ctx , msg , attr , & r - > in . info - > field ) ! = LDB_SUCCESS ) { \
2007-07-27 06:07:17 +04:00
return NT_STATUS_NO_MEMORY ; \
} \
set_el = ldb_msg_find_element ( msg , attr ) ; \
set_el - > flags = LDB_FLAG_MOD_REPLACE ; \
2006-07-04 06:46:24 +04:00
} while ( 0 )
2008-11-07 17:04:46 +03:00
# define SET_PARAMETERS(msg, field, attr) do { \
struct ldb_message_element * set_el ; \
2008-12-10 01:31:15 +03:00
if ( r - > in . info - > field . length ! = 0 ) { \
2010-06-22 00:19:21 +04:00
if ( samdb_msg_add_parameters ( sam_ctx , mem_ctx , msg , attr , & r - > in . info - > field ) ! = LDB_SUCCESS ) { \
2008-12-10 01:31:15 +03:00
return NT_STATUS_NO_MEMORY ; \
} \
set_el = ldb_msg_find_element ( msg , attr ) ; \
set_el - > flags = LDB_FLAG_MOD_REPLACE ; \
2008-11-07 17:04:46 +03:00
} \
} while ( 0 )
2018-10-09 23:20:25 +03:00
/*
* Clear a GUID cache
*/
static void clear_guid_cache ( struct samr_guid_cache * cache )
{
cache - > handle = 0 ;
cache - > size = 0 ;
TALLOC_FREE ( cache - > entries ) ;
}
2008-11-07 17:04:46 +03:00
2018-10-09 23:20:25 +03:00
/*
* initialize a GUID cache
*/
static void initialize_guid_cache ( struct samr_guid_cache * cache )
{
cache - > handle = 0 ;
cache - > size = 0 ;
cache - > entries = NULL ;
}
static NTSTATUS load_guid_cache (
struct samr_guid_cache * cache ,
struct samr_domain_state * d_state ,
unsigned int ldb_cnt ,
struct ldb_message * * res )
{
NTSTATUS status = NT_STATUS_OK ;
unsigned int i ;
TALLOC_CTX * frame = talloc_stackframe ( ) ;
clear_guid_cache ( cache ) ;
/*
* Store the GUID ' s in the cache .
*/
cache - > handle = 0 ;
cache - > size = ldb_cnt ;
cache - > entries = talloc_array ( d_state , struct GUID , ldb_cnt ) ;
if ( cache - > entries = = NULL ) {
clear_guid_cache ( cache ) ;
status = NT_STATUS_NO_MEMORY ;
goto exit ;
}
/*
* Extract a list of the GUIDs for all the matching objects
* we cache just the GUIDS to reduce the memory overhead of
* the result cache .
*/
for ( i = 0 ; i < ldb_cnt ; i + + ) {
cache - > entries [ i ] = samdb_result_guid ( res [ i ] , " objectGUID " ) ;
}
exit :
TALLOC_FREE ( frame ) ;
return status ;
}
2004-05-03 18:58:08 +04:00
2010-10-29 12:55:07 +04:00
/*
samr_Connect
2004-05-03 18:58:08 +04:00
create a connection to the SAM database
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_Connect ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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
2009-10-23 19:30:47 +04:00
c_state = talloc ( mem_ctx , 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 */
2018-04-11 21:41:30 +03:00
c_state - > sam_ctx = samdb_connect ( c_state ,
dce_call - > event_ctx ,
dce_call - > conn - > dce_ctx - > lp_ctx ,
dce_call - > conn - > auth_state . session_info ,
dce_call - > conn - > remote_address ,
0 ) ;
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-10-07 15:31:45 +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 ;
}
2010-10-29 12:55:07 +04:00
/*
samr_Close
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_Close ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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 ;
}
2010-10-29 12:55:07 +04:00
/*
samr_SetSecurity
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_SetSecurity ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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
}
2010-10-29 12:55:07 +04:00
/*
samr_QuerySecurity
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_QuerySecurity ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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
2008-10-28 00:57:51 +03:00
* r - > out . sdbuf = NULL ;
2004-05-28 17:23:30 +04:00
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 ) ;
2008-10-28 00:57:51 +03:00
* r - > out . sdbuf = sd ;
2004-05-28 17:23:30 +04:00
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_Shutdown
2004-05-03 18:58:08 +04:00
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
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_Shutdown ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
struct samr_Shutdown * r )
{
return NT_STATUS_ACCESS_DENIED ;
}
2010-10-29 12:55:07 +04:00
/*
samr_LookupDomain
2004-05-03 18:58:08 +04:00
this maps from a domain name to a SID
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_LookupDomain ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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 } ;
struct ldb_message * * dom_msgs ;
int ret ;
2008-11-07 04:42:45 +03: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 ,
2006-08-25 11:08:06 +04:00
mem_ctx , NULL , & dom_msgs , dom_attrs ,
2005-08-03 22:30:21 +04:00
" (objectClass=builtinDomain) " ) ;
2010-07-16 08:32:42 +04:00
} else if ( strcasecmp_m ( r - > in . domain_name - > string , lpcfg_sam_name ( dce_call - > conn - > dce_ctx - > lp_ctx ) ) = = 0 ) {
2009-05-26 06:31:39 +04:00
ret = gendb_search_dn ( c_state - > sam_ctx ,
2010-10-29 12:55:07 +04:00
mem_ctx , ldb_get_default_basedn ( c_state - > sam_ctx ) ,
2005-08-03 22:30:21 +04:00
& dom_msgs , dom_attrs ) ;
2009-05-26 06:31:39 +04:00
} else {
return NT_STATUS_NO_SUCH_DOMAIN ;
2005-08-03 22:30:21 +04:00
}
if ( ret ! = 1 ) {
return NT_STATUS_NO_SUCH_DOMAIN ;
}
2010-10-29 12:55:07 +04:00
2005-08-03 22:30:21 +04:00
sid = samdb_result_dom_sid ( mem_ctx , dom_msgs [ 0 ] ,
" objectSid " ) ;
2010-10-29 12:55:07 +04:00
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
}
2008-11-07 04:42:45 +03:00
* r - > out . sid = sid ;
2004-05-03 18:58:08 +04:00
return NT_STATUS_OK ;
}
2010-10-29 12:55:07 +04:00
/*
samr_EnumDomains
2004-05-03 18:58:08 +04:00
list the domains in the SAM
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_EnumDomains ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
struct samr_EnumDomains * r )
{
struct dcesrv_handle * h ;
struct samr_SamArray * array ;
2009-11-21 21:26:02 +03:00
uint32_t i , start_i ;
2004-05-03 18:58:08 +04:00
* r - > out . resume_handle = 0 ;
2008-11-07 04:57:58 +03:00
* r - > out . sam = NULL ;
* r - > out . num_entries = 0 ;
2004-05-03 18:58:08 +04:00
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
2009-05-26 06:31:39 +04:00
* r - > out . resume_handle = 2 ;
2004-05-03 18:58:08 +04:00
start_i = * r - > in . resume_handle ;
2009-05-26 06:31:39 +04:00
if ( start_i > = 2 ) {
2004-05-03 18:58:08 +04:00
/* 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
}
2010-10-29 12:55:07 +04:00
2004-05-03 18:58:08 +04:00
array - > count = 0 ;
array - > entries = NULL ;
2009-05-26 06:31:39 +04:00
array - > entries = talloc_array ( mem_ctx , struct samr_SamEntry , 2 - 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
}
2009-05-26 06:31:39 +04:00
for ( i = 0 ; i < 2 - start_i ; i + + ) {
2004-05-03 18:58:08 +04:00
array - > entries [ i ] . idx = start_i + i ;
2009-05-26 06:31:39 +04:00
if ( i = = 0 ) {
2010-07-16 08:32:42 +04:00
array - > entries [ i ] . name . string = lpcfg_sam_name ( dce_call - > conn - > dce_ctx - > lp_ctx ) ;
2005-08-03 22:30:21 +04:00
} else {
2009-05-26 06:31:39 +04:00
array - > entries [ i ] . name . string = " BUILTIN " ;
2005-08-03 22:30:21 +04:00
}
2004-05-03 18:58:08 +04:00
}
2008-11-07 04:57:58 +03:00
* r - > out . sam = array ;
* r - > out . num_entries = i ;
array - > count = * r - > out . num_entries ;
2004-05-03 18:58:08 +04:00
return NT_STATUS_OK ;
}
2010-10-29 12:55:07 +04:00
/*
samr_OpenDomain
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_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 ;
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
struct ldb_message * * dom_msgs ;
2004-05-08 04:02:31 +04:00
int ret ;
2018-10-09 23:20:25 +03:00
unsigned int i ;
2004-05-08 04:02:31 +04:00
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 ;
}
2009-10-23 19:30:47 +04:00
d_state = talloc ( mem_ctx , struct samr_domain_state ) ;
2009-05-26 06:31:39 +04:00
if ( ! d_state ) {
return NT_STATUS_NO_MEMORY ;
}
d_state - > domain_sid = talloc_steal ( d_state , r - > in . sid ) ;
if ( dom_sid_equal ( d_state - > domain_sid , dom_sid_parse_talloc ( mem_ctx , SID_BUILTIN ) ) ) {
d_state - > builtin = true ;
d_state - > domain_name = " BUILTIN " ;
} else {
d_state - > builtin = false ;
2010-07-16 08:32:42 +04:00
d_state - > domain_name = lpcfg_sam_name ( dce_call - > conn - > dce_ctx - > lp_ctx ) ;
2009-05-26 06:31:39 +04:00
}
2006-08-25 11:32:18 +04:00
2005-03-23 04:30:43 +03:00
ret = gendb_search ( c_state - > sam_ctx ,
2009-05-26 06:31:39 +04:00
mem_ctx , ldb_get_default_basedn ( c_state - > sam_ctx ) , & dom_msgs , dom_attrs ,
2010-10-29 12:55:07 +04:00
" (objectSid=%s) " ,
2005-06-24 04:18:20 +04:00
ldap_encode_ndr_dom_sid ( mem_ctx , r - > in . sid ) ) ;
2010-10-29 12:55:07 +04:00
2006-09-12 04:41:12 +04:00
if ( ret = = 0 ) {
2009-05-26 06:31:39 +04:00
talloc_free ( d_state ) ;
2006-09-12 04:41:12 +04:00
return NT_STATUS_NO_SUCH_DOMAIN ;
} else if ( ret > 1 ) {
2009-05-26 06:31:39 +04:00
talloc_free ( d_state ) ;
2005-08-03 23:58:58 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2006-09-12 04:41:12 +04:00
} else if ( ret = = - 1 ) {
2009-05-26 06:31:39 +04:00
talloc_free ( d_state ) ;
2006-09-12 04:41:12 +04:00
DEBUG ( 1 , ( " Failed to open domain %s: %s \n " , dom_sid_string ( mem_ctx , r - > in . sid ) , ldb_errstring ( c_state - > sam_ctx ) ) ) ;
2006-12-13 14:19:51 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2004-05-04 11:53:06 +04:00
}
2009-05-26 06:31:39 +04:00
d_state - > domain_dn = talloc_steal ( d_state , dom_msgs [ 0 ] - > dn ) ;
2010-07-16 08:32:42 +04:00
d_state - > role = lpcfg_server_role ( dce_call - > conn - > dce_ctx - > lp_ctx ) ;
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 ;
d_state - > access_mask = r - > in . access_mask ;
2004-05-04 11:53:06 +04:00
2008-03-14 04:26:03 +03:00
d_state - > lp_ctx = dce_call - > conn - > dce_ctx - > lp_ctx ;
2018-10-09 23:20:25 +03:00
for ( i = 0 ; i < SAMR_LAST_CACHE ; i + + ) {
initialize_guid_cache ( & d_state - > guid_caches [ i ] ) ;
}
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 ;
}
2010-10-29 12:55:07 +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
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_info_DomInfo1 ( struct samr_domain_state * state ,
2010-10-29 12:53:39 +04:00
TALLOC_CTX * mem_ctx ,
struct ldb_message * * dom_msgs ,
struct samr_DomInfo1 * info )
2004-12-30 20:01:49 +03:00
{
info - > min_password_length =
2010-10-14 11:41:42 +04:00
ldb_msg_find_attr_as_uint ( dom_msgs [ 0 ] , " minPwdLength " , 0 ) ;
2004-12-30 20:01:49 +03:00
info - > password_history_length =
2010-10-14 11:41:42 +04:00
ldb_msg_find_attr_as_uint ( dom_msgs [ 0 ] , " pwdHistoryLength " , 0 ) ;
2010-10-29 12:55:07 +04:00
info - > password_properties =
2010-10-14 11:41:42 +04:00
ldb_msg_find_attr_as_uint ( dom_msgs [ 0 ] , " pwdProperties " , 0 ) ;
2010-10-29 12:55:07 +04:00
info - > max_password_age =
2010-10-14 11:41:42 +04:00
ldb_msg_find_attr_as_int64 ( dom_msgs [ 0 ] , " maxPwdAge " , 0 ) ;
2010-10-29 12:55:07 +04:00
info - > min_password_age =
2010-10-14 11:41:42 +04:00
ldb_msg_find_attr_as_int64 ( dom_msgs [ 0 ] , " minPwdAge " , 0 ) ;
2004-12-30 20:01:49 +03:00
return NT_STATUS_OK ;
}
2004-05-27 08:13:58 +04:00
/*
return DomInfo2
*/
2010-10-29 12:55:07 +04:00
static NTSTATUS dcesrv_samr_info_DomGeneralInformation ( struct samr_domain_state * state ,
2008-07-21 07:42:07 +04:00
TALLOC_CTX * mem_ctx ,
struct ldb_message * * dom_msgs ,
struct samr_DomGeneralInformation * info )
2004-05-27 08:13:58 +04:00
{
2010-10-29 12:45:47 +04:00
/* MS-SAMR 2.2.4.1 - ReplicaSourceNodeName: "domainReplica" attribute */
info - > primary . string = ldb_msg_find_attr_as_string ( dom_msgs [ 0 ] ,
" domainReplica " ,
" " ) ;
2008-03-14 04:26:03 +03:00
2010-10-29 12:55:07 +04:00
info - > force_logoff_time = ldb_msg_find_attr_as_uint64 ( dom_msgs [ 0 ] , " forceLogoff " ,
2006-07-04 06:46:24 +04:00
0x8000000000000000LL ) ;
2004-05-27 08:13:58 +04:00
2010-10-29 13:03:26 +04:00
info - > oem_information . string = ldb_msg_find_attr_as_string ( dom_msgs [ 0 ] ,
" oEMInformation " ,
" " ) ;
2006-07-04 06:46:24 +04:00
info - > domain_name . string = state - > domain_name ;
2004-05-27 08:13:58 +04:00
2010-10-29 12:55:07 +04:00
info - > sequence_num = ldb_msg_find_attr_as_uint64 ( dom_msgs [ 0 ] , " modifiedCount " ,
2006-07-04 06:46:24 +04:00
0 ) ;
2007-12-07 04:37:13 +03:00
switch ( state - > role ) {
2012-06-10 16:08:20 +04:00
case ROLE_ACTIVE_DIRECTORY_DC :
2010-10-29 12:55:07 +04:00
/* This pulls the NetBIOS name from the
2006-12-13 14:19:51 +03:00
cn = NTDS Settings , cn = < NETBIOS name of PDC > , . . . .
string */
if ( samdb_is_pdc ( state - > sam_ctx ) ) {
info - > role = SAMR_ROLE_DOMAIN_PDC ;
} else {
info - > role = SAMR_ROLE_DOMAIN_BDC ;
}
break ;
2011-06-08 21:02:37 +04:00
case ROLE_DOMAIN_PDC :
2012-06-10 16:08:20 +04:00
case ROLE_DOMAIN_BDC :
2015-03-18 18:07:03 +03:00
case ROLE_AUTO :
2012-06-10 16:08:20 +04:00
return NT_STATUS_INTERNAL_ERROR ;
2006-12-13 14:19:51 +03:00
case ROLE_DOMAIN_MEMBER :
info - > role = SAMR_ROLE_DOMAIN_MEMBER ;
break ;
case ROLE_STANDALONE :
info - > role = SAMR_ROLE_STANDALONE ;
break ;
}
2006-06-15 03:47:45 +04:00
2010-10-25 20:14:02 +04:00
info - > num_users = samdb_search_count ( state - > sam_ctx , mem_ctx ,
state - > domain_dn ,
2006-07-04 06:46:24 +04:00
" (objectClass=user) " ) ;
2010-10-25 20:14:02 +04:00
info - > num_groups = samdb_search_count ( state - > sam_ctx , mem_ctx ,
state - > domain_dn ,
2011-01-15 15:15:54 +03:00
" (&(objectClass=group)(|(groupType=%d)(groupType=%d))) " ,
2010-10-25 22:48:18 +04:00
GTYPE_SECURITY_UNIVERSAL_GROUP ,
2010-01-13 00:16:36 +03:00
GTYPE_SECURITY_GLOBAL_GROUP ) ;
2010-10-25 20:14:02 +04:00
info - > num_aliases = samdb_search_count ( state - > sam_ctx , mem_ctx ,
state - > domain_dn ,
2011-01-15 15:15:54 +03:00
" (&(objectClass=group)(|(groupType=%d)(groupType=%d))) " ,
2010-10-25 22:48:18 +04:00
GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ,
2010-01-13 00:16:36 +03:00
GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ) ;
2004-05-27 08:13:58 +04:00
return NT_STATUS_OK ;
}
2004-05-03 18:58:08 +04:00
2004-12-30 22:11:25 +03:00
/*
return DomInfo3
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_info_DomInfo3 ( struct samr_domain_state * state ,
2010-10-29 12:53:39 +04:00
TALLOC_CTX * mem_ctx ,
struct ldb_message * * dom_msgs ,
struct samr_DomInfo3 * info )
2004-12-30 22:11:25 +03:00
{
2010-10-29 12:55:07 +04:00
info - > force_logoff_time = ldb_msg_find_attr_as_uint64 ( dom_msgs [ 0 ] , " forceLogoff " ,
2006-06-13 00:00:18 +04:00
0x8000000000000000LL ) ;
2004-12-30 22:11:25 +03:00
return NT_STATUS_OK ;
}
2006-07-04 06:46:24 +04:00
/*
return DomInfo4
*/
2008-07-21 07:42:07 +04:00
static NTSTATUS dcesrv_samr_info_DomOEMInformation ( struct samr_domain_state * state ,
2006-07-04 06:46:24 +04:00
TALLOC_CTX * mem_ctx ,
struct ldb_message * * dom_msgs ,
2008-07-21 07:42:07 +04:00
struct samr_DomOEMInformation * info )
2006-07-04 06:46:24 +04:00
{
2010-10-29 13:03:26 +04:00
info - > oem_information . string = ldb_msg_find_attr_as_string ( dom_msgs [ 0 ] ,
" oEMInformation " ,
" " ) ;
2006-07-04 06:46:24 +04:00
return NT_STATUS_OK ;
}
/*
return DomInfo5
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_info_DomInfo5 ( struct samr_domain_state * state ,
2010-10-29 12:53:39 +04:00
TALLOC_CTX * mem_ctx ,
struct ldb_message * * dom_msgs ,
struct samr_DomInfo5 * info )
2006-07-04 06:46:24 +04:00
{
info - > domain_name . string = state - > domain_name ;
return NT_STATUS_OK ;
}
/*
return DomInfo6
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_info_DomInfo6 ( struct samr_domain_state * state ,
2010-10-29 12:45:47 +04:00
TALLOC_CTX * mem_ctx ,
struct ldb_message * * dom_msgs ,
struct samr_DomInfo6 * info )
2006-07-04 06:46:24 +04:00
{
2010-10-29 12:45:47 +04:00
/* MS-SAMR 2.2.4.1 - ReplicaSourceNodeName: "domainReplica" attribute */
info - > primary . string = ldb_msg_find_attr_as_string ( dom_msgs [ 0 ] ,
" domainReplica " ,
" " ) ;
2008-03-14 04:26:03 +03:00
2006-07-04 06:46:24 +04:00
return NT_STATUS_OK ;
}
/*
return DomInfo7
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_info_DomInfo7 ( struct samr_domain_state * state ,
2010-10-29 12:53:39 +04:00
TALLOC_CTX * mem_ctx ,
struct ldb_message * * dom_msgs ,
struct samr_DomInfo7 * info )
2006-07-04 06:46:24 +04:00
{
2006-12-13 14:19:51 +03:00
2007-12-07 04:37:13 +03:00
switch ( state - > role ) {
2012-06-10 16:08:20 +04:00
case ROLE_ACTIVE_DIRECTORY_DC :
2010-10-29 12:55:07 +04:00
/* This pulls the NetBIOS name from the
2006-12-13 14:19:51 +03:00
cn = NTDS Settings , cn = < NETBIOS name of PDC > , . . . .
string */
if ( samdb_is_pdc ( state - > sam_ctx ) ) {
info - > role = SAMR_ROLE_DOMAIN_PDC ;
} else {
info - > role = SAMR_ROLE_DOMAIN_BDC ;
}
break ;
2011-06-08 21:02:37 +04:00
case ROLE_DOMAIN_PDC :
2015-03-18 18:07:43 +03:00
case ROLE_DOMAIN_BDC :
case ROLE_AUTO :
return NT_STATUS_INTERNAL_ERROR ;
2006-12-13 14:19:51 +03:00
case ROLE_DOMAIN_MEMBER :
info - > role = SAMR_ROLE_DOMAIN_MEMBER ;
break ;
case ROLE_STANDALONE :
info - > role = SAMR_ROLE_STANDALONE ;
break ;
}
2006-07-04 06:46:24 +04:00
return NT_STATUS_OK ;
}
/*
return DomInfo8
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_info_DomInfo8 ( struct samr_domain_state * state ,
2010-10-29 12:53:39 +04:00
TALLOC_CTX * mem_ctx ,
struct ldb_message * * dom_msgs ,
struct samr_DomInfo8 * info )
2006-07-04 06:46:24 +04:00
{
2010-10-29 12:55:07 +04:00
info - > sequence_num = ldb_msg_find_attr_as_uint64 ( dom_msgs [ 0 ] , " modifiedCount " ,
2006-07-04 06:46:24 +04:00
time ( NULL ) ) ;
2006-08-13 12:00:36 +04:00
info - > domain_create_time = ldb_msg_find_attr_as_uint ( dom_msgs [ 0 ] , " creationTime " ,
2006-07-04 06:46:24 +04:00
0x0LL ) ;
return NT_STATUS_OK ;
}
/*
return DomInfo9
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_info_DomInfo9 ( struct samr_domain_state * state ,
2010-10-29 12:53:39 +04:00
TALLOC_CTX * mem_ctx ,
struct ldb_message * * dom_msgs ,
struct samr_DomInfo9 * info )
2006-07-04 06:46:24 +04:00
{
2008-12-02 02:16:05 +03:00
info - > domain_server_state = DOMAIN_SERVER_ENABLED ;
2006-07-04 06:46:24 +04:00
return NT_STATUS_OK ;
}
/*
return DomInfo11
*/
2008-07-21 07:42:07 +04:00
static NTSTATUS dcesrv_samr_info_DomGeneralInformation2 ( struct samr_domain_state * state ,
2010-10-29 12:53:39 +04:00
TALLOC_CTX * mem_ctx ,
struct ldb_message * * dom_msgs ,
struct samr_DomGeneralInformation2 * info )
2006-07-04 06:46:24 +04:00
{
NTSTATUS status ;
2008-07-21 07:42:07 +04:00
status = dcesrv_samr_info_DomGeneralInformation ( state , mem_ctx , dom_msgs , & info - > general ) ;
2006-07-04 06:46:24 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2010-10-29 12:55:07 +04:00
info - > lockout_duration = ldb_msg_find_attr_as_int64 ( dom_msgs [ 0 ] , " lockoutDuration " ,
2006-07-04 06:46:24 +04:00
- 18000000000LL ) ;
2006-08-13 12:00:36 +04:00
info - > lockout_window = ldb_msg_find_attr_as_int64 ( dom_msgs [ 0 ] , " lockOutObservationWindow " ,
2006-07-04 06:46:24 +04:00
- 18000000000LL ) ;
2006-08-13 12:00:36 +04:00
info - > lockout_threshold = ldb_msg_find_attr_as_int64 ( dom_msgs [ 0 ] , " lockoutThreshold " , 0 ) ;
2006-07-04 06:46:24 +04:00
return NT_STATUS_OK ;
}
/*
return DomInfo12
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_info_DomInfo12 ( struct samr_domain_state * state ,
2010-10-29 12:53:39 +04:00
TALLOC_CTX * mem_ctx ,
struct ldb_message * * dom_msgs ,
struct samr_DomInfo12 * info )
2006-07-04 06:46:24 +04:00
{
2010-10-29 12:55:07 +04:00
info - > lockout_duration = ldb_msg_find_attr_as_int64 ( dom_msgs [ 0 ] , " lockoutDuration " ,
2006-07-04 06:46:24 +04:00
- 18000000000LL ) ;
2006-08-13 12:00:36 +04:00
info - > lockout_window = ldb_msg_find_attr_as_int64 ( dom_msgs [ 0 ] , " lockOutObservationWindow " ,
2006-07-04 06:46:24 +04:00
- 18000000000LL ) ;
2006-08-13 12:00:36 +04:00
info - > lockout_threshold = ldb_msg_find_attr_as_int64 ( dom_msgs [ 0 ] , " lockoutThreshold " , 0 ) ;
2006-07-04 06:46:24 +04:00
return NT_STATUS_OK ;
}
/*
return DomInfo13
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_info_DomInfo13 ( struct samr_domain_state * state ,
2010-10-29 12:53:39 +04:00
TALLOC_CTX * mem_ctx ,
struct ldb_message * * dom_msgs ,
struct samr_DomInfo13 * info )
2006-07-04 06:46:24 +04:00
{
2010-10-29 12:55:07 +04:00
info - > sequence_num = ldb_msg_find_attr_as_uint64 ( dom_msgs [ 0 ] , " modifiedCount " ,
2006-07-04 06:46:24 +04:00
time ( NULL ) ) ;
2006-08-13 12:00:36 +04:00
info - > domain_create_time = ldb_msg_find_attr_as_uint ( dom_msgs [ 0 ] , " creationTime " ,
2006-07-04 06:46:24 +04:00
0x0LL ) ;
2008-12-03 01:27:08 +03:00
info - > modified_count_at_last_promotion = 0 ;
2006-07-04 06:46:24 +04:00
return NT_STATUS_OK ;
}
2010-10-29 12:55:07 +04:00
/*
samr_QueryDomainInfo
2004-05-03 18:58:08 +04:00
*/
2010-10-29 12:53:39 +04:00
static NTSTATUS dcesrv_samr_QueryDomainInfo ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
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 ;
2008-11-05 04:59:51 +03:00
union samr_DomainInfo * info ;
2004-05-27 08:13:58 +04:00
2006-07-04 06:46:24 +04:00
struct ldb_message * * dom_msgs ;
const char * const * attrs = NULL ;
2010-10-29 12:55:07 +04:00
2008-11-05 04:59:51 +03:00
* r - > out . info = NULL ;
2004-05-27 08:13:58 +04:00
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 ;
2006-07-04 06:46:24 +04:00
switch ( r - > in . level ) {
2010-10-29 12:55:07 +04:00
case 1 :
2006-07-04 06:46:24 +04:00
{
2009-08-18 00:34:08 +04:00
static const char * const attrs2 [ ] = { " minPwdLength " ,
" pwdHistoryLength " ,
" pwdProperties " ,
" maxPwdAge " ,
" minPwdAge " ,
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 2 :
{
2007-12-20 02:02:15 +03:00
static const char * const attrs2 [ ] = { " forceLogoff " ,
2010-10-29 12:45:47 +04:00
" oEMInformation " ,
" modifiedCount " ,
" domainReplica " ,
2006-09-08 09:10:10 +04:00
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 3 :
{
2010-10-29 12:55:07 +04:00
static const char * const attrs2 [ ] = { " forceLogoff " ,
2006-09-08 09:10:10 +04:00
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 4 :
{
2010-10-29 12:55:07 +04:00
static const char * const attrs2 [ ] = { " oEMInformation " ,
2006-09-08 09:10:10 +04:00
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 5 :
2006-12-13 14:19:51 +03:00
{
attrs = NULL ;
break ;
}
2006-07-04 06:46:24 +04:00
case 6 :
2006-12-13 14:19:51 +03:00
{
2010-10-29 12:45:47 +04:00
static const char * const attrs2 [ ] = { " domainReplica " ,
NULL } ;
2006-12-13 14:19:51 +03:00
attrs = attrs2 ;
break ;
}
2006-07-04 06:46:24 +04:00
case 7 :
{
attrs = NULL ;
break ;
}
case 8 :
{
2010-10-29 12:55:07 +04:00
static const char * const attrs2 [ ] = { " modifiedCount " ,
" creationTime " ,
2006-09-08 09:10:10 +04:00
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 9 :
2009-11-10 18:26:23 +03:00
{
2006-07-04 06:46:24 +04:00
attrs = NULL ;
2009-11-10 18:26:23 +03:00
break ;
}
2006-07-04 06:46:24 +04:00
case 11 :
{
2009-08-18 00:34:08 +04:00
static const char * const attrs2 [ ] = { " oEMInformation " ,
" forceLogoff " ,
2010-10-29 12:55:07 +04:00
" modifiedCount " ,
" lockoutDuration " ,
" lockOutObservationWindow " ,
" lockoutThreshold " ,
2006-09-08 09:10:10 +04:00
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 12 :
{
2010-10-29 12:55:07 +04:00
static const char * const attrs2 [ ] = { " lockoutDuration " ,
" lockOutObservationWindow " ,
" lockoutThreshold " ,
2006-09-08 09:10:10 +04:00
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 13 :
{
2010-10-29 12:55:07 +04:00
static const char * const attrs2 [ ] = { " modifiedCount " ,
" creationTime " ,
2006-09-08 09:10:10 +04:00
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
2009-11-10 18:26:23 +03:00
default :
{
return NT_STATUS_INVALID_INFO_CLASS ;
}
2006-07-04 06:46:24 +04:00
}
/* some levels don't need a search */
if ( attrs ) {
int ret ;
ret = gendb_search_dn ( d_state - > sam_ctx , mem_ctx ,
d_state - > domain_dn , & dom_msgs , attrs ) ;
2010-06-12 01:57:39 +04:00
if ( ret = = 0 ) {
return NT_STATUS_NO_SUCH_DOMAIN ;
}
2006-07-04 06:46:24 +04:00
if ( ret ! = 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
}
2010-06-12 01:57:39 +04:00
/* allocate the info structure */
info = talloc_zero ( mem_ctx , union samr_DomainInfo ) ;
if ( info = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2008-11-05 04:59:51 +03:00
2010-06-12 01:57:39 +04:00
* r - > out . info = info ;
2004-05-27 08:13:58 +04:00
switch ( r - > in . level ) {
2004-12-30 20:01:49 +03:00
case 1 :
2010-10-29 12:55:07 +04:00
return dcesrv_samr_info_DomInfo1 ( d_state , mem_ctx , dom_msgs ,
2008-11-05 04:59:51 +03:00
& info - > info1 ) ;
2004-05-27 08:13:58 +04:00
case 2 :
2010-10-29 12:55:07 +04:00
return dcesrv_samr_info_DomGeneralInformation ( d_state , mem_ctx , dom_msgs ,
2008-11-05 04:59:51 +03:00
& info - > general ) ;
2004-12-30 22:11:25 +03:00
case 3 :
2010-10-29 12:55:07 +04:00
return dcesrv_samr_info_DomInfo3 ( d_state , mem_ctx , dom_msgs ,
2008-11-05 04:59:51 +03:00
& info - > info3 ) ;
2006-07-04 06:46:24 +04:00
case 4 :
2010-10-29 12:55:07 +04:00
return dcesrv_samr_info_DomOEMInformation ( d_state , mem_ctx , dom_msgs ,
2008-11-05 04:59:51 +03:00
& info - > oem ) ;
2006-07-04 06:46:24 +04:00
case 5 :
2010-10-29 12:55:07 +04:00
return dcesrv_samr_info_DomInfo5 ( d_state , mem_ctx , dom_msgs ,
2008-11-05 04:59:51 +03:00
& info - > info5 ) ;
2006-07-04 06:46:24 +04:00
case 6 :
2010-10-29 12:55:07 +04:00
return dcesrv_samr_info_DomInfo6 ( d_state , mem_ctx , dom_msgs ,
2008-11-05 04:59:51 +03:00
& info - > info6 ) ;
2006-07-04 06:46:24 +04:00
case 7 :
2010-10-29 12:55:07 +04:00
return dcesrv_samr_info_DomInfo7 ( d_state , mem_ctx , dom_msgs ,
2008-11-05 04:59:51 +03:00
& info - > info7 ) ;
2006-07-04 06:46:24 +04:00
case 8 :
2010-10-29 12:55:07 +04:00
return dcesrv_samr_info_DomInfo8 ( d_state , mem_ctx , dom_msgs ,
2008-11-05 04:59:51 +03:00
& info - > info8 ) ;
2006-07-04 06:46:24 +04:00
case 9 :
2010-10-29 12:55:07 +04:00
return dcesrv_samr_info_DomInfo9 ( d_state , mem_ctx , dom_msgs ,
2008-11-05 04:59:51 +03:00
& info - > info9 ) ;
2006-07-04 06:46:24 +04:00
case 11 :
2010-10-29 12:55:07 +04:00
return dcesrv_samr_info_DomGeneralInformation2 ( d_state , mem_ctx , dom_msgs ,
2008-11-05 04:59:51 +03:00
& info - > general2 ) ;
2006-07-04 06:46:24 +04:00
case 12 :
2010-10-29 12:55:07 +04:00
return dcesrv_samr_info_DomInfo12 ( d_state , mem_ctx , dom_msgs ,
2008-11-05 04:59:51 +03:00
& info - > info12 ) ;
2006-07-04 06:46:24 +04:00
case 13 :
2010-10-29 12:55:07 +04:00
return dcesrv_samr_info_DomInfo13 ( d_state , mem_ctx , dom_msgs ,
2008-11-05 04:59:51 +03:00
& info - > info13 ) ;
2009-11-10 18:26:23 +03:00
default :
return NT_STATUS_INVALID_INFO_CLASS ;
2004-05-27 08:13:58 +04:00
}
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_SetDomainInfo
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_SetDomainInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
struct samr_SetDomainInfo * r )
{
2006-07-04 06:46:24 +04:00
struct dcesrv_handle * h ;
struct samr_domain_state * d_state ;
struct ldb_message * msg ;
int ret ;
struct ldb_context * sam_ctx ;
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
d_state = h - > data ;
sam_ctx = d_state - > sam_ctx ;
msg = ldb_msg_new ( mem_ctx ) ;
if ( msg = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
msg - > dn = talloc_reference ( mem_ctx , d_state - > domain_dn ) ;
if ( ! msg - > dn ) {
return NT_STATUS_NO_MEMORY ;
}
switch ( r - > in . level ) {
case 1 :
SET_UINT ( msg , info1 . min_password_length , " minPwdLength " ) ;
SET_UINT ( msg , info1 . password_history_length , " pwdHistoryLength " ) ;
SET_UINT ( msg , info1 . password_properties , " pwdProperties " ) ;
SET_INT64 ( msg , info1 . max_password_age , " maxPwdAge " ) ;
SET_INT64 ( msg , info1 . min_password_age , " minPwdAge " ) ;
break ;
case 3 :
2008-07-21 07:42:07 +04:00
SET_UINT64 ( msg , info3 . force_logoff_time , " forceLogoff " ) ;
2006-07-04 06:46:24 +04:00
break ;
case 4 :
2008-07-21 07:42:07 +04:00
SET_STRING ( msg , oem . oem_information , " oEMInformation " ) ;
2006-07-04 06:46:24 +04:00
break ;
case 6 :
case 7 :
case 9 :
/* No op, we don't know where to set these */
return NT_STATUS_OK ;
case 12 :
2010-01-20 19:54:40 +03:00
/*
* It is not possible to set lockout_duration < lockout_window .
* ( The test is the other way around since the negative numbers
* are stored . . . )
*
* TODO :
* This check should be moved to the backend , i . e . to some
* ldb module under dsdb / samdb / ldb_modules / .
*
* This constraint is documented here for the samr rpc service :
* MS - SAMR 3.1 .1 .6 Attribute Constraints for Originating Updates
* http : //msdn.microsoft.com/en-us/library/cc245667%28PROT.10%29.aspx
*
* And here for the ldap backend :
* MS - ADTS 3.1 .1 .5 .3 .2 Constraints
* http : //msdn.microsoft.com/en-us/library/cc223462(PROT.10).aspx
*/
if ( r - > in . info - > info12 . lockout_duration >
r - > in . info - > info12 . lockout_window )
{
return NT_STATUS_INVALID_PARAMETER ;
}
2006-07-04 06:46:24 +04:00
SET_INT64 ( msg , info12 . lockout_duration , " lockoutDuration " ) ;
SET_INT64 ( msg , info12 . lockout_window , " lockOutObservationWindow " ) ;
SET_INT64 ( msg , info12 . lockout_threshold , " lockoutThreshold " ) ;
break ;
default :
/* many info classes are not valid for SetDomainInfo */
return NT_STATUS_INVALID_INFO_CLASS ;
}
/* modify the samdb record */
2007-07-27 06:07:17 +04:00
ret = ldb_modify ( sam_ctx , msg ) ;
2009-10-13 02:15:19 +04:00
if ( ret ! = LDB_SUCCESS ) {
2006-07-04 06:46:24 +04:00
DEBUG ( 1 , ( " Failed to modify record %s: %s \n " ,
2006-11-22 05:05:19 +03:00
ldb_dn_get_linearized ( d_state - > domain_dn ) ,
2006-07-04 06:46:24 +04:00
ldb_errstring ( sam_ctx ) ) ) ;
2011-04-01 08:58:55 +04:00
return dsdb_ldb_err_to_ntstatus ( ret ) ;
2006-07-04 06:46:24 +04:00
}
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_CreateDomainGroup
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_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
{
2010-05-21 02:17:44 +04:00
NTSTATUS status ;
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 ;
2005-06-24 04:18:20 +04:00
const char * groupname ;
2010-05-21 02:17:44 +04:00
struct dom_sid * group_sid ;
struct ldb_dn * group_dn ;
2004-05-09 15:21:46 +04:00
struct dcesrv_handle * g_handle ;
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 ;
2008-03-14 04:26:03 +03:00
if ( d_state - > builtin ) {
DEBUG ( 5 , ( " Cannot create a domain group in the BUILTIN domain " ) ) ;
return NT_STATUS_ACCESS_DENIED ;
}
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 ;
}
2010-05-21 02:17:44 +04:00
status = dsdb_add_domain_group ( d_state - > sam_ctx , mem_ctx , groupname , & group_sid , & group_dn ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2004-05-09 15:21:46 +04:00
}
2009-10-23 19:30:47 +04:00
a_state = talloc ( mem_ctx , 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 ) ;
2010-05-21 02:17:44 +04:00
a_state - > account_dn = talloc_steal ( a_state , group_dn ) ;
2005-03-28 03:31:43 +04:00
2010-05-21 02:17:44 +04:00
a_state - > account_name = talloc_steal ( a_state , groupname ) ;
2004-05-09 15:21:46 +04:00
/* 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 ;
2010-05-21 02:17:44 +04:00
* r - > out . rid = group_sid - > sub_auths [ group_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 ;
}
2018-10-18 00:16:24 +03:00
static int compare_msgRid ( struct ldb_message * * m1 , struct ldb_message * * m2 ) {
struct dom_sid * sid1 = NULL ;
struct dom_sid * sid2 = NULL ;
uint32_t rid1 ;
uint32_t rid2 ;
int res = 0 ;
NTSTATUS status ;
TALLOC_CTX * frame = talloc_stackframe ( ) ;
sid1 = samdb_result_dom_sid ( frame , * m1 , " objectSid " ) ;
sid2 = samdb_result_dom_sid ( frame , * m2 , " objectSid " ) ;
/*
* If entries don ' t have a SID we want to sort them to the end of
* the list .
*/
if ( sid1 = = NULL & & sid2 = = NULL ) {
res = 0 ;
goto exit ;
} else if ( sid2 = = NULL ) {
res = 1 ;
goto exit ;
} else if ( sid1 = = NULL ) {
res = - 1 ;
goto exit ;
}
/*
* Get and compare the rids , if we fail to extract a rid treat it as a
* missing SID and sort to the end of the list
*/
status = dom_sid_split_rid ( NULL , sid1 , NULL , & rid1 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
res = 1 ;
goto exit ;
}
status = dom_sid_split_rid ( NULL , sid2 , NULL , & rid2 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
res = - 1 ;
goto exit ;
}
if ( rid1 = = rid2 ) {
res = 0 ;
}
else if ( rid1 > rid2 ) {
res = 1 ;
}
else {
res = - 1 ;
}
exit :
TALLOC_FREE ( frame ) ;
return res ;
}
2010-10-29 12:55:07 +04:00
/*
samr_EnumDomainGroups
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_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 ;
2018-10-18 00:16:24 +03:00
uint32_t i ;
uint32_t count ;
uint32_t results ;
uint32_t max_entries ;
uint32_t remaining_entries ;
uint32_t resume_handle ;
2004-12-28 10:57:31 +03:00
struct samr_SamEntry * entries ;
2010-06-12 01:44:46 +04:00
const char * const attrs [ ] = { " objectSid " , " sAMAccountName " , NULL } ;
2018-10-18 00:16:24 +03:00
const char * const cache_attrs [ ] = { " objectSid " , " objectGUID " , NULL } ;
2008-11-07 16:51:21 +03:00
struct samr_SamArray * sam ;
2018-10-18 00:16:24 +03:00
struct samr_guid_cache * cache = NULL ;
2004-12-28 10:57:31 +03:00
* r - > out . resume_handle = 0 ;
2008-11-07 16:51:21 +03:00
* r - > out . sam = NULL ;
* r - > out . num_entries = 0 ;
2004-12-28 10:57:31 +03:00
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
d_state = h - > data ;
2018-10-18 00:16:24 +03:00
cache = & d_state - > guid_caches [ SAMR_ENUM_DOMAIN_GROUPS_CACHE ] ;
2004-12-30 20:01:49 +03:00
2018-10-18 00:16:24 +03:00
/*
* If the resume_handle is zero , query the database and cache the
* matching GUID ' s
*/
if ( * r - > in . resume_handle = = 0 ) {
NTSTATUS status ;
int ldb_cnt ;
clear_guid_cache ( cache ) ;
/*
* search for all domain groups in this domain .
*/
ldb_cnt = samdb_search_domain (
d_state - > sam_ctx ,
mem_ctx ,
d_state - > domain_dn ,
& res ,
cache_attrs ,
d_state - > domain_sid ,
" (&(|(groupType=%d)(groupType=%d))(objectClass=group)) " ,
GTYPE_SECURITY_UNIVERSAL_GROUP ,
GTYPE_SECURITY_GLOBAL_GROUP ) ;
if ( ldb_cnt < 0 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
/*
* Sort the results into RID order , while the spec states there
* is no order , Windows appears to sort the results by RID and
* so it is possible that there are clients that depend on
* this ordering
*/
TYPESAFE_QSORT ( res , ldb_cnt , compare_msgRid ) ;
2004-12-28 10:57:31 +03:00
2018-10-18 00:16:24 +03:00
/*
* cache the sorted GUID ' s
*/
status = load_guid_cache ( cache , d_state , ldb_cnt , res ) ;
TALLOC_FREE ( res ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
cache - > handle = 0 ;
2004-12-28 10:57:31 +03:00
}
2018-10-18 00:16:24 +03:00
/*
* If the resume handle is out of range we return an empty response
* and invalidate the cache .
*
* From the specification :
* Servers SHOULD validate that EnumerationContext is an expected
* value for the server ' s implementation . Windows does NOT validate
* the input , though the result of malformed information merely results
* in inconsistent output to the client .
*/
if ( * r - > in . resume_handle > = cache - > size ) {
clear_guid_cache ( cache ) ;
sam = talloc ( mem_ctx , struct samr_SamArray ) ;
if ( ! sam ) {
return NT_STATUS_NO_MEMORY ;
2010-06-12 13:39:25 +04:00
}
2018-10-18 00:16:24 +03:00
sam - > entries = NULL ;
sam - > count = 0 ;
2004-12-28 10:57:31 +03:00
2018-10-18 00:16:24 +03:00
* r - > out . sam = sam ;
* r - > out . resume_handle = 0 ;
return NT_STATUS_OK ;
2004-12-28 10:57:31 +03:00
}
2018-10-18 00:16:24 +03:00
/*
* Calculate the number of entries to return limit by max_size .
* Note that we use the w2k3 element size value of 54
*/
max_entries = 1 + ( r - > in . max_size / SAMR_ENUM_USERS_MULTIPLIER ) ;
remaining_entries = cache - > size - * r - > in . resume_handle ;
results = MIN ( remaining_entries , max_entries ) ;
2004-12-28 10:57:31 +03:00
2018-10-18 00:16:24 +03:00
/*
* Process the list of result GUID ' s .
* Read the details of each object and populate the Entries
* for the current level .
*/
count = 0 ;
resume_handle = * r - > in . resume_handle ;
entries = talloc_array ( mem_ctx , struct samr_SamEntry , results ) ;
if ( entries = = NULL ) {
clear_guid_cache ( cache ) ;
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < results ; i + + ) {
2018-10-18 03:54:31 +03:00
struct dom_sid * objectsid ;
uint32_t rid ;
2018-10-18 00:16:24 +03:00
struct ldb_result * rec ;
const uint32_t idx = * r - > in . resume_handle + i ;
int ret ;
2018-10-18 03:54:31 +03:00
NTSTATUS status ;
2018-10-18 00:16:24 +03:00
const char * name = NULL ;
resume_handle + + ;
/*
* Read an object from disk using the GUID as the key
*
* If the object can not be read , or it does not have a SID
* it is ignored .
*
* As a consequence of this , if all the remaining GUID ' s
* have been deleted an empty result will be returned .
* i . e . even if the previous call returned a non zero
* resume_handle it is possible for no results to be returned .
*
*/
ret = dsdb_search_by_dn_guid ( d_state - > sam_ctx ,
mem_ctx ,
& rec ,
& cache - > entries [ idx ] ,
attrs ,
0 ) ;
if ( ret = = LDB_ERR_NO_SUCH_OBJECT ) {
2018-11-15 03:44:23 +03:00
struct GUID_txt_buf guid_buf ;
2018-11-21 00:02:43 +03:00
DBG_WARNING (
" GUID [%s] not found \n " ,
GUID_buf_string ( & cache - > entries [ idx ] , & guid_buf ) ) ;
2018-10-18 00:16:24 +03:00
continue ;
} else if ( ret ! = LDB_SUCCESS ) {
clear_guid_cache ( cache ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2018-10-18 03:54:31 +03:00
objectsid = samdb_result_dom_sid ( mem_ctx ,
rec - > msgs [ 0 ] ,
" objectSID " ) ;
if ( objectsid = = NULL ) {
2018-11-15 03:44:23 +03:00
struct GUID_txt_buf guid_buf ;
2018-11-21 00:02:43 +03:00
DBG_WARNING (
" objectSID for GUID [%s] not found \n " ,
GUID_buf_string ( & cache - > entries [ idx ] , & guid_buf ) ) ;
2018-10-18 00:16:24 +03:00
continue ;
}
2018-10-18 03:54:31 +03:00
status = dom_sid_split_rid ( NULL ,
objectsid ,
NULL ,
& rid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
struct dom_sid_buf sid_buf ;
struct GUID_txt_buf guid_buf ;
2018-11-21 00:02:43 +03:00
DBG_WARNING (
" objectSID [%s] for GUID [%s] invalid \n " ,
dom_sid_str_buf ( objectsid , & sid_buf ) ,
GUID_buf_string ( & cache - > entries [ idx ] , & guid_buf ) ) ;
2018-10-18 03:54:31 +03:00
continue ;
}
entries [ count ] . idx = rid ;
2018-10-18 00:16:24 +03:00
name = ldb_msg_find_attr_as_string (
rec - > msgs [ 0 ] , " sAMAccountName " , " " ) ;
entries [ count ] . name . string = talloc_strdup ( entries , name ) ;
count + + ;
}
2004-12-28 10:57:31 +03:00
2008-11-07 16:51:21 +03:00
sam = talloc ( mem_ctx , struct samr_SamArray ) ;
if ( ! sam ) {
2018-10-18 00:16:24 +03:00
clear_guid_cache ( cache ) ;
2004-12-28 10:57:31 +03:00
return NT_STATUS_NO_MEMORY ;
}
2018-10-18 00:16:24 +03:00
sam - > entries = entries ;
sam - > count = count ;
2008-11-07 16:51:21 +03:00
* r - > out . sam = sam ;
2018-10-18 00:16:24 +03:00
* r - > out . resume_handle = resume_handle ;
* r - > out . num_entries = count ;
2004-12-28 10:57:31 +03:00
2018-10-18 00:16:24 +03:00
/*
* Signal no more results by returning zero resume handle ,
* the cache is also cleared at this point
*/
if ( * r - > out . resume_handle > = cache - > size ) {
* r - > out . resume_handle = 0 ;
clear_guid_cache ( cache ) ;
2010-06-12 01:44:46 +04:00
return NT_STATUS_OK ;
}
2018-10-18 00:16:24 +03:00
/*
* There are more results to be returned .
*/
return STATUS_MORE_ENTRIES ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_CreateUser2
2004-05-08 04:02:31 +04:00
2005-12-27 02:47:19 +03:00
This call uses transactions to ensure we don ' t get a new conflicting
user while we are processing this , and to ensure the user either
completly exists , or does not .
2004-05-06 11:32:51 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_CreateUser2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-06 11:32:51 +04:00
struct samr_CreateUser2 * r )
{
2010-05-21 02:14:53 +04:00
NTSTATUS status ;
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 ;
2010-05-21 02:14:53 +04:00
struct ldb_dn * dn ;
2005-03-28 03:31:43 +04:00
struct dom_sid * sid ;
2004-05-08 04:02:31 +04:00
struct dcesrv_handle * u_handle ;
2010-05-21 02:14:53 +04:00
const char * account_name ;
2005-12-22 12:32:26 +03: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 ;
2008-03-14 04:26:03 +03:00
if ( d_state - > builtin ) {
DEBUG ( 5 , ( " Cannot create a user in the BUILTIN domain " ) ) ;
return NT_STATUS_ACCESS_DENIED ;
2009-05-29 11:12:06 +04:00
} else if ( r - > in . acct_flags = = ACB_DOMTRUST ) {
/* Domain trust accounts must be created by the LSA calls */
return NT_STATUS_ACCESS_DENIED ;
2008-03-14 04:26:03 +03:00
}
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 ;
}
2011-08-11 09:46:26 +04:00
status = dsdb_add_user ( d_state - > sam_ctx , mem_ctx , account_name , r - > in . acct_flags , NULL ,
& sid , & dn ) ;
2010-05-21 02:14:53 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2004-05-08 04:02:31 +04:00
}
2009-10-23 19:30:47 +04: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 ) ;
2010-05-21 02:14:53 +04:00
a_state - > account_dn = talloc_steal ( a_state , dn ) ;
2005-12-22 12:32:26 +03:00
a_state - > account_name = talloc_steal ( a_state , account_name ) ;
2004-12-23 01:19:54 +03:00
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
}
2010-10-29 12:55:07 +04:00
/*
samr_CreateUser
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_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 */
2015-03-03 10:48:00 +03:00
r2 = ( struct samr_CreateUser2 ) {
. in . domain_handle = r - > in . domain_handle ,
. in . account_name = r - > in . account_name ,
. in . acct_flags = ACB_NORMAL ,
. in . access_mask = r - > in . access_mask ,
. out . user_handle = r - > out . user_handle ,
. out . access_granted = & access_granted ,
. out . rid = r - > out . rid
} ;
2004-05-06 11:32:51 +04:00
2007-01-17 17:49:36 +03:00
return dcesrv_samr_CreateUser2 ( dce_call , mem_ctx , & r2 ) ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_EnumDomainUsers
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_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 ;
2010-06-12 01:39:46 +04:00
struct ldb_message * * res ;
2018-10-18 03:54:31 +03:00
uint32_t i ;
uint32_t count ;
uint32_t results ;
uint32_t max_entries ;
uint32_t remaining_entries ;
uint32_t resume_handle ;
2004-05-08 18:42:45 +04:00
struct samr_SamEntry * entries ;
2009-08-18 00:34:08 +04:00
const char * const attrs [ ] = { " objectSid " , " sAMAccountName " ,
" userAccountControl " , NULL } ;
2018-10-18 03:54:31 +03:00
const char * const cache_attrs [ ] = { " objectSid " , " objectGUID " , NULL } ;
2008-11-07 13:25:01 +03:00
struct samr_SamArray * sam ;
2018-10-18 03:54:31 +03:00
struct samr_guid_cache * cache = NULL ;
2004-05-08 18:42:45 +04:00
* r - > out . resume_handle = 0 ;
2008-11-07 13:25:01 +03:00
* r - > out . sam = NULL ;
* r - > out . num_entries = 0 ;
2004-05-08 18:42:45 +04:00
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 ;
2018-10-18 03:54:31 +03:00
cache = & d_state - > guid_caches [ SAMR_ENUM_DOMAIN_USERS_CACHE ] ;
2010-10-29 12:55:07 +04:00
2018-10-18 03:54:31 +03:00
/*
* If the resume_handle is zero , query the database and cache the
* matching GUID ' s
*/
if ( * r - > in . resume_handle = = 0 ) {
NTSTATUS status ;
int ldb_cnt ;
clear_guid_cache ( cache ) ;
/*
* search for all domain users in this domain .
*/
ldb_cnt = samdb_search_domain ( d_state - > sam_ctx ,
mem_ctx ,
d_state - > domain_dn ,
& res ,
cache_attrs ,
d_state - > domain_sid ,
" (objectClass=user) " ) ;
if ( ldb_cnt < 0 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
/*
* Sort the results into RID order , while the spec states there
* is no order , Windows appears to sort the results by RID and
* so it is possible that there are clients that depend on
* this ordering
*/
TYPESAFE_QSORT ( res , ldb_cnt , compare_msgRid ) ;
/*
* cache the sorted GUID ' s
*/
status = load_guid_cache ( cache , d_state , ldb_cnt , res ) ;
TALLOC_FREE ( res ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
cache - > handle = 0 ;
2004-05-08 18:42:45 +04:00
}
2018-10-18 03:54:31 +03:00
/*
* If the resume handle is out of range we return an empty response
* and invalidate the cache .
*
* From the specification :
* Servers SHOULD validate that EnumerationContext is an expected
* value for the server ' s implementation . Windows does NOT validate
* the input , though the result of malformed information merely results
* in inconsistent output to the client .
*/
if ( * r - > in . resume_handle > = cache - > size ) {
clear_guid_cache ( cache ) ;
sam = talloc ( mem_ctx , struct samr_SamArray ) ;
if ( ! sam ) {
return NT_STATUS_NO_MEMORY ;
}
sam - > entries = NULL ;
sam - > count = 0 ;
* r - > out . sam = sam ;
* r - > out . resume_handle = 0 ;
return NT_STATUS_OK ;
2004-05-08 18:42:45 +04:00
}
2010-06-12 01:39:46 +04:00
2018-10-18 03:54:31 +03:00
/*
* Calculate the number of entries to return limit by max_size .
* Note that we use the w2k3 element size value of 54
*/
max_entries = 1 + ( r - > in . max_size / SAMR_ENUM_USERS_MULTIPLIER ) ;
remaining_entries = cache - > size - * r - > in . resume_handle ;
results = MIN ( remaining_entries , max_entries ) ;
/*
* Process the list of result GUID ' s .
* Read the details of each object and populate the Entries
* for the current level .
*/
2010-06-12 01:39:46 +04:00
count = 0 ;
2018-10-18 03:54:31 +03:00
resume_handle = * r - > in . resume_handle ;
entries = talloc_array ( mem_ctx , struct samr_SamEntry , results ) ;
if ( entries = = NULL ) {
clear_guid_cache ( cache ) ;
return NT_STATUS_NO_MEMORY ;
}
for ( i = 0 ; i < results ; i + + ) {
2018-11-15 02:48:15 +03:00
struct dom_sid * objectsid ;
uint32_t rid ;
2018-10-18 03:54:31 +03:00
struct ldb_result * rec ;
const uint32_t idx = * r - > in . resume_handle + i ;
int ret ;
2018-11-15 02:48:15 +03:00
NTSTATUS status ;
2018-10-18 03:54:31 +03:00
const char * name = NULL ;
2010-06-12 01:39:46 +04:00
2018-10-18 03:54:31 +03:00
resume_handle + + ;
/*
* Read an object from disk using the GUID as the key
*
* If the object can not be read , or it does not have a SID
* it is ignored .
*
* As a consequence of this , if all the remaining GUID ' s
* have been deleted an empty result will be returned .
* i . e . even if the previous call returned a non zero
* resume_handle it is possible for no results to be returned .
*
*/
ret = dsdb_search_by_dn_guid ( d_state - > sam_ctx ,
mem_ctx ,
& rec ,
& cache - > entries [ idx ] ,
attrs ,
0 ) ;
if ( ret = = LDB_ERR_NO_SUCH_OBJECT ) {
2018-11-15 03:44:29 +03:00
struct GUID_txt_buf guid_buf ;
2018-11-21 00:02:43 +03:00
DBG_WARNING (
" GUID [%s] not found \n " ,
GUID_buf_string ( & cache - > entries [ idx ] , & guid_buf ) ) ;
2007-07-26 11:27:46 +04:00
continue ;
2018-10-18 03:54:31 +03:00
} else if ( ret ! = LDB_SUCCESS ) {
clear_guid_cache ( cache ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2007-07-26 11:27:46 +04:00
}
2018-11-15 02:48:15 +03:00
objectsid = samdb_result_dom_sid ( mem_ctx ,
rec - > msgs [ 0 ] ,
" objectSID " ) ;
if ( objectsid = = NULL ) {
2018-11-15 03:44:29 +03:00
struct GUID_txt_buf guid_buf ;
2018-11-21 00:02:43 +03:00
DBG_WARNING (
" objectSID for GUID [%s] not found \n " ,
GUID_buf_string ( & cache - > entries [ idx ] , & guid_buf ) ) ;
2018-10-18 03:54:31 +03:00
continue ;
}
if ( r - > in . acct_flags & &
( ( samdb_result_acct_flags ( rec - > msgs [ 0 ] , NULL ) &
r - > in . acct_flags ) = = 0 ) ) {
continue ;
}
2018-11-15 02:48:15 +03:00
status = dom_sid_split_rid ( NULL ,
objectsid ,
NULL ,
& rid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
struct dom_sid_buf sid_buf ;
struct GUID_txt_buf guid_buf ;
2018-11-21 00:02:43 +03:00
DBG_WARNING (
" objectSID [%s] for GUID [%s] invalid \n " ,
dom_sid_str_buf ( objectsid , & sid_buf ) ,
GUID_buf_string ( & cache - > entries [ idx ] , & guid_buf ) ) ;
2018-11-15 02:48:15 +03:00
continue ;
}
entries [ count ] . idx = rid ;
2018-10-18 03:54:31 +03:00
name = ldb_msg_find_attr_as_string (
rec - > msgs [ 0 ] , " sAMAccountName " , " " ) ;
entries [ count ] . name . string = talloc_strdup ( entries , name ) ;
count + + ;
2004-05-08 18:42:45 +04:00
}
2008-11-07 13:25:01 +03:00
sam = talloc ( mem_ctx , struct samr_SamArray ) ;
if ( ! sam ) {
2018-10-18 03:54:31 +03:00
clear_guid_cache ( cache ) ;
2004-05-08 18:42:45 +04:00
return NT_STATUS_NO_MEMORY ;
}
2018-10-18 03:54:31 +03:00
sam - > entries = entries ;
sam - > count = count ;
2008-11-07 13:25:01 +03:00
* r - > out . sam = sam ;
2018-10-18 03:54:31 +03:00
* r - > out . resume_handle = resume_handle ;
* r - > out . num_entries = count ;
2004-05-08 18:42:45 +04:00
2018-10-18 03:54:31 +03:00
/*
* Signal no more results by returning zero resume handle ,
* the cache is also cleared at this point
*/
if ( * r - > out . resume_handle > = cache - > size ) {
* r - > out . resume_handle = 0 ;
clear_guid_cache ( cache ) ;
2007-07-26 11:27:46 +04:00
return NT_STATUS_OK ;
}
2018-10-18 03:54:31 +03:00
/*
* There are more results to be returned .
*/
return STATUS_MORE_ENTRIES ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_CreateDomAlias
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_CreateDomAlias ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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 ;
2010-05-21 02:21:37 +04:00
const char * alias_name ;
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 ;
2010-05-21 02:21:37 +04:00
struct ldb_dn * dn ;
NTSTATUS status ;
2004-12-23 01:19:54 +03:00
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 ;
2008-03-14 04:26:03 +03:00
if ( d_state - > builtin ) {
DEBUG ( 5 , ( " Cannot create a domain alias in the BUILTIN domain " ) ) ;
return NT_STATUS_ACCESS_DENIED ;
}
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 ;
}
2010-05-21 02:21:37 +04:00
status = dsdb_add_domain_alias ( d_state - > sam_ctx , mem_ctx , alias_name , & sid , & dn ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2004-12-23 01:19:54 +03:00
}
2009-10-23 19:30:47 +04:00
a_state = talloc ( mem_ctx , 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 ) ;
2010-05-21 02:21:37 +04:00
a_state - > account_dn = talloc_steal ( a_state , dn ) ;
2005-03-28 03:31:43 +04:00
2010-05-21 02:21:37 +04:00
a_state - > account_name = talloc_steal ( a_state , alias_name ) ;
2004-12-23 01:19:54 +03:00
/* 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
}
2010-10-29 12:55:07 +04:00
/*
samr_EnumDomainAliases
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_EnumDomainAliases ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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 ;
2009-11-21 21:26:02 +03:00
int i , ldb_cnt ;
uint32_t first , count ;
2004-12-28 10:57:31 +03:00
struct samr_SamEntry * entries ;
2010-06-12 01:42:14 +04:00
const char * const attrs [ ] = { " objectSid " , " sAMAccountName " , NULL } ;
2008-11-05 15:37:49 +03:00
struct samr_SamArray * sam ;
2004-12-28 10:57:31 +03:00
* r - > out . resume_handle = 0 ;
2008-11-05 15:37:49 +03:00
* r - > out . sam = NULL ;
* r - > out . num_entries = 0 ;
2004-12-28 10:57:31 +03:00
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
d_state = h - > data ;
2004-12-30 20:01:49 +03:00
2010-06-14 13:30:27 +04:00
/* search for all domain aliases in this domain. This could possibly be
2004-12-28 10:57:31 +03:00
cached and resumed based on resume_key */
2010-06-14 13:30:27 +04:00
ldb_cnt = samdb_search_domain ( d_state - > sam_ctx , mem_ctx , NULL ,
2010-10-29 12:55:07 +04:00
& res , attrs ,
2005-06-24 04:18:20 +04:00
d_state - > domain_sid ,
2006-06-13 00:00:18 +04:00
" (&(|(grouptype=%d)(grouptype=%d))) "
2004-12-30 20:01:49 +03:00
" (objectclass=group)) " ,
2006-06-13 00:00:18 +04:00
GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ,
GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ) ;
2010-06-12 01:42:14 +04:00
if ( ldb_cnt < 0 ) {
2004-12-28 10:57:31 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
/* 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 " ) ;
2010-06-12 13:39:25 +04:00
if ( alias_sid = = NULL ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2004-12-28 10:57:31 +03:00
entries [ count ] . idx =
alias_sid - > sub_auths [ alias_sid - > num_auths - 1 ] ;
entries [ count ] . name . string =
2010-10-14 11:41:42 +04:00
ldb_msg_find_attr_as_string ( res [ i ] , " sAMAccountName " , " " ) ;
2004-12-28 10:57:31 +03:00
count + = 1 ;
}
/* sort the results by rid */
2010-02-13 05:00:55 +03:00
TYPESAFE_QSORT ( entries , count , compare_SamEntry ) ;
2004-12-28 10:57:31 +03:00
/* find the first entry to return */
for ( first = 0 ;
first < count & & entries [ first ] . idx < = * r - > in . resume_handle ;
first + + ) ;
2010-06-12 01:42:14 +04:00
/* return the rest, limit by max_size. Note that we
use the w2k3 element size value of 54 */
2008-11-05 15:37:49 +03:00
* r - > out . num_entries = count - first ;
2010-06-12 01:42:14 +04:00
* r - > out . num_entries = MIN ( * r - > out . num_entries ,
1 + ( r - > in . max_size / SAMR_ENUM_USERS_MULTIPLIER ) ) ;
2004-12-28 10:57:31 +03:00
2008-11-05 15:37:49 +03:00
sam = talloc ( mem_ctx , struct samr_SamArray ) ;
if ( ! sam ) {
2004-12-28 10:57:31 +03:00
return NT_STATUS_NO_MEMORY ;
}
2008-11-05 15:37:49 +03:00
sam - > entries = entries + first ;
sam - > count = * r - > out . num_entries ;
2004-12-28 10:57:31 +03:00
2008-11-05 15:37:49 +03:00
* r - > out . sam = sam ;
2010-06-12 01:42:14 +04:00
if ( first = = count ) {
return NT_STATUS_OK ;
}
2008-11-05 15:37:49 +03:00
if ( * r - > out . num_entries < count - first ) {
2004-12-28 10:57:31 +03:00
* r - > out . resume_handle =
2008-11-05 15:37:49 +03:00
entries [ first + * r - > out . num_entries - 1 ] . idx ;
2004-12-28 10:57:31 +03:00
return STATUS_MORE_ENTRIES ;
}
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_GetAliasMembership
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_GetAliasMembership ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
struct samr_GetAliasMembership * r )
{
2004-12-30 01:57:20 +03:00
struct dcesrv_handle * h ;
struct samr_domain_state * d_state ;
2016-05-11 04:02:03 +03:00
char * filter ;
2010-06-12 14:14:59 +04:00
const char * const attrs [ ] = { " objectSid " , NULL } ;
2004-12-30 01:57:20 +03:00
struct ldb_message * * res ;
2010-06-10 14:42:04 +04:00
uint32_t i ;
int count = 0 ;
2004-12-30 01:57:20 +03:00
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
d_state = h - > data ;
2010-06-12 14:14:59 +04:00
filter = talloc_asprintf ( mem_ctx ,
" (&(|(grouptype=%d)(grouptype=%d)) "
" (objectclass=group)(| " ,
GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ,
GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ) ;
if ( filter = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2004-12-30 01:57:20 +03:00
2010-06-12 14:14:59 +04:00
for ( i = 0 ; i < r - > in . sids - > num_sids ; i + + ) {
2018-10-18 06:55:24 +03:00
struct dom_sid_buf buf ;
filter = talloc_asprintf_append (
filter ,
" (member=<SID=%s>) " ,
dom_sid_str_buf ( r - > in . sids - > sids [ i ] . sid , & buf ) ) ;
2004-12-30 01:57:20 +03:00
2010-06-12 14:14:59 +04:00
if ( filter = = NULL ) {
return NT_STATUS_NO_MEMORY ;
2004-12-30 01:57:20 +03:00
}
2010-06-12 14:14:59 +04:00
}
2004-12-30 01:57:20 +03:00
2010-06-12 14:14:59 +04:00
/* Find out if we had at least one valid member SID passed - otherwise
* just skip the search . */
if ( strstr ( filter , " member " ) ! = NULL ) {
2010-06-14 13:30:27 +04:00
count = samdb_search_domain ( d_state - > sam_ctx , mem_ctx , NULL ,
& res , attrs , d_state - > domain_sid ,
" %s)) " , filter ) ;
2010-06-12 14:14:59 +04:00
if ( count < 0 ) {
2004-12-30 01:57:20 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2010-06-12 14:14:59 +04:00
}
2004-12-30 01:57:20 +03:00
}
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 ) {
2010-06-12 14:14:59 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2004-12-30 01:57:20 +03:00
}
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
}
2010-10-29 12:55:07 +04:00
/*
samr_LookupNames
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_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 ;
2009-11-21 21:26:02 +03:00
uint32_t i , num_mapped ;
2004-05-08 04:02:31 +04:00
NTSTATUS status = NT_STATUS_OK ;
const char * const attrs [ ] = { " sAMAccountType " , " objectSid " , NULL } ;
int count ;
2008-11-05 16:28:17 +03:00
ZERO_STRUCTP ( r - > out . rids ) ;
ZERO_STRUCTP ( r - > out . types ) ;
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
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 ;
}
2008-11-05 16:28:17 +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 ) ;
if ( ! r - > out . rids - > ids | | ! r - > out . types - > ids ) {
2004-05-08 04:02:31 +04:00
return NT_STATUS_NO_MEMORY ;
}
2008-11-05 16:28:17 +03:00
r - > out . rids - > count = r - > in . num_names ;
r - > out . types - > count = r - > in . num_names ;
2004-05-08 04:02:31 +04:00
2007-06-06 16:51:45 +04:00
num_mapped = 0 ;
2004-05-08 04:02:31 +04:00
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
2008-11-05 16:28:17 +03:00
r - > out . rids - > ids [ i ] = 0 ;
r - > out . types - > ids [ i ] = SID_NAME_UNKNOWN ;
2004-05-08 04:02:31 +04:00
2010-10-29 12:55:07 +04:00
count = gendb_search ( d_state - > sam_ctx , mem_ctx , d_state - > domain_dn , & res , attrs ,
" sAMAccountName=%s " ,
2005-12-19 10:07:11 +03:00
ldb_binary_encode_string ( mem_ctx , 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 ;
}
2010-10-29 12:55:07 +04:00
2010-10-14 11:41:42 +04:00
atype = ldb_msg_find_attr_as_uint ( res [ 0 ] , " sAMAccountType " , 0 ) ;
2004-05-08 04:02:31 +04:00
if ( atype = = 0 ) {
status = STATUS_SOME_UNMAPPED ;
continue ;
}
2009-06-12 17:20:48 +04:00
rtype = ds_atype_map ( atype ) ;
2010-10-29 12:55:07 +04:00
2004-05-15 11:51:38 +04:00
if ( rtype = = SID_NAME_UNKNOWN ) {
2004-05-08 04:02:31 +04:00
status = STATUS_SOME_UNMAPPED ;
continue ;
}
2008-11-05 16:28:17 +03:00
r - > out . rids - > ids [ i ] = sid - > sub_auths [ sid - > num_auths - 1 ] ;
r - > out . types - > ids [ i ] = rtype ;
2007-06-06 16:51:45 +04:00
num_mapped + + ;
2004-05-08 04:02:31 +04:00
}
2010-10-29 12:55:07 +04:00
2007-06-06 16:51:45 +04:00
if ( num_mapped = = 0 ) {
return NT_STATUS_NONE_MAPPED ;
}
2004-05-08 04:02:31 +04:00
return status ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_LookupRids
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_LookupRids ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
struct samr_LookupRids * r )
{
2010-05-23 18:57:32 +04:00
NTSTATUS status ;
2004-12-27 02:31:19 +03:00
struct dcesrv_handle * h ;
struct samr_domain_state * d_state ;
2010-05-23 18:57:32 +04:00
const char * * names ;
struct lsa_String * lsa_names ;
2010-06-21 00:03:45 +04:00
enum lsa_SidType * ids ;
2004-12-27 02:31:19 +03:00
2008-11-05 04:12:38 +03:00
ZERO_STRUCTP ( r - > out . names ) ;
ZERO_STRUCTP ( r - > out . types ) ;
2004-12-27 02:31:19 +03:00
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 ;
2010-05-23 18:57:32 +04:00
lsa_names = talloc_zero_array ( mem_ctx , struct lsa_String , r - > in . num_rids ) ;
names = talloc_zero_array ( mem_ctx , const char * , r - > in . num_rids ) ;
2010-06-21 00:03:45 +04:00
ids = talloc_zero_array ( mem_ctx , enum lsa_SidType , r - > in . num_rids ) ;
2004-12-27 02:31:19 +03:00
2010-05-23 18:57:32 +04:00
if ( ( lsa_names = = NULL ) | | ( names = = NULL ) | | ( ids = = NULL ) )
2004-12-27 02:31:19 +03:00
return NT_STATUS_NO_MEMORY ;
2010-05-23 18:57:32 +04:00
r - > out . names - > names = lsa_names ;
2008-11-05 04:12:38 +03:00
r - > out . names - > count = r - > in . num_rids ;
2004-12-27 12:48:49 +03:00
2010-06-21 00:03:45 +04:00
r - > out . types - > ids = ( uint32_t * ) ids ;
2008-11-05 04:12:38 +03:00
r - > out . types - > count = r - > in . num_rids ;
2004-12-27 12:48:49 +03:00
2010-05-23 18:57:32 +04:00
status = dsdb_lookup_rids ( d_state - > sam_ctx , mem_ctx , d_state - > domain_sid ,
r - > in . num_rids , r - > in . rids , names , ids ) ;
if ( NT_STATUS_IS_OK ( status ) | | NT_STATUS_EQUAL ( status , NT_STATUS_NONE_MAPPED ) | | NT_STATUS_EQUAL ( status , STATUS_SOME_UNMAPPED ) ) {
uint32_t i ;
for ( i = 0 ; i < r - > in . num_rids ; i + + ) {
lsa_names [ i ] . string = names [ i ] ;
}
}
2004-12-27 02:31:19 +03:00
return status ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_OpenGroup
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_OpenGroup ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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 */
2014-04-29 15:31:42 +04:00
if ( d_state - > builtin ) {
ret = gendb_search ( d_state - > sam_ctx ,
mem_ctx , d_state - > domain_dn , & msgs , attrs ,
" (&(objectSid=%s)(objectClass=group) "
" (groupType=%d)) " ,
ldap_encode_ndr_dom_sid ( mem_ctx , sid ) ,
GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ) ;
} else {
ret = gendb_search ( d_state - > sam_ctx ,
mem_ctx , d_state - > domain_dn , & msgs , attrs ,
" (&(objectSid=%s)(objectClass=group) "
" (|(groupType=%d)(groupType=%d))) " ,
ldap_encode_ndr_dom_sid ( mem_ctx , sid ) ,
GTYPE_SECURITY_UNIVERSAL_GROUP ,
GTYPE_SECURITY_GLOBAL_GROUP ) ;
}
2004-05-09 19:39:12 +04:00
if ( ret = = 0 ) {
return NT_STATUS_NO_SUCH_GROUP ;
}
if ( ret ! = 1 ) {
2010-10-29 12:55:07 +04:00
DEBUG ( 0 , ( " Found %d records matching sid %s \n " ,
2005-06-24 04:18:20 +04:00
ret , dom_sid_string ( mem_ctx , sid ) ) ) ;
2004-05-09 19:39:12 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2010-10-14 11:41:42 +04:00
groupname = ldb_msg_find_attr_as_string ( msgs [ 0 ] , " sAMAccountName " , NULL ) ;
2004-05-09 19:39:12 +04:00
if ( groupname = = NULL ) {
2010-10-29 12:55:07 +04:00
DEBUG ( 0 , ( " sAMAccountName field missing for sid %s \n " ,
2005-06-24 04:18:20 +04:00
dom_sid_string ( mem_ctx , sid ) ) ) ;
2004-05-09 19:39:12 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2009-10-23 19:30:47 +04:00
a_state = talloc ( mem_ctx , 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
}
2010-10-29 12:55:07 +04:00
/*
samr_QueryGroupInfo
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_QueryGroupInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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 ;
2010-06-12 02:06:07 +04:00
struct ldb_message * msg , * * res ;
2004-05-09 19:39:12 +04:00
const char * const attrs [ 4 ] = { " sAMAccountName " , " description " ,
" numMembers " , NULL } ;
int ret ;
2008-11-10 13:26:43 +03:00
union samr_GroupInfo * info ;
2004-05-09 19:39:12 +04:00
2008-11-10 16:15:33 +03:00
* r - > out . info = NULL ;
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 ;
2010-10-29 12:55:07 +04:00
2010-06-12 02:06:07 +04:00
/* pull all the group attributes */
ret = gendb_search_dn ( a_state - > sam_ctx , mem_ctx ,
a_state - > account_dn , & res , attrs ) ;
if ( ret = = 0 ) {
2008-03-13 09:26:01 +03:00
return NT_STATUS_NO_SUCH_GROUP ;
}
2010-06-12 02:06:07 +04:00
if ( ret ! = 1 ) {
2004-05-09 19:39:12 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2010-06-12 02:06:07 +04:00
msg = res [ 0 ] ;
2004-05-09 19:39:12 +04:00
/* allocate the info structure */
2008-11-10 13:26:43 +03:00
info = talloc_zero ( mem_ctx , union samr_GroupInfo ) ;
if ( info = = NULL ) {
2004-05-09 19:39:12 +04:00
return NT_STATUS_NO_MEMORY ;
}
/* Fill in the level */
switch ( r - > in . level ) {
2005-01-29 05:46:37 +03:00
case GROUPINFOALL :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , all . name , " sAMAccountName " ) ;
2008-11-10 13:26:43 +03:00
info - > all . attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED ; /* Do like w2k3 */
2004-05-09 19:39:12 +04:00
QUERY_UINT ( msg , all . num_members , " numMembers " )
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , all . description , " description " ) ;
2004-05-09 19:39:12 +04:00
break ;
2005-01-29 05:46:37 +03:00
case GROUPINFONAME :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , name , " sAMAccountName " ) ;
2004-05-09 19:39:12 +04:00
break ;
2006-07-03 08:00:10 +04:00
case GROUPINFOATTRIBUTES :
2008-11-10 13:26:43 +03:00
info - > attributes . attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED ; /* Do like w2k3 */
2004-05-09 19:39:12 +04:00
break ;
2005-01-29 05:46:37 +03:00
case GROUPINFODESCRIPTION :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , description , " description " ) ;
2004-05-09 19:39:12 +04:00
break ;
2006-07-03 08:00:10 +04:00
case GROUPINFOALL2 :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , all2 . name , " sAMAccountName " ) ;
2008-11-10 13:26:43 +03:00
info - > all . attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED ; /* Do like w2k3 */
2006-07-03 08:00:10 +04:00
QUERY_UINT ( msg , all2 . num_members , " numMembers " )
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , all2 . description , " description " ) ;
2006-07-03 08:00:10 +04:00
break ;
2004-05-09 19:39:12 +04:00
default :
2008-11-10 13:26:43 +03:00
talloc_free ( info ) ;
2004-05-09 19:39:12 +04:00
return NT_STATUS_INVALID_INFO_CLASS ;
}
2008-11-10 13:26:43 +03:00
2008-11-10 16:15:33 +03:00
* r - > out . info = info ;
2008-11-10 13:26:43 +03:00
2004-05-09 19:39:12 +04:00
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_SetGroupInfo
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_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 ;
2006-07-04 06:46:24 +04:00
struct samr_account_state * g_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
2006-07-04 06:46:24 +04:00
g_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 ;
2010-10-29 12:55:07 +04:00
}
2005-01-02 10:51:13 +03:00
2006-07-04 06:46:24 +04:00
msg - > dn = ldb_dn_copy ( mem_ctx , g_state - > account_dn ) ;
2005-01-02 10:51:13 +03:00
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 :
2007-07-27 06:07:17 +04:00
SET_STRING ( msg , description , " 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 */
2007-07-27 06:07:17 +04:00
SET_STRING ( msg , name , " sAMAccountName " ) ;
2004-05-09 19:39:12 +04:00
break ;
2006-07-03 08:00:10 +04:00
case GROUPINFOATTRIBUTES :
2004-05-09 19:39:12 +04:00
/* This does not do anything obviously visible in W2k3 LDAP */
2006-09-21 09:44:39 +04:00
return NT_STATUS_OK ;
2004-05-09 19:39:12 +04:00
default :
return NT_STATUS_INVALID_INFO_CLASS ;
}
/* modify the samdb record */
2007-07-27 06:07:17 +04:00
ret = ldb_modify ( g_state - > sam_ctx , msg ) ;
2009-10-13 02:15:19 +04:00
if ( ret ! = LDB_SUCCESS ) {
2011-04-01 08:58:55 +04:00
return dsdb_ldb_err_to_ntstatus ( ret ) ;
2004-05-09 19:39:12 +04:00
}
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_AddGroupMember
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_AddGroupMember ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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 ;
2006-07-04 06:46:24 +04:00
struct ldb_result * res ;
const char * const attrs [ ] = { NULL } ;
2004-12-26 21:02:18 +03:00
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 ) ;
2009-10-13 02:15:19 +04:00
if ( membersid = = NULL ) {
2004-12-26 21:02:18 +03:00
return NT_STATUS_NO_MEMORY ;
2009-10-13 02:15:19 +04:00
}
2004-12-26 21:02:18 +03:00
2010-06-10 13:50:12 +04:00
/* according to MS-SAMR 3.1.5.8.2 all type of accounts are accepted */
2008-09-23 22:30:06 +04:00
ret = ldb_search ( d_state - > sam_ctx , mem_ctx , & res ,
2010-06-10 13:50:12 +04:00
d_state - > domain_dn , LDB_SCOPE_SUBTREE , attrs ,
" (objectSid=%s) " ,
ldap_encode_ndr_dom_sid ( mem_ctx , membersid ) ) ;
2004-12-26 21:02:18 +03:00
2009-10-13 02:15:19 +04:00
if ( ret ! = LDB_SUCCESS ) {
2006-07-04 06:46:24 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2004-12-26 21:02:18 +03:00
2006-07-04 06:46:24 +04:00
if ( res - > count = = 0 ) {
return NT_STATUS_NO_SUCH_USER ;
}
2010-10-29 12:55:07 +04:00
2006-07-04 06:46:24 +04:00
if ( res - > count > 1 ) {
2004-12-26 21:02:18 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2006-07-04 06:46:24 +04:00
}
2004-12-26 21:02:18 +03:00
2006-11-22 05:05:19 +03:00
memberdn = ldb_dn_alloc_linearized ( mem_ctx , res - > msgs [ 0 ] - > dn ) ;
2004-12-26 21:02:18 +03:00
if ( memberdn = = NULL )
2006-07-04 06:46:24 +04:00
return NT_STATUS_NO_MEMORY ;
2004-12-26 21:02:18 +03:00
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 ) ;
2009-10-13 02:15:19 +04:00
ret = samdb_msg_add_addval ( d_state - > sam_ctx , mem_ctx , mod , " member " ,
memberdn ) ;
if ( ret ! = LDB_SUCCESS ) {
2011-04-01 08:58:55 +04:00
return dsdb_ldb_err_to_ntstatus ( ret ) ;
2009-10-13 02:15:19 +04:00
}
2004-12-26 21:02:18 +03:00
2007-07-27 06:07:17 +04:00
ret = ldb_modify ( a_state - > sam_ctx , mod ) ;
2006-07-04 06:46:24 +04:00
switch ( ret ) {
case LDB_SUCCESS :
return NT_STATUS_OK ;
2010-06-10 13:48:33 +04:00
case LDB_ERR_ENTRY_ALREADY_EXISTS :
2006-07-04 06:46:24 +04:00
return NT_STATUS_MEMBER_IN_GROUP ;
2006-11-25 21:57:47 +03:00
case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS :
return NT_STATUS_ACCESS_DENIED ;
2006-07-04 06:46:24 +04:00
default :
2011-04-01 08:58:55 +04:00
return dsdb_ldb_err_to_ntstatus ( ret ) ;
2006-07-04 06:46:24 +04:00
}
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_DeleteDomainGroup
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_DeleteDomainGroup ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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
2007-11-27 03:25:11 +03:00
ret = ldb_delete ( a_state - > sam_ctx , a_state - > account_dn ) ;
2009-10-13 02:15:19 +04:00
if ( ret ! = LDB_SUCCESS ) {
2011-04-01 08:58:55 +04:00
return dsdb_ldb_err_to_ntstatus ( ret ) ;
2004-05-09 19:39:12 +04:00
}
2009-10-21 09:07:22 +04:00
talloc_free ( h ) ;
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
}
2010-10-29 12:55:07 +04:00
/*
samr_DeleteGroupMember
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_DeleteGroupMember ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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 ;
2006-07-04 06:46:24 +04:00
struct ldb_result * res ;
const char * const attrs [ ] = { NULL } ;
2004-12-26 21:02:18 +03:00
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 ) ;
2010-06-10 13:50:12 +04:00
if ( membersid = = NULL ) {
2004-12-26 21:02:18 +03:00
return NT_STATUS_NO_MEMORY ;
2010-06-10 13:50:12 +04:00
}
2004-12-26 21:02:18 +03:00
2010-06-10 13:50:12 +04:00
/* according to MS-SAMR 3.1.5.8.2 all type of accounts are accepted */
2008-09-23 22:30:06 +04:00
ret = ldb_search ( d_state - > sam_ctx , mem_ctx , & res ,
2010-06-10 13:50:12 +04:00
d_state - > domain_dn , LDB_SCOPE_SUBTREE , attrs ,
" (objectSid=%s) " ,
ldap_encode_ndr_dom_sid ( mem_ctx , membersid ) ) ;
2004-12-26 21:02:18 +03:00
2009-10-13 02:15:19 +04:00
if ( ret ! = LDB_SUCCESS ) {
2006-07-04 06:46:24 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2004-12-26 21:02:18 +03:00
2006-07-04 06:46:24 +04:00
if ( res - > count = = 0 ) {
return NT_STATUS_NO_SUCH_USER ;
}
2010-10-29 12:55:07 +04:00
2006-07-04 06:46:24 +04:00
if ( res - > count > 1 ) {
2004-12-26 21:02:18 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2006-07-04 06:46:24 +04:00
}
2004-12-26 21:02:18 +03:00
2006-11-22 05:05:19 +03:00
memberdn = ldb_dn_alloc_linearized ( mem_ctx , res - > msgs [ 0 ] - > dn ) ;
2004-12-26 21:02:18 +03:00
if ( memberdn = = NULL )
2006-07-04 06:46:24 +04:00
return NT_STATUS_NO_MEMORY ;
2004-12-26 21:02:18 +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 ( mem_ctx , a_state - > account_dn ) ;
2004-12-26 21:02:18 +03:00
2009-10-13 02:15:19 +04:00
ret = samdb_msg_add_delval ( d_state - > sam_ctx , mem_ctx , mod , " member " ,
memberdn ) ;
if ( ret ! = LDB_SUCCESS ) {
2006-07-04 06:46:24 +04:00
return NT_STATUS_NO_MEMORY ;
}
2004-12-26 21:02:18 +03:00
2007-07-27 06:07:17 +04:00
ret = ldb_modify ( a_state - > sam_ctx , mod ) ;
2006-07-04 06:46:24 +04:00
switch ( ret ) {
case LDB_SUCCESS :
return NT_STATUS_OK ;
2010-10-30 20:32:43 +04:00
case LDB_ERR_UNWILLING_TO_PERFORM :
2006-07-04 06:46:24 +04:00
return NT_STATUS_MEMBER_NOT_IN_GROUP ;
2006-11-25 21:57:47 +03:00
case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS :
return NT_STATUS_ACCESS_DENIED ;
2006-07-04 06:46:24 +04:00
default :
2011-04-01 08:58:55 +04:00
return dsdb_ldb_err_to_ntstatus ( ret ) ;
2006-07-04 06:46:24 +04:00
}
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_QueryGroupMember
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_QueryGroupMember ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-09-02 03:26:50 +04:00
struct samr_QueryGroupMember * r )
2004-05-03 18:58:08 +04:00
{
2004-12-26 21:02:18 +03:00
struct dcesrv_handle * h ;
struct samr_account_state * a_state ;
2010-06-12 19:45:14 +04:00
struct samr_domain_state * d_state ;
2010-10-07 15:01:29 +04:00
struct samr_RidAttrArray * array ;
2010-05-25 00:01:36 +04:00
unsigned int i , num_members ;
2010-06-12 19:45:14 +04:00
struct dom_sid * members ;
NTSTATUS status ;
2004-12-26 21:02:18 +03:00
DCESRV_PULL_HANDLE ( h , r - > in . group_handle , SAMR_HANDLE_GROUP ) ;
a_state = h - > data ;
2010-06-12 19:45:14 +04:00
d_state = a_state - > domain_state ;
2004-12-26 21:02:18 +03:00
2010-06-12 19:45:14 +04:00
status = dsdb_enum_group_mem ( d_state - > sam_ctx , mem_ctx ,
a_state - > account_dn , & members ,
& num_members ) ;
2010-05-21 02:42:21 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2004-12-26 21:02:18 +03:00
}
2010-10-07 15:01:29 +04:00
array = talloc_zero ( mem_ctx , struct samr_RidAttrArray ) ;
2010-06-12 19:45:14 +04:00
if ( array = = NULL ) {
2004-12-26 21:02:18 +03:00
return NT_STATUS_NO_MEMORY ;
2010-06-12 19:45:14 +04:00
}
2004-12-26 21:02:18 +03:00
2010-05-21 02:42:21 +04:00
if ( num_members = = 0 ) {
* r - > out . rids = array ;
2004-12-26 21:02:18 +03:00
2010-05-21 02:42:21 +04:00
return NT_STATUS_OK ;
}
2004-12-26 21:02:18 +03:00
2010-06-12 19:45:14 +04:00
array - > rids = talloc_array ( array , uint32_t , num_members ) ;
if ( array - > rids = = NULL ) {
2010-05-21 02:42:21 +04:00
return NT_STATUS_NO_MEMORY ;
2010-06-12 19:45:14 +04:00
}
2004-12-26 21:02:18 +03:00
2010-10-07 15:01:29 +04:00
array - > attributes = talloc_array ( array , uint32_t , num_members ) ;
if ( array - > attributes = = NULL ) {
2010-05-21 02:42:21 +04:00
return NT_STATUS_NO_MEMORY ;
2010-06-12 19:45:14 +04:00
}
2004-12-26 21:02:18 +03:00
2010-06-12 19:45:14 +04:00
array - > count = 0 ;
2010-05-21 02:42:21 +04:00
for ( i = 0 ; i < num_members ; i + + ) {
2010-06-12 19:45:14 +04:00
if ( ! dom_sid_in_domain ( d_state - > domain_sid , & members [ i ] ) ) {
2010-05-21 02:42:21 +04:00
continue ;
2004-12-26 21:02:18 +03:00
}
2010-06-12 19:45:14 +04:00
status = dom_sid_split_rid ( NULL , & members [ i ] , NULL ,
& array - > rids [ array - > count ] ) ;
2010-05-21 02:42:21 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2010-06-12 19:45:14 +04:00
2010-10-07 15:01:29 +04:00
array - > attributes [ array - > count ] = SE_GROUP_MANDATORY |
SE_GROUP_ENABLED_BY_DEFAULT |
SE_GROUP_ENABLED ;
2010-05-21 02:42:21 +04:00
array - > count + + ;
2004-12-26 21:02:18 +03:00
}
2008-11-05 04:00:12 +03:00
* r - > out . rids = array ;
2004-12-26 21:02:18 +03:00
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_SetMemberAttributesOfGroup
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_SetMemberAttributesOfGroup ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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
}
2010-10-29 12:55:07 +04:00
/*
samr_OpenAlias
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_OpenAlias ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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 */
2010-06-14 13:30:27 +04:00
ret = gendb_search ( d_state - > sam_ctx , mem_ctx , NULL , & msgs , attrs ,
2004-12-27 14:27:30 +03:00
" (&(objectSid=%s)(objectclass=group) "
2006-06-13 00:00:18 +04:00
" (|(grouptype=%d)(grouptype=%d))) " ,
2005-06-24 04:18:20 +04:00
ldap_encode_ndr_dom_sid ( mem_ctx , sid ) ,
2006-06-13 00:00:18 +04:00
GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ,
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 ) {
2010-10-29 12:55:07 +04:00
DEBUG ( 0 , ( " Found %d records matching sid %s \n " ,
2005-06-24 04:18:20 +04:00
ret , dom_sid_string ( mem_ctx , sid ) ) ) ;
2004-12-27 14:27:30 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2010-10-14 11:41:42 +04:00
alias_name = ldb_msg_find_attr_as_string ( msgs [ 0 ] , " sAMAccountName " , NULL ) ;
2005-04-13 10:26:43 +04:00
if ( alias_name = = NULL ) {
2010-10-29 12:55:07 +04:00
DEBUG ( 0 , ( " sAMAccountName field missing for sid %s \n " ,
2005-06-24 04:18:20 +04:00
dom_sid_string ( mem_ctx , sid ) ) ) ;
2004-12-27 14:27:30 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2009-10-23 19:30:47 +04:00
a_state = talloc ( mem_ctx , 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
}
2010-10-29 12:55:07 +04:00
/*
samr_QueryAliasInfo
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_QueryAliasInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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 ;
2008-11-10 13:26:43 +03:00
union samr_AliasInfo * info ;
2004-12-27 14:27:30 +03:00
2008-11-10 16:09:06 +03:00
* r - > out . info = NULL ;
2004-12-27 14:27:30 +03:00
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 ,
2010-06-12 02:06:36 +04:00
a_state - > account_dn , & res , attrs ) ;
if ( ret = = 0 ) {
return NT_STATUS_NO_SUCH_ALIAS ;
}
2004-12-27 14:27:30 +03:00
if ( ret ! = 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
msg = res [ 0 ] ;
/* allocate the info structure */
2008-11-10 13:26:43 +03:00
info = talloc_zero ( mem_ctx , union samr_AliasInfo ) ;
if ( info = = NULL ) {
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 ALIASINFOALL :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , all . name , " sAMAccountName " ) ;
2004-12-27 14:27:30 +03:00
QUERY_UINT ( msg , all . num_members , " numMembers " ) ;
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , all . description , " description " ) ;
2004-12-27 14:27:30 +03:00
break ;
2005-01-29 05:46:37 +03:00
case ALIASINFONAME :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , name , " sAMAccountName " ) ;
2004-12-27 14:27:30 +03:00
break ;
2005-01-29 05:46:37 +03:00
case ALIASINFODESCRIPTION :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , description , " description " ) ;
2004-12-27 14:27:30 +03:00
break ;
default :
2008-11-10 13:26:43 +03:00
talloc_free ( info ) ;
2004-12-27 14:27:30 +03:00
return NT_STATUS_INVALID_INFO_CLASS ;
}
2008-11-10 13:26:43 +03:00
2008-11-10 16:09:06 +03:00
* r - > out . info = info ;
2008-11-10 13:26:43 +03:00
2004-12-27 14:27:30 +03:00
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_SetAliasInfo
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_SetAliasInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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 ;
}
2005-08-18 19:02:01 +04:00
msg - > dn = ldb_dn_copy ( mem_ctx , a_state - > account_dn ) ;
2005-01-02 10:51:13 +03:00
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 :
2007-07-27 06:07:17 +04:00
SET_STRING ( msg , description , " description " ) ;
2004-12-27 14:27:30 +03:00
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 */
2007-07-27 06:07:17 +04:00
SET_STRING ( msg , name , " sAMAccountName " ) ;
2004-12-27 14:27:30 +03:00
break ;
default :
return NT_STATUS_INVALID_INFO_CLASS ;
}
/* modify the samdb record */
2007-07-27 06:07:17 +04:00
ret = ldb_modify ( a_state - > sam_ctx , msg ) ;
2009-10-13 19:29:52 +04:00
if ( ret ! = LDB_SUCCESS ) {
2011-04-01 08:58:55 +04:00
return dsdb_ldb_err_to_ntstatus ( ret ) ;
2004-12-27 14:27:30 +03:00
}
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_DeleteDomAlias
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_DeleteDomAlias ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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 ;
2007-11-27 03:25:11 +03:00
ret = ldb_delete ( a_state - > sam_ctx , a_state - > account_dn ) ;
2009-11-21 21:25:42 +03:00
if ( ret ! = LDB_SUCCESS ) {
2011-04-01 08:58:55 +04:00
return dsdb_ldb_err_to_ntstatus ( ret ) ;
2005-03-28 03:31:43 +04:00
}
2009-10-21 09:07:22 +04:00
talloc_free ( h ) ;
2005-03-28 03:31:43 +04:00
ZERO_STRUCTP ( r - > out . alias_handle ) ;
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_AddAliasMember
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_AddAliasMember ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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 ;
2006-07-04 06:46:24 +04:00
const char * const attrs [ ] = { NULL } ;
2005-08-18 19:02:01 +04:00
struct ldb_dn * memberdn = NULL ;
2004-12-28 01:20:17 +03:00
int ret ;
2006-07-06 09:23:29 +04:00
NTSTATUS status ;
2004-12-28 01:20:17 +03:00
DCESRV_PULL_HANDLE ( h , r - > in . alias_handle , SAMR_HANDLE_ALIAS ) ;
a_state = h - > data ;
d_state = a_state - > domain_state ;
2006-08-25 11:08:06 +04:00
ret = gendb_search ( d_state - > sam_ctx , mem_ctx , NULL ,
2010-10-29 12:55:07 +04:00
& msgs , attrs , " (objectsid=%s) " ,
2005-06-24 04:18:20 +04:00
ldap_encode_ndr_dom_sid ( mem_ctx , r - > in . sid ) ) ;
2004-12-28 01:20:17 +03:00
if ( ret = = 1 ) {
2006-07-04 06:46:24 +04:00
memberdn = msgs [ 0 ] - > dn ;
2004-12-28 01:20:17 +03:00
} else if ( ret = = 0 ) {
2009-08-18 00:34:08 +04:00
status = samdb_create_foreign_security_principal (
d_state - > sam_ctx , mem_ctx , r - > in . sid , & memberdn ) ;
2006-07-06 09:23:29 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2004-12-28 01:20:17 +03:00
}
} else {
2010-06-10 14:17:48 +04:00
DEBUG ( 0 , ( " Found %d records matching sid %s \n " ,
ret , dom_sid_string ( mem_ctx , r - > in . sid ) ) ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2004-12-28 01:20:17 +03:00
}
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
2009-10-13 02:15:19 +04:00
ret = samdb_msg_add_addval ( d_state - > sam_ctx , mem_ctx , mod , " member " ,
ldb_dn_alloc_linearized ( mem_ctx , memberdn ) ) ;
if ( ret ! = LDB_SUCCESS ) {
2011-04-01 08:58:55 +04:00
return dsdb_ldb_err_to_ntstatus ( ret ) ;
2009-10-13 02:15:19 +04:00
}
2004-12-28 01:20:17 +03:00
2010-06-10 17:47:48 +04:00
ret = ldb_modify ( a_state - > sam_ctx , mod ) ;
switch ( ret ) {
case LDB_SUCCESS :
return NT_STATUS_OK ;
case LDB_ERR_ENTRY_ALREADY_EXISTS :
return NT_STATUS_MEMBER_IN_GROUP ;
case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS :
return NT_STATUS_ACCESS_DENIED ;
default :
2011-04-01 08:58:55 +04:00
return dsdb_ldb_err_to_ntstatus ( ret ) ;
2009-10-13 02:15:19 +04:00
}
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_DeleteAliasMember
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_DeleteAliasMember ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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 ;
2009-10-13 02:15:19 +04:00
int ret ;
2004-12-28 01:20:17 +03:00
DCESRV_PULL_HANDLE ( h , r - > in . alias_handle , SAMR_HANDLE_ALIAS ) ;
a_state = h - > data ;
d_state = a_state - > domain_state ;
2006-08-25 11:08:06 +04:00
memberdn = samdb_search_string ( d_state - > sam_ctx , mem_ctx , NULL ,
2010-10-29 12:55:07 +04:00
" distinguishedName " , " (objectSid=%s) " ,
2005-06-24 04:18:20 +04:00
ldap_encode_ndr_dom_sid ( mem_ctx , r - > in . sid ) ) ;
2010-06-10 14:19:04 +04:00
if ( memberdn = = NULL ) {
2004-12-28 01:20:17 +03:00
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
2010-06-10 14:19:04 +04:00
}
2004-12-28 01:20:17 +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 ( mem_ctx , a_state - > account_dn ) ;
2004-12-28 01:20:17 +03:00
2009-10-13 02:15:19 +04:00
ret = samdb_msg_add_delval ( d_state - > sam_ctx , mem_ctx , mod , " member " ,
memberdn ) ;
2010-06-10 14:19:04 +04:00
if ( ret ! = LDB_SUCCESS ) {
2011-04-01 08:58:55 +04:00
return dsdb_ldb_err_to_ntstatus ( ret ) ;
2010-06-10 14:19:04 +04:00
}
2004-12-28 01:20:17 +03:00
2010-06-10 17:47:48 +04:00
ret = ldb_modify ( a_state - > sam_ctx , mod ) ;
switch ( ret ) {
case LDB_SUCCESS :
return NT_STATUS_OK ;
2010-10-30 20:32:43 +04:00
case LDB_ERR_UNWILLING_TO_PERFORM :
2010-06-10 17:47:48 +04:00
return NT_STATUS_MEMBER_NOT_IN_GROUP ;
case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS :
return NT_STATUS_ACCESS_DENIED ;
default :
2011-04-01 08:58:55 +04:00
return dsdb_ldb_err_to_ntstatus ( ret ) ;
2010-06-10 14:19:04 +04:00
}
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_GetMembersInAlias
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_GetMembersInAlias ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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 ;
2010-06-12 19:45:14 +04:00
struct lsa_SidPtr * array ;
2010-05-25 00:01:36 +04:00
unsigned int i , num_members ;
2010-05-21 02:42:21 +04:00
struct dom_sid * members ;
NTSTATUS status ;
2010-06-12 19:45:14 +04:00
2004-12-28 01:20:17 +03:00
DCESRV_PULL_HANDLE ( h , r - > in . alias_handle , SAMR_HANDLE_ALIAS ) ;
a_state = h - > data ;
d_state = a_state - > domain_state ;
2010-05-21 02:42:21 +04:00
status = dsdb_enum_group_mem ( d_state - > sam_ctx , mem_ctx ,
2010-06-12 19:45:14 +04:00
a_state - > account_dn , & members ,
& num_members ) ;
2010-05-21 02:42:21 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2008-11-04 07:48:10 +03:00
}
2004-12-28 01:20:17 +03:00
2010-05-21 02:42:21 +04:00
if ( num_members = = 0 ) {
2010-06-12 19:45:14 +04:00
r - > out . sids - > sids = NULL ;
2010-05-21 02:42:21 +04:00
return NT_STATUS_OK ;
}
2004-12-28 01:20:17 +03:00
2010-06-12 19:45:14 +04:00
array = talloc_array ( mem_ctx , struct lsa_SidPtr , num_members ) ;
if ( array = = NULL ) {
2010-05-21 02:42:21 +04:00
return NT_STATUS_NO_MEMORY ;
2010-06-12 19:45:14 +04:00
}
2004-12-28 01:20:17 +03:00
2010-05-21 02:42:21 +04:00
for ( i = 0 ; i < num_members ; i + + ) {
2010-06-12 19:45:14 +04:00
array [ i ] . sid = & members [ i ] ;
2004-12-28 01:20:17 +03:00
}
2010-05-25 00:01:36 +04:00
2010-05-21 02:42:21 +04:00
r - > out . sids - > num_sids = num_members ;
2010-06-12 19:45:14 +04:00
r - > out . sids - > sids = array ;
2004-12-28 01:20:17 +03:00
return NT_STATUS_OK ;
}
2004-05-03 18:58:08 +04:00
2010-10-29 12:55:07 +04:00
/*
samr_OpenUser
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_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 ,
2010-10-29 12:55:07 +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 ) {
2010-10-29 12:55:07 +04:00
DEBUG ( 0 , ( " Found %d records matching sid %s \n " , ret ,
2005-06-24 04:18:20 +04:00
dom_sid_string ( mem_ctx , sid ) ) ) ;
2004-05-08 04:02:31 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2010-10-14 11:41:42 +04:00
account_name = ldb_msg_find_attr_as_string ( msgs [ 0 ] , " sAMAccountName " , NULL ) ;
2004-06-05 07:22:10 +04:00
if ( account_name = = NULL ) {
2010-10-29 12:55:07 +04:00
DEBUG ( 0 , ( " sAMAccountName field missing for sid %s \n " ,
2005-06-24 04:18:20 +04:00
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
}
2010-10-29 12:55:07 +04:00
/*
samr_DeleteUser
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_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
2007-11-27 03:25:11 +03:00
ret = ldb_delete ( a_state - > sam_ctx , a_state - > account_dn ) ;
2009-10-13 02:15:19 +04:00
if ( ret ! = LDB_SUCCESS ) {
2010-10-29 12:55:07 +04:00
DEBUG ( 1 , ( " Failed to delete user: %s: %s \n " ,
ldb_dn_get_linearized ( a_state - > account_dn ) ,
2008-01-16 07:48:28 +03:00
ldb_errstring ( a_state - > sam_ctx ) ) ) ;
2011-04-01 08:58:55 +04:00
return dsdb_ldb_err_to_ntstatus ( ret ) ;
2004-05-08 04:02:31 +04:00
}
2009-10-21 09:07:22 +04:00
talloc_free ( h ) ;
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
}
2010-10-29 12:55:07 +04:00
/*
samr_QueryUserInfo
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_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 ;
2006-07-04 06:46:24 +04:00
struct ldb_context * sam_ctx ;
const char * const * attrs = NULL ;
2008-11-10 13:26:43 +03:00
union samr_UserInfo * info ;
2004-05-08 18:42:45 +04:00
2014-06-17 08:03:22 +04:00
NTSTATUS status ;
2008-11-10 16:42:27 +03:00
* r - > out . info = NULL ;
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 ;
2006-07-04 06:46:24 +04:00
sam_ctx = a_state - > sam_ctx ;
/* fill in the reply */
switch ( r - > in . level ) {
case 1 :
{
2009-08-18 00:34:08 +04:00
static const char * const attrs2 [ ] = { " sAMAccountName " ,
" displayName " ,
2016-06-09 05:56:44 +03:00
" primaryGroupID " ,
2009-08-18 00:34:08 +04:00
" description " ,
" comment " ,
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 2 :
{
2009-08-18 00:34:08 +04:00
static const char * const attrs2 [ ] = { " comment " ,
" countryCode " ,
" codePage " ,
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 3 :
{
2007-12-20 02:02:15 +03:00
static const char * const attrs2 [ ] = { " sAMAccountName " ,
2006-07-04 06:46:24 +04:00
" displayName " ,
" objectSid " ,
" primaryGroupID " ,
" homeDirectory " ,
" homeDrive " ,
" scriptPath " ,
" profilePath " ,
" userWorkstations " ,
" lastLogon " ,
" lastLogoff " ,
" pwdLastSet " ,
2016-06-04 01:48:56 +03:00
" msDS-UserPasswordExpiryTimeComputed " ,
2006-07-04 06:46:24 +04:00
" logonHours " ,
" badPwdCount " ,
2014-03-26 02:32:05 +04:00
" badPasswordTime " ,
2006-07-04 06:46:24 +04:00
" logonCount " ,
2009-08-18 00:34:08 +04:00
" userAccountControl " ,
2013-10-29 08:30:18 +04:00
" msDS-User-Account-Control-Computed " ,
2009-08-18 00:34:08 +04:00
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 4 :
{
2009-08-18 00:34:08 +04:00
static const char * const attrs2 [ ] = { " logonHours " ,
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 5 :
{
2010-10-29 12:55:07 +04:00
static const char * const attrs2 [ ] = { " sAMAccountName " ,
2006-07-04 06:46:24 +04:00
" displayName " ,
" objectSid " ,
" primaryGroupID " ,
" homeDirectory " ,
" homeDrive " ,
2010-10-29 12:55:07 +04:00
" scriptPath " ,
2006-07-04 06:46:24 +04:00
" profilePath " ,
" description " ,
" userWorkstations " ,
" lastLogon " ,
" lastLogoff " ,
" logonHours " ,
" badPwdCount " ,
2014-03-26 02:32:05 +04:00
" badPasswordTime " ,
2006-07-04 06:46:24 +04:00
" logonCount " ,
" pwdLastSet " ,
2018-04-11 01:33:21 +03:00
" msDS-ResultantPSO " ,
2016-06-04 01:48:56 +03:00
" msDS-UserPasswordExpiryTimeComputed " ,
2006-07-04 06:46:24 +04:00
" accountExpires " ,
" userAccountControl " ,
2013-10-29 08:30:18 +04:00
" msDS-User-Account-Control-Computed " ,
2006-07-04 06:46:24 +04:00
NULL } ;
attrs = attrs2 ;
break ;
}
case 6 :
{
2009-08-18 00:34:08 +04:00
static const char * const attrs2 [ ] = { " sAMAccountName " ,
" displayName " ,
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 7 :
{
2009-08-18 00:34:08 +04:00
static const char * const attrs2 [ ] = { " sAMAccountName " ,
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 8 :
{
2009-08-18 00:34:08 +04:00
static const char * const attrs2 [ ] = { " displayName " ,
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 9 :
{
2009-08-18 00:34:08 +04:00
static const char * const attrs2 [ ] = { " primaryGroupID " ,
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 10 :
{
2009-08-18 00:34:08 +04:00
static const char * const attrs2 [ ] = { " homeDirectory " ,
" homeDrive " ,
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 11 :
{
2009-08-18 00:34:08 +04:00
static const char * const attrs2 [ ] = { " scriptPath " ,
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 12 :
{
2009-08-18 00:34:08 +04:00
static const char * const attrs2 [ ] = { " profilePath " ,
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 13 :
{
2009-08-18 00:34:08 +04:00
static const char * const attrs2 [ ] = { " description " ,
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 14 :
{
2009-08-18 00:34:08 +04:00
static const char * const attrs2 [ ] = { " userWorkstations " ,
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 16 :
{
2009-08-18 00:34:08 +04:00
static const char * const attrs2 [ ] = { " userAccountControl " ,
2013-10-29 08:30:18 +04:00
" msDS-User-Account-Control-Computed " ,
2009-08-18 00:34:08 +04:00
" pwdLastSet " ,
2016-06-04 01:48:56 +03:00
" msDS-UserPasswordExpiryTimeComputed " ,
2009-08-18 00:34:08 +04:00
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 17 :
{
2009-08-18 00:34:08 +04:00
static const char * const attrs2 [ ] = { " accountExpires " ,
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
2009-11-10 18:26:23 +03:00
case 18 :
{
return NT_STATUS_NOT_SUPPORTED ;
}
2006-07-04 06:46:24 +04:00
case 20 :
{
2009-08-18 00:34:08 +04:00
static const char * const attrs2 [ ] = { " userParameters " ,
NULL } ;
2006-07-04 06:46:24 +04:00
attrs = attrs2 ;
break ;
}
case 21 :
{
2007-12-20 02:02:15 +03:00
static const char * const attrs2 [ ] = { " lastLogon " ,
2006-07-04 06:46:24 +04:00
" lastLogoff " ,
" pwdLastSet " ,
2018-04-11 01:33:21 +03:00
" msDS-ResultantPSO " ,
2016-06-04 01:48:56 +03:00
" msDS-UserPasswordExpiryTimeComputed " ,
2006-07-04 06:46:24 +04:00
" accountExpires " ,
" sAMAccountName " ,
" displayName " ,
" homeDirectory " ,
" homeDrive " ,
" scriptPath " ,
" profilePath " ,
" description " ,
" userWorkstations " ,
" comment " ,
" userParameters " ,
" objectSid " ,
" primaryGroupID " ,
" userAccountControl " ,
2013-10-29 08:30:18 +04:00
" msDS-User-Account-Control-Computed " ,
2006-07-04 06:46:24 +04:00
" logonHours " ,
" badPwdCount " ,
2014-03-26 02:32:05 +04:00
" badPasswordTime " ,
2006-07-04 06:46:24 +04:00
" logonCount " ,
" countryCode " ,
" codePage " ,
NULL } ;
attrs = attrs2 ;
break ;
}
2009-11-10 18:26:23 +03:00
case 23 :
case 24 :
case 25 :
case 26 :
{
return NT_STATUS_NOT_SUPPORTED ;
}
default :
{
return NT_STATUS_INVALID_INFO_CLASS ;
}
2006-07-04 06:46:24 +04:00
}
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 ,
2010-06-12 01:59:12 +04:00
a_state - > account_dn , & res , attrs ) ;
if ( ret = = 0 ) {
return NT_STATUS_NO_SUCH_USER ;
}
2004-05-08 18:42:45 +04:00
if ( ret ! = 1 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
msg = res [ 0 ] ;
/* allocate the info structure */
2008-11-10 13:26:43 +03:00
info = talloc_zero ( mem_ctx , union samr_UserInfo ) ;
if ( info = = NULL ) {
2004-05-08 18:42:45 +04:00
return NT_STATUS_NO_MEMORY ;
}
/* fill in the reply */
switch ( r - > in . level ) {
case 1 :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , info1 . account_name , " sAMAccountName " ) ;
QUERY_STRING ( msg , info1 . full_name , " displayName " ) ;
2004-11-13 16:45:41 +03:00
QUERY_UINT ( msg , info1 . primary_gid , " primaryGroupID " ) ;
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , info1 . description , " description " ) ;
QUERY_STRING ( msg , info1 . comment , " comment " ) ;
2004-05-08 18:42:45 +04:00
break ;
case 2 :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , info2 . comment , " comment " ) ;
2004-11-13 16:45:41 +03:00
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 :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , info3 . account_name , " sAMAccountName " ) ;
QUERY_STRING ( msg , info3 . full_name , " displayName " ) ;
2004-11-13 16:45:41 +03:00
QUERY_RID ( msg , info3 . rid , " objectSid " ) ;
QUERY_UINT ( msg , info3 . primary_gid , " primaryGroupID " ) ;
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , info3 . home_directory , " homeDirectory " ) ;
QUERY_STRING ( msg , info3 . home_drive , " homeDrive " ) ;
QUERY_STRING ( msg , info3 . logon_script , " scriptPath " ) ;
QUERY_STRING ( msg , info3 . profile_path , " profilePath " ) ;
QUERY_STRING ( msg , info3 . workstations , " userWorkstations " ) ;
2007-09-06 08:01:52 +04:00
QUERY_UINT64 ( msg , info3 . last_logon , " lastLogon " ) ;
QUERY_UINT64 ( msg , info3 . last_logoff , " lastLogoff " ) ;
QUERY_UINT64 ( msg , info3 . last_password_change , " pwdLastSet " ) ;
2004-11-13 16:45:41 +03:00
QUERY_APASSC ( msg , info3 . allow_password_change , " pwdLastSet " ) ;
2016-06-04 01:48:56 +03:00
QUERY_UINT64 ( msg , info3 . force_password_change , " msDS-UserPasswordExpiryTimeComputed " ) ;
2004-11-13 16:45:41 +03:00
QUERY_LHOURS ( msg , info3 . logon_hours , " logonHours " ) ;
2014-03-26 02:32:05 +04:00
/* level 3 gives the raw badPwdCount value */
2004-11-13 16:45:41 +03:00
QUERY_UINT ( msg , info3 . bad_password_count , " badPwdCount " ) ;
QUERY_UINT ( msg , info3 . logon_count , " logonCount " ) ;
2013-10-29 08:30:18 +04:00
QUERY_AFLAGS ( msg , info3 . acct_flags , " msDS-User-Account-Control-Computed " ) ;
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 :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , info5 . account_name , " sAMAccountName " ) ;
QUERY_STRING ( msg , info5 . full_name , " displayName " ) ;
2004-11-13 16:45:41 +03:00
QUERY_RID ( msg , info5 . rid , " objectSid " ) ;
QUERY_UINT ( msg , info5 . primary_gid , " primaryGroupID " ) ;
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , info5 . home_directory , " homeDirectory " ) ;
QUERY_STRING ( msg , info5 . home_drive , " homeDrive " ) ;
QUERY_STRING ( msg , info5 . logon_script , " scriptPath " ) ;
QUERY_STRING ( msg , info5 . profile_path , " profilePath " ) ;
QUERY_STRING ( msg , info5 . description , " description " ) ;
QUERY_STRING ( msg , info5 . workstations , " userWorkstations " ) ;
2007-09-06 08:01:52 +04:00
QUERY_UINT64 ( msg , info5 . last_logon , " lastLogon " ) ;
QUERY_UINT64 ( msg , info5 . last_logoff , " lastLogoff " ) ;
2004-11-13 16:45:41 +03:00
QUERY_LHOURS ( msg , info5 . logon_hours , " logonHours " ) ;
2014-03-26 02:32:05 +04:00
QUERY_BPWDCT ( msg , info5 . bad_password_count , " badPwdCount " ) ;
2004-11-13 16:45:41 +03:00
QUERY_UINT ( msg , info5 . logon_count , " logonCount " ) ;
2007-09-06 08:01:52 +04:00
QUERY_UINT64 ( msg , info5 . last_password_change , " pwdLastSet " ) ;
QUERY_UINT64 ( msg , info5 . acct_expiry , " accountExpires " ) ;
2013-10-29 08:30:18 +04:00
QUERY_AFLAGS ( msg , info5 . acct_flags , " msDS-User-Account-Control-Computed " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 6 :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , info6 . account_name , " sAMAccountName " ) ;
QUERY_STRING ( msg , info6 . full_name , " displayName " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 7 :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , info7 . account_name , " sAMAccountName " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 8 :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , info8 . full_name , " displayName " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 9 :
2007-07-27 06:07:17 +04:00
QUERY_UINT ( msg , info9 . primary_gid , " primaryGroupID " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 10 :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , info10 . home_directory , " homeDirectory " ) ;
QUERY_STRING ( msg , info10 . home_drive , " homeDrive " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 11 :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , info11 . logon_script , " scriptPath " ) ;
2004-05-08 18:42:45 +04:00
break ;
2004-05-09 13:39:47 +04:00
case 12 :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , info12 . profile_path , " profilePath " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 13 :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , info13 . description , " description " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 14 :
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , info14 . workstations , " userWorkstations " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 16 :
2013-10-29 08:30:18 +04:00
QUERY_AFLAGS ( msg , info16 . acct_flags , " msDS-User-Account-Control-Computed " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 17 :
2007-09-06 08:01:52 +04:00
QUERY_UINT64 ( msg , info17 . acct_expiry , " accountExpires " ) ;
2007-09-10 08:41:14 +04:00
break ;
2004-05-09 13:39:47 +04:00
case 20 :
2014-06-17 08:03:22 +04:00
status = samdb_result_parameters ( mem_ctx , msg , " userParameters " , & info - > info20 . parameters ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
talloc_free ( info ) ;
return status ;
}
2004-05-09 13:39:47 +04:00
break ;
case 21 :
2007-09-06 08:01:52 +04:00
QUERY_UINT64 ( msg , info21 . last_logon , " lastLogon " ) ;
QUERY_UINT64 ( msg , info21 . last_logoff , " lastLogoff " ) ;
QUERY_UINT64 ( msg , info21 . last_password_change , " pwdLastSet " ) ;
QUERY_UINT64 ( msg , info21 . acct_expiry , " accountExpires " ) ;
2004-06-05 08:32:50 +04:00
QUERY_APASSC ( msg , info21 . allow_password_change , " pwdLastSet " ) ;
2016-06-04 01:48:56 +03:00
QUERY_UINT64 ( msg , info21 . force_password_change , " msDS-UserPasswordExpiryTimeComputed " ) ;
2007-07-27 06:07:17 +04:00
QUERY_STRING ( msg , info21 . account_name , " sAMAccountName " ) ;
QUERY_STRING ( msg , info21 . full_name , " displayName " ) ;
QUERY_STRING ( msg , info21 . home_directory , " homeDirectory " ) ;
QUERY_STRING ( msg , info21 . home_drive , " homeDrive " ) ;
QUERY_STRING ( msg , info21 . logon_script , " scriptPath " ) ;
QUERY_STRING ( msg , info21 . profile_path , " profilePath " ) ;
QUERY_STRING ( msg , info21 . description , " description " ) ;
QUERY_STRING ( msg , info21 . workstations , " userWorkstations " ) ;
QUERY_STRING ( msg , info21 . comment , " comment " ) ;
2014-06-17 08:03:22 +04:00
status = samdb_result_parameters ( mem_ctx , msg , " userParameters " , & info - > info21 . parameters ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
talloc_free ( info ) ;
return status ;
}
2004-11-13 16:45:41 +03:00
QUERY_RID ( msg , info21 . rid , " objectSid " ) ;
QUERY_UINT ( msg , info21 . primary_gid , " primaryGroupID " ) ;
2013-10-29 08:30:18 +04:00
QUERY_AFLAGS ( msg , info21 . acct_flags , " msDS-User-Account-Control-Computed " ) ;
2010-07-05 17:54:21 +04:00
info - > info21 . fields_present = 0x08FFFFFF ;
2004-11-13 16:45:41 +03:00
QUERY_LHOURS ( msg , info21 . logon_hours , " logonHours " ) ;
2014-03-26 02:32:05 +04:00
QUERY_BPWDCT ( msg , info21 . bad_password_count , " badPwdCount " ) ;
2004-11-13 16:45:41 +03:00
QUERY_UINT ( msg , info21 . logon_count , " logonCount " ) ;
2010-07-05 17:54:21 +04:00
if ( ( info - > info21 . acct_flags & ACB_PW_EXPIRED ) ! = 0 ) {
info - > info21 . password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON ;
} else {
info - > info21 . password_expired = PASS_DONT_CHANGE_AT_NEXT_LOGON ;
}
2004-11-13 16:45:41 +03:00
QUERY_UINT ( msg , info21 . country_code , " countryCode " ) ;
QUERY_UINT ( msg , info21 . code_page , " codePage " ) ;
2004-05-09 13:39:47 +04:00
break ;
2010-10-29 12:55:07 +04:00
2004-05-09 13:39:47 +04:00
2004-05-08 18:42:45 +04:00
default :
2008-11-10 13:26:43 +03:00
talloc_free ( info ) ;
2004-05-08 18:42:45 +04:00
return NT_STATUS_INVALID_INFO_CLASS ;
}
2008-11-10 13:26:43 +03:00
2008-11-10 16:42:27 +03:00
* r - > out . info = info ;
2008-11-10 13:26:43 +03:00
2004-05-08 18:42:45 +04:00
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2004-05-09 13:39:47 +04:00
2010-10-29 12:55:07 +04:00
/*
samr_SetUserInfo
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_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 ;
2006-07-04 06:46:24 +04:00
struct ldb_context * sam_ctx ;
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 ;
2006-07-04 06:46:24 +04:00
sam_ctx = a_state - > sam_ctx ;
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 :
2007-07-27 06:07:17 +04:00
SET_STRING ( msg , info2 . comment , " 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 :
2007-07-27 06:07:17 +04:00
SET_LHOURS ( msg , info4 . logon_hours , " logonHours " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 6 :
2009-08-18 00:34:08 +04:00
SET_STRING ( msg , info6 . account_name , " samAccountName " ) ;
2007-07-27 06:07:17 +04:00
SET_STRING ( msg , info6 . full_name , " displayName " ) ;
2004-05-09 13:39:47 +04:00
break ;
2005-03-13 09:43:34 +03:00
case 7 :
2007-07-27 06:07:17 +04:00
SET_STRING ( msg , info7 . account_name , " samAccountName " ) ;
2005-03-13 09:43:34 +03:00
break ;
2004-05-09 13:39:47 +04:00
case 8 :
2007-07-27 06:07:17 +04:00
SET_STRING ( msg , info8 . full_name , " displayName " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 9 :
2007-07-27 06:07:17 +04:00
SET_UINT ( msg , info9 . primary_gid , " primaryGroupID " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 10 :
2007-07-27 06:07:17 +04:00
SET_STRING ( msg , info10 . home_directory , " homeDirectory " ) ;
SET_STRING ( msg , info10 . home_drive , " homeDrive " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 11 :
2007-07-27 06:07:17 +04:00
SET_STRING ( msg , info11 . logon_script , " scriptPath " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 12 :
2007-07-27 06:07:17 +04:00
SET_STRING ( msg , info12 . profile_path , " profilePath " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 13 :
2007-07-27 06:07:17 +04:00
SET_STRING ( msg , info13 . description , " description " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 14 :
2007-07-27 06:07:17 +04:00
SET_STRING ( msg , info14 . workstations , " userWorkstations " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 16 :
2007-07-27 06:07:17 +04:00
SET_AFLAGS ( msg , info16 . acct_flags , " userAccountControl " ) ;
2004-05-09 13:39:47 +04:00
break ;
2006-10-13 00:21:46 +04:00
case 17 :
2007-07-27 06:07:17 +04:00
SET_UINT64 ( msg , info17 . acct_expiry , " accountExpires " ) ;
2006-10-13 00:21:46 +04:00
break ;
2010-06-12 16:40:11 +04:00
case 18 :
status = samr_set_password_buffers ( dce_call ,
a_state - > sam_ctx ,
a_state - > account_dn ,
a_state - > domain_state - > domain_dn ,
mem_ctx ,
r - > in . info - > info18 . lm_pwd_active ? r - > in . info - > info18 . lm_pwd . hash : NULL ,
r - > in . info - > info18 . nt_pwd_active ? r - > in . info - > info18 . nt_pwd . hash : NULL ) ;
2010-06-22 00:26:31 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
if ( r - > in . info - > info18 . password_expired > 0 ) {
struct ldb_message_element * set_el ;
if ( samdb_msg_add_uint64 ( sam_ctx , mem_ctx , msg , " pwdLastSet " , 0 ) ! = LDB_SUCCESS ) {
return NT_STATUS_NO_MEMORY ;
}
set_el = ldb_msg_find_element ( msg , " pwdLastSet " ) ;
set_el - > flags = LDB_FLAG_MOD_REPLACE ;
}
2010-06-12 16:40:11 +04:00
break ;
2004-05-09 13:39:47 +04:00
case 20 :
2008-11-07 17:04:46 +03:00
SET_PARAMETERS ( msg , info20 . parameters , " userParameters " ) ;
2004-05-09 13:39:47 +04:00
break ;
case 21 :
2010-06-28 01:13:14 +04:00
if ( r - > in . info - > info21 . fields_present = = 0 )
return NT_STATUS_INVALID_PARAMETER ;
2009-08-18 00:34:08 +04:00
# define IFSET(bit) if (bit & r->in.info->info21.fields_present)
2010-07-05 01:21:07 +04:00
IFSET ( SAMR_FIELD_LAST_LOGON )
SET_UINT64 ( msg , info21 . last_logon , " lastLogon " ) ;
IFSET ( SAMR_FIELD_LAST_LOGOFF )
SET_UINT64 ( msg , info21 . last_logoff , " lastLogoff " ) ;
2007-09-04 06:22:04 +04:00
IFSET ( SAMR_FIELD_ACCT_EXPIRY )
2009-08-18 00:34:08 +04:00
SET_UINT64 ( msg , info21 . acct_expiry , " accountExpires " ) ;
2010-10-29 12:55:07 +04:00
IFSET ( SAMR_FIELD_ACCOUNT_NAME )
2007-07-27 06:07:17 +04:00
SET_STRING ( msg , info21 . account_name , " samAccountName " ) ;
2010-10-29 12:55:07 +04:00
IFSET ( SAMR_FIELD_FULL_NAME )
2007-07-27 06:07:17 +04:00
SET_STRING ( msg , info21 . full_name , " displayName " ) ;
2006-10-13 00:21:46 +04:00
IFSET ( SAMR_FIELD_HOME_DIRECTORY )
2007-07-27 06:07:17 +04:00
SET_STRING ( msg , info21 . home_directory , " homeDirectory " ) ;
2006-10-13 00:21:46 +04:00
IFSET ( SAMR_FIELD_HOME_DRIVE )
2007-07-27 06:07:17 +04:00
SET_STRING ( msg , info21 . home_drive , " homeDrive " ) ;
2009-08-18 00:34:08 +04:00
IFSET ( SAMR_FIELD_LOGON_SCRIPT )
SET_STRING ( msg , info21 . logon_script , " scriptPath " ) ;
IFSET ( SAMR_FIELD_PROFILE_PATH )
SET_STRING ( msg , info21 . profile_path , " profilePath " ) ;
IFSET ( SAMR_FIELD_DESCRIPTION )
SET_STRING ( msg , info21 . description , " description " ) ;
2006-10-13 00:21:46 +04:00
IFSET ( SAMR_FIELD_WORKSTATIONS )
2007-07-27 06:07:17 +04:00
SET_STRING ( msg , info21 . workstations , " userWorkstations " ) ;
2009-08-18 00:34:08 +04:00
IFSET ( SAMR_FIELD_COMMENT )
SET_STRING ( msg , info21 . comment , " comment " ) ;
2010-10-29 12:55:07 +04:00
IFSET ( SAMR_FIELD_PARAMETERS )
2008-11-07 17:04:46 +03:00
SET_PARAMETERS ( msg , info21 . parameters , " userParameters " ) ;
2009-08-18 00:34:08 +04:00
IFSET ( SAMR_FIELD_PRIMARY_GID )
SET_UINT ( msg , info21 . primary_gid , " primaryGroupID " ) ;
IFSET ( SAMR_FIELD_ACCT_FLAGS )
SET_AFLAGS ( msg , info21 . acct_flags , " userAccountControl " ) ;
IFSET ( SAMR_FIELD_LOGON_HOURS )
SET_LHOURS ( msg , info21 . logon_hours , " logonHours " ) ;
2010-07-05 01:21:07 +04:00
IFSET ( SAMR_FIELD_BAD_PWD_COUNT )
SET_UINT ( msg , info21 . bad_password_count , " badPwdCount " ) ;
IFSET ( SAMR_FIELD_NUM_LOGONS )
SET_UINT ( msg , info21 . logon_count , " logonCount " ) ;
2006-10-13 00:21:46 +04:00
IFSET ( SAMR_FIELD_COUNTRY_CODE )
2007-07-27 06:07:17 +04:00
SET_UINT ( msg , info21 . country_code , " countryCode " ) ;
2006-10-13 00:21:46 +04:00
IFSET ( SAMR_FIELD_CODE_PAGE )
2009-08-18 00:34:08 +04:00
SET_UINT ( msg , info21 . code_page , " codePage " ) ;
2010-06-21 16:41:27 +04:00
/* password change fields */
IFSET ( SAMR_FIELD_LAST_PWD_CHANGE )
return NT_STATUS_ACCESS_DENIED ;
IFSET ( ( SAMR_FIELD_LM_PASSWORD_PRESENT
| SAMR_FIELD_NT_PASSWORD_PRESENT ) ) {
uint8_t * lm_pwd_hash = NULL , * nt_pwd_hash = NULL ;
if ( r - > in . info - > info21 . lm_password_set ) {
if ( ( r - > in . info - > info21 . lm_owf_password . length ! = 16 )
| | ( r - > in . info - > info21 . lm_owf_password . size ! = 16 ) ) {
return NT_STATUS_INVALID_PARAMETER ;
}
lm_pwd_hash = ( uint8_t * ) r - > in . info - > info21 . lm_owf_password . array ;
}
if ( r - > in . info - > info21 . nt_password_set ) {
if ( ( r - > in . info - > info21 . nt_owf_password . length ! = 16 )
| | ( r - > in . info - > info21 . nt_owf_password . size ! = 16 ) ) {
return NT_STATUS_INVALID_PARAMETER ;
}
nt_pwd_hash = ( uint8_t * ) r - > in . info - > info21 . nt_owf_password . array ;
}
status = samr_set_password_buffers ( dce_call ,
a_state - > sam_ctx ,
a_state - > account_dn ,
a_state - > domain_state - > domain_dn ,
mem_ctx ,
lm_pwd_hash ,
nt_pwd_hash ) ;
2010-06-22 00:26:31 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
}
2010-07-05 19:42:40 +04:00
2010-06-22 00:26:31 +04:00
IFSET ( SAMR_FIELD_EXPIRED_FLAG ) {
2016-05-24 09:51:45 +03:00
const char * t = " 0 " ;
2010-06-22 00:26:31 +04:00
struct ldb_message_element * set_el ;
2010-07-05 19:42:40 +04:00
if ( r - > in . info - > info21 . password_expired
= = PASS_DONT_CHANGE_AT_NEXT_LOGON ) {
2016-05-24 09:51:45 +03:00
t = " -1 " ;
2010-07-05 19:42:40 +04:00
}
2016-05-24 09:51:45 +03:00
if ( ldb_msg_add_string ( msg , " pwdLastSet " , t ) ! = LDB_SUCCESS ) {
2010-06-22 00:26:31 +04:00
return NT_STATUS_NO_MEMORY ;
}
set_el = ldb_msg_find_element ( msg , " pwdLastSet " ) ;
set_el - > flags = LDB_FLAG_MOD_REPLACE ;
2010-06-21 16:41:27 +04:00
}
2004-05-26 08:20:17 +04:00
# undef IFSET
break ;
case 23 :
2010-06-28 01:13:14 +04:00
if ( r - > in . info - > info23 . info . fields_present = = 0 )
return NT_STATUS_INVALID_PARAMETER ;
2004-05-26 08:20:17 +04:00
# define IFSET(bit) if (bit & r->in.info->info23.info.fields_present)
2010-07-05 01:21:07 +04:00
IFSET ( SAMR_FIELD_LAST_LOGON )
SET_UINT64 ( msg , info23 . info . last_logon , " lastLogon " ) ;
IFSET ( SAMR_FIELD_LAST_LOGOFF )
SET_UINT64 ( msg , info23 . info . last_logoff , " lastLogoff " ) ;
2007-09-04 06:22:04 +04:00
IFSET ( SAMR_FIELD_ACCT_EXPIRY )
2009-08-18 00:34:08 +04:00
SET_UINT64 ( msg , info23 . info . acct_expiry , " accountExpires " ) ;
2010-10-29 12:55:07 +04:00
IFSET ( SAMR_FIELD_ACCOUNT_NAME )
2009-08-18 00:34:08 +04:00
SET_STRING ( msg , info23 . info . account_name , " samAccountName " ) ;
IFSET ( SAMR_FIELD_FULL_NAME )
SET_STRING ( msg , info23 . info . full_name , " displayName " ) ;
IFSET ( SAMR_FIELD_HOME_DIRECTORY )
SET_STRING ( msg , info23 . info . home_directory , " homeDirectory " ) ;
IFSET ( SAMR_FIELD_HOME_DRIVE )
SET_STRING ( msg , info23 . info . home_drive , " homeDrive " ) ;
IFSET ( SAMR_FIELD_LOGON_SCRIPT )
SET_STRING ( msg , info23 . info . logon_script , " scriptPath " ) ;
IFSET ( SAMR_FIELD_PROFILE_PATH )
SET_STRING ( msg , info23 . info . profile_path , " profilePath " ) ;
IFSET ( SAMR_FIELD_DESCRIPTION )
SET_STRING ( msg , info23 . info . description , " description " ) ;
IFSET ( SAMR_FIELD_WORKSTATIONS )
SET_STRING ( msg , info23 . info . workstations , " userWorkstations " ) ;
IFSET ( SAMR_FIELD_COMMENT )
SET_STRING ( msg , info23 . info . comment , " comment " ) ;
IFSET ( SAMR_FIELD_PARAMETERS )
2008-11-07 17:04:46 +03:00
SET_PARAMETERS ( msg , info23 . info . parameters , " userParameters " ) ;
2009-08-18 00:34:08 +04:00
IFSET ( SAMR_FIELD_PRIMARY_GID )
SET_UINT ( msg , info23 . info . primary_gid , " primaryGroupID " ) ;
IFSET ( SAMR_FIELD_ACCT_FLAGS )
SET_AFLAGS ( msg , info23 . info . acct_flags , " userAccountControl " ) ;
IFSET ( SAMR_FIELD_LOGON_HOURS )
SET_LHOURS ( msg , info23 . info . logon_hours , " logonHours " ) ;
2010-07-05 01:21:07 +04:00
IFSET ( SAMR_FIELD_BAD_PWD_COUNT )
SET_UINT ( msg , info23 . info . bad_password_count , " badPwdCount " ) ;
IFSET ( SAMR_FIELD_NUM_LOGONS )
SET_UINT ( msg , info23 . info . logon_count , " logonCount " ) ;
2009-08-18 00:34:08 +04:00
IFSET ( SAMR_FIELD_COUNTRY_CODE )
SET_UINT ( msg , info23 . info . country_code , " countryCode " ) ;
IFSET ( SAMR_FIELD_CODE_PAGE )
SET_UINT ( msg , info23 . info . code_page , " codePage " ) ;
2010-06-21 16:54:19 +04:00
/* password change fields */
IFSET ( SAMR_FIELD_LAST_PWD_CHANGE )
return NT_STATUS_ACCESS_DENIED ;
2008-12-04 20:18:06 +03:00
IFSET ( SAMR_FIELD_NT_PASSWORD_PRESENT ) {
2004-05-26 08:20:17 +04:00
status = samr_set_password ( dce_call ,
a_state - > sam_ctx ,
a_state - > account_dn ,
a_state - > domain_state - > domain_dn ,
2009-09-26 14:09:07 +04:00
mem_ctx ,
2004-05-26 08:20:17 +04:00
& r - > in . info - > info23 . password ) ;
2008-12-04 20:18:06 +03:00
} else IFSET ( SAMR_FIELD_LM_PASSWORD_PRESENT ) {
2004-10-20 06:26:59 +04:00
status = samr_set_password ( dce_call ,
a_state - > sam_ctx ,
a_state - > account_dn ,
a_state - > domain_state - > domain_dn ,
2009-09-26 14:09:07 +04:00
mem_ctx ,
2004-10-20 06:26:59 +04:00
& r - > in . info - > info23 . password ) ;
2004-05-26 08:20:17 +04:00
}
2010-06-22 00:26:31 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
IFSET ( SAMR_FIELD_EXPIRED_FLAG ) {
2016-05-24 09:51:45 +03:00
const char * t = " 0 " ;
2010-06-22 00:26:31 +04:00
struct ldb_message_element * set_el ;
2010-07-05 19:42:40 +04:00
if ( r - > in . info - > info23 . info . password_expired
= = PASS_DONT_CHANGE_AT_NEXT_LOGON ) {
2016-05-24 09:51:45 +03:00
t = " -1 " ;
2010-07-05 19:42:40 +04:00
}
2016-05-24 09:51:45 +03:00
if ( ldb_msg_add_string ( msg , " pwdLastSet " , t ) ! = LDB_SUCCESS ) {
2010-06-22 00:26:31 +04:00
return NT_STATUS_NO_MEMORY ;
}
set_el = ldb_msg_find_element ( msg , " pwdLastSet " ) ;
set_el - > flags = LDB_FLAG_MOD_REPLACE ;
}
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 ,
2009-09-26 14:09:07 +04:00
mem_ctx ,
2004-05-10 15:23:50 +04:00
& r - > in . info - > info24 . password ) ;
2010-06-22 00:26:31 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
if ( r - > in . info - > info24 . password_expired > 0 ) {
struct ldb_message_element * set_el ;
if ( samdb_msg_add_uint64 ( sam_ctx , mem_ctx , msg , " pwdLastSet " , 0 ) ! = LDB_SUCCESS ) {
return NT_STATUS_NO_MEMORY ;
}
set_el = ldb_msg_find_element ( msg , " pwdLastSet " ) ;
set_el - > flags = LDB_FLAG_MOD_REPLACE ;
}
2004-05-10 15:23:50 +04:00
break ;
2004-05-26 08:20:17 +04:00
case 25 :
2010-06-28 01:13:14 +04:00
if ( r - > in . info - > info25 . info . fields_present = = 0 )
return NT_STATUS_INVALID_PARAMETER ;
2004-05-26 08:20:17 +04:00
# define IFSET(bit) if (bit & r->in.info->info25.info.fields_present)
2010-07-05 01:21:07 +04:00
IFSET ( SAMR_FIELD_LAST_LOGON )
SET_UINT64 ( msg , info25 . info . last_logon , " lastLogon " ) ;
IFSET ( SAMR_FIELD_LAST_LOGOFF )
SET_UINT64 ( msg , info25 . info . last_logoff , " lastLogoff " ) ;
2007-09-04 06:22:04 +04:00
IFSET ( SAMR_FIELD_ACCT_EXPIRY )
2009-08-18 00:34:08 +04:00
SET_UINT64 ( msg , info25 . info . acct_expiry , " accountExpires " ) ;
2010-10-29 12:55:07 +04:00
IFSET ( SAMR_FIELD_ACCOUNT_NAME )
2009-08-18 00:34:08 +04:00
SET_STRING ( msg , info25 . info . account_name , " samAccountName " ) ;
IFSET ( SAMR_FIELD_FULL_NAME )
SET_STRING ( msg , info25 . info . full_name , " displayName " ) ;
IFSET ( SAMR_FIELD_HOME_DIRECTORY )
SET_STRING ( msg , info25 . info . home_directory , " homeDirectory " ) ;
IFSET ( SAMR_FIELD_HOME_DRIVE )
SET_STRING ( msg , info25 . info . home_drive , " homeDrive " ) ;
IFSET ( SAMR_FIELD_LOGON_SCRIPT )
SET_STRING ( msg , info25 . info . logon_script , " scriptPath " ) ;
IFSET ( SAMR_FIELD_PROFILE_PATH )
SET_STRING ( msg , info25 . info . profile_path , " profilePath " ) ;
IFSET ( SAMR_FIELD_DESCRIPTION )
SET_STRING ( msg , info25 . info . description , " description " ) ;
IFSET ( SAMR_FIELD_WORKSTATIONS )
SET_STRING ( msg , info25 . info . workstations , " userWorkstations " ) ;
IFSET ( SAMR_FIELD_COMMENT )
SET_STRING ( msg , info25 . info . comment , " comment " ) ;
IFSET ( SAMR_FIELD_PARAMETERS )
2008-11-07 17:04:46 +03:00
SET_PARAMETERS ( msg , info25 . info . parameters , " userParameters " ) ;
2009-08-18 00:34:08 +04:00
IFSET ( SAMR_FIELD_PRIMARY_GID )
SET_UINT ( msg , info25 . info . primary_gid , " primaryGroupID " ) ;
IFSET ( SAMR_FIELD_ACCT_FLAGS )
SET_AFLAGS ( msg , info25 . info . acct_flags , " userAccountControl " ) ;
IFSET ( SAMR_FIELD_LOGON_HOURS )
SET_LHOURS ( msg , info25 . info . logon_hours , " logonHours " ) ;
2010-07-05 01:21:07 +04:00
IFSET ( SAMR_FIELD_BAD_PWD_COUNT )
SET_UINT ( msg , info25 . info . bad_password_count , " badPwdCount " ) ;
IFSET ( SAMR_FIELD_NUM_LOGONS )
SET_UINT ( msg , info25 . info . logon_count , " logonCount " ) ;
2009-08-18 00:34:08 +04:00
IFSET ( SAMR_FIELD_COUNTRY_CODE )
SET_UINT ( msg , info25 . info . country_code , " countryCode " ) ;
IFSET ( SAMR_FIELD_CODE_PAGE )
SET_UINT ( msg , info25 . info . code_page , " codePage " ) ;
2010-06-21 16:54:19 +04:00
/* password change fields */
IFSET ( SAMR_FIELD_LAST_PWD_CHANGE )
return NT_STATUS_ACCESS_DENIED ;
2008-12-04 20:18:06 +03:00
IFSET ( SAMR_FIELD_NT_PASSWORD_PRESENT ) {
2004-05-26 08:20:17 +04:00
status = samr_set_password_ex ( dce_call ,
a_state - > sam_ctx ,
a_state - > account_dn ,
a_state - > domain_state - > domain_dn ,
2009-09-26 14:09:07 +04:00
mem_ctx ,
2004-05-26 08:20:17 +04:00
& r - > in . info - > info25 . password ) ;
2008-12-04 20:18:06 +03:00
} else IFSET ( SAMR_FIELD_LM_PASSWORD_PRESENT ) {
2004-10-20 06:26:59 +04:00
status = samr_set_password_ex ( dce_call ,
a_state - > sam_ctx ,
a_state - > account_dn ,
a_state - > domain_state - > domain_dn ,
2009-09-26 14:09:07 +04:00
mem_ctx ,
2004-10-20 06:26:59 +04:00
& r - > in . info - > info25 . password ) ;
2004-05-26 08:20:17 +04:00
}
2010-06-22 00:26:31 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
IFSET ( SAMR_FIELD_EXPIRED_FLAG ) {
2016-05-24 09:51:45 +03:00
const char * t = " 0 " ;
2010-06-22 00:26:31 +04:00
struct ldb_message_element * set_el ;
2010-07-05 19:42:40 +04:00
if ( r - > in . info - > info25 . info . password_expired
= = PASS_DONT_CHANGE_AT_NEXT_LOGON ) {
2016-05-24 09:51:45 +03:00
t = " -1 " ;
2010-07-05 19:42:40 +04:00
}
2016-05-24 09:51:45 +03:00
if ( ldb_msg_add_string ( msg , " pwdLastSet " , t ) ! = LDB_SUCCESS ) {
2010-06-22 00:26:31 +04:00
return NT_STATUS_NO_MEMORY ;
}
set_el = ldb_msg_find_element ( msg , " pwdLastSet " ) ;
set_el - > flags = LDB_FLAG_MOD_REPLACE ;
}
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 ,
2009-09-26 14:09:07 +04:00
mem_ctx ,
2004-05-26 08:20:17 +04:00
& r - > in . info - > info26 . password ) ;
2010-06-22 00:26:31 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
if ( r - > in . info - > info26 . password_expired > 0 ) {
2016-05-24 09:51:45 +03:00
const char * t = " 0 " ;
2010-06-22 00:26:31 +04:00
struct ldb_message_element * set_el ;
2013-06-09 12:46:06 +04:00
if ( r - > in . info - > info26 . password_expired
= = PASS_DONT_CHANGE_AT_NEXT_LOGON ) {
2016-05-24 09:51:45 +03:00
t = " -1 " ;
2013-06-09 12:46:06 +04:00
}
2016-05-24 09:51:45 +03:00
if ( ldb_msg_add_string ( msg , " pwdLastSet " , t ) ! = LDB_SUCCESS ) {
2010-06-22 00:26:31 +04:00
return NT_STATUS_NO_MEMORY ;
}
set_el = ldb_msg_find_element ( msg , " pwdLastSet " ) ;
set_el - > flags = LDB_FLAG_MOD_REPLACE ;
}
2004-05-26 08:20:17 +04:00
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 */
2009-10-13 02:48:15 +04:00
if ( msg - > num_elements > 0 ) {
ret = ldb_modify ( a_state - > sam_ctx , msg ) ;
if ( ret ! = LDB_SUCCESS ) {
DEBUG ( 1 , ( " Failed to modify record %s: %s \n " ,
ldb_dn_get_linearized ( a_state - > account_dn ) ,
ldb_errstring ( a_state - > sam_ctx ) ) ) ;
2011-04-01 08:58:55 +04:00
return dsdb_ldb_err_to_ntstatus ( ret ) ;
2009-10-13 02:48:15 +04:00
}
2004-05-08 18:42:45 +04:00
}
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_GetGroupsForUser
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_GetGroupsForUser ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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 ;
2016-06-08 07:49:01 +03:00
struct ldb_result * res , * res_memberof ;
const char * const attrs [ ] = { " primaryGroupID " ,
" memberOf " ,
NULL } ;
const char * const group_attrs [ ] = { " objectSid " ,
NULL } ;
2005-06-29 17:55:09 +04:00
struct samr_RidWithAttributeArray * array ;
2016-06-08 07:49:01 +03:00
struct ldb_message_element * memberof_el ;
int i , ret , count = 0 ;
uint32_t primary_group_id ;
char * filter ;
2004-12-30 01:57:20 +03:00
DCESRV_PULL_HANDLE ( h , r - > in . user_handle , SAMR_HANDLE_USER ) ;
a_state = h - > data ;
d_state = a_state - > domain_state ;
2016-06-08 07:49:01 +03:00
ret = dsdb_search_dn ( a_state - > sam_ctx , mem_ctx ,
& res ,
a_state - > account_dn ,
attrs , DSDB_SEARCH_SHOW_EXTENDED_DN ) ;
if ( ret = = LDB_ERR_NO_SUCH_OBJECT ) {
return NT_STATUS_NO_SUCH_USER ;
} else if ( ret ! = LDB_SUCCESS ) {
2004-12-30 01:57:20 +03:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2016-06-08 07:49:01 +03:00
} else if ( res - > count ! = 1 ) {
return NT_STATUS_NO_SUCH_USER ;
}
primary_group_id = ldb_msg_find_attr_as_uint ( res - > msgs [ 0 ] , " primaryGroupID " ,
0 ) ;
filter = talloc_asprintf ( mem_ctx ,
" (&(|(grouptype=%d)(grouptype=%d)) "
" (objectclass=group)(| " ,
GTYPE_SECURITY_UNIVERSAL_GROUP ,
GTYPE_SECURITY_GLOBAL_GROUP ) ;
if ( filter = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
memberof_el = ldb_msg_find_element ( res - > msgs [ 0 ] , " memberOf " ) ;
if ( memberof_el ! = NULL ) {
for ( i = 0 ; i < memberof_el - > num_values ; i + + ) {
const struct ldb_val * memberof_sid_binary ;
char * memberof_sid_escaped ;
struct ldb_dn * memberof_dn
= ldb_dn_from_ldb_val ( mem_ctx ,
a_state - > sam_ctx ,
& memberof_el - > values [ i ] ) ;
if ( memberof_dn = = NULL ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
memberof_sid_binary
= ldb_dn_get_extended_component ( memberof_dn ,
" SID " ) ;
if ( memberof_sid_binary = = NULL ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
memberof_sid_escaped = ldb_binary_encode ( mem_ctx ,
* memberof_sid_binary ) ;
if ( memberof_sid_escaped = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
filter = talloc_asprintf_append ( filter , " (objectSID=%s) " ,
memberof_sid_escaped ) ;
if ( filter = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
}
ret = dsdb_search ( a_state - > sam_ctx , mem_ctx ,
& res_memberof ,
d_state - > domain_dn ,
LDB_SCOPE_SUBTREE ,
group_attrs , 0 ,
" %s)) " , filter ) ;
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
count = res_memberof - > count ;
}
2004-12-30 01:57:20 +03:00
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
2009-08-18 00:34:08 +04:00
array - > rids = talloc_array ( mem_ctx , struct samr_RidWithAttribute ,
2016-06-08 07:49:01 +03:00
count + 1 ) ;
2009-08-18 00:34:08 +04:00
if ( array - > rids = = NULL )
return NT_STATUS_NO_MEMORY ;
2004-12-30 01:57:20 +03:00
2009-08-18 00:34:08 +04:00
/* Adds the primary group */
2016-06-08 07:49:01 +03:00
array - > rids [ 0 ] . rid = primary_group_id ;
2009-08-18 00:34:08 +04:00
array - > rids [ 0 ] . attributes = SE_GROUP_MANDATORY
2016-06-08 07:49:01 +03:00
| SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED ;
2009-08-18 00:34:08 +04:00
array - > count + = 1 ;
2004-12-30 01:57:20 +03:00
2009-08-18 00:34:08 +04:00
/* Adds the additional groups */
for ( i = 0 ; i < count ; i + + ) {
struct dom_sid * group_sid ;
2004-12-30 01:57:20 +03:00
2016-06-08 07:49:01 +03:00
group_sid = samdb_result_dom_sid ( mem_ctx ,
res_memberof - > msgs [ i ] ,
" objectSid " ) ;
2009-08-18 00:34:08 +04:00
if ( group_sid = = NULL ) {
2010-06-12 19:50:52 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
2004-12-30 01:57:20 +03:00
}
2009-08-18 00:34:08 +04:00
array - > rids [ i + 1 ] . rid =
group_sid - > sub_auths [ group_sid - > num_auths - 1 ] ;
array - > rids [ i + 1 ] . attributes = SE_GROUP_MANDATORY
| SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED ;
array - > count + = 1 ;
2004-12-30 01:57:20 +03:00
}
2008-11-05 12:58:35 +03:00
* r - > out . rids = array ;
2004-12-30 01:57:20 +03:00
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
2018-10-09 23:20:25 +03:00
* samr_QueryDisplayInfo
*
* A cache of the GUID ' s matching the last query is maintained
* in the SAMR_QUERY_DISPLAY_INFO_CACHE guid_cache maintained o
* n the dcesrv_handle .
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_QueryDisplayInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
struct samr_QueryDisplayInfo * r )
{
2004-12-29 02:01:34 +03:00
struct dcesrv_handle * h ;
struct samr_domain_state * d_state ;
2011-01-15 14:30:16 +03:00
struct ldb_result * res ;
2018-10-09 23:20:25 +03:00
uint32_t i ;
uint32_t results = 0 ;
uint32_t count = 0 ;
const char * const cache_attrs [ ] = { " objectGUID " , NULL } ;
const char * const attrs [ ] = {
" objectSID " , " sAMAccountName " , " displayName " , " description " , NULL } ;
2004-12-29 02:01:34 +03:00
struct samr_DispEntryFull * entriesFull = NULL ;
2006-12-13 14:19:51 +03:00
struct samr_DispEntryFullGroup * entriesFullGroup = NULL ;
2004-12-29 02:01:34 +03:00
struct samr_DispEntryAscii * entriesAscii = NULL ;
2009-08-18 00:34:08 +04:00
struct samr_DispEntryGeneral * entriesGeneral = NULL ;
2004-12-29 02:01:34 +03:00
const char * filter ;
2011-01-15 14:30:16 +03:00
int ret ;
2018-10-09 23:20:25 +03:00
NTSTATUS status ;
struct samr_guid_cache * cache = NULL ;
2004-12-29 02:01:34 +03:00
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
d_state = h - > data ;
2018-10-09 23:20:25 +03:00
cache = & d_state - > guid_caches [ SAMR_QUERY_DISPLAY_INFO_CACHE ] ;
/*
* Can the cached results be used ?
* The cache is discarded if the start index is zero , or the requested
* level is different from that in the cache .
*/
if ( ( r - > in . start_idx = = 0 ) | | ( r - > in . level ! = cache - > handle ) ) {
/*
* The cached results can not be used , so will need to query
* the database .
*/
2004-12-29 02:01:34 +03:00
2018-10-09 23:20:25 +03:00
/*
* Get the search filter for the current level
*/
switch ( r - > in . level ) {
case 1 :
case 4 :
filter = talloc_asprintf ( mem_ctx ,
" (&(objectclass=user) "
" (sAMAccountType=%d)) " ,
ATYPE_NORMAL_ACCOUNT ) ;
break ;
case 2 :
filter = talloc_asprintf ( mem_ctx ,
" (&(objectclass=user) "
" (sAMAccountType=%d)) " ,
ATYPE_WORKSTATION_TRUST ) ;
break ;
case 3 :
case 5 :
filter =
talloc_asprintf ( mem_ctx ,
" (&(|(groupType=%d)(groupType=%d)) "
" (objectClass=group)) " ,
GTYPE_SECURITY_UNIVERSAL_GROUP ,
GTYPE_SECURITY_GLOBAL_GROUP ) ;
break ;
default :
return NT_STATUS_INVALID_INFO_CLASS ;
}
clear_guid_cache ( cache ) ;
/*
* search for all requested objects in all domains .
*/
ret = dsdb_search ( d_state - > sam_ctx ,
mem_ctx ,
& res ,
ldb_get_default_basedn ( d_state - > sam_ctx ) ,
LDB_SCOPE_SUBTREE ,
cache_attrs ,
0 ,
" %s " ,
filter ) ;
if ( ret ! = LDB_SUCCESS ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
if ( ( res - > count = = 0 ) | | ( r - > in . max_entries = = 0 ) ) {
return NT_STATUS_OK ;
}
status = load_guid_cache ( cache , d_state , res - > count , res - > msgs ) ;
TALLOC_FREE ( res ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
cache - > handle = r - > in . level ;
2004-12-29 02:01:34 +03:00
}
2018-10-09 23:20:25 +03:00
* r - > out . total_size = cache - > size ;
/*
* if there are no entries or the requested start index is greater
* than the number of entries , we return an empty response .
*/
if ( r - > in . start_idx > = cache - > size ) {
* 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 ;
}
2004-12-29 02:01:34 +03:00
return NT_STATUS_OK ;
}
2018-10-09 23:20:25 +03:00
/*
* Allocate an array of the appropriate result structures for the
* current query level .
*
* r - > in . start_idx is always < cache - > size due to the check above
*/
results = MIN ( ( cache - > size - r - > in . start_idx ) , r - > in . max_entries ) ;
2004-12-29 02:01:34 +03:00
switch ( r - > in . level ) {
case 1 :
2018-10-09 23:20:25 +03:00
entriesGeneral = talloc_array (
mem_ctx , struct samr_DispEntryGeneral , results ) ;
2004-12-29 02:01:34 +03:00
break ;
case 2 :
2018-10-09 23:20:25 +03:00
entriesFull =
talloc_array ( mem_ctx , struct samr_DispEntryFull , results ) ;
2004-12-29 02:01:34 +03:00
break ;
2006-12-13 14:19:51 +03:00
case 3 :
2018-10-09 23:20:25 +03:00
entriesFullGroup = talloc_array (
mem_ctx , struct samr_DispEntryFullGroup , results ) ;
2006-12-13 14:19:51 +03:00
break ;
2004-12-29 02:01:34 +03:00
case 4 :
case 5 :
2018-10-09 23:20:25 +03:00
entriesAscii =
talloc_array ( mem_ctx , struct samr_DispEntryAscii , results ) ;
2004-12-29 02:01:34 +03:00
break ;
}
if ( ( entriesGeneral = = NULL ) & & ( entriesFull = = NULL ) & &
2006-12-13 14:19:51 +03:00
( entriesAscii = = NULL ) & & ( entriesFullGroup = = NULL ) )
2004-12-29 02:01:34 +03:00
return NT_STATUS_NO_MEMORY ;
2018-10-09 23:20:25 +03:00
/*
* Process the list of result GUID ' s .
* Read the details of each object and populate the result structure
* for the current level .
*/
2004-12-29 02:01:34 +03:00
count = 0 ;
2018-10-09 23:20:25 +03:00
for ( i = 0 ; i < results ; i + + ) {
2004-12-29 02:01:34 +03:00
struct dom_sid * objectsid ;
2018-10-09 23:20:25 +03:00
struct ldb_result * rec ;
const uint32_t idx = r - > in . start_idx + i ;
2018-11-14 23:53:25 +03:00
uint32_t rid ;
2004-12-29 02:01:34 +03:00
2018-10-09 23:20:25 +03:00
/*
* Read an object from disk using the GUID as the key
*
* If the object can not be read , or it does not have a SID
* it is ignored . In this case the number of entries returned
* will be less than the requested size , there will also be
* a gap in the idx numbers in the returned elements e . g . if
* there are 3 GUIDs a , b , c in the cache and b is deleted from
* disk then details for a , and c will be returned with
* idx values of 1 and 3 respectively .
*
*/
ret = dsdb_search_by_dn_guid ( d_state - > sam_ctx ,
mem_ctx ,
& rec ,
& cache - > entries [ idx ] ,
attrs ,
0 ) ;
if ( ret = = LDB_ERR_NO_SUCH_OBJECT ) {
struct GUID_txt_buf guid_buf ;
char * guid_str =
GUID_buf_string ( & cache - > entries [ idx ] ,
& guid_buf ) ;
DBG_WARNING ( " GUID [%s] not found \n " , guid_str ) ;
2004-12-29 02:01:34 +03:00
continue ;
2018-10-09 23:20:25 +03:00
} else if ( ret ! = LDB_SUCCESS ) {
clear_guid_cache ( cache ) ;
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
objectsid = samdb_result_dom_sid ( mem_ctx ,
rec - > msgs [ 0 ] ,
" objectSID " ) ;
if ( objectsid = = NULL ) {
struct GUID_txt_buf guid_buf ;
2018-11-21 00:02:43 +03:00
DBG_WARNING (
" objectSID for GUID [%s] not found \n " ,
GUID_buf_string ( & cache - > entries [ idx ] , & guid_buf ) ) ;
2018-10-09 23:20:25 +03:00
continue ;
}
2018-11-14 23:53:25 +03:00
status = dom_sid_split_rid ( NULL ,
objectsid ,
NULL ,
& rid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
struct dom_sid_buf sid_buf ;
struct GUID_txt_buf guid_buf ;
2018-11-21 00:02:43 +03:00
DBG_WARNING (
" objectSID [%s] for GUID [%s] invalid \n " ,
dom_sid_str_buf ( objectsid , & sid_buf ) ,
GUID_buf_string ( & cache - > entries [ idx ] , & guid_buf ) ) ;
2018-11-14 23:53:25 +03:00
continue ;
}
2004-12-29 02:01:34 +03:00
2018-10-09 23:20:25 +03:00
/*
* Populate the result structure for the current object
*/
2004-12-29 02:01:34 +03:00
switch ( r - > in . level ) {
case 1 :
2018-10-09 23:20:25 +03:00
entriesGeneral [ count ] . idx = idx + 1 ;
2018-11-14 23:53:25 +03:00
entriesGeneral [ count ] . rid = rid ;
2004-12-29 02:01:34 +03:00
entriesGeneral [ count ] . acct_flags =
2018-10-09 23:20:25 +03:00
samdb_result_acct_flags ( rec - > msgs [ 0 ] , NULL ) ;
2004-12-29 02:01:34 +03:00
entriesGeneral [ count ] . account_name . string =
2018-10-09 23:20:25 +03:00
ldb_msg_find_attr_as_string (
rec - > msgs [ 0 ] , " sAMAccountName " , " " ) ;
2004-12-29 02:01:34 +03:00
entriesGeneral [ count ] . full_name . string =
2018-10-09 23:20:25 +03:00
ldb_msg_find_attr_as_string (
rec - > msgs [ 0 ] , " displayName " , " " ) ;
2004-12-29 02:01:34 +03:00
entriesGeneral [ count ] . description . string =
2018-10-09 23:20:25 +03:00
ldb_msg_find_attr_as_string (
rec - > msgs [ 0 ] , " description " , " " ) ;
2004-12-29 02:01:34 +03:00
break ;
case 2 :
2018-10-09 23:20:25 +03:00
entriesFull [ count ] . idx = idx + 1 ;
2018-11-14 23:53:25 +03:00
entriesFull [ count ] . rid = rid ;
2007-07-26 07:50:24 +04:00
2018-10-09 23:20:25 +03:00
/*
* No idea why we need to or in ACB_NORMAL here ,
* but this is what Win2k3 seems to do . . .
*/
2004-12-29 02:01:34 +03:00
entriesFull [ count ] . acct_flags =
2018-10-09 23:20:25 +03:00
samdb_result_acct_flags ( rec - > msgs [ 0 ] , NULL ) |
ACB_NORMAL ;
2004-12-29 02:01:34 +03:00
entriesFull [ count ] . account_name . string =
2018-10-09 23:20:25 +03:00
ldb_msg_find_attr_as_string (
rec - > msgs [ 0 ] , " sAMAccountName " , " " ) ;
2004-12-29 02:01:34 +03:00
entriesFull [ count ] . description . string =
2018-10-09 23:20:25 +03:00
ldb_msg_find_attr_as_string (
rec - > msgs [ 0 ] , " description " , " " ) ;
2004-12-29 02:01:34 +03:00
break ;
2006-12-13 14:19:51 +03:00
case 3 :
2018-10-09 23:20:25 +03:00
entriesFullGroup [ count ] . idx = idx + 1 ;
2018-11-14 23:53:25 +03:00
entriesFullGroup [ count ] . rid = rid ;
2018-10-09 23:20:25 +03:00
/*
* We get a " 7 " here for groups
*/
entriesFullGroup [ count ] . acct_flags =
SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT |
SE_GROUP_ENABLED ;
2006-12-13 14:19:51 +03:00
entriesFullGroup [ count ] . account_name . string =
2018-10-09 23:20:25 +03:00
ldb_msg_find_attr_as_string (
rec - > msgs [ 0 ] , " sAMAccountName " , " " ) ;
2006-12-13 14:19:51 +03:00
entriesFullGroup [ count ] . description . string =
2018-10-09 23:20:25 +03:00
ldb_msg_find_attr_as_string (
rec - > msgs [ 0 ] , " description " , " " ) ;
2006-12-13 14:19:51 +03:00
break ;
2004-12-29 02:01:34 +03:00
case 4 :
case 5 :
2018-10-09 23:20:25 +03:00
entriesAscii [ count ] . idx = idx + 1 ;
2004-12-29 02:01:34 +03:00
entriesAscii [ count ] . account_name . string =
2018-10-09 23:20:25 +03:00
ldb_msg_find_attr_as_string (
rec - > msgs [ 0 ] , " sAMAccountName " , " " ) ;
2004-12-29 02:01:34 +03:00
break ;
}
2018-10-09 23:20:25 +03:00
count + + ;
2004-12-29 02:01:34 +03:00
}
2018-10-09 23:20:25 +03:00
/*
* Build the response based on the request level .
*/
* r - > out . returned_size = count ;
switch ( r - > in . level ) {
case 1 :
r - > out . info - > info1 . count = count ;
r - > out . info - > info1 . entries = entriesGeneral ;
break ;
case 2 :
r - > out . info - > info2 . count = count ;
r - > out . info - > info2 . entries = entriesFull ;
break ;
case 3 :
r - > out . info - > info3 . count = count ;
r - > out . info - > info3 . entries = entriesFullGroup ;
break ;
case 4 :
r - > out . info - > info4 . count = count ;
r - > out . info - > info4 . entries = entriesAscii ;
break ;
case 5 :
r - > out . info - > info5 . count = count ;
r - > out . info - > info5 . entries = entriesAscii ;
break ;
2004-12-29 02:01:34 +03:00
}
2018-10-09 23:20:25 +03:00
return ( ( r - > in . start_idx + results ) < cache - > size )
? STATUS_MORE_ENTRIES
: NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_GetDisplayEnumerationIndex
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_GetDisplayEnumerationIndex ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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
}
2010-10-29 12:55:07 +04:00
/*
samr_TestPrivateFunctionsDomain
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_TestPrivateFunctionsDomain ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
struct samr_TestPrivateFunctionsDomain * r )
{
2006-07-04 06:46:24 +04:00
return NT_STATUS_NOT_IMPLEMENTED ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_TestPrivateFunctionsUser
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_TestPrivateFunctionsUser ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
struct samr_TestPrivateFunctionsUser * r )
{
2006-07-03 08:00:10 +04:00
return NT_STATUS_NOT_IMPLEMENTED ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_GetUserPwInfo
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_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
2008-11-05 03:28:49 +03:00
ZERO_STRUCTP ( r - > out . info ) ;
2004-05-09 16:32:25 +04:00
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
2009-08-18 00:34:08 +04:00
r - > out . info - > min_password_length = samdb_search_uint ( a_state - > sam_ctx ,
mem_ctx , 0 , a_state - > domain_state - > domain_dn , " minPwdLength " ,
NULL ) ;
r - > out . info - > password_properties = samdb_search_uint ( a_state - > sam_ctx ,
mem_ctx , 0 , a_state - > account_dn , " pwdProperties " , NULL ) ;
2004-05-09 16:32:25 +04:00
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_RemoveMemberFromForeignDomain
2004-05-03 18:58:08 +04:00
*/
2010-11-06 20:18:44 +03:00
static NTSTATUS dcesrv_samr_RemoveMemberFromForeignDomain ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct samr_RemoveMemberFromForeignDomain * r )
2004-05-03 18:58:08 +04:00
{
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 ;
2010-11-06 20:18:44 +03:00
const char * no_attrs [ ] = { NULL } ;
2004-12-30 21:50:15 +03:00
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 ,
2010-10-29 12:55:07 +04:00
" distinguishedName " , " (objectSid=%s) " ,
2005-06-24 04:18:20 +04:00
ldap_encode_ndr_dom_sid ( mem_ctx , r - > in . sid ) ) ;
2006-07-04 06:46:24 +04:00
/* Nothing to do */
if ( memberdn = = NULL ) {
return NT_STATUS_OK ;
}
2004-12-30 21:50:15 +03:00
count = samdb_search_domain ( d_state - > sam_ctx , mem_ctx ,
2010-11-06 20:18:44 +03:00
d_state - > domain_dn , & res , no_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) "
2006-06-13 00:00:18 +04:00
" (|(groupType=%d)(groupType=%d))) " ,
2004-12-30 21:50:15 +03:00
memberdn ,
2006-06-13 00:00:18 +04:00
GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ,
GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ) ;
2004-12-30 21:50:15 +03:00
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 ;
2011-04-01 08:58:55 +04:00
int ret ;
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 ;
}
2010-11-06 20:18:44 +03:00
mod - > dn = res [ i ] - > dn ;
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 ,
2009-11-21 21:25:42 +03:00
" member " , memberdn ) ! = LDB_SUCCESS )
2004-12-30 21:50:15 +03:00
return NT_STATUS_NO_MEMORY ;
2011-04-01 08:58:55 +04:00
ret = ldb_modify ( d_state - > sam_ctx , mod ) ;
2005-01-02 10:51:13 +03:00
talloc_free ( mod ) ;
2011-04-01 08:58:55 +04:00
if ( ret ! = LDB_SUCCESS ) {
return dsdb_ldb_err_to_ntstatus ( ret ) ;
}
2004-12-30 21:50:15 +03:00
}
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_QueryDomainInfo2
2006-07-04 06:46:24 +04:00
just an alias for samr_QueryDomainInfo
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_QueryDomainInfo2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
struct samr_QueryDomainInfo2 * r )
{
2006-07-04 06:46:24 +04:00
struct samr_QueryDomainInfo r1 ;
NTSTATUS status ;
ZERO_STRUCT ( r1 . out ) ;
r1 . in . domain_handle = r - > in . domain_handle ;
r1 . in . level = r - > in . level ;
2008-11-05 04:59:51 +03:00
r1 . out . info = r - > out . info ;
2007-01-17 17:49:36 +03:00
status = dcesrv_samr_QueryDomainInfo ( dce_call , mem_ctx , & r1 ) ;
2010-10-29 12:55:07 +04:00
2006-07-04 06:46:24 +04:00
return status ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +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
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_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 ;
2015-03-03 10:48:00 +03:00
r1 = ( struct samr_QueryUserInfo ) {
. in . user_handle = r - > in . user_handle ,
. in . level = r - > in . level ,
. out . info = r - > out . info
} ;
2010-10-29 12:55:07 +04:00
2007-01-17 17:49:36 +03:00
status = dcesrv_samr_QueryUserInfo ( dce_call , mem_ctx , & r1 ) ;
2004-05-09 13:39:47 +04:00
return status ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_QueryDisplayInfo2
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_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 ;
2008-11-05 14:32:24 +03:00
q . out . total_size = r - > out . total_size ;
q . out . returned_size = r - > out . returned_size ;
q . out . info = r - > out . info ;
2004-12-30 20:01:49 +03:00
2007-01-17 17:49:36 +03:00
result = dcesrv_samr_QueryDisplayInfo ( dce_call , mem_ctx , & q ) ;
2004-12-30 20:01:49 +03:00
return result ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_GetDisplayEnumerationIndex2
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_GetDisplayEnumerationIndex2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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
}
2010-10-29 12:55:07 +04:00
/*
samr_QueryDisplayInfo3
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_QueryDisplayInfo3 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
struct samr_QueryDisplayInfo3 * r )
{
2006-07-04 06:46:24 +04: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 ;
2008-11-05 14:32:24 +03:00
q . out . total_size = r - > out . total_size ;
q . out . returned_size = r - > out . returned_size ;
q . out . info = r - > out . info ;
2006-07-04 06:46:24 +04:00
2007-01-17 17:49:36 +03:00
result = dcesrv_samr_QueryDisplayInfo ( dce_call , mem_ctx , & q ) ;
2006-07-04 06:46:24 +04:00
return result ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_AddMultipleMembersToAlias
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_AddMultipleMembersToAlias ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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
}
2010-10-29 12:55:07 +04:00
/*
samr_RemoveMultipleMembersFromAlias
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_RemoveMultipleMembersFromAlias ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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
}
2010-10-29 12:55:07 +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
2010-10-29 12:55:07 +04:00
note that w2k3 completely ignores the domain name in this call , and
2004-05-26 11:32:30 +04:00
always returns the information for the servers primary domain
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_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
2008-11-05 03:34:55 +03:00
ZERO_STRUCTP ( r - > out . info ) ;
2004-06-05 00:36:44 +04:00
2018-04-11 21:41:30 +03:00
sam_ctx = samdb_connect ( mem_ctx ,
dce_call - > event_ctx ,
dce_call - > conn - > dce_ctx - > lp_ctx ,
dce_call - > conn - > auth_state . session_info ,
dce_call - > conn - > remote_address ,
0 ) ;
2004-05-06 16:42:42 +04:00
if ( sam_ctx = = NULL ) {
return NT_STATUS_INVALID_SYSTEM_SERVICE ;
}
2005-09-02 03:26:50 +04:00
/* The domain name in this call is ignored */
2010-10-29 12:55:07 +04:00
ret = gendb_search_dn ( sam_ctx ,
2006-08-25 11:08:06 +04:00
mem_ctx , NULL , & msgs , attrs ) ;
2004-05-04 11:53:06 +04:00
if ( ret < = 0 ) {
2009-10-13 02:45:26 +04:00
talloc_free ( sam_ctx ) ;
2004-05-04 11:53:06 +04:00
return NT_STATUS_NO_SUCH_DOMAIN ;
}
if ( ret > 1 ) {
2005-04-25 16:46:18 +04:00
talloc_free ( msgs ) ;
2009-10-13 02:45:26 +04:00
talloc_free ( sam_ctx ) ;
2004-05-04 11:53:06 +04:00
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
2010-10-14 11:41:42 +04:00
r - > out . info - > min_password_length = ldb_msg_find_attr_as_uint ( msgs [ 0 ] ,
2009-08-18 00:34:08 +04:00
" minPwdLength " , 0 ) ;
2010-10-14 11:41:42 +04:00
r - > out . info - > password_properties = ldb_msg_find_attr_as_uint ( msgs [ 0 ] ,
2009-08-18 00:34:08 +04:00
" pwdProperties " , 1 ) ;
2004-05-04 11:53:06 +04:00
2005-04-25 16:46:18 +04:00
talloc_free ( msgs ) ;
2009-10-23 07:27:00 +04:00
talloc_unlink ( mem_ctx , sam_ctx ) ;
2009-10-13 02:15:19 +04:00
2004-05-04 11:53:06 +04:00
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_Connect2
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_Connect2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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
2007-01-17 17:49:36 +03:00
return dcesrv_samr_Connect ( dce_call , mem_ctx , & c ) ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +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
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_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 ;
2007-01-17 17:49:36 +03:00
return dcesrv_samr_SetUserInfo ( dce_call , mem_ctx , & r2 ) ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_SetBootKeyInformation
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_SetBootKeyInformation ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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
}
2010-10-29 12:55:07 +04:00
/*
samr_GetBootKeyInformation
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_GetBootKeyInformation ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
struct samr_GetBootKeyInformation * r )
{
2010-12-04 12:34:05 +03:00
/* Windows Server 2008 returns this */
return NT_STATUS_NOT_SUPPORTED ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_Connect3
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_Connect3 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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
2007-01-17 17:49:36 +03:00
return dcesrv_samr_Connect ( dce_call , mem_ctx , & c ) ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_Connect4
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_Connect4 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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
2007-01-17 17:49:36 +03:00
return dcesrv_samr_Connect ( dce_call , mem_ctx , & c ) ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_Connect5
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_Connect5 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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
2007-01-17 17:49:36 +03:00
status = dcesrv_samr_Connect ( dce_call , mem_ctx , & c ) ;
2004-05-03 18:58:08 +04:00
2008-11-05 03:51:51 +03:00
r - > out . info_out - > info1 . client_version = SAMR_CONNECT_AFTER_W2K ;
r - > out . info_out - > info1 . unknown2 = 0 ;
* r - > out . level_out = r - > in . level_in ;
2004-05-03 18:58:08 +04:00
return status ;
}
2010-10-29 12:55:07 +04:00
/*
samr_RidToSid
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_RidToSid ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-12-27 02:14:56 +03:00
struct samr_RidToSid * r )
2004-05-03 18:58:08 +04:00
{
2005-12-27 02:14:56 +03:00
struct samr_domain_state * d_state ;
struct dcesrv_handle * h ;
DCESRV_PULL_HANDLE ( h , r - > in . domain_handle , SAMR_HANDLE_DOMAIN ) ;
d_state = h - > data ;
/* form the users SID */
2008-10-28 02:03:28 +03:00
* r - > out . sid = dom_sid_add_rid ( mem_ctx , d_state - > domain_sid , r - > in . rid ) ;
if ( ! * r - > out . sid ) {
2005-12-27 02:14:56 +03:00
return NT_STATUS_NO_MEMORY ;
}
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
2010-10-29 12:55:07 +04:00
/*
samr_SetDsrmPassword
2004-05-03 18:58:08 +04:00
*/
2007-01-17 17:49:36 +03:00
static NTSTATUS dcesrv_samr_SetDsrmPassword ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-05-03 18:58:08 +04:00
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
}
2010-10-29 12:55:07 +04:00
/*
2009-11-04 14:02:02 +03:00
samr_ValidatePassword
For now the call checks the password complexity ( if active ) and the minimum
password length on level 2 and 3. Level 1 is ignored for now .
2004-05-03 18:58:08 +04:00
*/
2009-11-04 14:02:02 +03:00
static NTSTATUS dcesrv_samr_ValidatePassword ( struct dcesrv_call_state * dce_call ,
TALLOC_CTX * mem_ctx ,
struct samr_ValidatePassword * r )
2004-05-03 18:58:08 +04:00
{
2009-11-04 14:02:02 +03:00
struct samr_GetDomPwInfo r2 ;
2009-11-06 14:10:42 +03:00
struct samr_PwInfo pwInfo ;
2009-11-04 14:02:02 +03:00
DATA_BLOB password ;
enum samr_ValidationStatus res ;
NTSTATUS status ;
2014-01-30 22:01:34 +04:00
enum dcerpc_transport_t transport =
dcerpc_binding_get_transport ( dce_call - > conn - > endpoint - > ep_description ) ;
2012-12-11 17:43:07 +04:00
if ( transport ! = NCACN_IP_TCP & & transport ! = NCALRPC ) {
DCESRV_FAULT ( DCERPC_FAULT_ACCESS_DENIED ) ;
}
2009-11-04 14:02:02 +03:00
2015-06-26 09:10:46 +03:00
if ( dce_call - > conn - > auth_state . auth_level ! = DCERPC_AUTH_LEVEL_PRIVACY ) {
2016-02-29 00:48:11 +03:00
DCESRV_FAULT ( DCERPC_FAULT_ACCESS_DENIED ) ;
}
2009-10-02 10:02:42 +04:00
( * r - > out . rep ) = talloc_zero ( mem_ctx , union samr_ValidatePasswordRep ) ;
2009-11-04 14:02:02 +03:00
r2 . in . domain_name = NULL ;
2009-11-06 14:10:42 +03:00
r2 . out . info = & pwInfo ;
2009-11-04 14:02:02 +03:00
status = dcesrv_samr_GetDomPwInfo ( dce_call , mem_ctx , & r2 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
switch ( r - > in . level ) {
case NetValidateAuthentication :
/* we don't support this yet */
return NT_STATUS_NOT_SUPPORTED ;
break ;
case NetValidatePasswordChange :
password = data_blob_const ( r - > in . req - > req2 . password . string ,
r - > in . req - > req2 . password . length ) ;
2016-04-01 00:10:57 +03:00
res = samdb_check_password ( mem_ctx ,
dce_call - > conn - > dce_ctx - > lp_ctx ,
& password ,
2009-11-06 14:10:42 +03:00
pwInfo . password_properties ,
pwInfo . min_password_length ) ;
2009-11-04 14:02:02 +03:00
( * r - > out . rep ) - > ctr2 . status = res ;
break ;
case NetValidatePasswordReset :
password = data_blob_const ( r - > in . req - > req3 . password . string ,
r - > in . req - > req3 . password . length ) ;
2016-04-01 00:10:57 +03:00
res = samdb_check_password ( mem_ctx ,
dce_call - > conn - > dce_ctx - > lp_ctx ,
& password ,
2009-11-06 14:10:42 +03:00
pwInfo . password_properties ,
pwInfo . min_password_length ) ;
2009-11-04 14:02:02 +03:00
( * r - > out . rep ) - > ctr3 . status = res ;
break ;
2009-11-10 18:26:23 +03:00
default :
return NT_STATUS_INVALID_INFO_CLASS ;
break ;
2009-11-04 14:02:02 +03:00
}
2009-10-02 10:02:42 +04:00
return NT_STATUS_OK ;
2004-05-03 18:58:08 +04:00
}
/* include the generated boilerplate */
# include "librpc/gen_ndr/ndr_samr_s.c"