~lefteris-nikoltsios/+junk/samba-lp1016895

« back to all changes in this revision

Viewing changes to source4/dsdb/samdb/ldb_modules/objectguid.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:
31
31
 
32
32
#include "includes.h"
33
33
#include "ldb_module.h"
 
34
#include "dsdb/samdb/samdb.h"
 
35
#include "dsdb/samdb/ldb_modules/util.h"
34
36
#include "librpc/gen_ndr/ndr_misc.h"
35
37
#include "param/param.h"
36
38
 
37
 
static struct ldb_message_element *objectguid_find_attribute(const struct ldb_message *msg, const char *name)
38
 
{
39
 
        int i;
40
 
 
41
 
        for (i = 0; i < msg->num_elements; i++) {
42
 
                if (ldb_attr_cmp(name, msg->elements[i].name) == 0) {
43
 
                        return &msg->elements[i];
44
 
                }
45
 
        }
46
 
 
47
 
        return NULL;
48
 
}
49
 
 
50
39
/*
51
40
  add a time element to a record
52
41
*/
54
43
{
55
44
        struct ldb_message_element *el;
56
45
        char *s;
 
46
        int ret;
57
47
 
58
48
        if (ldb_msg_find_element(msg, attr) != NULL) {
59
 
                return 0;
 
49
                return LDB_SUCCESS;
60
50
        }
61
51
 
62
52
        s = ldb_timestring(msg, t);
63
53
        if (s == NULL) {
64
 
                return -1;
 
54
                return LDB_ERR_OPERATIONS_ERROR;
65
55
        }
66
56
 
67
 
        if (ldb_msg_add_string(msg, attr, s) != 0) {
68
 
                return -1;
 
57
        ret = ldb_msg_add_string(msg, attr, s);
 
58
        if (ret != LDB_SUCCESS) {
 
59
                return ret;
69
60
        }
70
61
 
71
62
        el = ldb_msg_find_element(msg, attr);
73
64
           is ignored */
74
65
        el->flags = LDB_FLAG_MOD_REPLACE;
75
66
 
76
 
        return 0;
 
67
        return LDB_SUCCESS;
77
68
}
78
69
 
79
70
/*
80
71
  add a uint64_t element to a record
81
72
*/
82
 
static int add_uint64_element(struct ldb_message *msg, const char *attr, uint64_t v)
 
73
static int add_uint64_element(struct ldb_context *ldb, struct ldb_message *msg,
 
74
                              const char *attr, uint64_t v)
83
75
{
84
76
        struct ldb_message_element *el;
 
77
        int ret;
85
78
 
86
79
        if (ldb_msg_find_element(msg, attr) != NULL) {
87
 
                return 0;
 
80
                return LDB_SUCCESS;
88
81
        }
89
82
 
90
 
        if (ldb_msg_add_fmt(msg, attr, "%llu", (unsigned long long)v) != 0) {
91
 
                return -1;
 
83
        ret = samdb_msg_add_uint64(ldb, msg, msg, attr, v);
 
84
        if (ret != LDB_SUCCESS) {
 
85
                return ret;
92
86
        }
93
87
 
94
88
        el = ldb_msg_find_element(msg, attr);
96
90
           is ignored */
97
91
        el->flags = LDB_FLAG_MOD_REPLACE;
98
92
 
99
 
        return 0;
 
93
        return LDB_SUCCESS;
100
94
}
101
95
 
102
96
struct og_context {
104
98
        struct ldb_request *req;
105
99
};
106
100
 
107
 
static int og_op_callback(struct ldb_request *req, struct ldb_reply *ares)
108
 
{
109
 
        struct og_context *ac;
110
 
 
111
 
        ac = talloc_get_type(req->context, struct og_context);
112
 
 
113
 
        if (!ares) {
114
 
                return ldb_module_done(ac->req, NULL, NULL,
115
 
                                        LDB_ERR_OPERATIONS_ERROR);
116
 
        }
117
 
        if (ares->error != LDB_SUCCESS) {
118
 
                return ldb_module_done(ac->req, ares->controls,
119
 
                                        ares->response, ares->error);
120
 
        }
121
 
 
122
 
        if (ares->type != LDB_REPLY_DONE) {
123
 
                talloc_free(ares);
124
 
                return ldb_module_done(ac->req, NULL, NULL,
125
 
                                        LDB_ERR_OPERATIONS_ERROR);
126
 
        }
127
 
 
128
 
        return ldb_module_done(ac->req, ares->controls,
129
 
                                ares->response, ares->error);
130
 
}
131
 
 
132
 
/* add_record: add objectGUID attribute */
 
101
/* add_record: add objectGUID and timestamp attributes */
133
102
static int objectguid_add(struct ldb_module *module, struct ldb_request *req)
134
103
{
135
104
        struct ldb_context *ldb;
136
105
        struct ldb_request *down_req;
137
 
        struct ldb_message_element *attribute;
138
106
        struct ldb_message *msg;
139
 
        struct ldb_val v;
 
107
        struct ldb_message_element *el;
140
108
        struct GUID guid;
141
109
        uint64_t seq_num;
142
 
        enum ndr_err_code ndr_err;
143
110
        int ret;
144
111
        time_t t = time(NULL);
145
112
        struct og_context *ac;
153
120
                return ldb_next_request(module, req);
154
121
        }
155
122
 
156
 
        if ((attribute = objectguid_find_attribute(req->op.add.message, "objectGUID")) != NULL ) {
157
 
                return ldb_next_request(module, req);
 
123
        el = ldb_msg_find_element(req->op.add.message, "objectGUID");
 
124
        if (el != NULL) {
 
125
                ldb_set_errstring(ldb,
 
126
                                  "objectguid: objectGUID must not be specified!");
 
127
                return LDB_ERR_UNWILLING_TO_PERFORM;
158
128
        }
159
129
 
160
130
        ac = talloc(req, struct og_context);
161
131
        if (ac == NULL) {
162
 
                return LDB_ERR_OPERATIONS_ERROR;
 
132
                return ldb_oom(ldb);
163
133
        }
164
134
        ac->module = module;
165
135
        ac->req = req;
167
137
        /* we have to copy the message as the caller might have it as a const */
168
138
        msg = ldb_msg_copy_shallow(ac, req->op.add.message);
169
139
        if (msg == NULL) {
170
 
                talloc_free(down_req);
171
 
                return LDB_ERR_OPERATIONS_ERROR;
 
140
                talloc_free(ac);
 
141
                return ldb_operr(ldb);
172
142
        }
173
143
 
174
144
        /* a new GUID */
175
145
        guid = GUID_random();
176
146
 
177
 
        ndr_err = ndr_push_struct_blob(&v, msg, 
178
 
                                       lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
179
 
                                       &guid,
180
 
                                       (ndr_push_flags_fn_t)ndr_push_GUID);
181
 
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
182
 
                return LDB_ERR_OPERATIONS_ERROR;
183
 
        }
184
 
 
185
 
        ret = ldb_msg_add_value(msg, "objectGUID", &v, NULL);
186
 
        if (ret) {
 
147
        ret = dsdb_msg_add_guid(msg, &guid, "objectGUID");
 
148
        if (ret != LDB_SUCCESS) {
187
149
                return ret;
188
150
        }
189
151
        
190
 
        if (add_time_element(msg, "whenCreated", t) != 0 ||
191
 
            add_time_element(msg, "whenChanged", t) != 0) {
192
 
                return LDB_ERR_OPERATIONS_ERROR;
 
152
        if (add_time_element(msg, "whenCreated", t) != LDB_SUCCESS ||
 
153
            add_time_element(msg, "whenChanged", t) != LDB_SUCCESS) {
 
154
                return ldb_operr(ldb);
193
155
        }
194
156
 
195
157
        /* Get a sequence number from the backend */
196
 
        /* FIXME: ldb_sequence_number is a semi-async call,
197
 
         * make sure this function is split and a callback is used */
198
158
        ret = ldb_sequence_number(ldb, LDB_SEQ_NEXT, &seq_num);
199
159
        if (ret == LDB_SUCCESS) {
200
 
                if (add_uint64_element(msg, "uSNCreated", seq_num) != 0 ||
201
 
                    add_uint64_element(msg, "uSNChanged", seq_num) != 0) {
202
 
                        return LDB_ERR_OPERATIONS_ERROR;
 
160
                if (add_uint64_element(ldb, msg, "uSNCreated",
 
161
                                       seq_num) != LDB_SUCCESS ||
 
162
                    add_uint64_element(ldb, msg, "uSNChanged",
 
163
                                       seq_num) != LDB_SUCCESS) {
 
164
                        return ldb_operr(ldb);
203
165
                }
204
166
        }
205
167
 
206
168
        ret = ldb_build_add_req(&down_req, ldb, ac,
207
169
                                msg,
208
170
                                req->controls,
209
 
                                ac, og_op_callback,
 
171
                                req, dsdb_next_callback,
210
172
                                req);
 
173
        LDB_REQ_SET_LOCATION(down_req);
211
174
        if (ret != LDB_SUCCESS) {
212
 
                return LDB_ERR_OPERATIONS_ERROR;
 
175
                return ret;
213
176
        }
214
177
 
215
178
        /* go on with the call chain */
222
185
        struct ldb_context *ldb;
223
186
        struct ldb_request *down_req;
224
187
        struct ldb_message *msg;
 
188
        struct ldb_message_element *el;
225
189
        int ret;
226
190
        time_t t = time(NULL);
227
191
        uint64_t seq_num;
229
193
 
230
194
        ldb = ldb_module_get_ctx(module);
231
195
 
232
 
        ldb_debug(ldb, LDB_DEBUG_TRACE, "objectguid_add_record\n");
 
196
        ldb_debug(ldb, LDB_DEBUG_TRACE, "objectguid_modify_record\n");
233
197
 
234
198
        /* do not manipulate our control entries */
235
199
        if (ldb_dn_is_special(req->op.add.message->dn)) {
236
200
                return ldb_next_request(module, req);
237
201
        }
238
202
 
 
203
        el = ldb_msg_find_element(req->op.mod.message, "objectGUID");
 
204
        if (el != NULL) {
 
205
                ldb_set_errstring(ldb,
 
206
                                  "objectguid: objectGUID must not be specified!");
 
207
                return LDB_ERR_CONSTRAINT_VIOLATION;
 
208
        }
 
209
 
239
210
        ac = talloc(req, struct og_context);
240
211
        if (ac == NULL) {
241
 
                return LDB_ERR_OPERATIONS_ERROR;
 
212
                return ldb_oom(ldb);
242
213
        }
243
214
        ac->module = module;
244
215
        ac->req = req;
246
217
        /* we have to copy the message as the caller might have it as a const */
247
218
        msg = ldb_msg_copy_shallow(ac, req->op.mod.message);
248
219
        if (msg == NULL) {
249
 
                return LDB_ERR_OPERATIONS_ERROR;
 
220
                return ldb_operr(ldb);
250
221
        }
251
222
 
252
 
        if (add_time_element(msg, "whenChanged", t) != 0) {
253
 
                return LDB_ERR_OPERATIONS_ERROR;
 
223
        if (add_time_element(msg, "whenChanged", t) != LDB_SUCCESS) {
 
224
                return ldb_operr(ldb);
254
225
        }
255
226
 
256
227
        /* Get a sequence number from the backend */
257
228
        ret = ldb_sequence_number(ldb, LDB_SEQ_NEXT, &seq_num);
258
229
        if (ret == LDB_SUCCESS) {
259
 
                if (add_uint64_element(msg, "uSNChanged", seq_num) != 0) {
260
 
                        return LDB_ERR_OPERATIONS_ERROR;
 
230
                if (add_uint64_element(ldb, msg, "uSNChanged",
 
231
                                       seq_num) != LDB_SUCCESS) {
 
232
                        return ldb_operr(ldb);
261
233
                }
262
234
        }
263
235
 
264
236
        ret = ldb_build_mod_req(&down_req, ldb, ac,
265
237
                                msg,
266
238
                                req->controls,
267
 
                                ac, og_op_callback,
 
239
                                req, dsdb_next_callback,
268
240
                                req);
 
241
        LDB_REQ_SET_LOCATION(down_req);
269
242
        if (ret != LDB_SUCCESS) {
270
 
                return LDB_ERR_OPERATIONS_ERROR;
 
243
                return ret;
271
244
        }
272
245
 
273
246
        /* go on with the call chain */
274
247
        return ldb_next_request(module, down_req);
275
248
}
276
249
 
277
 
_PUBLIC_ const struct ldb_module_ops ldb_objectguid_module_ops = {
 
250
static const struct ldb_module_ops ldb_objectguid_module_ops = {
278
251
        .name          = "objectguid",
279
252
        .add           = objectguid_add,
280
 
        .modify        = objectguid_modify,
 
253
        .modify        = objectguid_modify
281
254
};
 
255
 
 
256
int ldb_objectguid_module_init(const char *version)
 
257
{
 
258
        LDB_MODULE_CHECK_VERSION(version);
 
259
        return ldb_register_module(&ldb_objectguid_module_ops);
 
260
}