2007-01-09 14:15:56 +03:00
/*
Unix SMB / CIFS mplementation .
Helper functions for applying replicated objects
2007-03-14 22:10:21 +03:00
Copyright ( C ) Stefan Metzmacher < metze @ samba . org > 2007
2007-01-09 14:15:56 +03: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
2007-01-09 14:15:56 +03: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/>.
2007-01-09 14:15:56 +03:00
*/
# include "includes.h"
# include "dsdb/samdb/samdb.h"
# include "lib/ldb/include/ldb_errors.h"
2008-10-11 23:31:42 +04:00
# include "../lib/util/dlinklist.h"
2007-01-09 14:15:56 +03:00
# include "librpc/gen_ndr/ndr_misc.h"
# include "librpc/gen_ndr/ndr_drsuapi.h"
# include "librpc/gen_ndr/ndr_drsblobs.h"
2008-09-24 17:30:23 +04:00
# include "../lib/crypto/crypto.h"
2009-03-16 07:20:28 +03:00
# include "../libcli/drsuapi/drsuapi.h"
2007-02-15 15:40:13 +03:00
# include "libcli/auth/libcli_auth.h"
2008-01-02 07:05:05 +03:00
# include "param/param.h"
2007-02-12 14:46:35 +03:00
2008-10-01 08:28:32 +04:00
static WERROR dsdb_convert_object_ex ( struct ldb_context * ldb ,
const struct dsdb_schema * schema ,
const struct drsuapi_DsReplicaObjectListItemEx * in ,
const DATA_BLOB * gensec_skey ,
TALLOC_CTX * mem_ctx ,
struct dsdb_extended_replicated_object * out )
2007-01-09 14:15:56 +03:00
{
NTSTATUS nt_status ;
2007-11-09 21:24:51 +03:00
enum ndr_err_code ndr_err ;
2007-01-09 14:15:56 +03:00
WERROR status ;
uint32_t i ;
struct ldb_message * msg ;
2007-01-11 12:45:30 +03:00
struct replPropertyMetaDataBlob * md ;
2007-01-09 14:15:56 +03:00
struct ldb_val guid_value ;
NTTIME whenChanged = 0 ;
time_t whenChanged_t ;
const char * whenChanged_s ;
2007-01-13 13:53:12 +03:00
const char * rdn_name = NULL ;
const struct ldb_val * rdn_value = NULL ;
const struct dsdb_attribute * rdn_attr = NULL ;
2007-01-09 14:15:56 +03:00
uint32_t rdn_attid ;
2007-01-13 13:53:12 +03:00
struct drsuapi_DsReplicaAttribute * name_a = NULL ;
struct drsuapi_DsReplicaMetaData * name_d = NULL ;
struct replPropertyMetaData1 * rdn_m = NULL ;
2007-02-15 15:40:13 +03:00
struct dom_sid * sid = NULL ;
uint32_t rid = 0 ;
2007-01-09 14:15:56 +03:00
int ret ;
if ( ! in - > object . identifier ) {
return WERR_FOOBAR ;
}
if ( ! in - > object . identifier - > dn | | ! in - > object . identifier - > dn [ 0 ] ) {
return WERR_FOOBAR ;
}
2007-02-11 20:36:33 +03:00
if ( in - > object . attribute_ctr . num_attributes ! = 0 & & ! in - > meta_data_ctr ) {
return WERR_FOOBAR ;
}
if ( in - > object . attribute_ctr . num_attributes ! = in - > meta_data_ctr - > count ) {
return WERR_FOOBAR ;
}
2007-02-15 15:40:13 +03:00
sid = & in - > object . identifier - > sid ;
if ( sid - > num_auths > 0 ) {
rid = sid - > sub_auths [ sid - > num_auths - 1 ] ;
}
2007-01-09 14:15:56 +03:00
msg = ldb_msg_new ( mem_ctx ) ;
W_ERROR_HAVE_NO_MEMORY ( msg ) ;
msg - > dn = ldb_dn_new ( msg , ldb , in - > object . identifier - > dn ) ;
W_ERROR_HAVE_NO_MEMORY ( msg - > dn ) ;
rdn_name = ldb_dn_get_rdn_name ( msg - > dn ) ;
rdn_attr = dsdb_attribute_by_lDAPDisplayName ( schema , rdn_name ) ;
if ( ! rdn_attr ) {
return WERR_FOOBAR ;
}
rdn_attid = rdn_attr - > attributeID_id ;
rdn_value = ldb_dn_get_rdn_val ( msg - > dn ) ;
msg - > num_elements = in - > object . attribute_ctr . num_attributes ;
msg - > elements = talloc_array ( msg , struct ldb_message_element ,
msg - > num_elements ) ;
W_ERROR_HAVE_NO_MEMORY ( msg - > elements ) ;
2007-01-11 12:45:30 +03:00
md = talloc ( mem_ctx , struct replPropertyMetaDataBlob ) ;
W_ERROR_HAVE_NO_MEMORY ( md ) ;
2007-01-09 14:15:56 +03:00
2007-01-11 12:45:30 +03:00
md - > version = 1 ;
md - > reserved = 0 ;
md - > ctr . ctr1 . count = in - > meta_data_ctr - > count ;
md - > ctr . ctr1 . reserved = 0 ;
md - > ctr . ctr1 . array = talloc_array ( mem_ctx ,
struct replPropertyMetaData1 ,
md - > ctr . ctr1 . count + 1 ) ; /* +1 because of the RDN attribute */
W_ERROR_HAVE_NO_MEMORY ( md - > ctr . ctr1 . array ) ;
2007-01-09 14:15:56 +03:00
for ( i = 0 ; i < in - > meta_data_ctr - > count ; i + + ) {
struct drsuapi_DsReplicaAttribute * a ;
struct drsuapi_DsReplicaMetaData * d ;
struct replPropertyMetaData1 * m ;
2007-02-11 20:51:38 +03:00
struct ldb_message_element * e ;
2009-07-02 09:33:01 +04:00
int j ;
2007-01-09 14:15:56 +03:00
a = & in - > object . attribute_ctr . attributes [ i ] ;
d = & in - > meta_data_ctr - > meta_data [ i ] ;
2007-01-11 12:45:30 +03:00
m = & md - > ctr . ctr1 . array [ i ] ;
2007-02-11 20:51:38 +03:00
e = & msg - > elements [ i ] ;
2009-07-02 09:33:01 +04:00
for ( j = 0 ; j < a - > value_ctr . num_values ; j + + ) {
status = drsuapi_decrypt_attribute ( a - > value_ctr . values [ j ] . blob , gensec_skey , rid , a ) ;
W_ERROR_NOT_OK_RETURN ( status ) ;
}
2007-02-12 14:46:35 +03:00
2008-12-19 07:24:36 +03:00
status = dsdb_attribute_drsuapi_to_ldb ( ldb , schema , a , msg - > elements , e ) ;
2009-11-28 05:27:06 +03:00
if ( ! NT_STATUS_IS_OK ( status ) & & a - > value_ctr . num_values = = 0 ) {
/* w2k8-r2 occasionally sends bogus empty
attributes with rubbish attribute IDs . The
only think we can do is discard these */
DEBUG ( 0 , ( __location__ " : Discarding bogus empty DsReplicaAttribute with attid 0x%x \n " ,
a - > attid ) ) ;
ZERO_STRUCTP ( e ) ;
continue ;
}
2007-02-11 20:51:38 +03:00
W_ERROR_NOT_OK_RETURN ( status ) ;
2007-01-09 14:15:56 +03:00
m - > attid = a - > attid ;
m - > version = d - > version ;
2007-03-09 13:09:37 +03:00
m - > originating_change_time = d - > originating_change_time ;
m - > originating_invocation_id = d - > originating_invocation_id ;
m - > originating_usn = d - > originating_usn ;
2007-01-09 14:15:56 +03:00
m - > local_usn = 0 ;
2007-03-09 13:09:37 +03:00
if ( d - > originating_change_time > whenChanged ) {
whenChanged = d - > originating_change_time ;
2007-01-09 14:15:56 +03:00
}
if ( a - > attid = = DRSUAPI_ATTRIBUTE_name ) {
name_a = a ;
name_d = d ;
2007-01-11 12:45:30 +03:00
rdn_m = & md - > ctr . ctr1 . array [ md - > ctr . ctr1 . count ] ;
2007-01-09 14:15:56 +03:00
}
}
2009-11-28 05:27:06 +03:00
/* delete any empty elements */
for ( i = 0 ; i < msg - > num_elements ; i + + ) {
if ( msg - > elements [ i ] . name = = NULL ) {
ldb_msg_remove_element ( msg , & msg - > elements [ i ] ) ;
i - - ;
}
}
2007-01-13 13:53:12 +03:00
if ( rdn_m ) {
2009-09-11 12:01:27 +04:00
struct ldb_message_element * el ;
el = ldb_msg_find_element ( msg , rdn_attr - > lDAPDisplayName ) ;
if ( ! el ) {
2009-11-16 19:01:43 +03:00
ret = ldb_msg_add_value ( msg , rdn_attr - > lDAPDisplayName , rdn_value , NULL ) ;
2009-09-11 12:01:27 +04:00
if ( ret ! = LDB_SUCCESS ) {
return WERR_FOOBAR ;
}
} else {
if ( el - > num_values ! = 1 ) {
DEBUG ( 0 , ( __location__ " : Unexpected num_values=%u \n " ,
el - > num_values ) ) ;
return WERR_FOOBAR ;
}
if ( ! ldb_val_equal_exact ( & el - > values [ 0 ] , rdn_value ) ) {
DEBUG ( 0 , ( __location__ " : RDN value changed? '%*.*s' '%*.*s' \n " ,
( int ) el - > values [ 0 ] . length , ( int ) el - > values [ 0 ] . length , el - > values [ 0 ] . data ,
( int ) rdn_value - > length , ( int ) rdn_value - > length , rdn_value - > data ) ) ;
return WERR_FOOBAR ;
}
2007-01-13 13:53:12 +03:00
}
2007-01-09 14:15:56 +03:00
2007-01-13 13:53:12 +03:00
rdn_m - > attid = rdn_attid ;
rdn_m - > version = name_d - > version ;
2007-03-09 13:09:37 +03:00
rdn_m - > originating_change_time = name_d - > originating_change_time ;
rdn_m - > originating_invocation_id = name_d - > originating_invocation_id ;
rdn_m - > originating_usn = name_d - > originating_usn ;
2007-01-13 13:53:12 +03:00
rdn_m - > local_usn = 0 ;
md - > ctr . ctr1 . count + + ;
2007-01-09 14:15:56 +03:00
}
whenChanged_t = nt_time_to_unix ( whenChanged ) ;
whenChanged_s = ldb_timestring ( msg , whenChanged_t ) ;
W_ERROR_HAVE_NO_MEMORY ( whenChanged_s ) ;
2007-01-13 13:53:12 +03:00
2008-01-02 07:05:05 +03:00
ndr_err = ndr_push_struct_blob ( & guid_value , msg ,
lp_iconv_convenience ( ldb_get_opaque ( ldb , " loadparm " ) ) ,
& in - > object . identifier - > guid ,
2007-01-13 13:53:12 +03:00
( ndr_push_flags_fn_t ) ndr_push_GUID ) ;
2007-11-09 21:24:51 +03:00
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
nt_status = ndr_map_error2ntstatus ( ndr_err ) ;
2007-01-13 13:53:12 +03:00
return ntstatus_to_werror ( nt_status ) ;
2007-01-09 14:15:56 +03:00
}
2007-01-13 13:53:12 +03:00
out - > msg = msg ;
out - > guid_value = guid_value ;
out - > when_changed = whenChanged_s ;
out - > meta_data = md ;
2007-01-09 14:15:56 +03:00
return WERR_OK ;
}
2009-11-09 13:26:02 +03:00
WERROR dsdb_extended_replicated_objects_convert ( struct ldb_context * ldb ,
const char * partition_dn ,
const struct drsuapi_DsReplicaOIDMapping_Ctr * mapping_ctr ,
uint32_t object_count ,
const struct drsuapi_DsReplicaObjectListItemEx * first_object ,
uint32_t linked_attributes_count ,
const struct drsuapi_DsReplicaLinkedAttribute * linked_attributes ,
const struct repsFromTo1 * source_dsa ,
const struct drsuapi_DsReplicaCursor2CtrEx * uptodateness_vector ,
const DATA_BLOB * gensec_skey ,
TALLOC_CTX * mem_ctx ,
struct dsdb_extended_replicated_objects * * objects )
2007-01-09 14:15:56 +03:00
{
WERROR status ;
2007-01-14 18:35:10 +03:00
const struct dsdb_schema * schema ;
2007-01-09 14:15:56 +03:00
struct dsdb_extended_replicated_objects * out ;
2007-01-11 13:21:38 +03:00
const struct drsuapi_DsReplicaObjectListItemEx * cur ;
2007-01-09 14:15:56 +03:00
uint32_t i ;
2007-01-14 18:35:10 +03:00
schema = dsdb_get_schema ( ldb ) ;
if ( ! schema ) {
return WERR_DS_SCHEMA_NOT_LOADED ;
}
2009-10-26 04:06:16 +03:00
status = dsdb_schema_pfm_contains_drsuapi_pfm ( schema - > prefixmap , mapping_ctr ) ;
2007-01-09 14:15:56 +03:00
W_ERROR_NOT_OK_RETURN ( status ) ;
out = talloc_zero ( mem_ctx , struct dsdb_extended_replicated_objects ) ;
W_ERROR_HAVE_NO_MEMORY ( out ) ;
2007-01-13 14:37:13 +03:00
out - > version = DSDB_EXTENDED_REPLICATED_OBJECTS_VERSION ;
2007-01-09 14:15:56 +03:00
2007-01-13 14:37:13 +03:00
out - > partition_dn = ldb_dn_new ( out , ldb , partition_dn ) ;
2007-01-09 14:15:56 +03:00
W_ERROR_HAVE_NO_MEMORY ( out - > partition_dn ) ;
2007-01-12 19:02:10 +03:00
out - > source_dsa = source_dsa ;
out - > uptodateness_vector = uptodateness_vector ;
2007-01-12 16:17:25 +03:00
2007-01-09 14:15:56 +03:00
out - > num_objects = object_count ;
out - > objects = talloc_array ( out ,
struct dsdb_extended_replicated_object ,
out - > num_objects ) ;
W_ERROR_HAVE_NO_MEMORY ( out - > objects ) ;
2009-09-03 06:52:31 +04:00
/* pass the linked attributes down to the repl_meta_data
module */
out - > linked_attributes_count = linked_attributes_count ;
out - > linked_attributes = linked_attributes ;
2007-01-09 14:15:56 +03:00
for ( i = 0 , cur = first_object ; cur ; cur = cur - > next_object , i + + ) {
if ( i = = out - > num_objects ) {
return WERR_FOOBAR ;
}
2008-10-01 08:28:32 +04:00
status = dsdb_convert_object_ex ( ldb , schema ,
cur , gensec_skey ,
out - > objects , & out - > objects [ i ] ) ;
2009-09-10 11:42:36 +04:00
if ( ! W_ERROR_IS_OK ( status ) ) {
DEBUG ( 0 , ( " Failed to convert object %s \n " , cur - > object . identifier - > dn ) ) ;
return status ;
}
2007-01-09 14:15:56 +03:00
}
if ( i ! = out - > num_objects ) {
return WERR_FOOBAR ;
}
2009-11-09 13:26:02 +03:00
* objects = out ;
return WERR_OK ;
}
WERROR dsdb_extended_replicated_objects_commit ( struct ldb_context * ldb ,
struct dsdb_extended_replicated_objects * objects ,
uint64_t * notify_uSN )
{
struct ldb_result * ext_res ;
int ret ;
uint64_t seq_num1 , seq_num2 ;
2007-01-09 14:15:56 +03:00
/* TODO: handle linked attributes */
2009-09-02 05:17:43 +04:00
/* wrap the extended operation in a transaction
See [ MS - DRSR ] 3.3 .2 Transactions
*/
ret = ldb_transaction_start ( ldb ) ;
if ( ret ! = LDB_SUCCESS ) {
DEBUG ( 0 , ( __location__ " Failed to start transaction \n " ) ) ;
return WERR_FOOBAR ;
}
2009-11-09 13:26:02 +03:00
ret = dsdb_load_partition_usn ( ldb , objects - > partition_dn , & seq_num1 ) ;
2009-09-16 01:06:07 +04:00
if ( ret ! = LDB_SUCCESS ) {
DEBUG ( 0 , ( __location__ " Failed to load partition uSN \n " ) ) ;
ldb_transaction_cancel ( ldb ) ;
return WERR_FOOBAR ;
}
2009-11-09 13:26:02 +03:00
ret = ldb_extended ( ldb , DSDB_EXTENDED_REPLICATED_OBJECTS_OID , objects , & ext_res ) ;
2007-01-09 14:15:56 +03:00
if ( ret ! = LDB_SUCCESS ) {
2008-01-23 07:44:02 +03:00
DEBUG ( 0 , ( " Failed to apply records: %s: %s \n " ,
ldb_errstring ( ldb ) , ldb_strerror ( ret ) ) ) ;
2009-09-02 05:17:43 +04:00
ldb_transaction_cancel ( ldb ) ;
2007-01-09 14:15:56 +03:00
return WERR_FOOBAR ;
}
talloc_free ( ext_res ) ;
2009-09-16 01:06:07 +04:00
ret = ldb_transaction_prepare_commit ( ldb ) ;
if ( ret ! = LDB_SUCCESS ) {
DEBUG ( 0 , ( __location__ " Failed to prepare commit of transaction \n " ) ) ;
return WERR_FOOBAR ;
}
2009-11-09 13:26:02 +03:00
ret = dsdb_load_partition_usn ( ldb , objects - > partition_dn , & seq_num2 ) ;
2009-09-16 01:06:07 +04:00
if ( ret ! = LDB_SUCCESS ) {
DEBUG ( 0 , ( __location__ " Failed to load partition uSN \n " ) ) ;
ldb_transaction_cancel ( ldb ) ;
return WERR_FOOBAR ;
}
/* if this replication partner didn't need to be notified
before this transaction then it still doesn ' t need to be
notified , as the changes came from this server */
if ( seq_num2 > seq_num1 & & seq_num1 < = * notify_uSN ) {
* notify_uSN = seq_num2 ;
}
2009-09-02 05:17:43 +04:00
ret = ldb_transaction_commit ( ldb ) ;
if ( ret ! = LDB_SUCCESS ) {
DEBUG ( 0 , ( __location__ " Failed to commit transaction \n " ) ) ;
return WERR_FOOBAR ;
}
2009-09-16 01:06:07 +04:00
2009-09-15 20:23:14 +04:00
DEBUG ( 2 , ( " Replicated %u objects (%u linked attributes) for %s \n " ,
2009-11-09 13:26:02 +03:00
objects - > num_objects , objects - > linked_attributes_count ,
ldb_dn_get_linearized ( objects - > partition_dn ) ) ) ;
2009-09-15 20:23:14 +04:00
2007-01-09 14:15:56 +03:00
return WERR_OK ;
}
2008-10-01 08:28:32 +04:00
static WERROR dsdb_convert_object ( struct ldb_context * ldb ,
const struct dsdb_schema * schema ,
const struct drsuapi_DsReplicaObjectListItem * in ,
TALLOC_CTX * mem_ctx ,
struct ldb_message * * _msg )
{
WERROR status ;
uint32_t i ;
struct ldb_message * msg ;
if ( ! in - > object . identifier ) {
return WERR_FOOBAR ;
}
if ( ! in - > object . identifier - > dn | | ! in - > object . identifier - > dn [ 0 ] ) {
return WERR_FOOBAR ;
}
msg = ldb_msg_new ( mem_ctx ) ;
W_ERROR_HAVE_NO_MEMORY ( msg ) ;
msg - > dn = ldb_dn_new ( msg , ldb , in - > object . identifier - > dn ) ;
W_ERROR_HAVE_NO_MEMORY ( msg - > dn ) ;
msg - > num_elements = in - > object . attribute_ctr . num_attributes ;
msg - > elements = talloc_array ( msg , struct ldb_message_element ,
msg - > num_elements ) ;
W_ERROR_HAVE_NO_MEMORY ( msg - > elements ) ;
for ( i = 0 ; i < msg - > num_elements ; i + + ) {
struct drsuapi_DsReplicaAttribute * a ;
struct ldb_message_element * e ;
a = & in - > object . attribute_ctr . attributes [ i ] ;
e = & msg - > elements [ i ] ;
status = dsdb_attribute_drsuapi_to_ldb ( ldb , schema , a , msg - > elements , e ) ;
W_ERROR_NOT_OK_RETURN ( status ) ;
}
2009-09-11 09:15:39 +04:00
2008-10-01 08:28:32 +04:00
* _msg = msg ;
2009-09-11 09:15:39 +04:00
2008-10-01 08:28:32 +04:00
return WERR_OK ;
}
WERROR dsdb_origin_objects_commit ( struct ldb_context * ldb ,
TALLOC_CTX * mem_ctx ,
const struct drsuapi_DsReplicaObjectListItem * first_object ,
uint32_t * _num ,
struct drsuapi_DsReplicaObjectIdentifier2 * * _ids )
{
WERROR status ;
const struct dsdb_schema * schema ;
const struct drsuapi_DsReplicaObjectListItem * cur ;
struct ldb_message * * objects ;
struct drsuapi_DsReplicaObjectIdentifier2 * ids ;
uint32_t i ;
uint32_t num_objects = 0 ;
const char * const attrs [ ] = {
" objectGUID " ,
" objectSid " ,
NULL
} ;
struct ldb_result * res ;
int ret ;
schema = dsdb_get_schema ( ldb ) ;
if ( ! schema ) {
return WERR_DS_SCHEMA_NOT_LOADED ;
}
for ( cur = first_object ; cur ; cur = cur - > next_object ) {
num_objects + + ;
}
if ( num_objects = = 0 ) {
return WERR_OK ;
}
2009-10-06 11:55:14 +04:00
ret = ldb_transaction_start ( ldb ) ;
if ( ret ! = LDB_SUCCESS ) {
return WERR_DS_INTERNAL_FAILURE ;
}
2008-10-01 08:28:32 +04:00
objects = talloc_array ( mem_ctx , struct ldb_message * ,
num_objects ) ;
2009-10-06 11:55:14 +04:00
if ( objects = = NULL ) {
status = WERR_NOMEM ;
goto cancel ;
}
2008-10-01 08:28:32 +04:00
for ( i = 0 , cur = first_object ; cur ; cur = cur - > next_object , i + + ) {
status = dsdb_convert_object ( ldb , schema ,
cur , objects , & objects [ i ] ) ;
2009-10-06 11:55:14 +04:00
if ( ! W_ERROR_IS_OK ( status ) ) {
goto cancel ;
}
2008-10-01 08:28:32 +04:00
}
2009-10-07 09:20:16 +04:00
ids = talloc_array ( mem_ctx ,
2008-10-01 08:28:32 +04:00
struct drsuapi_DsReplicaObjectIdentifier2 ,
num_objects ) ;
2009-10-06 11:55:14 +04:00
if ( ids = = NULL ) {
status = WERR_NOMEM ;
goto cancel ;
}
2008-10-01 08:28:32 +04:00
for ( i = 0 ; i < num_objects ; i + + ) {
struct dom_sid * sid = NULL ;
2009-10-06 11:55:14 +04:00
struct ldb_request * add_req ;
2009-09-23 01:26:59 +04:00
DEBUG ( 6 , ( __location__ " : adding %s \n " ,
ldb_dn_get_linearized ( objects [ i ] - > dn ) ) ) ;
2009-10-06 11:55:14 +04:00
ret = ldb_build_add_req ( & add_req ,
ldb ,
objects ,
objects [ i ] ,
NULL ,
NULL ,
ldb_op_default_callback ,
NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
status = WERR_DS_INTERNAL_FAILURE ;
goto cancel ;
}
ret = ldb_request_add_control ( add_req , LDB_CONTROL_RELAX_OID , true , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
status = WERR_DS_INTERNAL_FAILURE ;
goto cancel ;
}
2009-09-23 01:26:59 +04:00
2009-10-06 11:55:14 +04:00
ret = ldb_request ( ldb , add_req ) ;
if ( ret = = LDB_SUCCESS ) {
ret = ldb_wait ( add_req - > handle , LDB_WAIT_ALL ) ;
}
if ( ret ! = LDB_SUCCESS ) {
DEBUG ( 0 , ( __location__ " : Failed add of %s - %s \n " ,
ldb_dn_get_linearized ( objects [ i ] - > dn ) , ldb_errstring ( ldb ) ) ) ;
status = WERR_DS_INTERNAL_FAILURE ;
2008-10-01 08:28:32 +04:00
goto cancel ;
}
2009-10-06 11:55:14 +04:00
talloc_free ( add_req ) ;
2008-10-01 08:28:32 +04:00
ret = ldb_search ( ldb , objects , & res , objects [ i ] - > dn ,
LDB_SCOPE_BASE , attrs ,
" (objectClass=*) " ) ;
2009-10-06 11:55:14 +04:00
if ( ret ! = LDB_SUCCESS ) {
status = WERR_DS_INTERNAL_FAILURE ;
2008-10-01 08:28:32 +04:00
goto cancel ;
}
ids [ i ] . guid = samdb_result_guid ( res - > msgs [ 0 ] , " objectGUID " ) ;
sid = samdb_result_dom_sid ( objects , res - > msgs [ 0 ] , " objectSid " ) ;
if ( sid ) {
ids [ i ] . sid = * sid ;
} else {
ZERO_STRUCT ( ids [ i ] . sid ) ;
}
}
2009-10-06 11:55:14 +04:00
ret = ldb_transaction_commit ( ldb ) ;
if ( ret ! = LDB_SUCCESS ) {
return WERR_DS_INTERNAL_FAILURE ;
}
2008-10-01 08:28:32 +04:00
talloc_free ( objects ) ;
* _num = num_objects ;
* _ids = ids ;
return WERR_OK ;
2009-10-06 11:55:14 +04:00
2008-10-01 08:28:32 +04:00
cancel :
talloc_free ( objects ) ;
ldb_transaction_cancel ( ldb ) ;
2009-10-06 11:55:14 +04:00
return status ;
2008-10-01 08:28:32 +04:00
}