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

« back to all changes in this revision

Viewing changes to source4/dsdb/samdb/ldb_modules/schema_load.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 mplementation.
 
3
 
 
4
   The module that handles the Schema FSMO Role Owner
 
5
   checkings, it also loads the dsdb_schema.
 
6
   
 
7
   Copyright (C) Stefan Metzmacher <metze@samba.org> 2007
 
8
   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009-2010
 
9
 
 
10
   This program is free software; you can redistribute it and/or modify
 
11
   it under the terms of the GNU General Public License as published by
 
12
   the Free Software Foundation; either version 3 of the License, or
 
13
   (at your option) any later version.
 
14
   
 
15
   This program is distributed in the hope that it will be useful,
 
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
   GNU General Public License for more details.
 
19
   
 
20
   You should have received a copy of the GNU General Public License
 
21
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
22
   
 
23
*/
 
24
 
 
25
#include "includes.h"
 
26
#include "ldb_module.h"
 
27
#include "dsdb/samdb/samdb.h"
 
28
#include "librpc/gen_ndr/ndr_misc.h"
 
29
#include "librpc/gen_ndr/ndr_drsuapi.h"
 
30
#include "librpc/gen_ndr/ndr_drsblobs.h"
 
31
#include "param/param.h"
 
32
#include "dsdb/samdb/ldb_modules/util.h"
 
33
 
 
34
struct schema_load_private_data {
 
35
        bool in_transaction;
 
36
};
 
37
 
 
38
static int dsdb_schema_from_db(struct ldb_module *module, struct ldb_dn *schema_dn, uint64_t current_usn,
 
39
                               struct dsdb_schema **schema);
 
40
 
 
41
struct dsdb_schema *dsdb_schema_refresh(struct ldb_module *module, struct dsdb_schema *schema, bool is_global_schema)
 
42
{
 
43
        uint64_t current_usn;
 
44
        int ret;
 
45
        struct ldb_result *res;
 
46
        struct ldb_request *treq;
 
47
        struct ldb_seqnum_request *tseq;
 
48
        struct ldb_seqnum_result *tseqr;
 
49
        struct dsdb_control_current_partition *ctrl;
 
50
        struct ldb_context *ldb = ldb_module_get_ctx(module);
 
51
        struct dsdb_schema *new_schema;
 
52
        
 
53
        struct schema_load_private_data *private_data = talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
 
54
        if (!private_data) {
 
55
                /* We can't refresh until the init function has run */
 
56
                return schema;
 
57
        }
 
58
 
 
59
        /* We don't allow a schema reload during a transaction - nobody else can modify our schema behind our backs */
 
60
        if (private_data->in_transaction) {
 
61
                return schema;
 
62
        }
 
63
 
 
64
        res = talloc_zero(schema, struct ldb_result);
 
65
        if (res == NULL) {
 
66
                return NULL;
 
67
        }
 
68
        tseq = talloc_zero(res, struct ldb_seqnum_request);
 
69
        if (tseq == NULL) {
 
70
                talloc_free(res);
 
71
                return NULL;
 
72
        }
 
73
        tseq->type = LDB_SEQ_HIGHEST_SEQ;
 
74
        
 
75
        ret = ldb_build_extended_req(&treq, ldb_module_get_ctx(module), res,
 
76
                                     LDB_EXTENDED_SEQUENCE_NUMBER,
 
77
                                     tseq,
 
78
                                     NULL,
 
79
                                     res,
 
80
                                     ldb_extended_default_callback,
 
81
                                     NULL);
 
82
        LDB_REQ_SET_LOCATION(treq);
 
83
        if (ret != LDB_SUCCESS) {
 
84
                talloc_free(res);
 
85
                return NULL;
 
86
        }
 
87
        
 
88
        ctrl = talloc(treq, struct dsdb_control_current_partition);
 
89
        if (!ctrl) {
 
90
                talloc_free(res);
 
91
                return NULL;
 
92
        }
 
93
        ctrl->version = DSDB_CONTROL_CURRENT_PARTITION_VERSION;
 
94
        ctrl->dn = schema->base_dn;
 
95
        
 
96
        ret = ldb_request_add_control(treq,
 
97
                                      DSDB_CONTROL_CURRENT_PARTITION_OID,
 
98
                                      false, ctrl);
 
99
        if (ret != LDB_SUCCESS) {
 
100
                talloc_free(res);
 
101
                return NULL;
 
102
        }
 
103
        
 
104
        ret = ldb_next_request(module, treq);
 
105
        if (ret != LDB_SUCCESS) {
 
106
                talloc_free(res);
 
107
                return NULL;
 
108
        }
 
109
        ret = ldb_wait(treq->handle, LDB_WAIT_ALL);
 
110
        if (ret != LDB_SUCCESS) {
 
111
                talloc_free(res);
 
112
                return NULL;
 
113
        }
 
114
        tseqr = talloc_get_type(res->extended->data,
 
115
                                struct ldb_seqnum_result);
 
116
        if (tseqr->seq_num == schema->reload_seq_number) {
 
117
                talloc_free(res);
 
118
                return schema;
 
119
        }
 
120
 
 
121
        schema->reload_seq_number = tseqr->seq_num;
 
122
        talloc_free(res);
 
123
                
 
124
        ret = dsdb_module_load_partition_usn(module, schema->base_dn, &current_usn, NULL, NULL);
 
125
        if (ret != LDB_SUCCESS || current_usn == schema->loaded_usn) {
 
126
                return schema;
 
127
        }
 
128
 
 
129
        ret = dsdb_schema_from_db(module, schema->base_dn, current_usn, &new_schema);
 
130
        if (ret != LDB_SUCCESS) {
 
131
                return schema;
 
132
        }
 
133
        
 
134
        if (is_global_schema) {
 
135
                dsdb_make_schema_global(ldb, new_schema);
 
136
        }
 
137
        return new_schema;
 
138
}
 
139
 
 
140
 
 
141
/*
 
142
  Given an LDB module (pointing at the schema DB), and the DN, set the populated schema
 
143
*/
 
144
 
 
145
static int dsdb_schema_from_db(struct ldb_module *module, struct ldb_dn *schema_dn, uint64_t current_usn,
 
146
                               struct dsdb_schema **schema)
 
147
{
 
148
        struct ldb_context *ldb = ldb_module_get_ctx(module);
 
149
        TALLOC_CTX *tmp_ctx;
 
150
        char *error_string;
 
151
        int ret;
 
152
        struct ldb_result *schema_res;
 
153
        struct ldb_result *a_res;
 
154
        struct ldb_result *c_res;
 
155
        static const char *schema_attrs[] = {
 
156
                "prefixMap",
 
157
                "schemaInfo",
 
158
                "fSMORoleOwner",
 
159
                NULL
 
160
        };
 
161
        unsigned flags;
 
162
 
 
163
        tmp_ctx = talloc_new(module);
 
164
        if (!tmp_ctx) {
 
165
                return ldb_oom(ldb);
 
166
        }
 
167
 
 
168
        /* we don't want to trace the schema load */
 
169
        flags = ldb_get_flags(ldb);
 
170
        ldb_set_flags(ldb, flags & ~LDB_FLG_ENABLE_TRACING);
 
171
 
 
172
        /*
 
173
         * setup the prefix mappings and schema info
 
174
         */
 
175
        ret = dsdb_module_search_dn(module, tmp_ctx, &schema_res,
 
176
                                    schema_dn, schema_attrs,
 
177
                                    DSDB_FLAG_NEXT_MODULE, NULL);
 
178
        if (ret == LDB_ERR_NO_SUCH_OBJECT) {
 
179
                ldb_reset_err_string(ldb);
 
180
                ldb_debug(ldb, LDB_DEBUG_WARNING,
 
181
                          "schema_load_init: no schema head present: (skip schema loading)\n");
 
182
                goto failed;
 
183
        } else if (ret != LDB_SUCCESS) {
 
184
                ldb_asprintf_errstring(ldb, 
 
185
                                       "dsdb_schema: failed to search the schema head: %s",
 
186
                                       ldb_errstring(ldb));
 
187
                goto failed;
 
188
        }
 
189
 
 
190
        /*
 
191
         * load the attribute definitions
 
192
         */
 
193
        ret = dsdb_module_search(module, tmp_ctx, &a_res,
 
194
                                 schema_dn, LDB_SCOPE_ONELEVEL, NULL,
 
195
                                 DSDB_FLAG_NEXT_MODULE,
 
196
                                 NULL,
 
197
                                 "(objectClass=attributeSchema)");
 
198
        if (ret != LDB_SUCCESS) {
 
199
                ldb_asprintf_errstring(ldb, 
 
200
                                       "dsdb_schema: failed to search attributeSchema objects: %s",
 
201
                                       ldb_errstring(ldb));
 
202
                goto failed;
 
203
        }
 
204
 
 
205
        /*
 
206
         * load the objectClass definitions
 
207
         */
 
208
        ret = dsdb_module_search(module, tmp_ctx, &c_res,
 
209
                                 schema_dn, LDB_SCOPE_ONELEVEL, NULL,
 
210
                                 DSDB_FLAG_NEXT_MODULE |
 
211
                                 DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT,
 
212
                                 NULL,
 
213
                                 "(objectClass=classSchema)");
 
214
        if (ret != LDB_SUCCESS) {
 
215
                ldb_asprintf_errstring(ldb, 
 
216
                                       "dsdb_schema: failed to search classSchema objects: %s",
 
217
                                       ldb_errstring(ldb));
 
218
                goto failed;
 
219
        }
 
220
 
 
221
        ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb,
 
222
                                           schema_res, a_res, c_res, schema, &error_string);
 
223
        if (ret != LDB_SUCCESS) {
 
224
                ldb_asprintf_errstring(ldb, 
 
225
                                       "dsdb_schema load failed: %s",
 
226
                                       error_string);
 
227
                goto failed;
 
228
        }
 
229
 
 
230
        (*schema)->refresh_in_progress = true;
 
231
 
 
232
        /* If we have the readOnlySchema opaque, then don't check for
 
233
         * runtime schema updates, as they are not permitted (we would
 
234
         * have to update the backend server schema too */
 
235
        if (!ldb_get_opaque(ldb, "readOnlySchema")) {
 
236
                (*schema)->refresh_fn = dsdb_schema_refresh;
 
237
                (*schema)->loaded_from_module = module;
 
238
                (*schema)->loaded_usn = current_usn;
 
239
        }
 
240
 
 
241
        /* "dsdb_set_schema()" steals schema into the ldb_context */
 
242
        ret = dsdb_set_schema(ldb, (*schema));
 
243
 
 
244
        (*schema)->refresh_in_progress = false;
 
245
 
 
246
        if (ret != LDB_SUCCESS) {
 
247
                ldb_debug_set(ldb, LDB_DEBUG_FATAL,
 
248
                              "schema_load_init: dsdb_set_schema() failed: %d:%s: %s",
 
249
                              ret, ldb_strerror(ret), ldb_errstring(ldb));
 
250
                goto failed;
 
251
        }
 
252
 
 
253
        /* Ensure this module won't go away before the callback */
 
254
        if (talloc_reference(*schema, ldb) == NULL) {
 
255
                ldb_oom(ldb);
 
256
                ret = LDB_ERR_OPERATIONS_ERROR;
 
257
        }
 
258
 
 
259
failed:
 
260
        if (flags & LDB_FLG_ENABLE_TRACING) {
 
261
                flags = ldb_get_flags(ldb);
 
262
                ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING);
 
263
        }
 
264
        talloc_free(tmp_ctx);
 
265
        return ret;
 
266
}       
 
267
 
 
268
 
 
269
static int schema_load_init(struct ldb_module *module)
 
270
{
 
271
        struct schema_load_private_data *private_data;
 
272
        struct dsdb_schema *schema;
 
273
        struct ldb_context *ldb = ldb_module_get_ctx(module);
 
274
        int ret;
 
275
        uint64_t current_usn;
 
276
        struct ldb_dn *schema_dn;
 
277
 
 
278
        private_data = talloc_zero(module, struct schema_load_private_data);
 
279
        if (private_data == NULL) {
 
280
                return ldb_oom(ldb);
 
281
        }
 
282
 
 
283
        ldb_module_set_private(module, private_data);
 
284
 
 
285
        ret = ldb_next_init(module);
 
286
        if (ret != LDB_SUCCESS) {
 
287
                return ret;
 
288
        }
 
289
 
 
290
        if (dsdb_get_schema(ldb, NULL)) {
 
291
                return LDB_SUCCESS;
 
292
        }
 
293
 
 
294
        schema_dn = ldb_get_schema_basedn(ldb);
 
295
        if (!schema_dn) {
 
296
                ldb_reset_err_string(ldb);
 
297
                ldb_debug(ldb, LDB_DEBUG_WARNING,
 
298
                          "schema_load_init: no schema dn present: (skip schema loading)\n");
 
299
                return LDB_SUCCESS;
 
300
        }
 
301
 
 
302
        ret = dsdb_module_load_partition_usn(module, schema_dn, &current_usn, NULL, NULL);
 
303
        if (ret != LDB_SUCCESS) {
 
304
                /* Ignore the error and just reload the DB more often */
 
305
                current_usn = 0;
 
306
        }
 
307
 
 
308
        return dsdb_schema_from_db(module, schema_dn, current_usn, &schema);
 
309
}
 
310
 
 
311
static int schema_load_start_transaction(struct ldb_module *module)
 
312
{
 
313
        struct schema_load_private_data *private_data =
 
314
                talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
 
315
 
 
316
        private_data->in_transaction = true;
 
317
 
 
318
        return ldb_next_start_trans(module);
 
319
}
 
320
 
 
321
static int schema_load_end_transaction(struct ldb_module *module)
 
322
{
 
323
        struct schema_load_private_data *private_data =
 
324
                talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
 
325
 
 
326
        private_data->in_transaction = false;
 
327
 
 
328
        return ldb_next_end_trans(module);
 
329
}
 
330
 
 
331
static int schema_load_del_transaction(struct ldb_module *module)
 
332
{
 
333
        struct schema_load_private_data *private_data =
 
334
                talloc_get_type(ldb_module_get_private(module), struct schema_load_private_data);
 
335
 
 
336
        private_data->in_transaction = false;
 
337
 
 
338
        return ldb_next_del_trans(module);
 
339
}
 
340
 
 
341
static int schema_load_extended(struct ldb_module *module, struct ldb_request *req)
 
342
{
 
343
        struct ldb_context *ldb;
 
344
 
 
345
        ldb = ldb_module_get_ctx(module);
 
346
 
 
347
        if (strcmp(req->op.extended.oid, DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID) != 0) {
 
348
                return ldb_next_request(module, req);
 
349
        }
 
350
 
 
351
        /* This is a no-op.  We reload as soon as we can */
 
352
        return ldb_module_done(req, NULL, NULL, LDB_SUCCESS);
 
353
}
 
354
 
 
355
 
 
356
static const struct ldb_module_ops ldb_schema_load_module_ops = {
 
357
        .name           = "schema_load",
 
358
        .init_context   = schema_load_init,
 
359
        .extended       = schema_load_extended,
 
360
        .start_transaction = schema_load_start_transaction,
 
361
        .end_transaction   = schema_load_end_transaction,
 
362
        .del_transaction   = schema_load_del_transaction,
 
363
};
 
364
 
 
365
int ldb_schema_load_module_init(const char *version)
 
366
{
 
367
        LDB_MODULE_CHECK_VERSION(version);
 
368
        return ldb_register_module(&ldb_schema_load_module_ops);
 
369
}