2008-06-24 01:13:21 +04:00
/*
Unix SMB / CIFS implementation .
Copyright ( C ) Stefan ( metze ) Metzmacher 2005
Copyright ( C ) Guenther Deschner 2008
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
2008-07-17 03:03:57 +04:00
# include "libnet/libnet.h"
2008-06-24 01:13:21 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int libnet_dssync_free_context ( struct dssync_context * ctx )
{
if ( ! ctx ) {
return 0 ;
}
if ( is_valid_policy_hnd ( & ctx - > bind_handle ) & & ctx - > cli ) {
rpccli_drsuapi_DsUnbind ( ctx - > cli , ctx , & ctx - > bind_handle , NULL ) ;
}
return 0 ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS libnet_dssync_init_context ( TALLOC_CTX * mem_ctx ,
struct dssync_context * * ctx_p )
{
struct dssync_context * ctx ;
ctx = TALLOC_ZERO_P ( mem_ctx , struct dssync_context ) ;
NT_STATUS_HAVE_NO_MEMORY ( ctx ) ;
talloc_set_destructor ( ctx , libnet_dssync_free_context ) ;
* ctx_p = ctx ;
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-06-26 17:06:58 +04:00
static DATA_BLOB * decrypt_attr_val ( TALLOC_CTX * mem_ctx ,
DATA_BLOB * session_key ,
uint32_t rid ,
enum drsuapi_DsAttributeId id ,
DATA_BLOB * raw_data )
{
bool rcrypt = false ;
DATA_BLOB out_data ;
ZERO_STRUCT ( out_data ) ;
switch ( id ) {
case DRSUAPI_ATTRIBUTE_dBCSPwd :
case DRSUAPI_ATTRIBUTE_unicodePwd :
case DRSUAPI_ATTRIBUTE_ntPwdHistory :
case DRSUAPI_ATTRIBUTE_lmPwdHistory :
rcrypt = true ;
break ;
case DRSUAPI_ATTRIBUTE_supplementalCredentials :
case DRSUAPI_ATTRIBUTE_priorValue :
case DRSUAPI_ATTRIBUTE_currentValue :
case DRSUAPI_ATTRIBUTE_trustAuthOutgoing :
case DRSUAPI_ATTRIBUTE_trustAuthIncoming :
case DRSUAPI_ATTRIBUTE_initialAuthOutgoing :
case DRSUAPI_ATTRIBUTE_initialAuthIncoming :
break ;
default :
return raw_data ;
}
out_data = decrypt_drsuapi_blob ( mem_ctx , session_key , rcrypt ,
rid , raw_data ) ;
if ( out_data . length ) {
return ( DATA_BLOB * ) talloc_memdup ( mem_ctx , & out_data , sizeof ( DATA_BLOB ) ) ;
}
return raw_data ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void parse_obj_identifier ( struct drsuapi_DsReplicaObjectIdentifier * id ,
uint32_t * rid )
{
if ( ! id | | ! rid ) {
return ;
}
* rid = 0 ;
if ( id - > sid . num_auths > 0 ) {
* rid = id - > sid . sub_auths [ id - > sid . num_auths - 1 ] ;
}
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void parse_obj_attribute ( TALLOC_CTX * mem_ctx ,
DATA_BLOB * session_key ,
uint32_t rid ,
struct drsuapi_DsReplicaAttribute * attr )
{
int i = 0 ;
for ( i = 0 ; i < attr - > value_ctr . num_values ; i + + ) {
DATA_BLOB * plain_data = NULL ;
plain_data = decrypt_attr_val ( mem_ctx ,
session_key ,
rid ,
attr - > attid ,
attr - > value_ctr . values [ i ] . blob ) ;
attr - > value_ctr . values [ i ] . blob = plain_data ;
}
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void libnet_dssync_decrypt_attributes ( TALLOC_CTX * mem_ctx ,
DATA_BLOB * session_key ,
struct drsuapi_DsReplicaObjectListItemEx * cur )
{
for ( ; cur ; cur = cur - > next_object ) {
uint32_t i ;
uint32_t rid = 0 ;
parse_obj_identifier ( cur - > object . identifier , & rid ) ;
for ( i = 0 ; i < cur - > object . attribute_ctr . num_attributes ; i + + ) {
struct drsuapi_DsReplicaAttribute * attr ;
attr = & cur - > object . attribute_ctr . attributes [ i ] ;
if ( attr - > value_ctr . num_values < 1 ) {
continue ;
}
if ( ! attr - > value_ctr . values [ 0 ] . blob ) {
continue ;
}
parse_obj_attribute ( mem_ctx ,
session_key ,
rid ,
attr ) ;
}
}
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-06-24 01:13:21 +04:00
static NTSTATUS libnet_dssync_bind ( TALLOC_CTX * mem_ctx ,
struct dssync_context * ctx )
{
NTSTATUS status ;
WERROR werr ;
struct GUID bind_guid ;
struct drsuapi_DsBindInfoCtr bind_info ;
struct drsuapi_DsBindInfo28 info28 ;
ZERO_STRUCT ( info28 ) ;
GUID_from_string ( DRSUAPI_DS_BIND_GUID , & bind_guid ) ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_BASE ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2 ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1 ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2 ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2 ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01 ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3 ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2 ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6 ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8 ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5 ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6 ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3 ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7 ;
info28 . supported_extensions | = DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT ;
info28 . site_guid = GUID_zero ( ) ;
2008-07-22 18:18:03 +04:00
info28 . pid = 508 ;
2008-06-24 01:13:21 +04:00
info28 . repl_epoch = 0 ;
bind_info . length = 28 ;
bind_info . info . info28 = info28 ;
status = rpccli_drsuapi_DsBind ( ctx - > cli , mem_ctx ,
& bind_guid ,
& bind_info ,
& ctx - > bind_handle ,
& werr ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
if ( ! W_ERROR_IS_OK ( werr ) ) {
return werror_to_ntstatus ( werr ) ;
}
2008-07-17 15:04:04 +04:00
ZERO_STRUCT ( ctx - > remote_info28 ) ;
switch ( bind_info . length ) {
case 24 : {
struct drsuapi_DsBindInfo24 * info24 ;
info24 = & bind_info . info . info24 ;
ctx - > remote_info28 . site_guid = info24 - > site_guid ;
ctx - > remote_info28 . supported_extensions = info24 - > supported_extensions ;
ctx - > remote_info28 . pid = info24 - > pid ;
ctx - > remote_info28 . repl_epoch = 0 ;
break ;
}
case 28 :
ctx - > remote_info28 = bind_info . info . info28 ;
break ;
case 48 : {
struct drsuapi_DsBindInfo48 * info48 ;
info48 = & bind_info . info . info48 ;
ctx - > remote_info28 . site_guid = info48 - > site_guid ;
ctx - > remote_info28 . supported_extensions = info48 - > supported_extensions ;
ctx - > remote_info28 . pid = info48 - > pid ;
ctx - > remote_info28 . repl_epoch = info48 - > repl_epoch ;
break ;
}
default :
DEBUG ( 1 , ( " Warning: invalid info length in bind info: %d \n " ,
bind_info . length ) ) ;
break ;
}
2008-06-24 01:13:21 +04:00
return status ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS libnet_dssync_lookup_nc ( TALLOC_CTX * mem_ctx ,
struct dssync_context * ctx )
{
NTSTATUS status ;
WERROR werr ;
int32_t level = 1 ;
union drsuapi_DsNameRequest req ;
int32_t level_out ;
struct drsuapi_DsNameString names [ 1 ] ;
union drsuapi_DsNameCtr ctr ;
names [ 0 ] . str = talloc_asprintf ( mem_ctx , " %s \\ " , ctx - > domain_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( names [ 0 ] . str ) ;
req . req1 . codepage = 1252 ; /* german */
req . req1 . language = 0x00000407 ; /* german */
req . req1 . count = 1 ;
req . req1 . names = names ;
req . req1 . format_flags = DRSUAPI_DS_NAME_FLAG_NO_FLAGS ;
req . req1 . format_offered = DRSUAPI_DS_NAME_FORMAT_UKNOWN ;
req . req1 . format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779 ;
status = rpccli_drsuapi_DsCrackNames ( ctx - > cli , mem_ctx ,
& ctx - > bind_handle ,
level ,
& req ,
& level_out ,
& ctr ,
& werr ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-06-26 12:22:40 +04:00
ctx - > error_message = talloc_asprintf ( mem_ctx ,
" Failed to lookup DN for domain name: %s " ,
get_friendly_werror_msg ( werr ) ) ;
2008-06-24 01:13:21 +04:00
return status ;
}
if ( ! W_ERROR_IS_OK ( werr ) ) {
return werror_to_ntstatus ( werr ) ;
}
if ( ctr . ctr1 - > count ! = 1 ) {
return NT_STATUS_UNSUCCESSFUL ;
}
if ( ctr . ctr1 - > array [ 0 ] . status ! = DRSUAPI_DS_NAME_STATUS_OK ) {
return NT_STATUS_UNSUCCESSFUL ;
}
ctx - > nc_dn = talloc_strdup ( mem_ctx , ctr . ctr1 - > array [ 0 ] . result_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( ctx - > nc_dn ) ;
2008-06-27 01:24:25 +04:00
if ( ! ctx - > dns_domain_name ) {
ctx - > dns_domain_name = talloc_strdup_upper ( mem_ctx ,
ctr . ctr1 - > array [ 0 ] . dns_domain_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( ctx - > dns_domain_name ) ;
}
2008-06-24 01:13:21 +04:00
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS libnet_dssync_init ( TALLOC_CTX * mem_ctx ,
struct dssync_context * ctx )
{
NTSTATUS status ;
status = libnet_dssync_bind ( mem_ctx , ctx ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
if ( ! ctx - > nc_dn ) {
status = libnet_dssync_lookup_nc ( mem_ctx , ctx ) ;
}
return status ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS libnet_dssync_process ( TALLOC_CTX * mem_ctx ,
struct dssync_context * ctx )
{
NTSTATUS status ;
WERROR werr ;
int32_t level = 8 ;
int32_t level_out = 0 ;
union drsuapi_DsGetNCChangesRequest req ;
union drsuapi_DsGetNCChangesCtr ctr ;
struct drsuapi_DsReplicaObjectIdentifier nc ;
struct dom_sid null_sid ;
struct drsuapi_DsGetNCChangesCtr1 * ctr1 = NULL ;
struct drsuapi_DsGetNCChangesCtr6 * ctr6 = NULL ;
2008-07-17 03:05:06 +04:00
struct replUpToDateVectorBlob * old_utdv = NULL ;
struct drsuapi_DsReplicaCursorCtrEx cursors ;
struct drsuapi_DsReplicaCursorCtrEx * pcursors = NULL ;
struct replUpToDateVectorBlob new_utdv ;
2008-06-24 01:13:21 +04:00
int32_t out_level = 0 ;
int y ;
2008-07-17 15:05:43 +04:00
uint32_t replica_flags = DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE |
DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP |
DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS |
DRSUAPI_DS_REPLICA_NEIGHBOUR_RETURN_OBJECT_PARENTS |
DRSUAPI_DS_REPLICA_NEIGHBOUR_NEVER_SYNCED ;
2008-06-24 01:13:21 +04:00
ZERO_STRUCT ( null_sid ) ;
ZERO_STRUCT ( req ) ;
nc . dn = ctx - > nc_dn ;
nc . guid = GUID_zero ( ) ;
nc . sid = null_sid ;
2008-07-17 03:05:06 +04:00
status = ctx - > ops - > startup ( ctx , mem_ctx , & old_utdv ) ;
2008-07-16 19:12:04 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
ctx - > error_message = talloc_asprintf ( mem_ctx ,
" Failed to call startup operation: %s " ,
nt_errstr ( status ) ) ;
goto out ;
}
2008-07-17 03:05:06 +04:00
if ( old_utdv ) {
pcursors = & cursors ;
ZERO_STRUCTP ( pcursors ) ;
switch ( old_utdv - > version ) {
case 1 :
pcursors - > count = old_utdv - > ctr . ctr1 . count ;
pcursors - > cursors = old_utdv - > ctr . ctr1 . cursors ;
break ;
case 2 :
pcursors - > count = old_utdv - > ctr . ctr2 . count ;
pcursors - > cursors = talloc_array ( mem_ctx ,
struct drsuapi_DsReplicaCursor ,
pcursors - > count ) ;
for ( y = 0 ; y < pcursors - > count ; y + + ) {
pcursors - > cursors [ y ] . source_dsa_invocation_id =
old_utdv - > ctr . ctr2 . cursors [ y ] . source_dsa_invocation_id ;
pcursors - > cursors [ y ] . highest_usn =
old_utdv - > ctr . ctr2 . cursors [ y ] . highest_usn ;
}
break ;
}
}
2008-07-17 15:05:43 +04:00
if ( ctx - > remote_info28 . supported_extensions
& DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8 )
{
level = 8 ;
req . req8 . naming_context = & nc ;
req . req8 . replica_flags = replica_flags ;
req . req8 . max_object_count = 402 ;
req . req8 . max_ndr_size = 402116 ;
2008-07-17 03:05:06 +04:00
req . req8 . uptodateness_vector = pcursors ;
2008-07-17 15:05:43 +04:00
} else {
level = 5 ;
req . req5 . naming_context = & nc ;
req . req5 . replica_flags = replica_flags ;
req . req5 . max_object_count = 402 ;
req . req5 . max_ndr_size = 402116 ;
2008-07-17 03:05:06 +04:00
req . req5 . uptodateness_vector = pcursors ;
2008-07-17 15:05:43 +04:00
}
2008-06-24 01:13:21 +04:00
for ( y = 0 ; ; y + + ) {
2008-06-27 03:41:26 +04:00
bool last_query = true ;
2008-06-24 01:13:21 +04:00
if ( level = = 8 ) {
DEBUG ( 1 , ( " start[%d] tmp_higest_usn: %llu , highest_usn: %llu \n " , y ,
( long long ) req . req8 . highwatermark . tmp_highest_usn ,
( long long ) req . req8 . highwatermark . highest_usn ) ) ;
2008-07-17 15:05:43 +04:00
} else if ( level = = 5 ) {
DEBUG ( 1 , ( " start[%d] tmp_higest_usn: %llu , highest_usn: %llu \n " , y ,
( long long ) req . req5 . highwatermark . tmp_highest_usn ,
( long long ) req . req5 . highwatermark . highest_usn ) ) ;
2008-06-24 01:13:21 +04:00
}
status = rpccli_drsuapi_DsGetNCChanges ( ctx - > cli , mem_ctx ,
& ctx - > bind_handle ,
level ,
& req ,
& level_out ,
& ctr ,
& werr ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-06-26 12:22:40 +04:00
ctx - > error_message = talloc_asprintf ( mem_ctx ,
" Failed to get NC Changes: %s " ,
get_friendly_werror_msg ( werr ) ) ;
2008-06-24 01:13:21 +04:00
goto out ;
}
if ( ! W_ERROR_IS_OK ( werr ) ) {
2008-06-26 12:22:40 +04:00
status = werror_to_ntstatus ( werr ) ;
2008-06-24 01:13:21 +04:00
goto out ;
}
if ( level_out = = 1 ) {
out_level = 1 ;
ctr1 = & ctr . ctr1 ;
} else if ( level_out = = 2 ) {
out_level = 1 ;
ctr1 = ctr . ctr2 . ctr . mszip1 . ctr1 ;
}
2008-06-25 02:21:37 +04:00
status = cli_get_session_key ( mem_ctx , ctx - > cli , & ctx - > session_key ) ;
2008-06-24 01:13:21 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-06-26 12:22:40 +04:00
ctx - > error_message = talloc_asprintf ( mem_ctx ,
" Failed to get Session Key: %s " ,
nt_errstr ( status ) ) ;
2008-06-24 01:13:21 +04:00
return status ;
}
if ( out_level = = 1 ) {
DEBUG ( 1 , ( " end[%d] tmp_highest_usn: %llu , highest_usn: %llu \n " , y ,
( long long ) ctr1 - > new_highwatermark . tmp_highest_usn ,
( long long ) ctr1 - > new_highwatermark . highest_usn ) ) ;
2008-06-26 17:06:58 +04:00
libnet_dssync_decrypt_attributes ( mem_ctx ,
& ctx - > session_key ,
ctr1 - > first_object ) ;
2008-07-16 17:30:03 +04:00
if ( ctr1 - > more_data ) {
2008-06-27 03:41:26 +04:00
req . req5 . highwatermark = ctr1 - > new_highwatermark ;
last_query = false ;
}
2008-07-16 19:12:04 +04:00
if ( ctx - > ops - > process_objects ) {
status = ctx - > ops - > process_objects ( ctx , mem_ctx ,
ctr1 - > first_object ,
& ctr1 - > mapping_ctr ) ;
2008-06-24 01:13:21 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-06-26 12:22:40 +04:00
ctx - > error_message = talloc_asprintf ( mem_ctx ,
" Failed to call processing function: %s " ,
nt_errstr ( status ) ) ;
2008-06-24 01:13:21 +04:00
goto out ;
}
}
2008-06-27 03:41:26 +04:00
if ( ! last_query ) {
2008-06-24 01:13:21 +04:00
continue ;
}
2008-07-17 03:05:06 +04:00
ZERO_STRUCT ( new_utdv ) ;
new_utdv . version = 1 ;
new_utdv . ctr . ctr1 . count = ctr1 - > uptodateness_vector - > count ;
new_utdv . ctr . ctr1 . cursors = ctr1 - > uptodateness_vector - > cursors ;
2008-06-24 01:13:21 +04:00
}
if ( level_out = = 6 ) {
out_level = 6 ;
ctr6 = & ctr . ctr6 ;
} else if ( level_out = = 7
& & ctr . ctr7 . level = = 6
& & ctr . ctr7 . type = = DRSUAPI_COMPRESSION_TYPE_MSZIP ) {
out_level = 6 ;
ctr6 = ctr . ctr7 . ctr . mszip6 . ctr6 ;
}
if ( out_level = = 6 ) {
DEBUG ( 1 , ( " end[%d] tmp_highest_usn: %llu , highest_usn: %llu \n " , y ,
( long long ) ctr6 - > new_highwatermark . tmp_highest_usn ,
( long long ) ctr6 - > new_highwatermark . highest_usn ) ) ;
2008-06-26 17:06:58 +04:00
libnet_dssync_decrypt_attributes ( mem_ctx ,
& ctx - > session_key ,
ctr6 - > first_object ) ;
2008-07-16 17:30:03 +04:00
if ( ctr6 - > more_data ) {
2008-06-27 03:41:26 +04:00
req . req8 . highwatermark = ctr6 - > new_highwatermark ;
last_query = false ;
}
2008-07-16 19:12:04 +04:00
if ( ctx - > ops - > process_objects ) {
status = ctx - > ops - > process_objects ( ctx , mem_ctx ,
ctr6 - > first_object ,
& ctr6 - > mapping_ctr ) ;
2008-06-24 01:13:21 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-06-26 12:22:40 +04:00
ctx - > error_message = talloc_asprintf ( mem_ctx ,
" Failed to call processing function: %s " ,
nt_errstr ( status ) ) ;
2008-06-24 01:13:21 +04:00
goto out ;
}
}
2008-06-27 03:41:26 +04:00
if ( ! last_query ) {
2008-06-24 01:13:21 +04:00
continue ;
}
2008-07-17 03:05:06 +04:00
ZERO_STRUCT ( new_utdv ) ;
new_utdv . version = 2 ;
new_utdv . ctr . ctr2 . count = ctr6 - > uptodateness_vector - > count ;
new_utdv . ctr . ctr2 . cursors = ctr6 - > uptodateness_vector - > cursors ;
2008-06-24 01:13:21 +04:00
}
2008-07-17 03:05:06 +04:00
status = ctx - > ops - > finish ( ctx , mem_ctx , & new_utdv ) ;
2008-07-16 19:12:04 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
ctx - > error_message = talloc_asprintf ( mem_ctx ,
" Failed to call finishing operation: %s " ,
nt_errstr ( status ) ) ;
goto out ;
}
2008-06-24 01:13:21 +04:00
break ;
}
out :
return status ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
NTSTATUS libnet_dssync ( TALLOC_CTX * mem_ctx ,
struct dssync_context * ctx )
{
NTSTATUS status ;
status = libnet_dssync_init ( mem_ctx , ctx ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto out ;
}
status = libnet_dssync_process ( mem_ctx , ctx ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto out ;
}
out :
return status ;
}