~ubuntu-branches/ubuntu/vivid/samba/vivid

« back to all changes in this revision

Viewing changes to source4/torture/drs/rpc/msds_intid.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Unix SMB/CIFS implementation.
 
3
 
 
4
   msDS-IntId attribute replication test.
 
5
 
 
6
   Copyright (C) Kamen Mazdrashki <kamenim@samba.org> 2010
 
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
#include "includes.h"
 
23
#include "lib/cmdline/popt_common.h"
 
24
#include "librpc/gen_ndr/ndr_drsuapi_c.h"
 
25
#include "librpc/gen_ndr/ndr_drsblobs.h"
 
26
#include "libcli/cldap/cldap.h"
 
27
#include "torture/torture.h"
 
28
#include "../libcli/drsuapi/drsuapi.h"
 
29
#include "auth/gensec/gensec.h"
 
30
#include "param/param.h"
 
31
#include "dsdb/samdb/samdb.h"
 
32
#include "torture/rpc/torture_rpc.h"
 
33
#include "torture/drs/proto.h"
 
34
#include "lib/tsocket/tsocket.h"
 
35
#include "libcli/resolve/resolve.h"
 
36
 
 
37
struct DsSyncBindInfo {
 
38
        struct dcerpc_pipe *drs_pipe;
 
39
        struct dcerpc_binding_handle *drs_handle;
 
40
        struct drsuapi_DsBind req;
 
41
        struct GUID bind_guid;
 
42
        struct drsuapi_DsBindInfoCtr our_bind_info_ctr;
 
43
        struct drsuapi_DsBindInfo28 our_bind_info28;
 
44
        struct drsuapi_DsBindInfo28 peer_bind_info28;
 
45
        struct policy_handle bind_handle;
 
46
};
 
47
 
 
48
struct DsaBindInfo {
 
49
        struct dcerpc_binding           *server_binding;
 
50
 
 
51
        struct dcerpc_pipe              *drs_pipe;
 
52
        struct dcerpc_binding_handle    *drs_handle;
 
53
 
 
54
        DATA_BLOB                       gensec_skey;
 
55
        struct drsuapi_DsBindInfo48     srv_info48;
 
56
        struct policy_handle            rpc_handle;
 
57
};
 
58
 
 
59
struct DsIntIdTestCtx {
 
60
        const char *ldap_url;
 
61
        const char *domain_dn;
 
62
        const char *config_dn;
 
63
        const char *schema_dn;
 
64
 
 
65
        /* what we need to do as 'Administrator' */
 
66
        struct cli_credentials  *creds;
 
67
        struct DsaBindInfo      dsa_bind;
 
68
        struct ldb_context      *ldb;
 
69
 
 
70
};
 
71
 
 
72
/* Format string to create provision LDIF with */
 
73
#define PROVISION_LDIF_FMT \
 
74
                "###########################################################\n" \
 
75
                "# Format string with positional params:\n" \
 
76
                "#  1 - (int) Unique ID between 1 and 2^16\n" \
 
77
                "#  2 - (string) Domain DN\n" \
 
78
                "###########################################################\n" \
 
79
                "\n" \
 
80
                "###########################################################\n" \
 
81
                "# Update schema\n" \
 
82
                "###########################################################\n" \
 
83
                "dn: CN=msds-intid-%1$d,CN=Schema,CN=Configuration,%2$s\n" \
 
84
                "changetype: add\n" \
 
85
                "objectClass: top\n" \
 
86
                "objectClass: attributeSchema\n" \
 
87
                "cn: msds-intid-%1$d\n" \
 
88
                "attributeID: 1.2.840.%1$d.1.5.9940\n" \
 
89
                "attributeSyntax: 2.5.5.10\n" \
 
90
                "omSyntax: 4\n" \
 
91
                "instanceType: 4\n" \
 
92
                "isSingleValued: TRUE\n" \
 
93
                "systemOnly: FALSE\n" \
 
94
                "\n" \
 
95
                "# schemaUpdateNow\n" \
 
96
                "DN:\n" \
 
97
                "changeType: modify\n" \
 
98
                "add: schemaUpdateNow\n" \
 
99
                "schemaUpdateNow: 1\n" \
 
100
                "-\n" \
 
101
                "\n" \
 
102
                "###########################################################\n" \
 
103
                "# Update User class\n" \
 
104
                "###########################################################\n" \
 
105
                "dn: CN=User,CN=Schema,CN=Configuration,%2$s\n" \
 
106
                "changetype: modify\n" \
 
107
                "add: mayContain\n" \
 
108
                "mayContain: msdsIntid%1$d\n" \
 
109
                "-\n" \
 
110
                "\n" \
 
111
                "# schemaUpdateNow\n" \
 
112
                "DN:\n" \
 
113
                "changeType: modify\n" \
 
114
                "add: schemaUpdateNow\n" \
 
115
                "schemaUpdateNow: 1\n" \
 
116
                "-\n" \
 
117
                "\n" \
 
118
                "###########################################################\n" \
 
119
                "# create user to test with\n" \
 
120
                "###########################################################\n" \
 
121
                "dn: CN=dsIntId_usr_%1$d,CN=Users,%2$s\n" \
 
122
                "changetype: add\n" \
 
123
                "objectClass: user\n" \
 
124
                "cn: dsIntId_usr_%1$d\n" \
 
125
                "name: dsIntId_usr_%1$d\n" \
 
126
                "displayName: dsIntId_usr_%1$d\n" \
 
127
                "sAMAccountName: dsIntId_usr_%1$d\n" \
 
128
                "msdsIntid%1$d: msDS-IntId-%1$d attribute value\n" \
 
129
                "\n"
 
130
 
 
131
 
 
132
static struct DsIntIdTestCtx *_dsintid_create_context(struct torture_context *tctx)
 
133
{
 
134
        NTSTATUS status;
 
135
        struct DsIntIdTestCtx *ctx;
 
136
        struct dcerpc_binding *server_binding;
 
137
        const char *binding = torture_setting_string(tctx, "binding", NULL);
 
138
 
 
139
        /* Create test suite context */
 
140
        ctx = talloc_zero(tctx, struct DsIntIdTestCtx);
 
141
        if (!ctx) {
 
142
                torture_result(tctx, TORTURE_FAIL, "Not enough memory!");
 
143
                return NULL;
 
144
        }
 
145
 
 
146
        /* parse binding object */
 
147
        status = dcerpc_parse_binding(ctx, binding, &server_binding);
 
148
        if (!NT_STATUS_IS_OK(status)) {
 
149
                torture_result(tctx, TORTURE_FAIL,
 
150
                               "Bad binding string '%s': %s", binding, nt_errstr(status));
 
151
                return NULL;
 
152
        }
 
153
 
 
154
        server_binding->flags |= DCERPC_SIGN | DCERPC_SEAL;
 
155
 
 
156
        /* populate test suite context */
 
157
        ctx->creds = cmdline_credentials;
 
158
        ctx->dsa_bind.server_binding = server_binding;
 
159
 
 
160
        ctx->ldap_url = talloc_asprintf(ctx, "ldap://%s", server_binding->host);
 
161
 
 
162
        return ctx;
 
163
}
 
164
 
 
165
static bool _test_DsaBind(struct torture_context *tctx,
 
166
                         TALLOC_CTX *mem_ctx,
 
167
                         struct cli_credentials *credentials,
 
168
                         uint32_t req_extensions,
 
169
                         struct DsaBindInfo *bi)
 
170
{
 
171
        NTSTATUS status;
 
172
        struct GUID bind_guid;
 
173
        struct drsuapi_DsBind r;
 
174
        struct drsuapi_DsBindInfoCtr bind_info_ctr;
 
175
        uint32_t supported_extensions;
 
176
 
 
177
        /* make DCE RPC connection */
 
178
        status = dcerpc_pipe_connect_b(mem_ctx,
 
179
                                       &bi->drs_pipe,
 
180
                                       bi->server_binding,
 
181
                                       &ndr_table_drsuapi,
 
182
                                       credentials, tctx->ev, tctx->lp_ctx);
 
183
        torture_assert_ntstatus_ok(tctx, status, "Failed to connect to server");
 
184
 
 
185
        bi->drs_handle = bi->drs_pipe->binding_handle;
 
186
 
 
187
        status = gensec_session_key(bi->drs_pipe->conn->security_state.generic_state,
 
188
                                    &bi->gensec_skey);
 
189
        torture_assert_ntstatus_ok(tctx, status, "failed to get gensec session key");
 
190
 
 
191
        /* Bind to DRSUAPI interface */
 
192
        GUID_from_string(DRSUAPI_DS_BIND_GUID_W2K3, &bind_guid);
 
193
 
 
194
        /*
 
195
         * Add flags that should be 1, according to MS docs.
 
196
         * It turns out DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3
 
197
         * is actually required in order for GetNCChanges() to
 
198
         * return schemaInfo entry in the prefixMap returned.
 
199
         * Use DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION so
 
200
         * we are able to fetch sensitive data.
 
201
         */
 
202
        supported_extensions = req_extensions
 
203
                             | DRSUAPI_SUPPORTED_EXTENSION_BASE
 
204
                             | DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION
 
205
                             | DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD
 
206
                             | DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3
 
207
                             | DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION;
 
208
 
 
209
        ZERO_STRUCT(bind_info_ctr);
 
210
        bind_info_ctr.length = 28;
 
211
        bind_info_ctr.info.info28.supported_extensions = supported_extensions;
 
212
 
 
213
        r.in.bind_guid = &bind_guid;
 
214
        r.in.bind_info = &bind_info_ctr;
 
215
        r.out.bind_handle = &bi->rpc_handle;
 
216
 
 
217
        status = dcerpc_drsuapi_DsBind_r(bi->drs_handle, mem_ctx, &r);
 
218
        torture_drsuapi_assert_call(tctx, bi->drs_pipe, status,
 
219
                                    &r, "dcerpc_drsuapi_DsBind_r");
 
220
 
 
221
 
 
222
        switch (r.out.bind_info->length) {
 
223
        case 24: {
 
224
                struct drsuapi_DsBindInfo24 *info24;
 
225
                info24 = &r.out.bind_info->info.info24;
 
226
                bi->srv_info48.supported_extensions     = info24->supported_extensions;
 
227
                bi->srv_info48.site_guid                = info24->site_guid;
 
228
                bi->srv_info48.pid                      = info24->pid;
 
229
                break;
 
230
        }
 
231
        case 28: {
 
232
                struct drsuapi_DsBindInfo28 *info28;
 
233
                info28 = &r.out.bind_info->info.info28;
 
234
                bi->srv_info48.supported_extensions     = info28->supported_extensions;
 
235
                bi->srv_info48.site_guid                = info28->site_guid;
 
236
                bi->srv_info48.pid                      = info28->pid;
 
237
                bi->srv_info48.repl_epoch               = info28->repl_epoch;
 
238
                break;
 
239
        }
 
240
        case 48:
 
241
                bi->srv_info48 = r.out.bind_info->info.info48;
 
242
                break;
 
243
        default:
 
244
                torture_result(tctx, TORTURE_FAIL,
 
245
                               "DsBind: unknown BindInfo length: %u",
 
246
                               r.out.bind_info->length);
 
247
                return false;
 
248
        }
 
249
 
 
250
        /* check if server supports extensions we've requested */
 
251
        if ((bi->srv_info48.supported_extensions & req_extensions) != req_extensions) {
 
252
                torture_result(tctx, TORTURE_FAIL,
 
253
                               "Server does not support requested extensions. "
 
254
                               "Requested: 0x%08X, Supported: 0x%08X",
 
255
                               req_extensions, bi->srv_info48.supported_extensions);
 
256
                return false;
 
257
        }
 
258
 
 
259
        return true;
 
260
}
 
261
 
 
262
static bool _test_LDAPBind(struct torture_context *tctx,
 
263
                           TALLOC_CTX *mem_ctx,
 
264
                           struct cli_credentials *credentials,
 
265
                           const char *ldap_url,
 
266
                           struct ldb_context **_ldb)
 
267
{
 
268
        bool ret = true;
 
269
 
 
270
        struct ldb_context *ldb;
 
271
 
 
272
        const char *modules_option[] = { "modules:paged_searches", NULL };
 
273
        ldb = ldb_init(mem_ctx, tctx->ev);
 
274
        if (ldb == NULL) {
 
275
                return false;
 
276
        }
 
277
 
 
278
        /* Despite us loading the schema from the AD server, we need
 
279
         * the samba handlers to get the extended DN syntax stuff */
 
280
        ret = ldb_register_samba_handlers(ldb);
 
281
        if (ret != LDB_SUCCESS) {
 
282
                talloc_free(ldb);
 
283
                return NULL;
 
284
        }
 
285
 
 
286
        ldb_set_modules_dir(ldb,
 
287
                            talloc_asprintf(ldb,
 
288
                                            "%s/ldb",
 
289
                                            lpcfg_modulesdir(tctx->lp_ctx)));
 
290
 
 
291
        if (ldb_set_opaque(ldb, "credentials", credentials) != LDB_SUCCESS) {
 
292
                talloc_free(ldb);
 
293
                return NULL;
 
294
        }
 
295
 
 
296
        if (ldb_set_opaque(ldb, "loadparm", tctx->lp_ctx) != LDB_SUCCESS) {
 
297
                talloc_free(ldb);
 
298
                return NULL;
 
299
        }
 
300
 
 
301
        ret = ldb_connect(ldb, ldap_url, 0, modules_option);
 
302
        if (ret != LDB_SUCCESS) {
 
303
                talloc_free(ldb);
 
304
                torture_assert_int_equal(tctx, ret, LDB_SUCCESS, "Failed to make LDB connection to target");
 
305
        }
 
306
 
 
307
        *_ldb = ldb;
 
308
 
 
309
        return true;
 
310
}
 
311
 
 
312
static bool _test_provision(struct torture_context *tctx, struct DsIntIdTestCtx *ctx)
 
313
{
 
314
        int ret;
 
315
        char *ldif_str;
 
316
        const char *pstr;
 
317
        struct ldb_ldif *ldif;
 
318
        uint32_t attr_id;
 
319
        struct ldb_context *ldb = ctx->ldb;
 
320
 
 
321
        /* We must have LDB connection ready by this time */
 
322
        SMB_ASSERT(ldb != NULL);
 
323
 
 
324
        ctx->domain_dn = ldb_dn_get_linearized(ldb_get_default_basedn(ldb));
 
325
        torture_assert(tctx, ctx->domain_dn != NULL, "Failed to get Domain DN");
 
326
 
 
327
        ctx->config_dn = ldb_dn_get_linearized(ldb_get_config_basedn(ldb));
 
328
        torture_assert(tctx, ctx->config_dn != NULL, "Failed to get Domain DN");
 
329
 
 
330
        ctx->schema_dn = ldb_dn_get_linearized(ldb_get_schema_basedn(ldb));
 
331
        torture_assert(tctx, ctx->schema_dn != NULL, "Failed to get Domain DN");
 
332
 
 
333
        /* prepare LDIF to provision with */
 
334
        attr_id = generate_random() % 0xFFFF;
 
335
        pstr = ldif_str = talloc_asprintf(ctx, PROVISION_LDIF_FMT,
 
336
                                          attr_id, ctx->domain_dn);
 
337
 
 
338
        /* Provision test data */
 
339
        while ((ldif = ldb_ldif_read_string(ldb, &pstr)) != NULL) {
 
340
                switch (ldif->changetype) {
 
341
                case LDB_CHANGETYPE_DELETE:
 
342
                        ret = ldb_delete(ldb, ldif->msg->dn);
 
343
                        break;
 
344
                case LDB_CHANGETYPE_MODIFY:
 
345
                        ret = ldb_modify(ldb, ldif->msg);
 
346
                        break;
 
347
                case LDB_CHANGETYPE_ADD:
 
348
                default:
 
349
                        ret = ldb_add(ldb, ldif->msg);
 
350
                        break;
 
351
                }
 
352
                if (ret != LDB_SUCCESS) {
 
353
                        char *msg = talloc_asprintf(ctx,
 
354
                                                    "Failed to apply ldif - %s (%s): \n%s",
 
355
                                                    ldb_errstring(ldb),
 
356
                                                    ldb_strerror(ret),
 
357
                                                    ldb_ldif_write_string(ldb, ctx, ldif));
 
358
                        torture_fail(tctx, msg);
 
359
 
 
360
                }
 
361
                ldb_ldif_read_free(ldb, ldif);
 
362
        }
 
363
 
 
364
        return true;
 
365
}
 
366
 
 
367
 
 
368
static bool _test_GetNCChanges(struct torture_context *tctx,
 
369
                               struct DsaBindInfo *bi,
 
370
                               const char *nc_dn_str,
 
371
                               TALLOC_CTX *mem_ctx,
 
372
                               struct drsuapi_DsGetNCChangesCtr6 **_ctr6)
 
373
{
 
374
        NTSTATUS status;
 
375
        struct drsuapi_DsGetNCChanges r;
 
376
        union drsuapi_DsGetNCChangesRequest req;
 
377
        struct drsuapi_DsReplicaObjectIdentifier nc;
 
378
        struct drsuapi_DsGetNCChangesCtr6 *ctr6_chunk = NULL;
 
379
        struct drsuapi_DsGetNCChangesCtr6 ctr6;
 
380
        uint32_t _level = 0;
 
381
        union drsuapi_DsGetNCChangesCtr ctr;
 
382
 
 
383
        struct dom_sid null_sid;
 
384
 
 
385
        ZERO_STRUCT(null_sid);
 
386
 
 
387
        /* fill-in Naming Context */
 
388
        nc.guid = GUID_zero();
 
389
        nc.sid  = null_sid;
 
390
        nc.dn   = nc_dn_str;
 
391
 
 
392
        /* fill-in request fields */
 
393
        req.req8.destination_dsa_guid           = GUID_random();
 
394
        req.req8.source_dsa_invocation_id       = GUID_zero();
 
395
        req.req8.naming_context                 = &nc;
 
396
        req.req8.highwatermark.tmp_highest_usn  = 0;
 
397
        req.req8.highwatermark.reserved_usn     = 0;
 
398
        req.req8.highwatermark.highest_usn      = 0;
 
399
        req.req8.uptodateness_vector            = NULL;
 
400
        req.req8.replica_flags                  = DRSUAPI_DRS_WRIT_REP
 
401
                                                | DRSUAPI_DRS_INIT_SYNC
 
402
                                                | DRSUAPI_DRS_PER_SYNC
 
403
                                                | DRSUAPI_DRS_GET_ANC
 
404
                                                | DRSUAPI_DRS_NEVER_SYNCED
 
405
                                                ;
 
406
        req.req8.max_object_count               = 402;
 
407
        req.req8.max_ndr_size                   = 402116;
 
408
 
 
409
        req.req8.extended_op                    = DRSUAPI_EXOP_NONE;
 
410
        req.req8.fsmo_info                      = 0;
 
411
        req.req8.partial_attribute_set          = NULL;
 
412
        req.req8.partial_attribute_set_ex       = NULL;
 
413
        req.req8.mapping_ctr.num_mappings       = 0;
 
414
        req.req8.mapping_ctr.mappings           = NULL;
 
415
 
 
416
        r.in.bind_handle        = &bi->rpc_handle;
 
417
        r.in.level              = 8;
 
418
        r.in.req                = &req;
 
419
 
 
420
        ZERO_STRUCT(r.out);
 
421
        r.out.level_out         = &_level;
 
422
        r.out.ctr               = &ctr;
 
423
 
 
424
        ZERO_STRUCT(ctr6);
 
425
        do {
 
426
                ZERO_STRUCT(ctr);
 
427
 
 
428
                status = dcerpc_drsuapi_DsGetNCChanges_r(bi->drs_handle, mem_ctx, &r);
 
429
                torture_drsuapi_assert_call(tctx, bi->drs_pipe, status,
 
430
                                            &r, "dcerpc_drsuapi_DsGetNCChanges_r");
 
431
 
 
432
                /* we expect to get level 6 reply */
 
433
                torture_assert_int_equal(tctx, _level, 6, "Expected level 6 reply");
 
434
 
 
435
                /* store this chunk for later use */
 
436
                ctr6_chunk = &r.out.ctr->ctr6;
 
437
 
 
438
                if (!ctr6.first_object) {
 
439
                        ctr6 = *ctr6_chunk;
 
440
                } else {
 
441
                        struct drsuapi_DsReplicaObjectListItemEx *cur;
 
442
 
 
443
                        ctr6.object_count += ctr6_chunk->object_count;
 
444
                        for (cur = ctr6.first_object; cur->next_object; cur = cur->next_object) {}
 
445
                        cur->next_object = ctr6_chunk->first_object;
 
446
 
 
447
                        /* TODO: store the chunk of linked_attributes if needed */
 
448
                }
 
449
 
 
450
                /* prepare for next request */
 
451
                r.in.req->req8.highwatermark = ctr6_chunk->new_highwatermark;
 
452
 
 
453
        } while (ctr6_chunk->more_data);
 
454
 
 
455
        *_ctr6 = talloc(mem_ctx, struct drsuapi_DsGetNCChangesCtr6);
 
456
        torture_assert(mem_ctx, *_ctr6, "Not enough memory");
 
457
        **_ctr6 = ctr6;
 
458
 
 
459
        return true;
 
460
}
 
461
 
 
462
static char * _make_error_message(TALLOC_CTX *mem_ctx,
 
463
                                  enum drsuapi_DsAttributeId drs_attid,
 
464
                                  const struct dsdb_attribute *dsdb_attr,
 
465
                                  const struct drsuapi_DsReplicaObjectIdentifier *identifier)
 
466
{
 
467
        return talloc_asprintf(mem_ctx, "\nInvalid ATTID for %1$s (%2$s)\n"
 
468
                               " drs_attid:      %3$11d (0x%3$08X)\n"
 
469
                               " msDS_IntId:     %4$11d (0x%4$08X)\n"
 
470
                               " attributeId_id: %5$11d (0x%5$08X)",
 
471
                               dsdb_attr->lDAPDisplayName,
 
472
                               identifier->dn,
 
473
                               drs_attid,
 
474
                               dsdb_attr->msDS_IntId,
 
475
                               dsdb_attr->attributeID_id);
 
476
}
 
477
 
 
478
/**
 
479
 * Fetch Schema NC and check ATTID values returned.
 
480
 * When Schema partition is replicated, ATTID
 
481
 * should always be made using prefixMap
 
482
 */
 
483
static bool test_dsintid_schema(struct torture_context *tctx, struct DsIntIdTestCtx *ctx)
 
484
{
 
485
        uint32_t i;
 
486
        const struct dsdb_schema *ldap_schema;
 
487
        struct drsuapi_DsGetNCChangesCtr6 *ctr6 = NULL;
 
488
        const struct dsdb_attribute *dsdb_attr;
 
489
        const struct drsuapi_DsReplicaAttribute *drs_attr;
 
490
        const struct drsuapi_DsReplicaAttributeCtr *attr_ctr;
 
491
        const struct drsuapi_DsReplicaObjectListItemEx *cur;
 
492
        const struct drsuapi_DsReplicaLinkedAttribute *la;
 
493
        TALLOC_CTX *mem_ctx;
 
494
 
 
495
        mem_ctx = talloc_new(ctx);
 
496
        torture_assert(tctx, mem_ctx, "Not enough memory");
 
497
 
 
498
        /* fetch whole Schema partition */
 
499
        torture_comment(tctx, "Fetch partition: %s\n", ctx->schema_dn);
 
500
        if (!_test_GetNCChanges(tctx, &ctx->dsa_bind, ctx->schema_dn, mem_ctx, &ctr6)) {
 
501
                torture_fail(tctx, "_test_GetNCChanges() failed");
 
502
        }
 
503
 
 
504
        /* load schema if not loaded yet */
 
505
        torture_comment(tctx, "Loading schema...\n");
 
506
        if (!drs_util_dsdb_schema_load_ldb(tctx, ctx->ldb, &ctr6->mapping_ctr, false)) {
 
507
                torture_fail(tctx, "drs_util_dsdb_schema_load_ldb() failed");
 
508
        }
 
509
        ldap_schema = dsdb_get_schema(ctx->ldb, NULL);
 
510
 
 
511
        /* verify ATTIDs fetched */
 
512
        torture_comment(tctx, "Verify ATTIDs fetched\n");
 
513
        for (cur = ctr6->first_object; cur; cur = cur->next_object) {
 
514
                attr_ctr = &cur->object.attribute_ctr;
 
515
                for (i = 0; i < attr_ctr->num_attributes; i++) {
 
516
                        drs_attr = &attr_ctr->attributes[i];
 
517
                        dsdb_attr = dsdb_attribute_by_attributeID_id(ldap_schema,
 
518
                                                                     drs_attr->attid);
 
519
 
 
520
                        torture_assert(tctx,
 
521
                                       drs_attr->attid == dsdb_attr->attributeID_id,
 
522
                                       _make_error_message(ctx, drs_attr->attid,
 
523
                                                           dsdb_attr,
 
524
                                                           cur->object.identifier));
 
525
                        if (dsdb_attr->msDS_IntId) {
 
526
                                torture_assert(tctx,
 
527
                                               drs_attr->attid != dsdb_attr->msDS_IntId,
 
528
                                               _make_error_message(ctx, drs_attr->attid,
 
529
                                                                   dsdb_attr,
 
530
                                                                   cur->object.identifier));
 
531
                        }
 
532
                }
 
533
        }
 
534
 
 
535
        /* verify ATTIDs for Linked Attributes */
 
536
        torture_comment(tctx, "Verify ATTIDs for Linked Attributes (%u)\n",
 
537
                        ctr6->linked_attributes_count);
 
538
        for (i = 0; i < ctr6->linked_attributes_count; i++) {
 
539
                la = &ctr6->linked_attributes[i];
 
540
                dsdb_attr = dsdb_attribute_by_attributeID_id(ldap_schema, la->attid);
 
541
 
 
542
                torture_assert(tctx,
 
543
                               la->attid == dsdb_attr->attributeID_id,
 
544
                               _make_error_message(ctx, la->attid,
 
545
                                                   dsdb_attr,
 
546
                                                   la->identifier))
 
547
                if (dsdb_attr->msDS_IntId) {
 
548
                        torture_assert(tctx,
 
549
                                       la->attid != dsdb_attr->msDS_IntId,
 
550
                                       _make_error_message(ctx, la->attid,
 
551
                                                           dsdb_attr,
 
552
                                                           la->identifier))
 
553
                }
 
554
        }
 
555
 
 
556
        talloc_free(mem_ctx);
 
557
 
 
558
        return true;
 
559
}
 
560
 
 
561
/**
 
562
 * Fetch non-Schema NC and check ATTID values returned.
 
563
 * When non-Schema partition is replicated, ATTID
 
564
 * should be msDS-IntId value for the attribute
 
565
 * if this value exists
 
566
 */
 
567
static bool _test_dsintid(struct torture_context *tctx,
 
568
                          struct DsIntIdTestCtx *ctx,
 
569
                          const char *nc_dn_str)
 
570
{
 
571
        uint32_t i;
 
572
        const struct dsdb_schema *ldap_schema;
 
573
        struct drsuapi_DsGetNCChangesCtr6 *ctr6 = NULL;
 
574
        const struct dsdb_attribute *dsdb_attr;
 
575
        const struct drsuapi_DsReplicaAttribute *drs_attr;
 
576
        const struct drsuapi_DsReplicaAttributeCtr *attr_ctr;
 
577
        const struct drsuapi_DsReplicaObjectListItemEx *cur;
 
578
        const struct drsuapi_DsReplicaLinkedAttribute *la;
 
579
        TALLOC_CTX *mem_ctx;
 
580
 
 
581
        mem_ctx = talloc_new(ctx);
 
582
        torture_assert(tctx, mem_ctx, "Not enough memory");
 
583
 
 
584
        /* fetch whole Schema partition */
 
585
        torture_comment(tctx, "Fetch partition: %s\n", nc_dn_str);
 
586
        if (!_test_GetNCChanges(tctx, &ctx->dsa_bind, nc_dn_str, mem_ctx, &ctr6)) {
 
587
                torture_fail(tctx, "_test_GetNCChanges() failed");
 
588
        }
 
589
 
 
590
        /* load schema if not loaded yet */
 
591
        torture_comment(tctx, "Loading schema...\n");
 
592
        if (!drs_util_dsdb_schema_load_ldb(tctx, ctx->ldb, &ctr6->mapping_ctr, false)) {
 
593
                torture_fail(tctx, "drs_util_dsdb_schema_load_ldb() failed");
 
594
        }
 
595
        ldap_schema = dsdb_get_schema(ctx->ldb, NULL);
 
596
 
 
597
        /* verify ATTIDs fetched */
 
598
        torture_comment(tctx, "Verify ATTIDs fetched\n");
 
599
        for (cur = ctr6->first_object; cur; cur = cur->next_object) {
 
600
                attr_ctr = &cur->object.attribute_ctr;
 
601
                for (i = 0; i < attr_ctr->num_attributes; i++) {
 
602
                        drs_attr = &attr_ctr->attributes[i];
 
603
                        dsdb_attr = dsdb_attribute_by_attributeID_id(ldap_schema,
 
604
                                                                     drs_attr->attid);
 
605
                        if (dsdb_attr->msDS_IntId) {
 
606
                                torture_assert(tctx,
 
607
                                               drs_attr->attid == dsdb_attr->msDS_IntId,
 
608
                                               _make_error_message(ctx, drs_attr->attid,
 
609
                                                                   dsdb_attr,
 
610
                                                                   cur->object.identifier));
 
611
                        } else {
 
612
                                torture_assert(tctx,
 
613
                                               drs_attr->attid == dsdb_attr->attributeID_id,
 
614
                                               _make_error_message(ctx, drs_attr->attid,
 
615
                                                                   dsdb_attr,
 
616
                                                                   cur->object.identifier));
 
617
                        }
 
618
                }
 
619
        }
 
620
 
 
621
        /* verify ATTIDs for Linked Attributes */
 
622
        torture_comment(tctx, "Verify ATTIDs for Linked Attributes (%u)\n",
 
623
                        ctr6->linked_attributes_count);
 
624
        for (i = 0; i < ctr6->linked_attributes_count; i++) {
 
625
                la = &ctr6->linked_attributes[i];
 
626
                dsdb_attr = dsdb_attribute_by_attributeID_id(ldap_schema, la->attid);
 
627
 
 
628
                if (dsdb_attr->msDS_IntId) {
 
629
                        torture_assert(tctx,
 
630
                                       la->attid == dsdb_attr->msDS_IntId,
 
631
                                       _make_error_message(ctx, la->attid,
 
632
                                                           dsdb_attr,
 
633
                                                           la->identifier));
 
634
                } else {
 
635
                        torture_assert(tctx,
 
636
                                       la->attid == dsdb_attr->attributeID_id,
 
637
                                       _make_error_message(ctx, la->attid,
 
638
                                                           dsdb_attr,
 
639
                                                           la->identifier));
 
640
                }
 
641
        }
 
642
 
 
643
        talloc_free(mem_ctx);
 
644
 
 
645
        return true;
 
646
}
 
647
 
 
648
/**
 
649
 * Fetch Domain NC and check ATTID values returned.
 
650
 * When Domain partition is replicated, ATTID
 
651
 * should be msDS-IntId value for the attribute
 
652
 * if this value exists
 
653
 */
 
654
static bool test_dsintid_configuration(struct torture_context *tctx, struct DsIntIdTestCtx *ctx)
 
655
{
 
656
        return _test_dsintid(tctx, ctx, ctx->config_dn);
 
657
}
 
658
 
 
659
/**
 
660
 * Fetch Configuration NC and check ATTID values returned.
 
661
 * When Configuration partition is replicated, ATTID
 
662
 * should be msDS-IntId value for the attribute
 
663
 * if this value exists
 
664
 */
 
665
static bool test_dsintid_domain(struct torture_context *tctx, struct DsIntIdTestCtx *ctx)
 
666
{
 
667
        return _test_dsintid(tctx, ctx, ctx->domain_dn);
 
668
}
 
669
 
 
670
 
 
671
/**
 
672
 * DSSYNC test case setup
 
673
 */
 
674
static bool torture_dsintid_tcase_setup(struct torture_context *tctx, void **data)
 
675
{
 
676
        bool bret;
 
677
        struct DsIntIdTestCtx *ctx;
 
678
 
 
679
        *data = ctx = _dsintid_create_context(tctx);
 
680
        torture_assert(tctx, ctx, "test_create_context() failed");
 
681
 
 
682
        bret = _test_DsaBind(tctx, ctx, ctx->creds,
 
683
                             DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8 |
 
684
                             DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6,
 
685
                             &ctx->dsa_bind);
 
686
        torture_assert(tctx, bret, "_test_DsaBind() failed");
 
687
 
 
688
        bret = _test_LDAPBind(tctx, ctx, ctx->creds, ctx->ldap_url, &ctx->ldb);
 
689
        torture_assert(tctx, bret, "_test_LDAPBind() failed");
 
690
 
 
691
        bret = _test_provision(tctx, ctx);
 
692
        torture_assert(tctx, bret, "_test_provision() failed");
 
693
 
 
694
        return true;
 
695
}
 
696
 
 
697
/**
 
698
 * DSSYNC test case cleanup
 
699
 */
 
700
static bool torture_dsintid_tcase_teardown(struct torture_context *tctx, void *data)
 
701
{
 
702
        struct DsIntIdTestCtx *ctx;
 
703
        struct drsuapi_DsUnbind r;
 
704
        struct policy_handle bind_handle;
 
705
 
 
706
        ctx = talloc_get_type(data, struct DsIntIdTestCtx);
 
707
 
 
708
        ZERO_STRUCT(r);
 
709
        r.out.bind_handle = &bind_handle;
 
710
 
 
711
        /* Release DRSUAPI handle */
 
712
        r.in.bind_handle = &ctx->dsa_bind.rpc_handle;
 
713
        dcerpc_drsuapi_DsUnbind_r(ctx->dsa_bind.drs_handle, ctx, &r);
 
714
 
 
715
        talloc_free(ctx);
 
716
 
 
717
        return true;
 
718
}
 
719
 
 
720
/**
 
721
 * DSSYNC test case implementation
 
722
 */
 
723
void torture_drs_rpc_dsintid_tcase(struct torture_suite *suite)
 
724
{
 
725
        typedef bool (*run_func) (struct torture_context *test, void *tcase_data);
 
726
 
 
727
        struct torture_test *test;
 
728
        struct torture_tcase *tcase = torture_suite_add_tcase(suite, "msDSIntId");
 
729
 
 
730
        torture_tcase_set_fixture(tcase,
 
731
                                  torture_dsintid_tcase_setup,
 
732
                                  torture_dsintid_tcase_teardown);
 
733
 
 
734
        test = torture_tcase_add_simple_test(tcase, "Schema", (run_func)test_dsintid_schema);
 
735
        test = torture_tcase_add_simple_test(tcase, "Configuration", (run_func)test_dsintid_configuration);
 
736
        test = torture_tcase_add_simple_test(tcase, "Domain", (run_func)test_dsintid_domain);
 
737
}