root/source3/libnet/libnet_dssync.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. libnet_dssync_free_context
  2. libnet_dssync_init_context
  3. decrypt_attr_val
  4. parse_obj_identifier
  5. parse_obj_attribute
  6. libnet_dssync_decrypt_attributes
  7. libnet_dssync_bind
  8. libnet_dssync_lookup_nc
  9. libnet_dssync_init
  10. libnet_dssync_build_request
  11. libnet_dssync_getncchanges
  12. libnet_dssync_process
  13. libnet_dssync

   1 /*
   2    Unix SMB/CIFS implementation.
   3 
   4    Copyright (C) Stefan (metze) Metzmacher 2005
   5    Copyright (C) Guenther Deschner 2008
   6    Copyright (C) Michael Adam 2008
   7 
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12 
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17 
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 
  23 #include "includes.h"
  24 #include "libnet/libnet.h"
  25 
  26 /****************************************************************
  27 ****************************************************************/
  28 
  29 static int libnet_dssync_free_context(struct dssync_context *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
  30 {
  31         if (!ctx) {
  32                 return 0;
  33         }
  34 
  35         if (is_valid_policy_hnd(&ctx->bind_handle) && ctx->cli) {
  36                 rpccli_drsuapi_DsUnbind(ctx->cli, ctx, &ctx->bind_handle, NULL);
  37         }
  38 
  39         return 0;
  40 }
  41 
  42 /****************************************************************
  43 ****************************************************************/
  44 
  45 NTSTATUS libnet_dssync_init_context(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  46                                     struct dssync_context **ctx_p)
  47 {
  48         struct dssync_context *ctx;
  49 
  50         ctx = TALLOC_ZERO_P(mem_ctx, struct dssync_context);
  51         NT_STATUS_HAVE_NO_MEMORY(ctx);
  52 
  53         talloc_set_destructor(ctx, libnet_dssync_free_context);
  54         ctx->clean_old_entries = false;
  55 
  56         *ctx_p = ctx;
  57 
  58         return NT_STATUS_OK;
  59 }
  60 
  61 /****************************************************************
  62 ****************************************************************/
  63 
  64 static DATA_BLOB *decrypt_attr_val(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  65                                    DATA_BLOB *session_key,
  66                                    uint32_t rid,
  67                                    enum drsuapi_DsAttributeId id,
  68                                    DATA_BLOB *raw_data)
  69 {
  70         bool rcrypt = false;
  71         DATA_BLOB out_data;
  72 
  73         ZERO_STRUCT(out_data);
  74 
  75         switch (id) {
  76                 case DRSUAPI_ATTRIBUTE_dBCSPwd:
  77                 case DRSUAPI_ATTRIBUTE_unicodePwd:
  78                 case DRSUAPI_ATTRIBUTE_ntPwdHistory:
  79                 case DRSUAPI_ATTRIBUTE_lmPwdHistory:
  80                         rcrypt  = true;
  81                         break;
  82                 case DRSUAPI_ATTRIBUTE_supplementalCredentials:
  83                 case DRSUAPI_ATTRIBUTE_priorValue:
  84                 case DRSUAPI_ATTRIBUTE_currentValue:
  85                 case DRSUAPI_ATTRIBUTE_trustAuthOutgoing:
  86                 case DRSUAPI_ATTRIBUTE_trustAuthIncoming:
  87                 case DRSUAPI_ATTRIBUTE_initialAuthOutgoing:
  88                 case DRSUAPI_ATTRIBUTE_initialAuthIncoming:
  89                         break;
  90                 default:
  91                         return raw_data;
  92         }
  93 
  94         out_data = decrypt_drsuapi_blob(mem_ctx, session_key, rcrypt,
  95                                           rid, raw_data);
  96 
  97         if (out_data.length) {
  98                 return (DATA_BLOB *)talloc_memdup(mem_ctx, &out_data, sizeof(DATA_BLOB));
  99         }
 100 
 101         return raw_data;
 102 }
 103 
 104 /****************************************************************
 105 ****************************************************************/
 106 
 107 static void parse_obj_identifier(struct drsuapi_DsReplicaObjectIdentifier *id,
     /* [<][>][^][v][top][bottom][index][help] */
 108                                  uint32_t *rid)
 109 {
 110         if (!id || !rid) {
 111                 return;
 112         }
 113 
 114         *rid = 0;
 115 
 116         if (id->sid.num_auths > 0) {
 117                 *rid = id->sid.sub_auths[id->sid.num_auths - 1];
 118         }
 119 }
 120 
 121 /****************************************************************
 122 ****************************************************************/
 123 
 124 static void parse_obj_attribute(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 125                                 DATA_BLOB *session_key,
 126                                 uint32_t rid,
 127                                 struct drsuapi_DsReplicaAttribute *attr)
 128 {
 129         int i = 0;
 130 
 131         for (i=0; i<attr->value_ctr.num_values; i++) {
 132 
 133                 DATA_BLOB *plain_data = NULL;
 134 
 135                 plain_data = decrypt_attr_val(mem_ctx,
 136                                               session_key,
 137                                               rid,
 138                                               attr->attid,
 139                                               attr->value_ctr.values[i].blob);
 140 
 141                 attr->value_ctr.values[i].blob = plain_data;
 142         }
 143 }
 144 
 145 /****************************************************************
 146 ****************************************************************/
 147 
 148 static void libnet_dssync_decrypt_attributes(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 149                                              DATA_BLOB *session_key,
 150                                              struct drsuapi_DsReplicaObjectListItemEx *cur)
 151 {
 152         for (; cur; cur = cur->next_object) {
 153 
 154                 uint32_t i;
 155                 uint32_t rid = 0;
 156 
 157                 parse_obj_identifier(cur->object.identifier, &rid);
 158 
 159                 for (i=0; i < cur->object.attribute_ctr.num_attributes; i++) {
 160 
 161                         struct drsuapi_DsReplicaAttribute *attr;
 162 
 163                         attr = &cur->object.attribute_ctr.attributes[i];
 164 
 165                         if (attr->value_ctr.num_values < 1) {
 166                                 continue;
 167                         }
 168 
 169                         if (!attr->value_ctr.values[0].blob) {
 170                                 continue;
 171                         }
 172 
 173                         parse_obj_attribute(mem_ctx,
 174                                             session_key,
 175                                             rid,
 176                                             attr);
 177                 }
 178         }
 179 }
 180 /****************************************************************
 181 ****************************************************************/
 182 
 183 static NTSTATUS libnet_dssync_bind(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 184                                    struct dssync_context *ctx)
 185 {
 186         NTSTATUS status;
 187         WERROR werr;
 188 
 189         struct GUID bind_guid;
 190         struct drsuapi_DsBindInfoCtr bind_info;
 191         struct drsuapi_DsBindInfo28 info28;
 192 
 193         ZERO_STRUCT(info28);
 194 
 195         GUID_from_string(DRSUAPI_DS_BIND_GUID, &bind_guid);
 196 
 197         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_BASE;
 198         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION;
 199         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI;
 200         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2;
 201         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS;
 202         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1;
 203         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION;
 204         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE;
 205         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2;
 206         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION;
 207         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2;
 208         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD;
 209         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND;
 210         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO;
 211         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION;
 212         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01;
 213         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP;
 214         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY;
 215         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3;
 216         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2;
 217         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6;
 218         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS;
 219         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8;
 220         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5;
 221         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6;
 222         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3;
 223         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7;
 224         info28.supported_extensions     |= DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT;
 225         info28.site_guid                = GUID_zero();
 226         info28.pid                      = 508;
 227         info28.repl_epoch               = 0;
 228 
 229         bind_info.length = 28;
 230         bind_info.info.info28 = info28;
 231 
 232         status = rpccli_drsuapi_DsBind(ctx->cli, mem_ctx,
 233                                        &bind_guid,
 234                                        &bind_info,
 235                                        &ctx->bind_handle,
 236                                        &werr);
 237 
 238         if (!NT_STATUS_IS_OK(status)) {
 239                 return status;
 240         }
 241 
 242         if (!W_ERROR_IS_OK(werr)) {
 243                 return werror_to_ntstatus(werr);
 244         }
 245 
 246         ZERO_STRUCT(ctx->remote_info28);
 247         switch (bind_info.length) {
 248         case 24: {
 249                 struct drsuapi_DsBindInfo24 *info24;
 250                 info24 = &bind_info.info.info24;
 251                 ctx->remote_info28.site_guid            = info24->site_guid;
 252                 ctx->remote_info28.supported_extensions = info24->supported_extensions;
 253                 ctx->remote_info28.pid                  = info24->pid;
 254                 ctx->remote_info28.repl_epoch           = 0;
 255                 break;
 256         }
 257         case 28:
 258                 ctx->remote_info28 = bind_info.info.info28;
 259                 break;
 260         case 48: {
 261                 struct drsuapi_DsBindInfo48 *info48;
 262                 info48 = &bind_info.info.info48;
 263                 ctx->remote_info28.site_guid            = info48->site_guid;
 264                 ctx->remote_info28.supported_extensions = info48->supported_extensions;
 265                 ctx->remote_info28.pid                  = info48->pid;
 266                 ctx->remote_info28.repl_epoch           = info48->repl_epoch;
 267                 break;
 268         }
 269         default:
 270                 DEBUG(1, ("Warning: invalid info length in bind info: %d\n",
 271                           bind_info.length));
 272                 break;
 273         }
 274 
 275         return status;
 276 }
 277 
 278 /****************************************************************
 279 ****************************************************************/
 280 
 281 static NTSTATUS libnet_dssync_lookup_nc(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 282                                         struct dssync_context *ctx)
 283 {
 284         NTSTATUS status;
 285         WERROR werr;
 286         int32_t level = 1;
 287         union drsuapi_DsNameRequest req;
 288         int32_t level_out;
 289         struct drsuapi_DsNameString names[1];
 290         union drsuapi_DsNameCtr ctr;
 291 
 292         names[0].str = talloc_asprintf(mem_ctx, "%s\\", ctx->domain_name);
 293         NT_STATUS_HAVE_NO_MEMORY(names[0].str);
 294 
 295         req.req1.codepage       = 1252; /* german */
 296         req.req1.language       = 0x00000407; /* german */
 297         req.req1.count          = 1;
 298         req.req1.names          = names;
 299         req.req1.format_flags   = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
 300         req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_UNKNOWN;
 301         req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
 302 
 303         status = rpccli_drsuapi_DsCrackNames(ctx->cli, mem_ctx,
 304                                              &ctx->bind_handle,
 305                                              level,
 306                                              &req,
 307                                              &level_out,
 308                                              &ctr,
 309                                              &werr);
 310         if (!NT_STATUS_IS_OK(status)) {
 311                 ctx->error_message = talloc_asprintf(ctx,
 312                         "Failed to lookup DN for domain name: %s",
 313                         get_friendly_werror_msg(werr));
 314                 return status;
 315         }
 316 
 317         if (!W_ERROR_IS_OK(werr)) {
 318                 return werror_to_ntstatus(werr);
 319         }
 320 
 321         if (ctr.ctr1->count != 1) {
 322                 return NT_STATUS_UNSUCCESSFUL;
 323         }
 324 
 325         if (ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
 326                 return NT_STATUS_UNSUCCESSFUL;
 327         }
 328 
 329         ctx->nc_dn = talloc_strdup(mem_ctx, ctr.ctr1->array[0].result_name);
 330         NT_STATUS_HAVE_NO_MEMORY(ctx->nc_dn);
 331 
 332         if (!ctx->dns_domain_name) {
 333                 ctx->dns_domain_name = talloc_strdup_upper(mem_ctx,
 334                         ctr.ctr1->array[0].dns_domain_name);
 335                 NT_STATUS_HAVE_NO_MEMORY(ctx->dns_domain_name);
 336         }
 337 
 338         return NT_STATUS_OK;
 339 }
 340 
 341 /****************************************************************
 342 ****************************************************************/
 343 
 344 static NTSTATUS libnet_dssync_init(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 345                                    struct dssync_context *ctx)
 346 {
 347         NTSTATUS status;
 348 
 349         status = libnet_dssync_bind(mem_ctx, ctx);
 350         if (!NT_STATUS_IS_OK(status)) {
 351                 return status;
 352         }
 353 
 354         if (!ctx->nc_dn) {
 355                 status = libnet_dssync_lookup_nc(mem_ctx, ctx);
 356         }
 357 
 358         return status;
 359 }
 360 
 361 /****************************************************************
 362 ****************************************************************/
 363 
 364 static NTSTATUS libnet_dssync_build_request(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 365                                             struct dssync_context *ctx,
 366                                             const char *dn,
 367                                             struct replUpToDateVectorBlob *utdv,
 368                                             int32_t *plevel,
 369                                             union drsuapi_DsGetNCChangesRequest *preq)
 370 {
 371         NTSTATUS status;
 372         uint32_t count;
 373         int32_t level;
 374         union drsuapi_DsGetNCChangesRequest req;
 375         struct dom_sid null_sid;
 376         enum drsuapi_DsExtendedOperation extended_op;
 377         struct drsuapi_DsReplicaObjectIdentifier *nc = NULL;
 378         struct drsuapi_DsReplicaCursorCtrEx *cursors = NULL;
 379 
 380         uint32_t replica_flags  = DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE |
 381                                   DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP |
 382                                   DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS |
 383                                   DRSUAPI_DS_REPLICA_NEIGHBOUR_RETURN_OBJECT_PARENTS |
 384                                   DRSUAPI_DS_REPLICA_NEIGHBOUR_NEVER_SYNCED;
 385 
 386         ZERO_STRUCT(null_sid);
 387         ZERO_STRUCT(req);
 388 
 389         if (ctx->remote_info28.supported_extensions
 390             & DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8)
 391         {
 392                 level = 8;
 393         } else {
 394                 level = 5;
 395         }
 396 
 397         nc = TALLOC_ZERO_P(mem_ctx, struct drsuapi_DsReplicaObjectIdentifier);
 398         if (!nc) {
 399                 status = NT_STATUS_NO_MEMORY;
 400                 goto fail;
 401         }
 402         nc->dn = dn;
 403         nc->guid = GUID_zero();
 404         nc->sid = null_sid;
 405 
 406         if (!ctx->single_object_replication &&
 407             !ctx->force_full_replication && utdv)
 408         {
 409                 cursors = TALLOC_ZERO_P(mem_ctx,
 410                                          struct drsuapi_DsReplicaCursorCtrEx);
 411                 if (!cursors) {
 412                         status = NT_STATUS_NO_MEMORY;
 413                         goto fail;
 414                 }
 415 
 416                 switch (utdv->version) {
 417                 case 1:
 418                         cursors->count = utdv->ctr.ctr1.count;
 419                         cursors->cursors = utdv->ctr.ctr1.cursors;
 420                         break;
 421                 case 2:
 422                         cursors->count = utdv->ctr.ctr2.count;
 423                         cursors->cursors = talloc_array(cursors,
 424                                                 struct drsuapi_DsReplicaCursor,
 425                                                 cursors->count);
 426                         if (!cursors->cursors) {
 427                                 status = NT_STATUS_NO_MEMORY;
 428                                 goto fail;
 429                         }
 430                         for (count = 0; count < cursors->count; count++) {
 431                                 cursors->cursors[count].source_dsa_invocation_id =
 432                                         utdv->ctr.ctr2.cursors[count].source_dsa_invocation_id;
 433                                 cursors->cursors[count].highest_usn =
 434                                         utdv->ctr.ctr2.cursors[count].highest_usn;
 435                         }
 436                         break;
 437                 }
 438         }
 439 
 440         if (ctx->single_object_replication) {
 441                 extended_op = DRSUAPI_EXOP_REPL_OBJ;
 442         } else {
 443                 extended_op = DRSUAPI_EXOP_NONE;
 444         }
 445 
 446         if (level == 8) {
 447                 req.req8.naming_context         = nc;
 448                 req.req8.replica_flags          = replica_flags;
 449                 req.req8.max_object_count       = 402;
 450                 req.req8.max_ndr_size           = 402116;
 451                 req.req8.uptodateness_vector    = cursors;
 452                 req.req8.extended_op            = extended_op;
 453         } else if (level == 5) {
 454                 req.req5.naming_context         = nc;
 455                 req.req5.replica_flags          = replica_flags;
 456                 req.req5.max_object_count       = 402;
 457                 req.req5.max_ndr_size           = 402116;
 458                 req.req5.uptodateness_vector    = cursors;
 459                 req.req5.extended_op            = extended_op;
 460         } else {
 461                 status = NT_STATUS_INVALID_PARAMETER;
 462                 goto fail;
 463         }
 464 
 465         if (plevel) {
 466                 *plevel = level;
 467         }
 468 
 469         if (preq) {
 470                 *preq = req;
 471         }
 472 
 473         return NT_STATUS_OK;
 474 
 475 fail:
 476         TALLOC_FREE(nc);
 477         TALLOC_FREE(cursors);
 478         return status;
 479 }
 480 
 481 static NTSTATUS libnet_dssync_getncchanges(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 482                                            struct dssync_context *ctx,
 483                                            int32_t level,
 484                                            union drsuapi_DsGetNCChangesRequest *req,
 485                                            struct replUpToDateVectorBlob **pnew_utdv)
 486 {
 487         NTSTATUS status;
 488         WERROR werr;
 489         union drsuapi_DsGetNCChangesCtr ctr;
 490         struct drsuapi_DsGetNCChangesCtr1 *ctr1 = NULL;
 491         struct drsuapi_DsGetNCChangesCtr6 *ctr6 = NULL;
 492         struct replUpToDateVectorBlob *new_utdv = NULL;
 493         int32_t level_out = 0;
 494         int32_t out_level = 0;
 495         int y;
 496         bool last_query;
 497 
 498         if (!ctx->single_object_replication) {
 499                 new_utdv = TALLOC_ZERO_P(mem_ctx, struct replUpToDateVectorBlob);
 500                 if (!new_utdv) {
 501                         status = NT_STATUS_NO_MEMORY;
 502                         goto out;
 503                 }
 504         }
 505 
 506         for (y=0, last_query = false; !last_query; y++) {
 507                 struct drsuapi_DsReplicaObjectListItemEx *first_object = NULL;
 508                 struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr = NULL;
 509 
 510                 if (level == 8) {
 511                         DEBUG(1,("start[%d] tmp_higest_usn: %llu , highest_usn: %llu\n",y,
 512                                 (long long)req->req8.highwatermark.tmp_highest_usn,
 513                                 (long long)req->req8.highwatermark.highest_usn));
 514                 } else if (level == 5) {
 515                         DEBUG(1,("start[%d] tmp_higest_usn: %llu , highest_usn: %llu\n",y,
 516                                 (long long)req->req5.highwatermark.tmp_highest_usn,
 517                                 (long long)req->req5.highwatermark.highest_usn));
 518                 }
 519 
 520                 status = rpccli_drsuapi_DsGetNCChanges(ctx->cli, mem_ctx,
 521                                                        &ctx->bind_handle,
 522                                                        level,
 523                                                        req,
 524                                                        &level_out,
 525                                                        &ctr,
 526                                                        &werr);
 527                 if (!NT_STATUS_IS_OK(status)) {
 528                         ctx->error_message = talloc_asprintf(ctx,
 529                                 "Failed to get NC Changes: %s",
 530                                 get_friendly_werror_msg(werr));
 531                         goto out;
 532                 }
 533 
 534                 if (!W_ERROR_IS_OK(werr)) {
 535                         status = werror_to_ntstatus(werr);
 536                         goto out;
 537                 }
 538 
 539                 if (level_out == 1) {
 540                         out_level = 1;
 541                         ctr1 = &ctr.ctr1;
 542                 } else if (level_out == 2 && ctr.ctr2.mszip1.ts) {
 543                         out_level = 1;
 544                         ctr1 = &ctr.ctr2.mszip1.ts->ctr1;
 545                 } else if (level_out == 6) {
 546                         out_level = 6;
 547                         ctr6 = &ctr.ctr6;
 548                 } else if (level_out == 7
 549                            && ctr.ctr7.level == 6
 550                            && ctr.ctr7.type == DRSUAPI_COMPRESSION_TYPE_MSZIP
 551                            && ctr.ctr7.ctr.mszip6.ts) {
 552                         out_level = 6;
 553                         ctr6 = &ctr.ctr7.ctr.mszip6.ts->ctr6;
 554                 } else if (level_out == 7
 555                            && ctr.ctr7.level == 6
 556                            && ctr.ctr7.type == DRSUAPI_COMPRESSION_TYPE_XPRESS
 557                            && ctr.ctr7.ctr.xpress6.ts) {
 558                         out_level = 6;
 559                         ctr6 = &ctr.ctr7.ctr.xpress6.ts->ctr6;
 560                 }
 561 
 562                 if (out_level == 1) {
 563                         DEBUG(1,("end[%d] tmp_highest_usn: %llu , highest_usn: %llu\n",y,
 564                                 (long long)ctr1->new_highwatermark.tmp_highest_usn,
 565                                 (long long)ctr1->new_highwatermark.highest_usn));
 566 
 567                         first_object = ctr1->first_object;
 568                         mapping_ctr = &ctr1->mapping_ctr;
 569 
 570                         if (ctr1->more_data) {
 571                                 req->req5.highwatermark = ctr1->new_highwatermark;
 572                         } else {
 573                                 last_query = true;
 574                                 if (ctr1->uptodateness_vector &&
 575                                     !ctx->single_object_replication)
 576                                 {
 577                                         new_utdv->version = 1;
 578                                         new_utdv->ctr.ctr1.count =
 579                                                 ctr1->uptodateness_vector->count;
 580                                         new_utdv->ctr.ctr1.cursors =
 581                                                 ctr1->uptodateness_vector->cursors;
 582                                 }
 583                         }
 584                 } else if (out_level == 6) {
 585                         DEBUG(1,("end[%d] tmp_highest_usn: %llu , highest_usn: %llu\n",y,
 586                                 (long long)ctr6->new_highwatermark.tmp_highest_usn,
 587                                 (long long)ctr6->new_highwatermark.highest_usn));
 588 
 589                         first_object = ctr6->first_object;
 590                         mapping_ctr = &ctr6->mapping_ctr;
 591 
 592                         if (ctr6->more_data) {
 593                                 req->req8.highwatermark = ctr6->new_highwatermark;
 594                         } else {
 595                                 last_query = true;
 596                                 if (ctr6->uptodateness_vector &&
 597                                     !ctx->single_object_replication)
 598                                 {
 599                                         new_utdv->version = 2;
 600                                         new_utdv->ctr.ctr2.count =
 601                                                 ctr6->uptodateness_vector->count;
 602                                         new_utdv->ctr.ctr2.cursors =
 603                                                 ctr6->uptodateness_vector->cursors;
 604                                 }
 605                         }
 606                 }
 607 
 608                 status = cli_get_session_key(mem_ctx, ctx->cli, &ctx->session_key);
 609                 if (!NT_STATUS_IS_OK(status)) {
 610                         ctx->error_message = talloc_asprintf(ctx,
 611                                 "Failed to get Session Key: %s",
 612                                 nt_errstr(status));
 613                         goto out;
 614                 }
 615 
 616                 libnet_dssync_decrypt_attributes(mem_ctx,
 617                                                  &ctx->session_key,
 618                                                  first_object);
 619 
 620                 if (ctx->ops->process_objects) {
 621                         status = ctx->ops->process_objects(ctx, mem_ctx,
 622                                                            first_object,
 623                                                            mapping_ctr);
 624                         if (!NT_STATUS_IS_OK(status)) {
 625                                 ctx->error_message = talloc_asprintf(ctx,
 626                                         "Failed to call processing function: %s",
 627                                         nt_errstr(status));
 628                                 goto out;
 629                         }
 630                 }
 631         }
 632 
 633         *pnew_utdv = new_utdv;
 634 
 635 out:
 636         return status;
 637 }
 638 
 639 static NTSTATUS libnet_dssync_process(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 640                                       struct dssync_context *ctx)
 641 {
 642         NTSTATUS status;
 643 
 644         int32_t level = 0;
 645         union drsuapi_DsGetNCChangesRequest req;
 646         struct replUpToDateVectorBlob *old_utdv = NULL;
 647         struct replUpToDateVectorBlob *pnew_utdv = NULL;
 648         const char **dns;
 649         uint32_t dn_count;
 650         uint32_t count;
 651 
 652         if (ctx->ops->startup) {
 653                 status = ctx->ops->startup(ctx, mem_ctx, &old_utdv);
 654                 if (!NT_STATUS_IS_OK(status)) {
 655                         ctx->error_message = talloc_asprintf(ctx,
 656                                 "Failed to call startup operation: %s",
 657                                 nt_errstr(status));
 658                         goto out;
 659                 }
 660         }
 661 
 662         if (ctx->single_object_replication && ctx->object_dns) {
 663                 dns = ctx->object_dns;
 664                 dn_count = ctx->object_count;
 665         } else {
 666                 dns = &ctx->nc_dn;
 667                 dn_count = 1;
 668         }
 669 
 670         status = NT_STATUS_OK;
 671 
 672         for (count=0; count < dn_count; count++) {
 673                 status = libnet_dssync_build_request(mem_ctx, ctx,
 674                                                      dns[count],
 675                                                      old_utdv, &level,
 676                                                      &req);
 677                 if (!NT_STATUS_IS_OK(status)) {
 678                         goto out;
 679                 }
 680 
 681                 status = libnet_dssync_getncchanges(mem_ctx, ctx, level, &req,
 682                                                     &pnew_utdv);
 683                 if (!NT_STATUS_IS_OK(status)) {
 684                         ctx->error_message = talloc_asprintf(ctx,
 685                                 "Failed to call DsGetNCCHanges: %s",
 686                                 nt_errstr(status));
 687                         goto out;
 688                 }
 689         }
 690 
 691         if (ctx->ops->finish) {
 692                 status = ctx->ops->finish(ctx, mem_ctx, pnew_utdv);
 693                 if (!NT_STATUS_IS_OK(status)) {
 694                         ctx->error_message = talloc_asprintf(ctx,
 695                                 "Failed to call finishing operation: %s",
 696                                 nt_errstr(status));
 697                         goto out;
 698                 }
 699         }
 700 
 701  out:
 702         return status;
 703 }
 704 
 705 /****************************************************************
 706 ****************************************************************/
 707 
 708 NTSTATUS libnet_dssync(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 709                        struct dssync_context *ctx)
 710 {
 711         NTSTATUS status;
 712         TALLOC_CTX *tmp_ctx;
 713 
 714         tmp_ctx = talloc_new(mem_ctx);
 715         if (!tmp_ctx) {
 716                 return NT_STATUS_NO_MEMORY;
 717         }
 718 
 719         status = libnet_dssync_init(tmp_ctx, ctx);
 720         if (!NT_STATUS_IS_OK(status)) {
 721                 goto out;
 722         }
 723 
 724         status = libnet_dssync_process(tmp_ctx, ctx);
 725         if (!NT_STATUS_IS_OK(status)) {
 726                 goto out;
 727         }
 728 
 729  out:
 730         TALLOC_FREE(tmp_ctx);
 731         return status;
 732 }
 733 

/* [<][>][^][v][top][bottom][index][help] */