~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/libnet/libnet_dssync_keytab.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
   Copyright (C) Guenther Deschner <gd@samba.org> 2008
 
5
   Copyright (C) Michael Adam 2008
 
6
 
 
7
   This program is free software; you can redistribute it and/or modify
 
8
   it under the terms of the GNU General Public License as published by
 
9
   the Free Software Foundation; either version 3 of the License, or
 
10
   (at your option) any later version.
 
11
 
 
12
   This program is distributed in the hope that it will be useful,
 
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
   GNU General Public License for more details.
 
16
 
 
17
   You should have received a copy of the GNU General Public License
 
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
19
*/
 
20
 
 
21
#include "includes.h"
 
22
#include "libnet/libnet.h"
 
23
#include "librpc/gen_ndr/ndr_drsblobs.h"
 
24
 
 
25
#if defined(HAVE_ADS) && defined(ENCTYPE_ARCFOUR_HMAC)
 
26
 
 
27
static NTSTATUS keytab_startup(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
 
28
                               struct replUpToDateVectorBlob **pold_utdv)
 
29
{
 
30
        krb5_error_code ret = 0;
 
31
        struct libnet_keytab_context *keytab_ctx;
 
32
        struct libnet_keytab_entry *entry;
 
33
        struct replUpToDateVectorBlob *old_utdv = NULL;
 
34
        char *principal;
 
35
 
 
36
        ret = libnet_keytab_init(mem_ctx, ctx->output_filename, &keytab_ctx);
 
37
        if (ret) {
 
38
                return krb5_to_nt_status(ret);
 
39
        }
 
40
 
 
41
        keytab_ctx->dns_domain_name = ctx->dns_domain_name;
 
42
        keytab_ctx->clean_old_entries = ctx->clean_old_entries;
 
43
        ctx->private_data = keytab_ctx;
 
44
 
 
45
        principal = talloc_asprintf(mem_ctx, "UTDV/%s@%s",
 
46
                                    ctx->nc_dn, ctx->dns_domain_name);
 
47
        NT_STATUS_HAVE_NO_MEMORY(principal);
 
48
 
 
49
        entry = libnet_keytab_search(keytab_ctx, principal, 0, ENCTYPE_NULL,
 
50
                                     mem_ctx);
 
51
        if (entry) {
 
52
                enum ndr_err_code ndr_err;
 
53
                old_utdv = talloc(mem_ctx, struct replUpToDateVectorBlob);
 
54
 
 
55
                ndr_err = ndr_pull_struct_blob(&entry->password, old_utdv,
 
56
                                NULL, old_utdv,
 
57
                                (ndr_pull_flags_fn_t)ndr_pull_replUpToDateVectorBlob);
 
58
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 
59
                        NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
 
60
                        ctx->error_message = talloc_asprintf(ctx,
 
61
                                        "Failed to pull UpToDateVector: %s",
 
62
                                        nt_errstr(status));
 
63
                        return status;
 
64
                }
 
65
 
 
66
                if (DEBUGLEVEL >= 10) {
 
67
                        NDR_PRINT_DEBUG(replUpToDateVectorBlob, old_utdv);
 
68
                }
 
69
        }
 
70
 
 
71
        if (pold_utdv) {
 
72
                *pold_utdv = old_utdv;
 
73
        }
 
74
 
 
75
        return NT_STATUS_OK;
 
76
}
 
77
 
 
78
static NTSTATUS keytab_finish(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
 
79
                              struct replUpToDateVectorBlob *new_utdv)
 
80
{
 
81
        NTSTATUS status = NT_STATUS_OK;
 
82
        krb5_error_code ret = 0;
 
83
        struct libnet_keytab_context *keytab_ctx =
 
84
                (struct libnet_keytab_context *)ctx->private_data;
 
85
 
 
86
        if (new_utdv) {
 
87
                enum ndr_err_code ndr_err;
 
88
                DATA_BLOB blob;
 
89
 
 
90
                if (DEBUGLEVEL >= 10) {
 
91
                        NDR_PRINT_DEBUG(replUpToDateVectorBlob, new_utdv);
 
92
                }
 
93
 
 
94
                ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, new_utdv,
 
95
                                (ndr_push_flags_fn_t)ndr_push_replUpToDateVectorBlob);
 
96
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 
97
                        status = ndr_map_error2ntstatus(ndr_err);
 
98
                        ctx->error_message = talloc_asprintf(ctx,
 
99
                                        "Failed to push UpToDateVector: %s",
 
100
                                        nt_errstr(status));
 
101
                        goto done;
 
102
                }
 
103
 
 
104
                status = libnet_keytab_add_to_keytab_entries(mem_ctx, keytab_ctx, 0,
 
105
                                                             ctx->nc_dn, "UTDV",
 
106
                                                             ENCTYPE_NULL,
 
107
                                                             blob);
 
108
                if (!NT_STATUS_IS_OK(status)) {
 
109
                        goto done;
 
110
                }
 
111
        }
 
112
 
 
113
        ret = libnet_keytab_add(keytab_ctx);
 
114
        if (ret) {
 
115
                status = krb5_to_nt_status(ret);
 
116
                ctx->error_message = talloc_asprintf(ctx,
 
117
                        "Failed to add entries to keytab %s: %s",
 
118
                        keytab_ctx->keytab_name, error_message(ret));
 
119
                goto done;
 
120
        }
 
121
 
 
122
        ctx->result_message = talloc_asprintf(ctx,
 
123
                "Vampired %d accounts to keytab %s",
 
124
                keytab_ctx->count,
 
125
                keytab_ctx->keytab_name);
 
126
 
 
127
done:
 
128
        TALLOC_FREE(keytab_ctx);
 
129
        return status;
 
130
}
 
131
 
 
132
/****************************************************************
 
133
****************************************************************/
 
134
 
 
135
static  NTSTATUS parse_supplemental_credentials(TALLOC_CTX *mem_ctx,
 
136
                        const DATA_BLOB *blob,
 
137
                        struct package_PrimaryKerberosCtr3 **pkb3,
 
138
                        struct package_PrimaryKerberosCtr4 **pkb4)
 
139
{
 
140
        NTSTATUS status;
 
141
        enum ndr_err_code ndr_err;
 
142
        struct supplementalCredentialsBlob scb;
 
143
        struct supplementalCredentialsPackage *scpk = NULL;
 
144
        DATA_BLOB scpk_blob;
 
145
        struct package_PrimaryKerberosBlob *pkb;
 
146
        bool newer_keys = false;
 
147
        uint32_t j;
 
148
 
 
149
        ndr_err = ndr_pull_struct_blob_all(blob, mem_ctx, NULL, &scb,
 
150
                        (ndr_pull_flags_fn_t)ndr_pull_supplementalCredentialsBlob);
 
151
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 
152
                status = ndr_map_error2ntstatus(ndr_err);
 
153
                goto done;
 
154
        }
 
155
        if (scb.sub.signature !=
 
156
            SUPPLEMENTAL_CREDENTIALS_SIGNATURE)
 
157
        {
 
158
                if (DEBUGLEVEL >= 10) {
 
159
                        NDR_PRINT_DEBUG(supplementalCredentialsBlob, &scb);
 
160
                }
 
161
                status = NT_STATUS_INVALID_PARAMETER;
 
162
                goto done;
 
163
        }
 
164
        for (j=0; j < scb.sub.num_packages; j++) {
 
165
                if (strcmp("Primary:Kerberos-Newer-Keys",
 
166
                    scb.sub.packages[j].name) == 0)
 
167
                {
 
168
                        scpk = &scb.sub.packages[j];
 
169
                        if (!scpk->data || !scpk->data[0]) {
 
170
                                scpk = NULL;
 
171
                                continue;
 
172
                        }
 
173
                        newer_keys = true;
 
174
                        break;
 
175
                } else  if (strcmp("Primary:Kerberos",
 
176
                                   scb.sub.packages[j].name) == 0)
 
177
                {
 
178
                        /*
 
179
                         * grab this but don't break here:
 
180
                         * there might still be newer-keys ...
 
181
                         */
 
182
                        scpk = &scb.sub.packages[j];
 
183
                        if (!scpk->data || !scpk->data[0]) {
 
184
                                scpk = NULL;
 
185
                        }
 
186
                }
 
187
        }
 
188
 
 
189
        if (!scpk) {
 
190
                /* no data */
 
191
                status = NT_STATUS_OK;
 
192
                goto done;
 
193
        }
 
194
 
 
195
        scpk_blob = strhex_to_data_blob(mem_ctx, scpk->data);
 
196
        if (!scpk_blob.data) {
 
197
                status = NT_STATUS_NO_MEMORY;
 
198
                goto done;
 
199
        }
 
200
 
 
201
        pkb = TALLOC_ZERO_P(mem_ctx, struct package_PrimaryKerberosBlob);
 
202
        if (!pkb) {
 
203
                status = NT_STATUS_NO_MEMORY;
 
204
                goto done;
 
205
        }
 
206
        ndr_err = ndr_pull_struct_blob(&scpk_blob, mem_ctx, NULL, pkb,
 
207
                        (ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
 
208
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 
209
                status = ndr_map_error2ntstatus(ndr_err);
 
210
                goto done;
 
211
        }
 
212
 
 
213
        if (!newer_keys && pkb->version != 3) {
 
214
                status = NT_STATUS_INVALID_PARAMETER;
 
215
                goto done;
 
216
        }
 
217
 
 
218
        if (newer_keys && pkb->version != 4) {
 
219
                status = NT_STATUS_INVALID_PARAMETER;
 
220
                goto done;
 
221
        }
 
222
 
 
223
        if (pkb->version == 4 && pkb4) {
 
224
                *pkb4 = &pkb->ctr.ctr4;
 
225
        } else if (pkb->version == 3 && pkb3) {
 
226
                *pkb3 = &pkb->ctr.ctr3;
 
227
        }
 
228
 
 
229
        status = NT_STATUS_OK;
 
230
 
 
231
done:
 
232
        return status;
 
233
}
 
234
 
 
235
static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
 
236
                             struct libnet_keytab_context *ctx,
 
237
                             struct drsuapi_DsReplicaObjectListItemEx *cur)
 
238
{
 
239
        NTSTATUS status = NT_STATUS_OK;
 
240
        uchar nt_passwd[16];
 
241
        DATA_BLOB *blob;
 
242
        int i = 0;
 
243
        struct drsuapi_DsReplicaAttribute *attr;
 
244
        bool got_pwd = false;
 
245
 
 
246
        struct package_PrimaryKerberosCtr3 *pkb3 = NULL;
 
247
        struct package_PrimaryKerberosCtr4 *pkb4 = NULL;
 
248
 
 
249
        char *object_dn = NULL;
 
250
        char *upn = NULL;
 
251
        char **spn = NULL;
 
252
        uint32_t num_spns = 0;
 
253
        char *name = NULL;
 
254
        uint32_t kvno = 0;
 
255
        uint32_t uacc = 0;
 
256
        uint32_t sam_type = 0;
 
257
 
 
258
        uint32_t pwd_history_len = 0;
 
259
        uint8_t *pwd_history = NULL;
 
260
 
 
261
        ZERO_STRUCT(nt_passwd);
 
262
 
 
263
        object_dn = talloc_strdup(mem_ctx, cur->object.identifier->dn);
 
264
        if (!object_dn) {
 
265
                return NT_STATUS_NO_MEMORY;
 
266
        }
 
267
 
 
268
        DEBUG(3, ("parsing object '%s'\n", object_dn));
 
269
 
 
270
        for (i=0; i < cur->object.attribute_ctr.num_attributes; i++) {
 
271
 
 
272
                attr = &cur->object.attribute_ctr.attributes[i];
 
273
 
 
274
                if (attr->attid == DRSUAPI_ATTRIBUTE_servicePrincipalName) {
 
275
                        uint32_t count;
 
276
                        num_spns = attr->value_ctr.num_values;
 
277
                        spn = TALLOC_ARRAY(mem_ctx, char *, num_spns);
 
278
                        for (count = 0; count < num_spns; count++) {
 
279
                                blob = attr->value_ctr.values[count].blob;
 
280
                                pull_string_talloc(spn, NULL, 0,
 
281
                                                   &spn[count],
 
282
                                                   blob->data, blob->length,
 
283
                                                   STR_UNICODE);
 
284
                        }
 
285
                }
 
286
 
 
287
                if (attr->value_ctr.num_values != 1) {
 
288
                        continue;
 
289
                }
 
290
 
 
291
                if (!attr->value_ctr.values[0].blob) {
 
292
                        continue;
 
293
                }
 
294
 
 
295
                blob = attr->value_ctr.values[0].blob;
 
296
 
 
297
                switch (attr->attid) {
 
298
                        case DRSUAPI_ATTRIBUTE_unicodePwd:
 
299
 
 
300
                                if (blob->length != 16) {
 
301
                                        break;
 
302
                                }
 
303
 
 
304
                                memcpy(&nt_passwd, blob->data, 16);
 
305
                                got_pwd = true;
 
306
 
 
307
                                /* pick the kvno from the meta_data version,
 
308
                                 * thanks, metze, for explaining this */
 
309
 
 
310
                                if (!cur->meta_data_ctr) {
 
311
                                        break;
 
312
                                }
 
313
                                if (cur->meta_data_ctr->count !=
 
314
                                    cur->object.attribute_ctr.num_attributes) {
 
315
                                        break;
 
316
                                }
 
317
                                kvno = cur->meta_data_ctr->meta_data[i].version;
 
318
                                break;
 
319
                        case DRSUAPI_ATTRIBUTE_ntPwdHistory:
 
320
                                pwd_history_len = blob->length / 16;
 
321
                                pwd_history = blob->data;
 
322
                                break;
 
323
                        case DRSUAPI_ATTRIBUTE_userPrincipalName:
 
324
                                pull_string_talloc(mem_ctx, NULL, 0, &upn,
 
325
                                                   blob->data, blob->length,
 
326
                                                   STR_UNICODE);
 
327
                                break;
 
328
                        case DRSUAPI_ATTRIBUTE_sAMAccountName:
 
329
                                pull_string_talloc(mem_ctx, NULL, 0, &name,
 
330
                                                   blob->data, blob->length,
 
331
                                                   STR_UNICODE);
 
332
                                break;
 
333
                        case DRSUAPI_ATTRIBUTE_sAMAccountType:
 
334
                                sam_type = IVAL(blob->data, 0);
 
335
                                break;
 
336
                        case DRSUAPI_ATTRIBUTE_userAccountControl:
 
337
                                uacc = IVAL(blob->data, 0);
 
338
                                break;
 
339
                        case DRSUAPI_ATTRIBUTE_supplementalCredentials:
 
340
                                status = parse_supplemental_credentials(mem_ctx,
 
341
                                                                        blob,
 
342
                                                                        &pkb3,
 
343
                                                                        &pkb4);
 
344
                                if (!NT_STATUS_IS_OK(status)) {
 
345
                                        DEBUG(2, ("parsing of supplemental "
 
346
                                                  "credentials failed: %s\n",
 
347
                                                  nt_errstr(status)));
 
348
                                }
 
349
                                break;
 
350
                        default:
 
351
                                break;
 
352
                }
 
353
        }
 
354
 
 
355
        if (!got_pwd) {
 
356
                DEBUG(10, ("no password (unicodePwd) found - skipping.\n"));
 
357
                return NT_STATUS_OK;
 
358
        }
 
359
 
 
360
        if (name) {
 
361
                status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, 0, object_dn,
 
362
                                                             "SAMACCOUNTNAME",
 
363
                                                             ENCTYPE_NULL,
 
364
                                                             data_blob_talloc(mem_ctx, name,
 
365
                                                             strlen(name) + 1));
 
366
                if (!NT_STATUS_IS_OK(status)) {
 
367
                        return status;
 
368
                }
 
369
        } else {
 
370
                /* look into keytab ... */
 
371
                struct libnet_keytab_entry *entry = NULL;
 
372
                char *principal = NULL;
 
373
 
 
374
                DEBUG(10, ("looking for SAMACCOUNTNAME/%s@%s in keytayb...\n",
 
375
                           object_dn, ctx->dns_domain_name));
 
376
 
 
377
                principal = talloc_asprintf(mem_ctx, "%s/%s@%s",
 
378
                                            "SAMACCOUNTNAME",
 
379
                                            object_dn,
 
380
                                            ctx->dns_domain_name);
 
381
                if (!principal) {
 
382
                        DEBUG(1, ("talloc failed\n"));
 
383
                        return NT_STATUS_NO_MEMORY;
 
384
                }
 
385
                entry = libnet_keytab_search(ctx, principal, 0, ENCTYPE_NULL,
 
386
                                             mem_ctx);
 
387
                if (entry) {
 
388
                        name = (char *)TALLOC_MEMDUP(mem_ctx,
 
389
                                                     entry->password.data,
 
390
                                                     entry->password.length);
 
391
                        if (!name) {
 
392
                                DEBUG(1, ("talloc failed!"));
 
393
                                return NT_STATUS_NO_MEMORY;
 
394
                        } else {
 
395
                                DEBUG(10, ("found name %s\n", name));
 
396
                        }
 
397
                        TALLOC_FREE(entry);
 
398
                } else {
 
399
                        DEBUG(10, ("entry not found\n"));
 
400
                }
 
401
                TALLOC_FREE(principal);
 
402
        }
 
403
 
 
404
        if (!name) {
 
405
                DEBUG(10, ("no name (sAMAccountName) found - skipping.\n"));
 
406
                return NT_STATUS_OK;
 
407
        }
 
408
 
 
409
        DEBUG(1,("#%02d: %s:%d, ", ctx->count, name, kvno));
 
410
        DEBUGADD(1,("sAMAccountType: 0x%08x, userAccountControl: 0x%08x",
 
411
                sam_type, uacc));
 
412
        if (upn) {
 
413
                DEBUGADD(1,(", upn: %s", upn));
 
414
        }
 
415
        if (num_spns > 0) {
 
416
                DEBUGADD(1, (", spns: ["));
 
417
                for (i = 0; i < num_spns; i++) {
 
418
                        DEBUGADD(1, ("%s%s", spn[i],
 
419
                                     (i+1 == num_spns)?"]":", "));
 
420
                }
 
421
        }
 
422
        DEBUGADD(1,("\n"));
 
423
 
 
424
        status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno, name, NULL,
 
425
                                                     ENCTYPE_ARCFOUR_HMAC,
 
426
                                                     data_blob_talloc(mem_ctx, nt_passwd, 16));
 
427
 
 
428
        if (!NT_STATUS_IS_OK(status)) {
 
429
                return status;
 
430
        }
 
431
 
 
432
        /* add kerberos keys (if any) */
 
433
 
 
434
        if (pkb4) {
 
435
                for (i=0; i < pkb4->num_keys; i++) {
 
436
                        if (!pkb4->keys[i].value) {
 
437
                                continue;
 
438
                        }
 
439
                        status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno,
 
440
                                                                     name,
 
441
                                                                     NULL,
 
442
                                                                     pkb4->keys[i].keytype,
 
443
                                                                     *pkb4->keys[i].value);
 
444
                        if (!NT_STATUS_IS_OK(status)) {
 
445
                                return status;
 
446
                        }
 
447
                }
 
448
                for (i=0; i < pkb4->num_old_keys; i++) {
 
449
                        if (!pkb4->old_keys[i].value) {
 
450
                                continue;
 
451
                        }
 
452
                        status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno - 1,
 
453
                                                                     name,
 
454
                                                                     NULL,
 
455
                                                                     pkb4->old_keys[i].keytype,
 
456
                                                                     *pkb4->old_keys[i].value);
 
457
                        if (!NT_STATUS_IS_OK(status)) {
 
458
                                return status;
 
459
                        }
 
460
                }
 
461
                for (i=0; i < pkb4->num_older_keys; i++) {
 
462
                        if (!pkb4->older_keys[i].value) {
 
463
                                continue;
 
464
                        }
 
465
                        status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno - 2,
 
466
                                                                     name,
 
467
                                                                     NULL,
 
468
                                                                     pkb4->older_keys[i].keytype,
 
469
                                                                     *pkb4->older_keys[i].value);
 
470
                        if (!NT_STATUS_IS_OK(status)) {
 
471
                                return status;
 
472
                        }
 
473
                }
 
474
        }
 
475
 
 
476
        if (pkb3) {
 
477
                for (i=0; i < pkb3->num_keys; i++) {
 
478
                        if (!pkb3->keys[i].value) {
 
479
                                continue;
 
480
                        }
 
481
                        status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno, name,
 
482
                                                                     NULL,
 
483
                                                                     pkb3->keys[i].keytype,
 
484
                                                                     *pkb3->keys[i].value);
 
485
                        if (!NT_STATUS_IS_OK(status)) {
 
486
                                return status;
 
487
                        }
 
488
                }
 
489
                for (i=0; i < pkb3->num_old_keys; i++) {
 
490
                        if (!pkb3->old_keys[i].value) {
 
491
                                continue;
 
492
                        }
 
493
                        status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno - 1,
 
494
                                                                     name,
 
495
                                                                     NULL,
 
496
                                                                     pkb3->old_keys[i].keytype,
 
497
                                                                     *pkb3->old_keys[i].value);
 
498
                        if (!NT_STATUS_IS_OK(status)) {
 
499
                                return status;
 
500
                        }
 
501
                }
 
502
        }
 
503
 
 
504
        if ((kvno < 0) && (kvno < pwd_history_len)) {
 
505
                return status;
 
506
        }
 
507
 
 
508
        /* add password history */
 
509
 
 
510
        /* skip first entry */
 
511
        if (got_pwd) {
 
512
                kvno--;
 
513
                i = 1;
 
514
        } else {
 
515
                i = 0;
 
516
        }
 
517
 
 
518
        for (; i<pwd_history_len; i++) {
 
519
                status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno--, name, NULL,
 
520
                                                             ENCTYPE_ARCFOUR_HMAC,
 
521
                                                             data_blob_talloc(mem_ctx, &pwd_history[i*16], 16));
 
522
                if (!NT_STATUS_IS_OK(status)) {
 
523
                        break;
 
524
                }
 
525
        }
 
526
 
 
527
        return status;
 
528
}
 
529
 
 
530
static bool dn_is_in_object_list(struct dssync_context *ctx,
 
531
                                 const char *dn)
 
532
{
 
533
        uint32_t count;
 
534
 
 
535
        if (ctx->object_count == 0) {
 
536
                return true;
 
537
        }
 
538
 
 
539
        for (count = 0; count < ctx->object_count; count++) {
 
540
                if (strequal(ctx->object_dns[count], dn)) {
 
541
                        return true;
 
542
                }
 
543
        }
 
544
 
 
545
        return false;
 
546
}
 
547
 
 
548
/****************************************************************
 
549
****************************************************************/
 
550
 
 
551
static NTSTATUS keytab_process_objects(struct dssync_context *ctx,
 
552
                                       TALLOC_CTX *mem_ctx,
 
553
                                       struct drsuapi_DsReplicaObjectListItemEx *cur,
 
554
                                       struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr)
 
555
{
 
556
        NTSTATUS status = NT_STATUS_OK;
 
557
        struct libnet_keytab_context *keytab_ctx =
 
558
                (struct libnet_keytab_context *)ctx->private_data;
 
559
 
 
560
        for (; cur; cur = cur->next_object) {
 
561
                /*
 
562
                 * When not in single object replication mode,
 
563
                 * the object_dn list is used as a positive write filter.
 
564
                 */
 
565
                if (!ctx->single_object_replication &&
 
566
                    !dn_is_in_object_list(ctx, cur->object.identifier->dn))
 
567
                {
 
568
                        continue;
 
569
                }
 
570
 
 
571
                status = parse_object(mem_ctx, keytab_ctx, cur);
 
572
                if (!NT_STATUS_IS_OK(status)) {
 
573
                        goto out;
 
574
                }
 
575
        }
 
576
 
 
577
 out:
 
578
        return status;
 
579
}
 
580
 
 
581
#else
 
582
 
 
583
static NTSTATUS keytab_startup(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
 
584
                               struct replUpToDateVectorBlob **pold_utdv)
 
585
{
 
586
        return NT_STATUS_NOT_SUPPORTED;
 
587
}
 
588
 
 
589
static NTSTATUS keytab_finish(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
 
590
                              struct replUpToDateVectorBlob *new_utdv)
 
591
{
 
592
        return NT_STATUS_NOT_SUPPORTED;
 
593
}
 
594
 
 
595
static NTSTATUS keytab_process_objects(struct dssync_context *ctx,
 
596
                                       TALLOC_CTX *mem_ctx,
 
597
                                       struct drsuapi_DsReplicaObjectListItemEx *cur,
 
598
                                       struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr)
 
599
{
 
600
        return NT_STATUS_NOT_SUPPORTED;
 
601
}
 
602
#endif /* defined(HAVE_ADS) && defined(ENCTYPE_ARCFOUR_HMAC) */
 
603
 
 
604
const struct dssync_ops libnet_dssync_keytab_ops = {
 
605
        .startup                = keytab_startup,
 
606
        .process_objects        = keytab_process_objects,
 
607
        .finish                 = keytab_finish,
 
608
};