~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/torture/rpc/dssync.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
   Unix SMB/CIFS implementation.
 
3
 
 
4
   DsGetNCChanges replication test
 
5
 
 
6
   Copyright (C) Stefan (metze) Metzmacher 2005
 
7
   Copyright (C) Brad Henry 2005
 
8
   
 
9
   This program is free software; you can redistribute it and/or modify
 
10
   it under the terms of the GNU General Public License as published by
 
11
   the Free Software Foundation; either version 3 of the License, or
 
12
   (at your option) any later version.
 
13
   
 
14
   This program is distributed in the hope that it will be useful,
 
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
   GNU General Public License for more details.
 
18
   
 
19
   You should have received a copy of the GNU General Public License
 
20
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
21
*/
 
22
 
 
23
#include "includes.h"
 
24
#include "lib/cmdline/popt_common.h"
 
25
#include "librpc/gen_ndr/ndr_drsuapi_c.h"
 
26
#include "librpc/gen_ndr/ndr_drsblobs.h"
 
27
#include "libcli/cldap/cldap.h"
 
28
#include "libcli/ldap/ldap_client.h"
 
29
#include "torture/torture.h"
 
30
#include "torture/ldap/proto.h"
 
31
#include "libcli/auth/libcli_auth.h"
 
32
#include "../lib/crypto/crypto.h"
 
33
#include "auth/credentials/credentials.h"
 
34
#include "libcli/auth/libcli_auth.h"
 
35
#include "auth/gensec/gensec.h"
 
36
#include "param/param.h"
 
37
#include "dsdb/samdb/samdb.h"
 
38
 
 
39
struct DsSyncBindInfo {
 
40
        struct dcerpc_pipe *pipe;
 
41
        struct drsuapi_DsBind req;
 
42
        struct GUID bind_guid;
 
43
        struct drsuapi_DsBindInfoCtr our_bind_info_ctr;
 
44
        struct drsuapi_DsBindInfo28 our_bind_info28;
 
45
        struct drsuapi_DsBindInfo28 peer_bind_info28;
 
46
        struct policy_handle bind_handle;
 
47
};
 
48
 
 
49
struct DsSyncLDAPInfo {
 
50
        struct ldap_connection *conn;
 
51
};
 
52
 
 
53
struct DsSyncTest {
 
54
        struct dcerpc_binding *drsuapi_binding;
 
55
        
 
56
        const char *ldap_url;
 
57
        const char *site_name;
 
58
        
 
59
        const char *domain_dn;
 
60
 
 
61
        /* what we need to do as 'Administrator' */
 
62
        struct {
 
63
                struct cli_credentials *credentials;
 
64
                struct DsSyncBindInfo drsuapi;
 
65
                struct DsSyncLDAPInfo ldap;
 
66
        } admin;
 
67
 
 
68
        /* what we need to do as the new dc machine account */
 
69
        struct {
 
70
                struct cli_credentials *credentials;
 
71
                struct DsSyncBindInfo drsuapi;
 
72
                struct drsuapi_DsGetDCInfo2 dc_info2;
 
73
                struct GUID invocation_id;
 
74
                struct GUID object_guid;
 
75
        } new_dc;
 
76
 
 
77
        /* info about the old dc */
 
78
        struct {
 
79
                struct drsuapi_DsGetDomainControllerInfo dc_info;
 
80
        } old_dc;
 
81
};
 
82
 
 
83
static struct DsSyncTest *test_create_context(struct torture_context *tctx)
 
84
{
 
85
        NTSTATUS status;
 
86
        struct DsSyncTest *ctx;
 
87
        struct drsuapi_DsBindInfo28 *our_bind_info28;
 
88
        struct drsuapi_DsBindInfoCtr *our_bind_info_ctr;
 
89
        const char *binding = torture_setting_string(tctx, "binding", NULL);
 
90
        ctx = talloc_zero(tctx, struct DsSyncTest);
 
91
        if (!ctx) return NULL;
 
92
 
 
93
        status = dcerpc_parse_binding(ctx, binding, &ctx->drsuapi_binding);
 
94
        if (!NT_STATUS_IS_OK(status)) {
 
95
                printf("Bad binding string %s\n", binding);
 
96
                return NULL;
 
97
        }
 
98
        ctx->drsuapi_binding->flags |= DCERPC_SIGN | DCERPC_SEAL;
 
99
 
 
100
        ctx->ldap_url = talloc_asprintf(ctx, "ldap://%s/", ctx->drsuapi_binding->host);
 
101
 
 
102
        /* ctx->admin ...*/
 
103
        ctx->admin.credentials                          = cmdline_credentials;
 
104
 
 
105
        our_bind_info28                         = &ctx->admin.drsuapi.our_bind_info28;
 
106
        our_bind_info28->supported_extensions   = 0xFFFFFFFF;
 
107
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3;
 
108
        our_bind_info28->site_guid              = GUID_zero();
 
109
        our_bind_info28->pid                    = 0;
 
110
        our_bind_info28->repl_epoch             = 1;
 
111
 
 
112
        our_bind_info_ctr                       = &ctx->admin.drsuapi.our_bind_info_ctr;
 
113
        our_bind_info_ctr->length               = 28;
 
114
        our_bind_info_ctr->info.info28          = *our_bind_info28;
 
115
 
 
116
        GUID_from_string(DRSUAPI_DS_BIND_GUID, &ctx->admin.drsuapi.bind_guid);
 
117
 
 
118
        ctx->admin.drsuapi.req.in.bind_guid             = &ctx->admin.drsuapi.bind_guid;
 
119
        ctx->admin.drsuapi.req.in.bind_info             = our_bind_info_ctr;
 
120
        ctx->admin.drsuapi.req.out.bind_handle          = &ctx->admin.drsuapi.bind_handle;
 
121
 
 
122
        /* ctx->new_dc ...*/
 
123
        ctx->new_dc.credentials                 = cmdline_credentials;
 
124
 
 
125
        our_bind_info28                         = &ctx->new_dc.drsuapi.our_bind_info28;
 
126
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_BASE;
 
127
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION;
 
128
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI;
 
129
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2;
 
130
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS;
 
131
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1;
 
132
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION;
 
133
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE;
 
134
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2;
 
135
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION;
 
136
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2;
 
137
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD;
 
138
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND;
 
139
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO;
 
140
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION;
 
141
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01;
 
142
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP;
 
143
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY;
 
144
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3;
 
145
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2;
 
146
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6;
 
147
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS;
 
148
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8;
 
149
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5;
 
150
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6;
 
151
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3;
 
152
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7;
 
153
        our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT;
 
154
        if (lp_parm_bool(tctx->lp_ctx, NULL, "dssync", "xpress", false)) {
 
155
                our_bind_info28->supported_extensions   |= DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS;
 
156
        }
 
157
        our_bind_info28->site_guid              = GUID_zero();
 
158
        our_bind_info28->pid                    = 0;
 
159
        our_bind_info28->repl_epoch             = 0;
 
160
 
 
161
        our_bind_info_ctr                       = &ctx->new_dc.drsuapi.our_bind_info_ctr;
 
162
        our_bind_info_ctr->length               = 28;
 
163
        our_bind_info_ctr->info.info28          = *our_bind_info28;
 
164
 
 
165
        GUID_from_string(DRSUAPI_DS_BIND_GUID_W2K3, &ctx->new_dc.drsuapi.bind_guid);
 
166
 
 
167
        ctx->new_dc.drsuapi.req.in.bind_guid            = &ctx->new_dc.drsuapi.bind_guid;
 
168
        ctx->new_dc.drsuapi.req.in.bind_info            = our_bind_info_ctr;
 
169
        ctx->new_dc.drsuapi.req.out.bind_handle         = &ctx->new_dc.drsuapi.bind_handle;
 
170
 
 
171
        ctx->new_dc.invocation_id                       = ctx->new_dc.drsuapi.bind_guid;
 
172
 
 
173
        /* ctx->old_dc ...*/
 
174
 
 
175
        return ctx;
 
176
}
 
177
 
 
178
static bool _test_DsBind(struct torture_context *tctx,
 
179
                         struct DsSyncTest *ctx, struct cli_credentials *credentials, struct DsSyncBindInfo *b)
 
180
{
 
181
        NTSTATUS status;
 
182
        bool ret = true;
 
183
 
 
184
        status = dcerpc_pipe_connect_b(ctx,
 
185
                                       &b->pipe, ctx->drsuapi_binding, 
 
186
                                       &ndr_table_drsuapi,
 
187
                                       credentials, tctx->ev, tctx->lp_ctx);
 
188
        
 
189
        if (!NT_STATUS_IS_OK(status)) {
 
190
                printf("Failed to connect to server as a BDC: %s\n", nt_errstr(status));
 
191
                return false;
 
192
        }
 
193
 
 
194
        status = dcerpc_drsuapi_DsBind(b->pipe, ctx, &b->req);
 
195
        if (!NT_STATUS_IS_OK(status)) {
 
196
                const char *errstr = nt_errstr(status);
 
197
                if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
 
198
                        errstr = dcerpc_errstr(ctx, b->pipe->last_fault_code);
 
199
                }
 
200
                printf("dcerpc_drsuapi_DsBind failed - %s\n", errstr);
 
201
                ret = false;
 
202
        } else if (!W_ERROR_IS_OK(b->req.out.result)) {
 
203
                printf("DsBind failed - %s\n", win_errstr(b->req.out.result));
 
204
                ret = false;
 
205
        }
 
206
 
 
207
        ZERO_STRUCT(b->peer_bind_info28);
 
208
        if (b->req.out.bind_info) {
 
209
                switch (b->req.out.bind_info->length) {
 
210
                case 24: {
 
211
                        struct drsuapi_DsBindInfo24 *info24;
 
212
                        info24 = &b->req.out.bind_info->info.info24;
 
213
                        b->peer_bind_info28.supported_extensions= info24->supported_extensions;
 
214
                        b->peer_bind_info28.site_guid           = info24->site_guid;
 
215
                        b->peer_bind_info28.pid                 = info24->pid;
 
216
                        b->peer_bind_info28.repl_epoch          = 0;
 
217
                        break;
 
218
                }
 
219
                case 48: {
 
220
                        struct drsuapi_DsBindInfo48 *info48;
 
221
                        info48 = &b->req.out.bind_info->info.info48;
 
222
                        b->peer_bind_info28.supported_extensions= info48->supported_extensions;
 
223
                        b->peer_bind_info28.site_guid           = info48->site_guid;
 
224
                        b->peer_bind_info28.pid                 = info48->pid;
 
225
                        b->peer_bind_info28.repl_epoch          = info48->repl_epoch;
 
226
                        break;
 
227
                }
 
228
                case 28:
 
229
                        b->peer_bind_info28 = b->req.out.bind_info->info.info28;
 
230
                        break;
 
231
                default:
 
232
                        printf("DsBind - warning: unknown BindInfo length: %u\n",
 
233
                               b->req.out.bind_info->length);
 
234
                }
 
235
        }
 
236
 
 
237
        return ret;
 
238
}
 
239
 
 
240
static bool test_LDAPBind(struct torture_context *tctx, struct DsSyncTest *ctx, 
 
241
                          struct cli_credentials *credentials, struct DsSyncLDAPInfo *l)
 
242
{
 
243
        NTSTATUS status;
 
244
        bool ret = true;
 
245
 
 
246
        status = torture_ldap_connection(tctx, &l->conn, ctx->ldap_url);
 
247
        if (!NT_STATUS_IS_OK(status)) {
 
248
                printf("failed to connect to LDAP: %s\n", ctx->ldap_url);
 
249
                return false;
 
250
        }
 
251
 
 
252
        printf("connected to LDAP: %s\n", ctx->ldap_url);
 
253
 
 
254
        status = torture_ldap_bind_sasl(l->conn, credentials, tctx->lp_ctx);
 
255
        if (!NT_STATUS_IS_OK(status)) {
 
256
                printf("failed to bind to LDAP:\n");
 
257
                return false;
 
258
        }
 
259
        printf("bound to LDAP.\n");
 
260
 
 
261
        return ret;
 
262
}
 
263
 
 
264
static bool test_GetInfo(struct torture_context *tctx, struct DsSyncTest *ctx)
 
265
{
 
266
        NTSTATUS status;
 
267
        struct drsuapi_DsCrackNames r;
 
268
        union drsuapi_DsNameRequest req;
 
269
        union drsuapi_DsNameCtr ctr;
 
270
        int32_t level_out = 0;
 
271
        struct drsuapi_DsNameString names[1];
 
272
        bool ret = true;
 
273
        struct cldap_socket *cldap;
 
274
        struct cldap_netlogon search;
 
275
 
 
276
        cldap = cldap_socket_init(ctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
 
277
 
 
278
        r.in.bind_handle                = &ctx->admin.drsuapi.bind_handle;
 
279
        r.in.level                      = 1;
 
280
        r.in.req                        = &req;
 
281
        r.in.req->req1.codepage         = 1252; /* western european */
 
282
        r.in.req->req1.language         = 0x00000407; /* german */
 
283
        r.in.req->req1.count            = 1;
 
284
        r.in.req->req1.names            = names;
 
285
        r.in.req->req1.format_flags     = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
 
286
        r.in.req->req1.format_offered   = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
 
287
        r.in.req->req1.format_desired   = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
 
288
        names[0].str = talloc_asprintf(ctx, "%s\\", lp_workgroup(tctx->lp_ctx));
 
289
 
 
290
        r.out.level_out                 = &level_out;
 
291
        r.out.ctr                       = &ctr;
 
292
 
 
293
        status = dcerpc_drsuapi_DsCrackNames(ctx->admin.drsuapi.pipe, ctx, &r);
 
294
        if (!NT_STATUS_IS_OK(status)) {
 
295
                const char *errstr = nt_errstr(status);
 
296
                if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
 
297
                        errstr = dcerpc_errstr(ctx, ctx->admin.drsuapi.pipe->last_fault_code);
 
298
                }
 
299
                printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
 
300
                return false;
 
301
        } else if (!W_ERROR_IS_OK(r.out.result)) {
 
302
                printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
 
303
                return false;
 
304
        }
 
305
 
 
306
        ctx->domain_dn = r.out.ctr->ctr1->array[0].result_name;
 
307
        
 
308
        ZERO_STRUCT(search);
 
309
        search.in.dest_address = ctx->drsuapi_binding->host;
 
310
        search.in.dest_port = lp_cldap_port(tctx->lp_ctx);
 
311
        search.in.acct_control = -1;
 
312
        search.in.version               = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
 
313
        search.in.map_response = true;
 
314
        status = cldap_netlogon(cldap, ctx, &search);
 
315
        if (!NT_STATUS_IS_OK(status)) {
 
316
                const char *errstr = nt_errstr(status);
 
317
                ctx->site_name = talloc_asprintf(ctx, "%s", "Default-First-Site-Name");
 
318
                printf("cldap_netlogon() returned %s. Defaulting to Site-Name: %s\n", errstr, ctx->site_name);          
 
319
        } else {
 
320
                ctx->site_name = talloc_steal(ctx, search.out.netlogon.data.nt5_ex.client_site);
 
321
                printf("cldap_netlogon() returned Client Site-Name: %s.\n",ctx->site_name);
 
322
                printf("cldap_netlogon() returned Server Site-Name: %s.\n",search.out.netlogon.data.nt5_ex.server_site);
 
323
        }
 
324
 
 
325
        if (!ctx->domain_dn) {
 
326
                struct ldb_context *ldb = ldb_init(ctx, tctx->ev);
 
327
                struct ldb_dn *dn = samdb_dns_domain_to_dn(ldb, ctx, search.out.netlogon.data.nt5_ex.dns_domain);
 
328
                ctx->domain_dn = ldb_dn_alloc_linearized(ctx, dn);
 
329
                talloc_free(dn);
 
330
                talloc_free(ldb);
 
331
        }
 
332
 
 
333
        return ret;
 
334
}
 
335
 
 
336
static DATA_BLOB decrypt_blob(TALLOC_CTX *mem_ctx,
 
337
                              const DATA_BLOB *gensec_skey,
 
338
                              bool rcrypt,
 
339
                              struct drsuapi_DsReplicaObjectIdentifier *id,
 
340
                              uint32_t rid,
 
341
                              const DATA_BLOB *buffer)
 
342
{
 
343
        DATA_BLOB confounder;
 
344
        DATA_BLOB enc_buffer;
 
345
 
 
346
        struct MD5Context md5;
 
347
        uint8_t _enc_key[16];
 
348
        DATA_BLOB enc_key;
 
349
 
 
350
        DATA_BLOB dec_buffer;
 
351
 
 
352
        uint32_t crc32_given;
 
353
        uint32_t crc32_calc;
 
354
        DATA_BLOB checked_buffer;
 
355
 
 
356
        DATA_BLOB plain_buffer;
 
357
 
 
358
        /*
 
359
         * the combination "c[3] s[1] e[1] d[0]..."
 
360
         * was successful!!!!!!!!!!!!!!!!!!!!!!!!!!
 
361
         */
 
362
 
 
363
        /* 
 
364
         * the first 16 bytes at the beginning are the confounder
 
365
         * followed by the 4 byte crc32 checksum
 
366
         */
 
367
        if (buffer->length < 20) {
 
368
                return data_blob_const(NULL, 0);
 
369
        }
 
370
        confounder = data_blob_const(buffer->data, 16);
 
371
        enc_buffer = data_blob_const(buffer->data + 16, buffer->length - 16);
 
372
 
 
373
        /* 
 
374
         * build the encryption key md5 over the session key followed
 
375
         * by the confounder
 
376
         * 
 
377
         * here the gensec session key is used and
 
378
         * not the dcerpc ncacn_ip_tcp "SystemLibraryDTC" key!
 
379
         */
 
380
        enc_key = data_blob_const(_enc_key, sizeof(_enc_key));
 
381
        MD5Init(&md5);
 
382
        MD5Update(&md5, gensec_skey->data, gensec_skey->length);
 
383
        MD5Update(&md5, confounder.data, confounder.length);
 
384
        MD5Final(enc_key.data, &md5);
 
385
 
 
386
        /*
 
387
         * copy the encrypted buffer part and 
 
388
         * decrypt it using the created encryption key using arcfour
 
389
         */
 
390
        dec_buffer = data_blob_talloc(mem_ctx, enc_buffer.data, enc_buffer.length);
 
391
        if (!dec_buffer.data) {
 
392
                return data_blob_const(NULL, 0);
 
393
        }
 
394
        arcfour_crypt_blob(dec_buffer.data, dec_buffer.length, &enc_key);
 
395
 
 
396
        /* 
 
397
         * the first 4 byte are the crc32 checksum
 
398
         * of the remaining bytes
 
399
         */
 
400
        crc32_given = IVAL(dec_buffer.data, 0);
 
401
        crc32_calc = crc32_calc_buffer(dec_buffer.data + 4 , dec_buffer.length - 4);
 
402
        if (crc32_given != crc32_calc) {
 
403
                DEBUG(0,("CRC32: given[0x%08X] calc[0x%08X]\n",
 
404
                      crc32_given, crc32_calc));
 
405
                return data_blob_const(NULL, 0);
 
406
        }
 
407
        checked_buffer = data_blob_talloc(mem_ctx, dec_buffer.data + 4, dec_buffer.length - 4);
 
408
        if (!checked_buffer.data) {
 
409
                return data_blob_const(NULL, 0);
 
410
        }
 
411
 
 
412
        /*
 
413
         * some attributes seem to be in a usable form after this decryption
 
414
         * (supplementalCredentials, priorValue, currentValue, trustAuthOutgoing,
 
415
         *  trustAuthIncoming, initialAuthOutgoing, initialAuthIncoming)
 
416
         * At least supplementalCredentials contains plaintext
 
417
         * like "Primary:Kerberos" (in unicode form)
 
418
         *
 
419
         * some attributes seem to have some additional encryption
 
420
         * dBCSPwd, unicodePwd, ntPwdHistory, lmPwdHistory
 
421
         *
 
422
         * it's the sam_rid_crypt() function, as the value is constant,
 
423
         * so it doesn't depend on sessionkeys.
 
424
         */
 
425
        if (rcrypt) {
 
426
                uint32_t i, num_hashes;
 
427
 
 
428
                if ((checked_buffer.length % 16) != 0) {
 
429
                        return data_blob_const(NULL, 0);
 
430
                }
 
431
 
 
432
                plain_buffer = data_blob_talloc(mem_ctx, checked_buffer.data, checked_buffer.length);
 
433
                if (!plain_buffer.data) {
 
434
                        return data_blob_const(NULL, 0);
 
435
                }
 
436
                        
 
437
                num_hashes = plain_buffer.length / 16;
 
438
                for (i = 0; i < num_hashes; i++) {
 
439
                        uint32_t offset = i * 16;
 
440
                        sam_rid_crypt(rid, checked_buffer.data + offset, plain_buffer.data + offset, 0);
 
441
                }
 
442
        } else {
 
443
                plain_buffer = checked_buffer;
 
444
        }
 
445
 
 
446
        return plain_buffer;
 
447
}
 
448
 
 
449
static void test_analyse_objects(struct torture_context *tctx, 
 
450
                                 struct DsSyncTest *ctx,
 
451
                                 const DATA_BLOB *gensec_skey,
 
452
                                 struct drsuapi_DsReplicaObjectListItemEx *cur)
 
453
{
 
454
        static uint32_t object_id;
 
455
        const char *save_values_dir;
 
456
 
 
457
        if (!lp_parm_bool(tctx->lp_ctx, NULL, "dssync", "print_pwd_blobs", false)) {
 
458
                return; 
 
459
        }
 
460
 
 
461
        save_values_dir = lp_parm_string(tctx->lp_ctx, NULL, "dssync", "save_pwd_blobs_dir");
 
462
 
 
463
        for (; cur; cur = cur->next_object) {
 
464
                const char *dn;
 
465
                struct dom_sid *sid = NULL;
 
466
                uint32_t rid = 0;
 
467
                bool dn_printed = false;
 
468
                uint32_t i;
 
469
 
 
470
                if (!cur->object.identifier) continue;
 
471
 
 
472
                dn = cur->object.identifier->dn;
 
473
                if (cur->object.identifier->sid.num_auths > 0) {
 
474
                        sid = &cur->object.identifier->sid;
 
475
                        rid = sid->sub_auths[sid->num_auths - 1];
 
476
                }
 
477
 
 
478
                for (i=0; i < cur->object.attribute_ctr.num_attributes; i++) {
 
479
                        const char *name = NULL;
 
480
                        bool rcrypt = false;
 
481
                        DATA_BLOB *enc_data = NULL;
 
482
                        DATA_BLOB plain_data;
 
483
                        struct drsuapi_DsReplicaAttribute *attr;
 
484
                        ndr_pull_flags_fn_t pull_fn = NULL;
 
485
                        ndr_print_fn_t print_fn = NULL;
 
486
                        void *ptr = NULL;
 
487
                        attr = &cur->object.attribute_ctr.attributes[i];
 
488
 
 
489
                        switch (attr->attid) {
 
490
                        case DRSUAPI_ATTRIBUTE_dBCSPwd:
 
491
                                name    = "dBCSPwd";
 
492
                                rcrypt  = true;
 
493
                                break;
 
494
                        case DRSUAPI_ATTRIBUTE_unicodePwd:
 
495
                                name    = "unicodePwd";
 
496
                                rcrypt  = true;
 
497
                                break;
 
498
                        case DRSUAPI_ATTRIBUTE_ntPwdHistory:
 
499
                                name    = "ntPwdHistory";
 
500
                                rcrypt  = true;
 
501
                                break;
 
502
                        case DRSUAPI_ATTRIBUTE_lmPwdHistory:
 
503
                                name    = "lmPwdHistory";
 
504
                                rcrypt  = true;
 
505
                                break;
 
506
                        case DRSUAPI_ATTRIBUTE_supplementalCredentials:
 
507
                                name    = "supplementalCredentials";
 
508
                                pull_fn = (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob;
 
509
                                print_fn = (ndr_print_fn_t)ndr_print_supplementalCredentialsBlob;
 
510
                                ptr = talloc(ctx, struct supplementalCredentialsBlob);
 
511
                                break;
 
512
                        case DRSUAPI_ATTRIBUTE_priorValue:
 
513
                                name    = "priorValue";
 
514
                                break;
 
515
                        case DRSUAPI_ATTRIBUTE_currentValue:
 
516
                                name    = "currentValue";
 
517
                                break;
 
518
                        case DRSUAPI_ATTRIBUTE_trustAuthOutgoing:
 
519
                                name    = "trustAuthOutgoing";
 
520
                                pull_fn = (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob;
 
521
                                print_fn = (ndr_print_fn_t)ndr_print_trustAuthInOutBlob;
 
522
                                ptr = talloc(ctx, struct trustAuthInOutBlob);
 
523
                                break;
 
524
                        case DRSUAPI_ATTRIBUTE_trustAuthIncoming:
 
525
                                name    = "trustAuthIncoming";
 
526
                                pull_fn = (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob;
 
527
                                print_fn = (ndr_print_fn_t)ndr_print_trustAuthInOutBlob;
 
528
                                ptr = talloc(ctx, struct trustAuthInOutBlob);
 
529
                                break;
 
530
                        case DRSUAPI_ATTRIBUTE_initialAuthOutgoing:
 
531
                                name    = "initialAuthOutgoing";
 
532
                                break;
 
533
                        case DRSUAPI_ATTRIBUTE_initialAuthIncoming:
 
534
                                name    = "initialAuthIncoming";
 
535
                                break;
 
536
                        default:
 
537
                                continue;
 
538
                        }
 
539
 
 
540
                        if (attr->value_ctr.num_values != 1) continue;
 
541
 
 
542
                        if (!attr->value_ctr.values[0].blob) continue;
 
543
 
 
544
                        enc_data = attr->value_ctr.values[0].blob;
 
545
                        ZERO_STRUCT(plain_data);
 
546
 
 
547
                        plain_data = decrypt_blob(ctx, gensec_skey, rcrypt,
 
548
                                                  cur->object.identifier, rid,
 
549
                                                  enc_data);
 
550
                        if (!dn_printed) {
 
551
                                object_id++;
 
552
                                DEBUG(0,("DN[%u] %s\n", object_id, dn));
 
553
                                dn_printed = true;
 
554
                        }
 
555
                        DEBUGADD(0,("ATTR: %s enc.length=%lu plain.length=%lu\n",
 
556
                                    name, (long)enc_data->length, (long)plain_data.length));
 
557
                        if (plain_data.length) {
 
558
                                enum ndr_err_code ndr_err;
 
559
                                dump_data(0, plain_data.data, plain_data.length);
 
560
                                if (save_values_dir) {
 
561
                                        char *fname;
 
562
                                        fname = talloc_asprintf(ctx, "%s/%s%02d",
 
563
                                                                save_values_dir,
 
564
                                                                name, object_id);
 
565
                                        if (fname) {
 
566
                                                bool ok;
 
567
                                                ok = file_save(fname, plain_data.data, plain_data.length);
 
568
                                                if (!ok) {
 
569
                                                        DEBUGADD(0,("Failed to save '%s'\n", fname));
 
570
                                                }
 
571
                                        }
 
572
                                        talloc_free(fname);
 
573
                                }
 
574
 
 
575
                                if (pull_fn) {
 
576
                                        /* Can't use '_all' because of PIDL bugs with relative pointers */
 
577
                                        ndr_err = ndr_pull_struct_blob(&plain_data, ptr,
 
578
                                                                       lp_iconv_convenience(tctx->lp_ctx), ptr,
 
579
                                                                       pull_fn);
 
580
                                        if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 
581
                                                ndr_print_debug(print_fn, name, ptr);
 
582
                                        } else {
 
583
                                                DEBUG(0, ("Failed to decode %s\n", name));
 
584
                                        }
 
585
                                }
 
586
                        } else {
 
587
                                dump_data(0, enc_data->data, enc_data->length);
 
588
                        }
 
589
                        talloc_free(ptr);
 
590
                }
 
591
        }
 
592
}
 
593
 
 
594
static bool test_FetchData(struct torture_context *tctx, struct DsSyncTest *ctx)
 
595
{
 
596
        NTSTATUS status;
 
597
        bool ret = true;
 
598
        int i, y = 0;
 
599
        uint64_t highest_usn = 0;
 
600
        const char *partition = NULL;
 
601
        struct drsuapi_DsGetNCChanges r;
 
602
        union drsuapi_DsGetNCChangesRequest req;
 
603
        struct drsuapi_DsReplicaObjectIdentifier nc;
 
604
        struct drsuapi_DsGetNCChangesCtr1 *ctr1 = NULL;
 
605
        struct drsuapi_DsGetNCChangesCtr6 *ctr6 = NULL;
 
606
        int32_t out_level = 0;
 
607
        struct GUID null_guid;
 
608
        struct dom_sid null_sid;
 
609
        DATA_BLOB gensec_skey;
 
610
        struct {
 
611
                int32_t level;
 
612
        } array[] = {
 
613
/*              {
 
614
                        5
 
615
                },
 
616
*/              {
 
617
                        8
 
618
                }
 
619
        };
 
620
 
 
621
        ZERO_STRUCT(null_guid);
 
622
        ZERO_STRUCT(null_sid);
 
623
 
 
624
        partition = lp_parm_string(tctx->lp_ctx, NULL, "dssync", "partition");
 
625
        if (partition == NULL) {
 
626
                partition = ctx->domain_dn;
 
627
                printf("dssync:partition not specified, defaulting to %s.\n", ctx->domain_dn);
 
628
        }
 
629
 
 
630
        highest_usn = lp_parm_int(tctx->lp_ctx, NULL, "dssync", "highest_usn", 0);
 
631
 
 
632
        array[0].level = lp_parm_int(tctx->lp_ctx, NULL, "dssync", "get_nc_changes_level", array[0].level);
 
633
 
 
634
        if (lp_parm_bool(tctx->lp_ctx, NULL, "dssync", "print_pwd_blobs", false)) {
 
635
                const struct samr_Password *nthash;
 
636
                nthash = cli_credentials_get_nt_hash(ctx->new_dc.credentials, ctx);
 
637
                if (nthash) {
 
638
                        dump_data_pw("CREDENTIALS nthash:", nthash->hash, sizeof(nthash->hash));
 
639
                }
 
640
        }
 
641
        status = gensec_session_key(ctx->new_dc.drsuapi.pipe->conn->security_state.generic_state,
 
642
                                    &gensec_skey);
 
643
        if (!NT_STATUS_IS_OK(status)) {
 
644
                printf("failed to get gensec session key: %s\n", nt_errstr(status));
 
645
                return false;
 
646
        }
 
647
 
 
648
        for (i=0; i < ARRAY_SIZE(array); i++) {
 
649
                printf("testing DsGetNCChanges level %d\n",
 
650
                        array[i].level);
 
651
 
 
652
                r.in.bind_handle        = &ctx->new_dc.drsuapi.bind_handle;
 
653
                r.in.level              = array[i].level;
 
654
 
 
655
                switch (r.in.level) {
 
656
                case 5:
 
657
                        nc.guid = null_guid;
 
658
                        nc.sid  = null_sid;
 
659
                        nc.dn   = partition; 
 
660
 
 
661
                        r.in.req                                        = &req;
 
662
                        r.in.req->req5.destination_dsa_guid             = ctx->new_dc.invocation_id;
 
663
                        r.in.req->req5.source_dsa_invocation_id         = null_guid;
 
664
                        r.in.req->req5.naming_context                   = &nc;
 
665
                        r.in.req->req5.highwatermark.tmp_highest_usn    = highest_usn;
 
666
                        r.in.req->req5.highwatermark.reserved_usn       = 0;
 
667
                        r.in.req->req5.highwatermark.highest_usn        = highest_usn;
 
668
                        r.in.req->req5.uptodateness_vector              = NULL;
 
669
                        r.in.req->req5.replica_flags                    = 0;
 
670
                        if (lp_parm_bool(tctx->lp_ctx, NULL, "dssync", "compression", false)) {
 
671
                                r.in.req->req5.replica_flags            |= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES;
 
672
                        }
 
673
                        if (lp_parm_bool(tctx->lp_ctx, NULL, "dssync", "neighbour_writeable", true)) {
 
674
                                r.in.req->req5.replica_flags            |= DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE;
 
675
                        }
 
676
                        r.in.req->req5.replica_flags                    |= DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
 
677
                                                                        | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS
 
678
                                                                        | DRSUAPI_DS_REPLICA_NEIGHBOUR_RETURN_OBJECT_PARENTS
 
679
                                                                        | DRSUAPI_DS_REPLICA_NEIGHBOUR_NEVER_SYNCED
 
680
                                                                        ;
 
681
                        r.in.req->req5.max_object_count                 = 133;
 
682
                        r.in.req->req5.max_ndr_size                     = 1336770;
 
683
                        r.in.req->req5.extended_op                      = DRSUAPI_EXOP_NONE;
 
684
                        r.in.req->req5.fsmo_info                        = 0;
 
685
 
 
686
                        break;
 
687
                case 8:
 
688
                        nc.guid = null_guid;
 
689
                        nc.sid  = null_sid;
 
690
                        nc.dn   = partition; 
 
691
                        /* nc.dn can be set to any other ad partition */
 
692
 
 
693
                        r.in.req                                        = &req;
 
694
                        r.in.req->req8.destination_dsa_guid             = ctx->new_dc.invocation_id;
 
695
                        r.in.req->req8.source_dsa_invocation_id         = null_guid;
 
696
                        r.in.req->req8.naming_context                   = &nc;
 
697
                        r.in.req->req8.highwatermark.tmp_highest_usn    = highest_usn;
 
698
                        r.in.req->req8.highwatermark.reserved_usn       = 0;
 
699
                        r.in.req->req8.highwatermark.highest_usn        = highest_usn;
 
700
                        r.in.req->req8.uptodateness_vector              = NULL;
 
701
                        r.in.req->req8.replica_flags                    = 0;
 
702
                        if (lp_parm_bool(tctx->lp_ctx, NULL, "dssync", "compression", false)) {
 
703
                                r.in.req->req8.replica_flags            |= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES;
 
704
                        }
 
705
                        if (lp_parm_bool(tctx->lp_ctx, NULL, "dssync", "neighbour_writeable", true)) {
 
706
                                r.in.req->req8.replica_flags            |= DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE;
 
707
                        }
 
708
                        r.in.req->req8.replica_flags                    |= DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
 
709
                                                                        | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS
 
710
                                                                        | DRSUAPI_DS_REPLICA_NEIGHBOUR_RETURN_OBJECT_PARENTS
 
711
                                                                        | DRSUAPI_DS_REPLICA_NEIGHBOUR_NEVER_SYNCED
 
712
                                                                        ;
 
713
                        r.in.req->req8.max_object_count                 = 402;
 
714
                        r.in.req->req8.max_ndr_size                     = 402116;
 
715
 
 
716
                        r.in.req->req8.extended_op                      = DRSUAPI_EXOP_NONE;
 
717
                        r.in.req->req8.fsmo_info                        = 0;
 
718
                        r.in.req->req8.partial_attribute_set            = NULL;
 
719
                        r.in.req->req8.partial_attribute_set_ex         = NULL;
 
720
                        r.in.req->req8.mapping_ctr.num_mappings         = 0;
 
721
                        r.in.req->req8.mapping_ctr.mappings             = NULL;
 
722
 
 
723
                        break;
 
724
                }
 
725
                
 
726
                printf("Dumping AD partition: %s\n", nc.dn);
 
727
                for (y=0; ;y++) {
 
728
                        int32_t _level = 0;
 
729
                        union drsuapi_DsGetNCChangesCtr ctr;
 
730
 
 
731
                        ZERO_STRUCT(r.out);
 
732
 
 
733
                        r.out.level_out = &_level;
 
734
                        r.out.ctr       = &ctr;
 
735
 
 
736
                        if (r.in.level == 5) {
 
737
                                DEBUG(0,("start[%d] tmp_higest_usn: %llu , highest_usn: %llu\n",y,
 
738
                                        (long long)r.in.req->req5.highwatermark.tmp_highest_usn,
 
739
                                        (long long)r.in.req->req5.highwatermark.highest_usn));
 
740
                        }
 
741
 
 
742
                        if (r.in.level == 8) {
 
743
                                DEBUG(0,("start[%d] tmp_higest_usn: %llu , highest_usn: %llu\n",y,
 
744
                                        (long long)r.in.req->req8.highwatermark.tmp_highest_usn,
 
745
                                        (long long)r.in.req->req8.highwatermark.highest_usn));
 
746
                        }
 
747
 
 
748
                        status = dcerpc_drsuapi_DsGetNCChanges(ctx->new_dc.drsuapi.pipe, ctx, &r);
 
749
                        if (!NT_STATUS_IS_OK(status)) {
 
750
                                const char *errstr = nt_errstr(status);
 
751
                                if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
 
752
                                        errstr = dcerpc_errstr(ctx, ctx->new_dc.drsuapi.pipe->last_fault_code);
 
753
                                }
 
754
                                printf("dcerpc_drsuapi_DsGetNCChanges failed - %s\n", errstr);
 
755
                                ret = false;
 
756
                        } else if (!W_ERROR_IS_OK(r.out.result)) {
 
757
                                printf("DsGetNCChanges failed - %s\n", win_errstr(r.out.result));
 
758
                                ret = false;
 
759
                        }
 
760
 
 
761
                        if (ret == true && *r.out.level_out == 1) {
 
762
                                out_level = 1;
 
763
                                ctr1 = &r.out.ctr->ctr1;
 
764
                        } else if (ret == true && *r.out.level_out == 2 &&
 
765
                                   r.out.ctr->ctr2.mszip1.ts) {
 
766
                                out_level = 1;
 
767
                                ctr1 = &r.out.ctr->ctr2.mszip1.ts->ctr1;
 
768
                        }
 
769
 
 
770
                        if (out_level == 1) {
 
771
                                DEBUG(0,("end[%d] tmp_highest_usn: %llu , highest_usn: %llu\n",y,
 
772
                                        (long long)ctr1->new_highwatermark.tmp_highest_usn,
 
773
                                        (long long)ctr1->new_highwatermark.highest_usn));
 
774
 
 
775
                                test_analyse_objects(tctx, ctx, &gensec_skey, ctr1->first_object);
 
776
 
 
777
                                if (ctr1->more_data) {
 
778
                                        r.in.req->req5.highwatermark = ctr1->new_highwatermark;
 
779
                                        continue;
 
780
                                }
 
781
                        }
 
782
 
 
783
                        if (ret == true && *r.out.level_out == 6) {
 
784
                                out_level = 6;
 
785
                                ctr6 = &r.out.ctr->ctr6;
 
786
                        } else if (ret == true && *r.out.level_out == 7
 
787
                                   && r.out.ctr->ctr7.level == 6
 
788
                                   && r.out.ctr->ctr7.type == DRSUAPI_COMPRESSION_TYPE_MSZIP
 
789
                                   && r.out.ctr->ctr7.ctr.mszip6.ts) {
 
790
                                out_level = 6;
 
791
                                ctr6 = &r.out.ctr->ctr7.ctr.mszip6.ts->ctr6;
 
792
                        } else if (ret == true && *r.out.level_out == 7
 
793
                                   && r.out.ctr->ctr7.level == 6
 
794
                                   && r.out.ctr->ctr7.type == DRSUAPI_COMPRESSION_TYPE_XPRESS
 
795
                                   && r.out.ctr->ctr7.ctr.xpress6.ts) {
 
796
                                out_level = 6;
 
797
                                ctr6 = &r.out.ctr->ctr7.ctr.xpress6.ts->ctr6;
 
798
                        }
 
799
 
 
800
                        if (out_level == 6) {
 
801
                                DEBUG(0,("end[%d] tmp_highest_usn: %llu , highest_usn: %llu\n",y,
 
802
                                        (long long)ctr6->new_highwatermark.tmp_highest_usn,
 
803
                                        (long long)ctr6->new_highwatermark.highest_usn));
 
804
 
 
805
                                test_analyse_objects(tctx, ctx, &gensec_skey, ctr6->first_object);
 
806
 
 
807
                                if (ctr6->more_data) {
 
808
                                        r.in.req->req8.highwatermark = ctr6->new_highwatermark;
 
809
                                        continue;
 
810
                                }
 
811
                        }
 
812
 
 
813
                        break;
 
814
                }
 
815
        }
 
816
 
 
817
        return ret;
 
818
}
 
819
 
 
820
static bool test_FetchNT4Data(struct torture_context *tctx, 
 
821
                              struct DsSyncTest *ctx)
 
822
{
 
823
        NTSTATUS status;
 
824
        bool ret = true;
 
825
        struct drsuapi_DsGetNT4ChangeLog r;
 
826
        union drsuapi_DsGetNT4ChangeLogRequest req;
 
827
        union drsuapi_DsGetNT4ChangeLogInfo info;
 
828
        uint32_t level_out = 0;
 
829
        struct GUID null_guid;
 
830
        struct dom_sid null_sid;
 
831
        DATA_BLOB cookie;
 
832
 
 
833
        ZERO_STRUCT(null_guid);
 
834
        ZERO_STRUCT(null_sid);
 
835
        ZERO_STRUCT(cookie);
 
836
 
 
837
        ZERO_STRUCT(r);
 
838
        r.in.bind_handle        = &ctx->new_dc.drsuapi.bind_handle;
 
839
        r.in.level              = 1;
 
840
        r.out.info              = &info;
 
841
        r.out.level_out         = &level_out;
 
842
 
 
843
        req.req1.unknown1       = lp_parm_int(tctx->lp_ctx, NULL, "dssync", "nt4-1", 3);
 
844
        req.req1.unknown2       = lp_parm_int(tctx->lp_ctx, NULL, "dssync", "nt4-2", 0x00004000);
 
845
 
 
846
        while (1) {
 
847
                req.req1.length = cookie.length;
 
848
                req.req1.data   = cookie.data;
 
849
 
 
850
                r.in.req = &req;
 
851
 
 
852
                status = dcerpc_drsuapi_DsGetNT4ChangeLog(ctx->new_dc.drsuapi.pipe, ctx, &r);
 
853
                if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
 
854
                        printf("DsGetNT4ChangeLog not supported by target server\n");
 
855
                        break;
 
856
                } else if (!NT_STATUS_IS_OK(status)) {
 
857
                        const char *errstr = nt_errstr(status);
 
858
                        if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
 
859
                                errstr = dcerpc_errstr(ctx, ctx->new_dc.drsuapi.pipe->last_fault_code);
 
860
                        }
 
861
                        printf("dcerpc_drsuapi_DsGetNT4ChangeLog failed - %s\n", errstr);
 
862
                        ret = false;
 
863
                } else if (W_ERROR_EQUAL(r.out.result, WERR_INVALID_DOMAIN_ROLE)) {
 
864
                        printf("DsGetNT4ChangeLog not supported by target server\n");
 
865
                        break;
 
866
                } else if (!W_ERROR_IS_OK(r.out.result)) {
 
867
                        printf("DsGetNT4ChangeLog failed - %s\n", win_errstr(r.out.result));
 
868
                        ret = false;
 
869
                } else if (*r.out.level_out != 1) {
 
870
                        printf("DsGetNT4ChangeLog unknown level - %u\n", *r.out.level_out);
 
871
                        ret = false;
 
872
                } else if (NT_STATUS_IS_OK(r.out.info->info1.status)) {
 
873
                } else if (NT_STATUS_EQUAL(r.out.info->info1.status, STATUS_MORE_ENTRIES)) {
 
874
                        cookie.length   = r.out.info->info1.length1;
 
875
                        cookie.data     = r.out.info->info1.data1;
 
876
                        continue;
 
877
                } else {
 
878
                        printf("DsGetNT4ChangeLog failed - %s\n", nt_errstr(r.out.info->info1.status));
 
879
                        ret = false;
 
880
                }
 
881
 
 
882
                break;
 
883
        }
 
884
 
 
885
        return ret;
 
886
}
 
887
 
 
888
bool torture_rpc_dssync(struct torture_context *torture)
 
889
{
 
890
        bool ret = true;
 
891
        TALLOC_CTX *mem_ctx;
 
892
        struct DsSyncTest *ctx;
 
893
        
 
894
        mem_ctx = talloc_init("torture_rpc_dssync");
 
895
        ctx = test_create_context(torture);
 
896
        
 
897
        ret &= _test_DsBind(torture, ctx, ctx->admin.credentials, &ctx->admin.drsuapi);
 
898
        if (!ret) {
 
899
                return ret;
 
900
        }
 
901
        ret &= test_LDAPBind(torture, ctx, ctx->admin.credentials, &ctx->admin.ldap);
 
902
        if (!ret) {
 
903
                return ret;
 
904
        }
 
905
        ret &= test_GetInfo(torture, ctx);
 
906
        ret &= _test_DsBind(torture, ctx, ctx->new_dc.credentials, &ctx->new_dc.drsuapi);
 
907
        if (!ret) {
 
908
                return ret;
 
909
        }
 
910
        ret &= test_FetchData(torture, ctx);
 
911
        ret &= test_FetchNT4Data(torture, ctx);
 
912
 
 
913
        return ret;
 
914
}