2004-10-10 05:35:33 +04:00
/*
Unix SMB / CIFS implementation .
endpoint server for the drsuapi pipe
Copyright ( C ) Stefan Metzmacher 2004
2006-12-28 06:31:50 +03:00
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2006
2004-10-10 05:35:33 +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-10-10 05:35:33 +04:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2004-10-10 05:35:33 +04:00
*/
# include "includes.h"
2004-11-01 13:30:34 +03:00
# include "librpc/gen_ndr/ndr_drsuapi.h"
2004-11-02 10:42:47 +03:00
# include "rpc_server/dcerpc_server.h"
2004-10-10 05:35:33 +04:00
# include "rpc_server/common/common.h"
# include "rpc_server/drsuapi/dcesrv_drsuapi.h"
2005-12-28 18:38:36 +03:00
# include "dsdb/samdb/samdb.h"
2007-02-23 10:56:29 +03:00
# include "lib/ldb/include/ldb_errors.h"
2007-12-02 19:09:52 +03:00
# include "param/param.h"
2009-09-03 19:37:31 +04:00
# include "librpc/gen_ndr/ndr_drsblobs.h"
2009-09-09 12:04:07 +04:00
# include "messaging/irpc.h"
2004-10-10 05:35:33 +04:00
/*
drsuapi_DsBind
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_drsuapi_DsBind ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-10-10 05:35:33 +04:00
struct drsuapi_DsBind * r )
{
struct drsuapi_bind_state * b_state ;
struct dcesrv_handle * handle ;
2004-12-14 10:18:58 +03:00
struct drsuapi_DsBindInfoCtr * bind_info ;
struct GUID site_guid ;
2007-02-23 10:56:29 +03:00
struct ldb_result * site_res ;
struct ldb_dn * server_site_dn ;
2007-12-20 02:02:15 +03:00
static const char * site_attrs [ ] = { " objectGUID " , NULL } ;
2007-02-23 10:56:29 +03:00
struct ldb_result * ntds_res ;
struct ldb_dn * ntds_dn ;
2007-12-20 02:02:15 +03:00
static const char * ntds_attrs [ ] = { " ms-DS-ReplicationEpoch " , NULL } ;
2008-07-22 17:35:23 +04:00
uint32_t pid ;
2007-02-23 10:56:29 +03:00
uint32_t repl_epoch ;
int ret ;
2004-10-10 05:35:33 +04:00
2004-10-14 15:11:21 +04:00
r - > out . bind_info = NULL ;
2004-10-10 05:35:33 +04:00
ZERO_STRUCTP ( r - > out . bind_handle ) ;
2007-02-23 10:56:29 +03:00
b_state = talloc_zero ( mem_ctx , struct drsuapi_bind_state ) ;
2006-04-29 15:48:56 +04:00
W_ERROR_HAVE_NO_MEMORY ( b_state ) ;
2004-10-10 05:35:33 +04:00
2007-02-23 10:56:29 +03:00
/*
* connect to the samdb
*/
2008-04-17 14:23:44 +04:00
b_state - > sam_ctx = samdb_connect ( b_state , dce_call - > event_ctx , dce_call - > conn - > dce_ctx - > lp_ctx , dce_call - > conn - > auth_state . session_info ) ;
2004-11-16 13:56:51 +03:00
if ( ! b_state - > sam_ctx ) {
return WERR_FOOBAR ;
}
2004-10-10 05:35:33 +04:00
2007-02-23 10:56:29 +03:00
/*
* find out the guid of our own site
*/
server_site_dn = samdb_server_site_dn ( b_state - > sam_ctx , mem_ctx ) ;
W_ERROR_HAVE_NO_MEMORY ( server_site_dn ) ;
2008-09-23 22:30:06 +04:00
ret = ldb_search ( b_state - > sam_ctx , mem_ctx , & site_res ,
2007-02-23 10:56:29 +03:00
server_site_dn , LDB_SCOPE_BASE , site_attrs ,
" (objectClass=*) " ) ;
if ( ret ! = LDB_SUCCESS ) {
return WERR_DS_DRA_INTERNAL_ERROR ;
}
if ( site_res - > count ! = 1 ) {
return WERR_DS_DRA_INTERNAL_ERROR ;
}
site_guid = samdb_result_guid ( site_res - > msgs [ 0 ] , " objectGUID " ) ;
/*
* lookup the local servers Replication Epoch
*/
ntds_dn = samdb_ntds_settings_dn ( b_state - > sam_ctx ) ;
W_ERROR_HAVE_NO_MEMORY ( ntds_dn ) ;
2008-09-23 22:30:06 +04:00
ret = ldb_search ( b_state - > sam_ctx , mem_ctx , & ntds_res ,
2007-02-23 10:56:29 +03:00
ntds_dn , LDB_SCOPE_BASE , ntds_attrs ,
" (objectClass=*) " ) ;
if ( ret ! = LDB_SUCCESS ) {
return WERR_DS_DRA_INTERNAL_ERROR ;
}
if ( ntds_res - > count ! = 1 ) {
return WERR_DS_DRA_INTERNAL_ERROR ;
}
repl_epoch = samdb_result_uint ( ntds_res - > msgs [ 0 ] , " ms-DS-ReplicationEpoch " , 0 ) ;
/*
2008-07-22 17:35:23 +04:00
* The " process identifier " of the client .
* According to the WSPP docs , sectin 5.35 , this is
* for informational and debugging purposes only .
* The assignment is implementation specific .
2007-02-23 10:56:29 +03:00
*/
2008-07-22 17:35:23 +04:00
pid = 0 ;
2007-02-23 10:56:29 +03:00
/*
* store the clients bind_guid
*/
if ( r - > in . bind_guid ) {
b_state - > remote_bind_guid = * r - > in . bind_guid ;
2004-10-10 05:35:33 +04:00
}
2007-02-23 10:56:29 +03:00
/*
* store the clients bind_info
*/
if ( r - > in . bind_info ) {
switch ( r - > in . bind_info - > length ) {
case 24 : {
struct drsuapi_DsBindInfo24 * info24 ;
info24 = & r - > in . bind_info - > info . info24 ;
b_state - > remote_info28 . supported_extensions = info24 - > supported_extensions ;
b_state - > remote_info28 . site_guid = info24 - > site_guid ;
2008-07-22 17:35:23 +04:00
b_state - > remote_info28 . pid = info24 - > pid ;
2007-02-23 10:56:29 +03:00
b_state - > remote_info28 . repl_epoch = 0 ;
break ;
}
case 28 :
b_state - > remote_info28 = r - > in . bind_info - > info . info28 ;
break ;
}
}
2004-10-10 05:35:33 +04:00
2007-02-23 10:56:29 +03:00
/*
* fill in our local bind info 28
*/
b_state - > local_info28 . supported_extensions = 0 ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_BASE ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2 ;
#if 0 /* we don't support MSZIP compression (only decompression) */
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS ;
# endif
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1 ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2 ;
if ( 0 /*domain.behavior_version == 2*/ ) {
/* TODO: find out how this is really triggered! */
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION ;
}
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2 ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01 ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3 ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_00100000 ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2 ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6 ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8 ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5 ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6 ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3 ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7 ;
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT ;
#if 0 /* we don't support XPRESS compression yet */
b_state - > local_info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS ;
# endif
b_state - > local_info28 . site_guid = site_guid ;
2008-07-22 17:35:23 +04:00
b_state - > local_info28 . pid = pid ;
b_state - > local_info28 . repl_epoch = repl_epoch ;
2007-02-23 10:56:29 +03:00
/*
* allocate the return bind_info
*/
2005-01-27 10:08:20 +03:00
bind_info = talloc ( mem_ctx , struct drsuapi_DsBindInfoCtr ) ;
2006-04-29 15:48:56 +04:00
W_ERROR_HAVE_NO_MEMORY ( bind_info ) ;
2004-12-14 10:18:58 +03:00
2007-02-23 10:56:29 +03:00
bind_info - > length = 28 ;
bind_info - > info . info28 = b_state - > local_info28 ;
2004-12-14 10:18:58 +03:00
2007-02-23 10:56:29 +03:00
/*
* allocate a bind handle
*/
handle = dcesrv_handle_new ( dce_call - > context , DRSUAPI_BIND_HANDLE ) ;
W_ERROR_HAVE_NO_MEMORY ( handle ) ;
handle - > data = talloc_steal ( handle , b_state ) ;
2004-11-29 14:13:56 +03:00
2007-02-23 10:56:29 +03:00
/*
* prepare reply
*/
2004-11-29 14:13:56 +03:00
r - > out . bind_info = bind_info ;
2004-10-10 05:35:33 +04:00
* r - > out . bind_handle = handle - > wire_handle ;
2004-10-15 15:08:14 +04:00
return WERR_OK ;
2004-10-10 05:35:33 +04:00
}
/*
drsuapi_DsUnbind
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_drsuapi_DsUnbind ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-01-10 15:15:26 +03:00
struct drsuapi_DsUnbind * r )
2004-10-10 05:35:33 +04:00
{
struct dcesrv_handle * h ;
* r - > out . bind_handle = * r - > in . bind_handle ;
2004-10-15 15:08:14 +04:00
DCESRV_PULL_HANDLE_WERR ( h , r - > in . bind_handle , DRSUAPI_BIND_HANDLE ) ;
2004-10-10 05:35:33 +04:00
2005-01-10 15:15:26 +03:00
talloc_free ( h ) ;
2004-10-10 05:35:33 +04:00
ZERO_STRUCTP ( r - > out . bind_handle ) ;
2004-10-15 15:08:14 +04:00
return WERR_OK ;
2004-10-10 05:35:33 +04:00
}
/*
2004-11-29 14:13:56 +03:00
drsuapi_DsReplicaSync
2004-10-10 05:35:33 +04:00
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_drsuapi_DsReplicaSync ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2009-09-09 12:04:07 +04:00
struct drsuapi_DsReplicaSync * r )
2004-10-10 05:35:33 +04:00
{
2009-09-09 12:04:07 +04:00
struct server_id * repld ;
struct irpc_request * ireq ;
if ( DEBUGLVL ( 4 ) ) {
NDR_PRINT_IN_DEBUG ( drsuapi_DsReplicaSync , r ) ;
}
repld = irpc_servers_byname ( dce_call - > msg_ctx , mem_ctx , " dreplsrv " ) ;
if ( repld = = NULL | | repld [ 0 ] . id = = 0 ) {
DEBUG ( 0 , ( " DsReplicaSync: Unable to find dreplsrv task \n " ) ) ;
return WERR_DS_DRA_INTERNAL_ERROR ;
}
ireq = IRPC_CALL_SEND ( dce_call - > msg_ctx , repld [ 0 ] ,
drsuapi , DRSUAPI_DSREPLICASYNC ,
r , mem_ctx ) ;
if ( ireq = = NULL ) {
DEBUG ( 0 , ( " DsReplicaSync: Failed to forward request to dreplsrv task \n " ) ) ;
return WERR_DS_DRA_INTERNAL_ERROR ;
}
/* we are not interested in a reply */
talloc_free ( ireq ) ;
2004-11-29 14:13:56 +03:00
return WERR_OK ;
2004-10-10 05:35:33 +04:00
}
2009-09-02 18:39:28 +04:00
int drsuapi_search_with_extended_dn ( struct ldb_context * ldb ,
TALLOC_CTX * mem_ctx ,
struct ldb_result * * _res ,
struct ldb_dn * basedn ,
enum ldb_scope scope ,
const char * const * attrs ,
const char * format , . . . )
{
va_list ap ;
int ret ;
struct ldb_request * req ;
char * filter ;
TALLOC_CTX * tmp_ctx ;
struct ldb_result * res ;
tmp_ctx = talloc_new ( mem_ctx ) ;
res = talloc_zero ( tmp_ctx , struct ldb_result ) ;
if ( ! res ) {
return LDB_ERR_OPERATIONS_ERROR ;
}
va_start ( ap , format ) ;
filter = talloc_vasprintf ( tmp_ctx , format , ap ) ;
va_end ( ap ) ;
if ( filter = = NULL ) {
talloc_free ( tmp_ctx ) ;
return LDB_ERR_OPERATIONS_ERROR ;
}
ret = ldb_build_search_req ( & req , ldb , tmp_ctx ,
basedn ,
scope ,
filter ,
attrs ,
NULL ,
res ,
ldb_search_default_callback ,
NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
talloc_free ( tmp_ctx ) ;
return ret ;
}
ret = ldb_request_add_control ( req , LDB_CONTROL_EXTENDED_DN_OID , true , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
return ret ;
}
ret = ldb_request ( ldb , req ) ;
if ( ret = = LDB_SUCCESS ) {
ret = ldb_wait ( req - > handle , LDB_WAIT_ALL ) ;
}
talloc_free ( req ) ;
* _res = res ;
return ret ;
}
2004-10-10 05:35:33 +04:00
/*
2005-03-11 15:15:50 +03:00
drsuapi_DsGetNCChanges
2004-10-10 05:35:33 +04:00
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_drsuapi_DsGetNCChanges ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-03-11 15:15:50 +03:00
struct drsuapi_DsGetNCChanges * r )
2004-10-10 05:35:33 +04:00
{
2009-09-02 18:39:28 +04:00
struct ldb_result * site_res ;
struct drsuapi_DsReplicaObjectIdentifier * ncRoot ;
struct drsuapi_bind_state * b_state ;
struct ldb_dn * ncRoot_dn ;
int ret ;
int i ;
int j ;
int uSN ;
struct dsdb_schema * schema ;
struct drsuapi_DsReplicaOIDMapping_Ctr * ctr ;
time_t t = time ( NULL ) ;
NTTIME now ;
struct drsuapi_DsReplicaObjectListItemEx * currentObject ;
struct dom_sid * zero_sid ;
struct ldb_dn * obj_dn ;
2009-09-03 19:37:31 +04:00
enum ndr_err_code ndr_err ;
const struct ldb_val * md_value ;
struct replPropertyMetaDataBlob md ;
ZERO_STRUCT ( md ) ;
md . version = 1 ;
2009-09-02 18:39:28 +04:00
b_state = talloc_zero ( mem_ctx , struct drsuapi_bind_state ) ;
W_ERROR_HAVE_NO_MEMORY ( b_state ) ;
zero_sid = talloc_zero ( mem_ctx , struct dom_sid ) ;
/*
* connect to the samdb
*/
b_state - > sam_ctx = samdb_connect ( b_state , dce_call - > event_ctx , dce_call - > conn - > dce_ctx - > lp_ctx , dce_call - > conn - > auth_state . session_info ) ;
if ( ! b_state - > sam_ctx ) {
return WERR_FOOBAR ;
}
/* Check request revision. */
if ( r - > in . level ! = 8 ) {
return WERR_REVISION_MISMATCH ;
}
/* Perform access checks. */
if ( r - > in . req - > req8 . naming_context = = NULL ) {
return WERR_DS_DRA_INVALID_PARAMETER ;
}
ncRoot = r - > in . req - > req8 . naming_context ;
if ( ncRoot = = NULL ) {
return WERR_DS_DRA_BAD_NC ;
}
2009-09-08 05:49:28 +04:00
DEBUG ( 4 , ( " DsGetNSChanges with uSHChanged >= %llu \n " ,
( unsigned long long ) r - > in . req - > req8 . highwatermark . highest_usn ) ) ;
2009-09-02 18:39:28 +04:00
/* Construct response. */
ncRoot_dn = ldb_dn_new ( mem_ctx , b_state - > sam_ctx , ncRoot - > dn ) ;
ret = drsuapi_search_with_extended_dn ( b_state - > sam_ctx , mem_ctx , & site_res ,
ncRoot_dn , LDB_SCOPE_SUBTREE , NULL ,
" (&(uSNChanged>=%lld)(objectClass=*)) " , r - > in . req - > req8 . highwatermark . highest_usn ) ;
if ( ret ! = LDB_SUCCESS ) {
return WERR_DS_DRA_INTERNAL_ERROR ;
}
* r - > out . level_out = 6 ;
r - > out . ctr - > ctr6 . naming_context = talloc ( mem_ctx , struct drsuapi_DsReplicaObjectIdentifier ) ;
* r - > out . ctr - > ctr6 . naming_context = * ncRoot ;
/* TODO: linked attributes*/
r - > out . ctr - > ctr6 . linked_attributes_count = 0 ;
r - > out . ctr - > ctr6 . linked_attributes = NULL ;
r - > out . ctr - > ctr6 . object_count = 0 ;
r - > out . ctr - > ctr6 . more_data = false ;
r - > out . ctr - > ctr6 . uptodateness_vector = NULL ;
/* Prefix mapping */
schema = dsdb_get_schema ( b_state - > sam_ctx ) ;
if ( ! schema ) {
DEBUG ( 0 , ( " No schema in b_state->sam_ctx " ) ) ;
}
dsdb_get_oid_mappings_drsuapi ( schema , true , mem_ctx , & ctr ) ;
r - > out . ctr - > ctr6 . mapping_ctr = * ctr ;
r - > out . ctr - > ctr6 . source_dsa_guid = * ( samdb_ntds_objectGUID ( b_state - > sam_ctx ) ) ;
r - > out . ctr - > ctr6 . source_dsa_invocation_id = * ( samdb_ntds_invocation_id ( b_state - > sam_ctx ) ) ;
r - > out . ctr - > ctr6 . old_highwatermark = r - > in . req - > req8 . highwatermark ;
r - > out . ctr - > ctr6 . new_highwatermark = r - > in . req - > req8 . highwatermark ;
r - > out . ctr - > ctr6 . first_object = talloc ( mem_ctx , struct drsuapi_DsReplicaObjectListItemEx ) ;
currentObject = r - > out . ctr - > ctr6 . first_object ;
for ( i = 0 ; i < site_res - > count ; i + + ) {
uSN = ldb_msg_find_attr_as_int ( site_res - > msgs [ i ] , " uSNChanged " , - 1 ) ;
r - > out . ctr - > ctr6 . object_count + + ;
if ( uSN > r - > out . ctr - > ctr6 . new_highwatermark . highest_usn ) {
r - > out . ctr - > ctr6 . new_highwatermark . highest_usn = uSN ;
}
if ( ldb_dn_compare ( ncRoot_dn , site_res - > msgs [ i ] - > dn ) = = 0 ) {
currentObject - > is_nc_prefix = true ;
currentObject - > parent_object_guid = NULL ;
} else {
currentObject - > is_nc_prefix = false ;
currentObject - > parent_object_guid = talloc ( mem_ctx , struct GUID ) ;
* currentObject - > parent_object_guid = samdb_result_guid ( site_res - > msgs [ i ] , " parentGUID " ) ;
}
currentObject - > next_object = NULL ;
2009-09-03 19:37:31 +04:00
2009-09-02 18:39:28 +04:00
currentObject - > meta_data_ctr = talloc ( mem_ctx , struct drsuapi_DsReplicaMetaDataCtr ) ;
2009-09-03 19:37:31 +04:00
md_value = ldb_msg_find_ldb_val ( site_res - > msgs [ i ] , " replPropertyMetaData " ) ;
if ( md_value ) {
ndr_err = ndr_pull_struct_blob ( md_value , mem_ctx ,
lp_iconv_convenience ( ldb_get_opaque ( b_state - > sam_ctx , " loadparm " ) ) , & md ,
( ndr_pull_flags_fn_t ) ndr_pull_replPropertyMetaDataBlob ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
return WERR_DS_DRA_INTERNAL_ERROR ;
}
if ( md . version ! = 1 ) {
return WERR_DS_DRA_INTERNAL_ERROR ;
}
currentObject - > meta_data_ctr - > count = md . ctr . ctr1 . count ;
currentObject - > meta_data_ctr - > meta_data = talloc_array ( mem_ctx , struct drsuapi_DsReplicaMetaData , md . ctr . ctr1 . count ) ;
for ( j = 0 ; j < md . ctr . ctr1 . count ; j + + ) {
currentObject - > meta_data_ctr - > meta_data [ j ] . originating_change_time = md . ctr . ctr1 . array [ j ] . originating_change_time ;
currentObject - > meta_data_ctr - > meta_data [ j ] . version = md . ctr . ctr1 . array [ j ] . version ;
currentObject - > meta_data_ctr - > meta_data [ j ] . originating_invocation_id = md . ctr . ctr1 . array [ j ] . originating_invocation_id ;
currentObject - > meta_data_ctr - > meta_data [ j ] . originating_usn = md . ctr . ctr1 . array [ j ] . originating_usn ;
}
} else {
currentObject - > meta_data_ctr - > meta_data = talloc ( mem_ctx , struct drsuapi_DsReplicaMetaData ) ;
currentObject - > meta_data_ctr - > count = 0 ;
}
2009-09-02 18:39:28 +04:00
currentObject - > object . identifier = talloc ( mem_ctx , struct drsuapi_DsReplicaObjectIdentifier ) ;
obj_dn = ldb_msg_find_attr_as_dn ( b_state - > sam_ctx , mem_ctx , site_res - > msgs [ i ] , " distinguishedName " ) ;
currentObject - > object . identifier - > dn = ldb_dn_get_linearized ( obj_dn ) ;
currentObject - > object . identifier - > guid = GUID_zero ( ) ;
currentObject - > object . identifier - > sid = * zero_sid ;
currentObject - > object . attribute_ctr . num_attributes = site_res - > msgs [ i ] - > num_elements ;
/* Exclude non-replicate attributes from the responce.*/
for ( j = 0 ; j < site_res - > msgs [ i ] - > num_elements ; j + + ) {
const struct dsdb_attribute * sa ;
sa = dsdb_attribute_by_lDAPDisplayName ( schema , site_res - > msgs [ i ] - > elements [ j ] . name ) ;
if ( sa & & sa - > systemFlags & 0x00000001 ) {
ldb_msg_remove_attr ( site_res - > msgs [ i ] , site_res - > msgs [ i ] - > elements [ j ] . name ) ;
currentObject - > object . attribute_ctr . num_attributes - - ;
}
}
currentObject - > object . attribute_ctr . attributes = talloc_array ( mem_ctx , struct drsuapi_DsReplicaAttribute ,
currentObject - > object . attribute_ctr . num_attributes ) ;
for ( j = 0 ; j < currentObject - > object . attribute_ctr . num_attributes ; j + + ) {
dsdb_attribute_ldb_to_drsuapi ( b_state - > sam_ctx , schema , & site_res - > msgs [ i ] - > elements [ j ] , mem_ctx ,
& currentObject - > object . attribute_ctr . attributes [ j ] ) ;
}
if ( i = = ( site_res - > count - 1 ) ) {
break ;
}
currentObject - > next_object = talloc ( mem_ctx , struct drsuapi_DsReplicaObjectListItemEx ) ;
currentObject = currentObject - > next_object ;
}
r - > out . ctr - > ctr6 . uptodateness_vector = talloc ( mem_ctx , struct drsuapi_DsReplicaCursor2CtrEx ) ;
r - > out . ctr - > ctr6 . uptodateness_vector - > version = 2 ;
r - > out . ctr - > ctr6 . uptodateness_vector - > count = 1 ;
r - > out . ctr - > ctr6 . uptodateness_vector - > reserved1 = 0 ;
r - > out . ctr - > ctr6 . uptodateness_vector - > reserved2 = 0 ;
r - > out . ctr - > ctr6 . uptodateness_vector - > cursors = talloc ( mem_ctx , struct drsuapi_DsReplicaCursor2 ) ;
r - > out . ctr - > ctr6 . uptodateness_vector - > cursors [ 0 ] . source_dsa_invocation_id = * ( samdb_ntds_invocation_id ( b_state - > sam_ctx ) ) ;
r - > out . ctr - > ctr6 . uptodateness_vector - > cursors [ 0 ] . highest_usn = r - > out . ctr - > ctr6 . new_highwatermark . highest_usn ;
unix_to_nt_time ( & now , t ) ;
r - > out . ctr - > ctr6 . uptodateness_vector - > cursors [ 0 ] . last_sync_success = now ;
return WERR_OK ;
2004-10-10 05:35:33 +04:00
}
/*
DRSUAPI_REPLICA_ADD
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_DRSUAPI_REPLICA_ADD ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-10-10 05:35:33 +04:00
struct DRSUAPI_REPLICA_ADD * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
DRSUAPI_REPLICA_DEL
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_DRSUAPI_REPLICA_DEL ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-10-10 05:35:33 +04:00
struct DRSUAPI_REPLICA_DEL * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
DRSUAPI_REPLICA_MODIFY
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_DRSUAPI_REPLICA_MODIFY ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-10-10 05:35:33 +04:00
struct DRSUAPI_REPLICA_MODIFY * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
DRSUAPI_VERIFY_NAMES
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_DRSUAPI_VERIFY_NAMES ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-10-10 05:35:33 +04:00
struct DRSUAPI_VERIFY_NAMES * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2006-07-04 14:25:04 +04:00
drsuapi_DsGetMemberships
2004-10-10 05:35:33 +04:00
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_drsuapi_DsGetMemberships ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-07-04 14:25:04 +04:00
struct drsuapi_DsGetMemberships * r )
2004-10-10 05:35:33 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
DRSUAPI_INTER_DOMAIN_MOVE
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_DRSUAPI_INTER_DOMAIN_MOVE ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-10-10 05:35:33 +04:00
struct DRSUAPI_INTER_DOMAIN_MOVE * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2007-01-03 22:09:34 +03:00
drsuapi_DsGetNT4ChangeLog
2004-10-10 05:35:33 +04:00
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_drsuapi_DsGetNT4ChangeLog ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2007-01-03 22:09:34 +03:00
struct drsuapi_DsGetNT4ChangeLog * r )
2004-10-10 05:35:33 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2005-10-24 02:20:42 +04:00
drsuapi_DsCrackNames
2004-10-10 05:35:33 +04:00
*/
2008-10-20 20:59:51 +04:00
static WERROR dcesrv_drsuapi_DsCrackNames ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-10-24 02:20:42 +04:00
struct drsuapi_DsCrackNames * r )
{
WERROR status ;
struct drsuapi_bind_state * b_state ;
struct dcesrv_handle * h ;
2008-10-17 22:08:59 +04:00
* r - > out . level_out = r - > in . level ;
2005-10-24 02:20:42 +04:00
DCESRV_PULL_HANDLE_WERR ( h , r - > in . bind_handle , DRSUAPI_BIND_HANDLE ) ;
b_state = h - > data ;
2008-10-17 22:08:59 +04:00
r - > out . ctr = talloc_zero ( mem_ctx , union drsuapi_DsNameCtr ) ;
W_ERROR_HAVE_NO_MEMORY ( r - > out . ctr ) ;
2005-10-24 02:20:42 +04:00
switch ( r - > in . level ) {
case 1 : {
struct drsuapi_DsNameCtr1 * ctr1 ;
struct drsuapi_DsNameInfo1 * names ;
int count ;
int i ;
ctr1 = talloc ( mem_ctx , struct drsuapi_DsNameCtr1 ) ;
2006-04-29 15:48:56 +04:00
W_ERROR_HAVE_NO_MEMORY ( ctr1 ) ;
2005-10-24 02:20:42 +04:00
2008-10-17 22:08:59 +04:00
count = r - > in . req - > req1 . count ;
2005-10-24 02:20:42 +04:00
names = talloc_array ( mem_ctx , struct drsuapi_DsNameInfo1 , count ) ;
2006-04-29 15:48:56 +04:00
W_ERROR_HAVE_NO_MEMORY ( names ) ;
2005-10-24 02:20:42 +04:00
for ( i = 0 ; i < count ; i + + ) {
status = DsCrackNameOneName ( b_state - > sam_ctx , mem_ctx ,
2008-10-17 22:08:59 +04:00
r - > in . req - > req1 . format_flags ,
r - > in . req - > req1 . format_offered ,
r - > in . req - > req1 . format_desired ,
r - > in . req - > req1 . names [ i ] . str ,
2005-10-24 02:20:42 +04:00
& names [ i ] ) ;
if ( ! W_ERROR_IS_OK ( status ) ) {
return status ;
}
}
ctr1 - > count = count ;
ctr1 - > array = names ;
2008-10-17 22:08:59 +04:00
r - > out . ctr - > ctr1 = ctr1 ;
2005-10-24 02:20:42 +04:00
return WERR_OK ;
}
}
return WERR_UNKNOWN_LEVEL ;
}
2004-10-10 05:35:33 +04:00
/*
2004-11-23 11:57:42 +03:00
drsuapi_DsWriteAccountSpn
2004-10-10 05:35:33 +04:00
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_drsuapi_DsWriteAccountSpn ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-11-23 11:57:42 +03:00
struct drsuapi_DsWriteAccountSpn * r )
2004-10-10 05:35:33 +04:00
{
2006-11-17 14:27:33 +03:00
struct drsuapi_bind_state * b_state ;
struct dcesrv_handle * h ;
2008-10-17 20:59:31 +04:00
* r - > out . level_out = r - > in . level ;
2006-11-17 14:27:33 +03:00
DCESRV_PULL_HANDLE_WERR ( h , r - > in . bind_handle , DRSUAPI_BIND_HANDLE ) ;
b_state = h - > data ;
2008-10-17 20:59:31 +04:00
r - > out . res = talloc ( mem_ctx , union drsuapi_DsWriteAccountSpnResult ) ;
W_ERROR_HAVE_NO_MEMORY ( r - > out . res ) ;
2006-11-17 14:27:33 +03:00
switch ( r - > in . level ) {
case 1 : {
struct drsuapi_DsWriteAccountSpnRequest1 * req ;
struct ldb_message * msg ;
int count , i , ret ;
2008-10-17 20:59:31 +04:00
req = & r - > in . req - > req1 ;
2006-11-17 14:27:33 +03:00
count = req - > count ;
msg = ldb_msg_new ( mem_ctx ) ;
if ( msg = = NULL ) {
return WERR_NOMEM ;
}
2006-11-22 03:59:34 +03:00
msg - > dn = ldb_dn_new ( msg , b_state - > sam_ctx , req - > object_dn ) ;
if ( ! ldb_dn_validate ( msg - > dn ) ) {
2008-10-17 20:59:31 +04:00
r - > out . res - > res1 . status = WERR_OK ;
2006-11-17 14:27:33 +03:00
return WERR_OK ;
}
/* construct mods */
for ( i = 0 ; i < count ; i + + ) {
samdb_msg_add_string ( b_state - > sam_ctx ,
msg , msg , " servicePrincipalName " ,
req - > spn_names [ i ] . str ) ;
}
for ( i = 0 ; i < msg - > num_elements ; i + + ) {
switch ( req - > operation ) {
case DRSUAPI_DS_SPN_OPERATION_ADD :
msg - > elements [ i ] . flags = LDB_FLAG_MOD_ADD ;
break ;
case DRSUAPI_DS_SPN_OPERATION_REPLACE :
msg - > elements [ i ] . flags = LDB_FLAG_MOD_REPLACE ;
break ;
case DRSUAPI_DS_SPN_OPERATION_DELETE :
msg - > elements [ i ] . flags = LDB_FLAG_MOD_DELETE ;
break ;
}
}
/* Apply to database */
2007-11-27 03:25:11 +03:00
ret = ldb_modify ( b_state - > sam_ctx , msg ) ;
2006-11-17 14:27:33 +03:00
if ( ret ! = 0 ) {
DEBUG ( 0 , ( " Failed to modify SPNs on %s: %s \n " ,
2006-11-22 05:05:19 +03:00
ldb_dn_get_linearized ( msg - > dn ) ,
2006-11-17 14:27:33 +03:00
ldb_errstring ( b_state - > sam_ctx ) ) ) ;
2008-10-17 20:59:31 +04:00
r - > out . res - > res1 . status = WERR_ACCESS_DENIED ;
2006-11-17 14:27:33 +03:00
} else {
2008-10-17 20:59:31 +04:00
r - > out . res - > res1 . status = WERR_OK ;
2006-11-17 14:27:33 +03:00
}
return WERR_OK ;
}
}
return WERR_UNKNOWN_LEVEL ;
2004-10-10 05:35:33 +04:00
}
/*
2006-11-22 21:40:27 +03:00
drsuapi_DsRemoveDSServer
2004-10-10 05:35:33 +04:00
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_drsuapi_DsRemoveDSServer ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-11-22 21:40:27 +03:00
struct drsuapi_DsRemoveDSServer * r )
2004-10-10 05:35:33 +04:00
{
2008-10-02 13:28:13 +04:00
struct drsuapi_bind_state * b_state ;
struct dcesrv_handle * h ;
struct ldb_dn * ntds_dn ;
int ret ;
bool ok ;
ZERO_STRUCT ( r - > out . res ) ;
r - > out . level_out = 1 ;
DCESRV_PULL_HANDLE_WERR ( h , r - > in . bind_handle , DRSUAPI_BIND_HANDLE ) ;
b_state = h - > data ;
switch ( r - > in . level ) {
case 1 :
ntds_dn = ldb_dn_new ( mem_ctx , b_state - > sam_ctx , r - > in . req - > req1 . server_dn ) ;
W_ERROR_HAVE_NO_MEMORY ( ntds_dn ) ;
ok = ldb_dn_validate ( ntds_dn ) ;
if ( ! ok ) {
return WERR_FOOBAR ;
}
/* TODO: it's likely that we need more checks here */
ok = ldb_dn_add_child_fmt ( ntds_dn , " CN=NTDS Settings " ) ;
if ( ! ok ) {
return WERR_FOOBAR ;
}
if ( r - > in . req - > req1 . commit ) {
ret = ldb_delete ( b_state - > sam_ctx , ntds_dn ) ;
if ( ret ! = LDB_SUCCESS ) {
return WERR_FOOBAR ;
}
}
return WERR_OK ;
default :
break ;
}
return WERR_FOOBAR ;
2004-10-10 05:35:33 +04:00
}
/*
DRSUAPI_REMOVE_DS_DOMAIN
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_DRSUAPI_REMOVE_DS_DOMAIN ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-10-10 05:35:33 +04:00
struct DRSUAPI_REMOVE_DS_DOMAIN * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
2006-12-22 10:04:06 +03:00
/* Obtain the site name from a server DN */
2008-10-20 20:59:51 +04:00
static const char * result_site_name ( struct ldb_dn * site_dn )
2006-12-22 10:04:06 +03:00
{
/* Format is cn=<NETBIOS name>,cn=Servers,cn=<site>,cn=sites.... */
const struct ldb_val * val = ldb_dn_get_component_val ( site_dn , 2 ) ;
const char * name = ldb_dn_get_component_name ( site_dn , 2 ) ;
if ( ! name | | ( ldb_attr_cmp ( name , " cn " ) ! = 0 ) ) {
/* Ensure this matches the format. This gives us a
* bit more confidence that a ' cn ' value will be a
* ascii string */
return NULL ;
}
if ( val ) {
return ( char * ) val - > data ;
}
return NULL ;
}
/*
drsuapi_DsGetDomainControllerInfo
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_drsuapi_DsGetDomainControllerInfo_1 ( struct drsuapi_bind_state * b_state ,
2006-12-22 10:04:06 +03:00
TALLOC_CTX * mem_ctx ,
struct drsuapi_DsGetDomainControllerInfo * r )
{
struct ldb_dn * sites_dn ;
struct ldb_result * res ;
const char * attrs_account_1 [ ] = { " cn " , " dnsHostName " , NULL } ;
const char * attrs_account_2 [ ] = { " cn " , " dnsHostName " , " objectGUID " , NULL } ;
const char * attrs_none [ ] = { NULL } ;
const char * attrs_site [ ] = { " objectGUID " , NULL } ;
const char * attrs_ntds [ ] = { " options " , " objectGUID " , NULL } ;
const char * attrs_1 [ ] = { " serverReference " , " cn " , " dnsHostName " , NULL } ;
const char * attrs_2 [ ] = { " serverReference " , " cn " , " dnsHostName " , " objectGUID " , NULL } ;
const char * * attrs ;
struct drsuapi_DsGetDCInfoCtr1 * ctr1 ;
struct drsuapi_DsGetDCInfoCtr2 * ctr2 ;
int ret , i ;
2008-10-17 21:10:22 +04:00
* r - > out . level_out = r - > in . req - > req1 . level ;
r - > out . ctr = talloc ( mem_ctx , union drsuapi_DsGetDCInfoCtr ) ;
W_ERROR_HAVE_NO_MEMORY ( r - > out . ctr ) ;
2006-12-22 10:04:06 +03:00
2007-02-15 14:57:23 +03:00
sites_dn = samdb_sites_dn ( b_state - > sam_ctx , mem_ctx ) ;
2006-12-22 10:04:06 +03:00
if ( ! sites_dn ) {
return WERR_DS_OBJ_NOT_FOUND ;
}
2008-10-17 21:10:22 +04:00
switch ( * r - > out . level_out ) {
2006-12-22 10:04:06 +03:00
case - 1 :
2006-12-27 05:01:38 +03:00
/* this level is not like the others */
return WERR_UNKNOWN_LEVEL ;
2006-12-22 10:04:06 +03:00
case 1 :
attrs = attrs_1 ;
break ;
case 2 :
attrs = attrs_2 ;
break ;
default :
return WERR_UNKNOWN_LEVEL ;
}
2008-09-23 22:30:06 +04:00
ret = ldb_search ( b_state - > sam_ctx , mem_ctx , & res , sites_dn , LDB_SCOPE_SUBTREE , attrs ,
2006-12-22 10:04:06 +03:00
" objectClass=server " ) ;
if ( ret ) {
2007-04-23 11:26:08 +04:00
DEBUG ( 1 , ( " searching for servers in sites DN %s failed: %s \n " ,
ldb_dn_get_linearized ( sites_dn ) , ldb_errstring ( b_state - > sam_ctx ) ) ) ;
2006-12-22 10:04:06 +03:00
return WERR_GENERAL_FAILURE ;
}
2008-10-17 21:10:22 +04:00
switch ( * r - > out . level_out ) {
2006-12-22 10:04:06 +03:00
case 1 :
2008-10-17 21:10:22 +04:00
ctr1 = & r - > out . ctr - > ctr1 ;
2006-12-22 10:04:06 +03:00
ctr1 - > count = res - > count ;
ctr1 - > array = talloc_zero_array ( mem_ctx ,
struct drsuapi_DsGetDCInfo1 ,
res - > count ) ;
for ( i = 0 ; i < res - > count ; i + + ) {
struct ldb_dn * domain_dn ;
struct ldb_result * res_domain ;
struct ldb_result * res_account ;
2007-08-06 07:01:59 +04:00
struct ldb_dn * ntds_dn = ldb_dn_copy ( mem_ctx , res - > msgs [ i ] - > dn ) ;
2006-12-22 10:04:06 +03:00
struct ldb_dn * ref_dn
= ldb_msg_find_attr_as_dn ( b_state - > sam_ctx ,
mem_ctx , res - > msgs [ i ] ,
" serverReference " ) ;
if ( ! ntds_dn | | ! ldb_dn_add_child_fmt ( ntds_dn , " CN=NTDS Settings " ) ) {
return WERR_NOMEM ;
}
2008-09-23 22:30:06 +04:00
ret = ldb_search ( b_state - > sam_ctx , mem_ctx , & res_account , ref_dn ,
2006-12-22 10:04:06 +03:00
LDB_SCOPE_BASE , attrs_account_1 , " objectClass=computer " ) ;
2007-04-23 11:26:08 +04:00
if ( ret = = LDB_SUCCESS & & res_account - > count = = 1 ) {
2007-11-14 00:38:55 +03:00
const char * errstr ;
2006-12-22 10:04:06 +03:00
ctr1 - > array [ i ] . dns_name
= ldb_msg_find_attr_as_string ( res_account - > msgs [ 0 ] , " dNSHostName " , NULL ) ;
ctr1 - > array [ i ] . netbios_name
= ldb_msg_find_attr_as_string ( res_account - > msgs [ 0 ] , " cn " , NULL ) ;
ctr1 - > array [ i ] . computer_dn
= ldb_dn_get_linearized ( res_account - > msgs [ 0 ] - > dn ) ;
/* Determine if this is the PDC */
2007-11-14 00:38:55 +03:00
ret = samdb_search_for_parent_domain ( b_state - > sam_ctx ,
mem_ctx , res_account - > msgs [ 0 ] - > dn ,
& domain_dn , & errstr ) ;
2006-12-22 10:04:06 +03:00
2007-11-14 00:38:55 +03:00
if ( ret = = LDB_SUCCESS ) {
2008-09-23 22:30:06 +04:00
ret = ldb_search ( b_state - > sam_ctx , mem_ctx , & res_domain , domain_dn ,
2006-12-22 10:04:06 +03:00
LDB_SCOPE_BASE , attrs_none , " fSMORoleOwner=%s " ,
ldb_dn_get_linearized ( ntds_dn ) ) ;
if ( ret ) {
return WERR_GENERAL_FAILURE ;
}
if ( res_domain - > count = = 1 ) {
2007-10-07 02:25:41 +04:00
ctr1 - > array [ i ] . is_pdc = true ;
2006-12-22 10:04:06 +03:00
}
}
}
2007-04-23 11:26:08 +04:00
if ( ( ret ! = LDB_SUCCESS ) & & ( ret ! = LDB_ERR_NO_SUCH_OBJECT ) ) {
DEBUG ( 5 , ( " warning: searching for computer DN %s failed: %s \n " ,
ldb_dn_get_linearized ( ref_dn ) , ldb_errstring ( b_state - > sam_ctx ) ) ) ;
}
2006-12-22 10:04:06 +03:00
/* Look at server DN and extract site component */
ctr1 - > array [ i ] . site_name = result_site_name ( res - > msgs [ i ] - > dn ) ;
ctr1 - > array [ i ] . server_dn = ldb_dn_get_linearized ( res - > msgs [ i ] - > dn ) ;
2007-10-07 02:25:41 +04:00
ctr1 - > array [ i ] . is_enabled = true ;
2006-12-22 10:04:06 +03:00
}
break ;
case 2 :
2008-10-17 21:10:22 +04:00
ctr2 = & r - > out . ctr - > ctr2 ;
2006-12-22 10:04:06 +03:00
ctr2 - > count = res - > count ;
ctr2 - > array = talloc_zero_array ( mem_ctx ,
struct drsuapi_DsGetDCInfo2 ,
res - > count ) ;
for ( i = 0 ; i < res - > count ; i + + ) {
struct ldb_dn * domain_dn ;
struct ldb_result * res_domain ;
struct ldb_result * res_account ;
2007-08-06 07:01:59 +04:00
struct ldb_dn * ntds_dn = ldb_dn_copy ( mem_ctx , res - > msgs [ i ] - > dn ) ;
2006-12-22 10:04:06 +03:00
struct ldb_result * res_ntds ;
2007-08-06 07:01:59 +04:00
struct ldb_dn * site_dn = ldb_dn_copy ( mem_ctx , res - > msgs [ i ] - > dn ) ;
2006-12-22 10:04:06 +03:00
struct ldb_result * res_site ;
struct ldb_dn * ref_dn
= ldb_msg_find_attr_as_dn ( b_state - > sam_ctx ,
mem_ctx , res - > msgs [ i ] ,
" serverReference " ) ;
if ( ! ntds_dn | | ! ldb_dn_add_child_fmt ( ntds_dn , " CN=NTDS Settings " ) ) {
return WERR_NOMEM ;
}
/* Format is cn=<NETBIOS name>,cn=Servers,cn=<site>,cn=sites.... */
if ( ! site_dn | | ! ldb_dn_remove_child_components ( site_dn , 2 ) ) {
return WERR_NOMEM ;
}
2008-09-23 22:30:06 +04:00
ret = ldb_search ( b_state - > sam_ctx , mem_ctx , & res_ntds , ntds_dn ,
2006-12-22 10:04:06 +03:00
LDB_SCOPE_BASE , attrs_ntds , " objectClass=nTDSDSA " ) ;
2007-04-23 11:26:08 +04:00
if ( ret = = LDB_SUCCESS & & res_ntds - > count = = 1 ) {
2006-12-22 10:04:06 +03:00
ctr2 - > array [ i ] . is_gc
= ( ldb_msg_find_attr_as_int ( res_ntds - > msgs [ 0 ] , " options " , 0 ) = = 1 ) ;
ctr2 - > array [ i ] . ntds_guid
= samdb_result_guid ( res_ntds - > msgs [ 0 ] , " objectGUID " ) ;
ctr2 - > array [ i ] . ntds_dn = ldb_dn_get_linearized ( res_ntds - > msgs [ 0 ] - > dn ) ;
}
2007-04-23 11:26:08 +04:00
if ( ( ret ! = LDB_SUCCESS ) & & ( ret ! = LDB_ERR_NO_SUCH_OBJECT ) ) {
DEBUG ( 5 , ( " warning: searching for NTDS DN %s failed: %s \n " ,
ldb_dn_get_linearized ( ntds_dn ) , ldb_errstring ( b_state - > sam_ctx ) ) ) ;
}
2006-12-22 10:04:06 +03:00
2008-09-23 22:30:06 +04:00
ret = ldb_search ( b_state - > sam_ctx , mem_ctx , & res_site , site_dn ,
2006-12-22 10:04:06 +03:00
LDB_SCOPE_BASE , attrs_site , " objectClass=site " ) ;
2007-04-23 11:26:08 +04:00
if ( ret = = LDB_SUCCESS & & res_site - > count = = 1 ) {
2006-12-22 10:04:06 +03:00
ctr2 - > array [ i ] . site_guid
= samdb_result_guid ( res_site - > msgs [ 0 ] , " objectGUID " ) ;
ctr2 - > array [ i ] . site_dn = ldb_dn_get_linearized ( res_site - > msgs [ 0 ] - > dn ) ;
}
2007-04-23 11:26:08 +04:00
if ( ( ret ! = LDB_SUCCESS ) & & ( ret ! = LDB_ERR_NO_SUCH_OBJECT ) ) {
DEBUG ( 5 , ( " warning: searching for site DN %s failed: %s \n " ,
ldb_dn_get_linearized ( site_dn ) , ldb_errstring ( b_state - > sam_ctx ) ) ) ;
}
2006-12-22 10:04:06 +03:00
2008-09-23 22:30:06 +04:00
ret = ldb_search ( b_state - > sam_ctx , mem_ctx , & res_account , ref_dn ,
2006-12-22 10:04:06 +03:00
LDB_SCOPE_BASE , attrs_account_2 , " objectClass=computer " ) ;
2007-04-23 11:26:08 +04:00
if ( ret = = LDB_SUCCESS & & res_account - > count = = 1 ) {
2007-11-14 00:38:55 +03:00
const char * errstr ;
2006-12-22 10:04:06 +03:00
ctr2 - > array [ i ] . dns_name
= ldb_msg_find_attr_as_string ( res_account - > msgs [ 0 ] , " dNSHostName " , NULL ) ;
ctr2 - > array [ i ] . netbios_name
= ldb_msg_find_attr_as_string ( res_account - > msgs [ 0 ] , " cn " , NULL ) ;
ctr2 - > array [ i ] . computer_dn = ldb_dn_get_linearized ( res_account - > msgs [ 0 ] - > dn ) ;
ctr2 - > array [ i ] . computer_guid
= samdb_result_guid ( res_account - > msgs [ 0 ] , " objectGUID " ) ;
/* Determine if this is the PDC */
2007-11-14 00:38:55 +03:00
ret = samdb_search_for_parent_domain ( b_state - > sam_ctx ,
mem_ctx , res_account - > msgs [ 0 ] - > dn ,
& domain_dn , & errstr ) ;
2006-12-22 10:04:06 +03:00
2007-11-14 00:38:55 +03:00
if ( ret = = LDB_SUCCESS ) {
2008-09-23 22:30:06 +04:00
ret = ldb_search ( b_state - > sam_ctx , mem_ctx , & res_domain , domain_dn ,
2006-12-22 10:04:06 +03:00
LDB_SCOPE_BASE , attrs_none , " fSMORoleOwner=%s " ,
ldb_dn_get_linearized ( ntds_dn ) ) ;
2007-04-23 11:26:08 +04:00
if ( ret = = LDB_SUCCESS & & res_domain - > count = = 1 ) {
2007-10-07 02:25:41 +04:00
ctr2 - > array [ i ] . is_pdc = true ;
2006-12-22 10:04:06 +03:00
}
2007-04-23 11:26:08 +04:00
if ( ( ret ! = LDB_SUCCESS ) & & ( ret ! = LDB_ERR_NO_SUCH_OBJECT ) ) {
DEBUG ( 5 , ( " warning: searching for domain DN %s failed: %s \n " ,
ldb_dn_get_linearized ( domain_dn ) , ldb_errstring ( b_state - > sam_ctx ) ) ) ;
}
2006-12-22 10:04:06 +03:00
}
}
2007-04-23 11:26:08 +04:00
if ( ( ret ! = LDB_SUCCESS ) & & ( ret ! = LDB_ERR_NO_SUCH_OBJECT ) ) {
DEBUG ( 5 , ( " warning: searching for computer account DN %s failed: %s \n " ,
ldb_dn_get_linearized ( ref_dn ) , ldb_errstring ( b_state - > sam_ctx ) ) ) ;
}
2006-12-22 10:04:06 +03:00
/* Look at server DN and extract site component */
ctr2 - > array [ i ] . site_name = result_site_name ( res - > msgs [ i ] - > dn ) ;
ctr2 - > array [ i ] . server_dn = ldb_dn_get_linearized ( res - > msgs [ i ] - > dn ) ;
ctr2 - > array [ i ] . server_guid
= samdb_result_guid ( res - > msgs [ i ] , " objectGUID " ) ;
2007-10-07 02:25:41 +04:00
ctr2 - > array [ i ] . is_enabled = true ;
2006-12-22 10:04:06 +03:00
}
break ;
}
return WERR_OK ;
}
2004-10-10 05:35:33 +04:00
/*
2004-10-15 13:48:40 +04:00
drsuapi_DsGetDomainControllerInfo
2004-10-10 05:35:33 +04:00
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_drsuapi_DsGetDomainControllerInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-09-17 05:11:50 +04:00
struct drsuapi_DsGetDomainControllerInfo * r )
2004-10-10 05:35:33 +04:00
{
2006-12-22 10:04:06 +03:00
struct dcesrv_handle * h ;
struct drsuapi_bind_state * b_state ;
DCESRV_PULL_HANDLE_WERR ( h , r - > in . bind_handle , DRSUAPI_BIND_HANDLE ) ;
b_state = h - > data ;
switch ( r - > in . level ) {
case 1 :
2007-01-17 17:49:36 +03:00
return dcesrv_drsuapi_DsGetDomainControllerInfo_1 ( b_state , mem_ctx , r ) ;
2006-12-22 10:04:06 +03:00
}
return WERR_UNKNOWN_LEVEL ;
2004-10-10 05:35:33 +04:00
}
/*
2005-03-11 15:15:50 +03:00
drsuapi_DsAddEntry
2004-10-10 05:35:33 +04:00
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_drsuapi_DsAddEntry ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2005-03-11 15:15:50 +03:00
struct drsuapi_DsAddEntry * r )
2004-10-10 05:35:33 +04:00
{
2008-10-01 08:28:32 +04:00
WERROR status ;
struct drsuapi_bind_state * b_state ;
struct dcesrv_handle * h ;
uint32_t num = 0 ;
struct drsuapi_DsReplicaObjectIdentifier2 * ids = NULL ;
/* TODO: check which out level the client supports */
ZERO_STRUCTP ( r - > out . ctr ) ;
r - > out . level_out = 3 ;
r - > out . ctr - > ctr3 . level = 1 ;
r - > out . ctr - > ctr3 . error = talloc_zero ( mem_ctx , union drsuapi_DsAddEntryError ) ;
DCESRV_PULL_HANDLE_WERR ( h , r - > in . bind_handle , DRSUAPI_BIND_HANDLE ) ;
b_state = h - > data ;
switch ( r - > in . level ) {
case 2 :
status = dsdb_origin_objects_commit ( b_state - > sam_ctx ,
mem_ctx ,
& r - > in . req - > req2 . first_object ,
& num ,
& ids ) ;
if ( ! W_ERROR_IS_OK ( status ) ) {
r - > out . ctr - > ctr3 . error - > info1 . status = status ;
W_ERROR_NOT_OK_RETURN ( status ) ;
}
r - > out . ctr - > ctr3 . count = num ;
r - > out . ctr - > ctr3 . objects = ids ;
return WERR_OK ;
default :
break ;
}
return WERR_FOOBAR ;
2004-10-10 05:35:33 +04:00
}
/*
DRSUAPI_EXECUTE_KCC
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_DRSUAPI_EXECUTE_KCC ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-10-10 05:35:33 +04:00
struct DRSUAPI_EXECUTE_KCC * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2004-12-07 15:20:28 +03:00
drsuapi_DsReplicaGetInfo
2004-10-10 05:35:33 +04:00
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_drsuapi_DsReplicaGetInfo ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-12-07 15:20:28 +03:00
struct drsuapi_DsReplicaGetInfo * r )
2004-10-10 05:35:33 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
DRSUAPI_ADD_SID_HISTORY
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_DRSUAPI_ADD_SID_HISTORY ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-10-10 05:35:33 +04:00
struct DRSUAPI_ADD_SID_HISTORY * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2006-07-04 14:25:04 +04:00
drsuapi_DsGetMemberships2
2004-10-10 05:35:33 +04:00
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_drsuapi_DsGetMemberships2 ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2006-07-04 14:25:04 +04:00
struct drsuapi_DsGetMemberships2 * r )
2004-10-10 05:35:33 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
DRSUAPI_REPLICA_VERIFY_OBJECTS
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_DRSUAPI_REPLICA_VERIFY_OBJECTS ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-10-10 05:35:33 +04:00
struct DRSUAPI_REPLICA_VERIFY_OBJECTS * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
DRSUAPI_GET_OBJECT_EXISTENCE
*/
2007-01-17 17:49:36 +03:00
static WERROR dcesrv_DRSUAPI_GET_OBJECT_EXISTENCE ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
2004-10-10 05:35:33 +04:00
struct DRSUAPI_GET_OBJECT_EXISTENCE * r )
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/*
2007-05-30 13:54:19 +04:00
drsuapi_QuerySitesByCost
2004-10-10 05:35:33 +04:00
*/
2007-05-30 13:54:19 +04:00
static WERROR dcesrv_drsuapi_QuerySitesByCost ( struct dcesrv_call_state * dce_call , TALLOC_CTX * mem_ctx ,
struct drsuapi_QuerySitesByCost * r )
2004-10-10 05:35:33 +04:00
{
DCESRV_FAULT ( DCERPC_FAULT_OP_RNG_ERROR ) ;
}
/* include the generated boilerplate */
# include "librpc/gen_ndr/ndr_drsuapi_s.c"