When Windows initially creates a new value, the value name is "New Value #1".
[ira/wip.git] / source / lib / registry / ldb.c
1 /*
2    Unix SMB/CIFS implementation.
3    Registry interface
4    Copyright (C) Jelmer Vernooij  2004-2007.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21 #include "registry.h"
22 #include "lib/ldb/include/ldb.h"
23 #include "lib/ldb/include/ldb_errors.h"
24 #include "ldb_wrap.h"
25 #include "librpc/gen_ndr/winreg.h"
26 #include "param/param.h"
27
28 static struct hive_operations reg_backend_ldb;
29
30 struct ldb_key_data
31 {
32         struct hive_key key;
33         struct ldb_context *ldb;
34         struct ldb_dn *dn;
35         struct ldb_message **subkeys, **values;
36         int subkey_count, value_count;
37 };
38
39 static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg,
40                                  const char **name, uint32_t *type,
41                                  DATA_BLOB *data)
42 {
43         const struct ldb_val *val;
44         uint32_t value_type;
45
46         if (name != NULL)
47                 *name = talloc_strdup(mem_ctx,
48                                       ldb_msg_find_attr_as_string(msg, "value",
49                                       NULL));
50
51         value_type = ldb_msg_find_attr_as_uint(msg, "type", 0);
52         if (type != NULL)
53                 *type = value_type; 
54         val = ldb_msg_find_ldb_val(msg, "data");
55
56         switch (value_type)
57         {
58         case REG_SZ:
59         case REG_EXPAND_SZ:
60                 data->length = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF8, CH_UTF16,
61                                                      val->data, val->length,
62                                                      (void **)&data->data);
63                 break;
64
65         case REG_DWORD: {
66                 uint32_t tmp = strtoul((char *)val->data, NULL, 0);
67                 *data = data_blob_talloc(mem_ctx, &tmp, 4);
68                 }
69                 break;
70
71         default:
72                 *data = data_blob_talloc(mem_ctx, val->data, val->length);
73                 break;
74         }
75 }
76
77 static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx,
78                                               TALLOC_CTX *mem_ctx,
79                                               const char *name,
80                                               uint32_t type, DATA_BLOB data)
81 {
82         struct ldb_val val;
83         struct ldb_message *msg = talloc_zero(mem_ctx, struct ldb_message);
84         char *type_s;
85
86         ldb_msg_add_string(msg, "value", talloc_strdup(mem_ctx, name));
87
88         switch (type) {
89         case REG_SZ:
90         case REG_EXPAND_SZ:
91                 val.length = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX,
92                                                    (void *)data.data,
93                                                    data.length,
94                                                    (void **)&val.data);
95                 ldb_msg_add_value(msg, "data", &val, NULL);
96                 break;
97
98         case REG_DWORD:
99                 ldb_msg_add_string(msg, "data",
100                                    talloc_asprintf(mem_ctx, "0x%x",
101                                                    IVAL(data.data, 0)));
102                 break;
103         default:
104                 ldb_msg_add_value(msg, "data", &data, NULL);
105         }
106
107
108         type_s = talloc_asprintf(mem_ctx, "%u", type);
109         ldb_msg_add_string(msg, "type", type_s);
110
111         return msg;
112 }
113
114
115 static char *reg_ldb_escape(TALLOC_CTX *mem_ctx, const char *value)
116 {
117         struct ldb_val val;
118
119         val.data = discard_const_p(uint8_t, value);
120         val.length = strlen(value);
121
122         return ldb_dn_escape_value(mem_ctx, val);
123 }
124
125 static int reg_close_ldb_key(struct ldb_key_data *key)
126 {
127         if (key->subkeys != NULL) {
128                 talloc_free(key->subkeys);
129                 key->subkeys = NULL;
130         }
131
132         if (key->values != NULL) {
133                 talloc_free(key->values);
134                 key->values = NULL;
135         }
136         return 0;
137 }
138
139 static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx,
140                                       const struct hive_key *from,
141                                       const char *path, const char *add)
142 {
143         TALLOC_CTX *local_ctx;
144         struct ldb_dn *ret;
145         char *mypath = talloc_strdup(mem_ctx, path);
146         char *begin;
147         struct ldb_key_data *kd = talloc_get_type(from, struct ldb_key_data);
148         struct ldb_context *ldb = kd->ldb;
149
150         local_ctx = talloc_new(mem_ctx);
151
152         if (add) {
153                 ret = ldb_dn_new(mem_ctx, ldb, add);
154         } else {
155                 ret = ldb_dn_new(mem_ctx, ldb, NULL);
156         }
157         if (!ldb_dn_validate(ret)) {
158                 talloc_free(ret);
159                 talloc_free(local_ctx);
160                 return NULL;
161         }
162
163         while (mypath) {
164                 char *keyname;
165
166                 begin = strrchr(mypath, '\\');
167
168                 if (begin) keyname = begin + 1;
169                 else keyname = mypath;
170
171                 if(strlen(keyname)) {
172                         ldb_dn_add_base_fmt(ret, "key=%s", keyname);
173                 }
174
175                 if(begin) {
176                         *begin = '\0';
177                 } else {
178                         break;
179                 }
180         }
181
182         ldb_dn_add_base(ret, kd->dn);
183
184         talloc_free(local_ctx);
185
186         return ret;
187 }
188
189 static WERROR cache_subkeys(struct ldb_key_data *kd)
190 {
191         struct ldb_context *c = kd->ldb;
192         struct ldb_result *res;
193         int ret;
194
195         ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &res);
196
197         if (ret != LDB_SUCCESS) {
198                 DEBUG(0, ("Error getting subkeys for '%s': %s\n",
199                         ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));
200                 return WERR_FOOBAR;
201         }
202
203         kd->subkey_count = res->count;
204         kd->subkeys = talloc_steal(kd, res->msgs);
205         talloc_free(res);
206
207         return WERR_OK;
208 }
209
210 static WERROR cache_values(struct ldb_key_data *kd)
211 {
212         struct ldb_context *c = kd->ldb;
213         struct ldb_result *res;
214         int ret;
215
216         ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL,
217                          "(value=*)", NULL, &res);
218
219         if (ret != LDB_SUCCESS) {
220                 DEBUG(0, ("Error getting values for '%s': %s\n",
221                         ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));
222                 return WERR_FOOBAR;
223         }
224         kd->value_count = res->count;
225         kd->values = talloc_steal(kd, res->msgs);
226         talloc_free(res);
227         return WERR_OK;
228 }
229
230
231 static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx,
232                                    const struct hive_key *k, uint32_t idx,
233                                    const char **name,
234                                    const char **classname,
235                                    NTTIME *last_mod_time)
236 {
237         struct ldb_message_element *el;
238         struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
239
240         /* Do a search if necessary */
241         if (kd->subkeys == NULL) {
242                 W_ERROR_NOT_OK_RETURN(cache_subkeys(kd));
243         }
244
245         if (idx >= kd->subkey_count)
246                 return WERR_NO_MORE_ITEMS;
247
248         el = ldb_msg_find_element(kd->subkeys[idx], "key");
249         SMB_ASSERT(el != NULL);
250         SMB_ASSERT(el->num_values != 0);
251
252         if (name != NULL)
253                 *name = talloc_strdup(mem_ctx, (char *)el->values[0].data);
254
255         if (classname != NULL)
256                 *classname = NULL; /* TODO: Store properly */
257
258         if (last_mod_time != NULL)
259                 *last_mod_time = 0; /* TODO: we need to add this to the
260                                                 ldb backend properly */
261
262         return WERR_OK;
263 }
264
265 static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, struct hive_key *k,
266                                   int idx, const char **name,
267                                   uint32_t *data_type, DATA_BLOB *data)
268 {
269         struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
270
271         /* Do the search if necessary */
272         if (kd->values == NULL) {
273                 W_ERROR_NOT_OK_RETURN(cache_values(kd));
274         }
275
276         if (idx >= kd->value_count)
277                 return WERR_NO_MORE_ITEMS;
278
279         reg_ldb_unpack_value(mem_ctx, kd->values[idx],
280                              name, data_type, data);
281
282         return WERR_OK;
283 }
284
285 static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k,
286                             const char *name, uint32_t *data_type,
287                             DATA_BLOB *data)
288 {
289         struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data);
290         struct ldb_context *c = kd->ldb;
291         struct ldb_result *res;
292         int ret;
293         char *query = talloc_asprintf(mem_ctx, "(value=%s)", name);
294
295         ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, query, NULL, &res);
296
297         talloc_free(query);
298
299         if (ret != LDB_SUCCESS) {
300                 DEBUG(0, ("Error getting values for '%s': %s\n",
301                         ldb_dn_get_linearized(kd->dn), ldb_errstring(c)));
302                 return WERR_FOOBAR;
303         }
304
305         if (res->count == 0)
306                 return WERR_NOT_FOUND;
307
308         reg_ldb_unpack_value(mem_ctx, res->msgs[0], NULL, data_type, data);
309
310         return WERR_OK;
311 }
312
313 static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h,
314                            const char *name, struct hive_key **key)
315 {
316         struct ldb_result *res;
317         struct ldb_dn *ldap_path;
318         int ret;
319         struct ldb_key_data *newkd;
320         struct ldb_key_data *kd = talloc_get_type(h, struct ldb_key_data);
321         struct ldb_context *c = kd->ldb;
322
323         ldap_path = reg_path_to_ldb(mem_ctx, h, name, NULL);
324
325         ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL, &res);
326
327         if (ret != LDB_SUCCESS) {
328                 DEBUG(3, ("Error opening key '%s': %s\n",
329                         ldb_dn_get_linearized(ldap_path), ldb_errstring(c)));
330                 return WERR_FOOBAR;
331         } else if (res->count == 0) {
332                 DEBUG(3, ("Key '%s' not found\n",
333                         ldb_dn_get_linearized(ldap_path)));
334                 talloc_free(res);
335                 return WERR_NOT_FOUND;
336         }
337
338         newkd = talloc_zero(mem_ctx, struct ldb_key_data);
339         newkd->key.ops = &reg_backend_ldb;
340         newkd->ldb = talloc_reference(newkd, kd->ldb);
341         newkd->dn = ldb_dn_copy(mem_ctx, res->msgs[0]->dn);
342
343         *key = (struct hive_key *)newkd;
344
345         talloc_free(res);
346
347         return WERR_OK;
348 }
349
350 WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location,
351                          struct auth_session_info *session_info,
352                          struct cli_credentials *credentials,
353                          struct loadparm_context *lp_ctx,
354                          struct hive_key **k)
355 {
356         struct ldb_key_data *kd;
357         struct ldb_context *wrap;
358         struct ldb_message *attrs_msg;
359
360         if (location == NULL)
361                 return WERR_INVALID_PARAM;
362
363         wrap = ldb_wrap_connect(parent_ctx, lp_ctx,
364                                 location, session_info, credentials, 0, NULL);
365
366         if (wrap == NULL) {
367                 DEBUG(1, (__FILE__": unable to connect\n"));
368                 return WERR_FOOBAR;
369         }
370
371         attrs_msg = ldb_msg_new(wrap);
372         W_ERROR_HAVE_NO_MEMORY(attrs_msg);
373         attrs_msg->dn = ldb_dn_new(attrs_msg, wrap, "@ATTRIBUTES");
374         W_ERROR_HAVE_NO_MEMORY(attrs_msg->dn);
375         ldb_msg_add_string(attrs_msg, "key", "CASE_INSENSITIVE");
376         ldb_msg_add_string(attrs_msg, "value", "CASE_INSENSITIVE");
377
378         ldb_add(wrap, attrs_msg);
379
380         ldb_set_debug_stderr(wrap);
381
382         kd = talloc_zero(parent_ctx, struct ldb_key_data);
383         kd->key.ops = &reg_backend_ldb;
384         kd->ldb = talloc_reference(kd, wrap);
385         talloc_set_destructor (kd, reg_close_ldb_key);
386         kd->dn = ldb_dn_new(kd, wrap, "hive=NONE");
387
388         *k = (struct hive_key *)kd;
389
390         return WERR_OK;
391 }
392
393 static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent,
394                           const char *name, const char *classname,
395                           struct security_descriptor *sd,
396                           struct hive_key **newkey)
397 {
398         const struct ldb_key_data *parentkd = (const struct ldb_key_data *)parent;
399         struct ldb_message *msg;
400         struct ldb_key_data *newkd;
401         int ret;
402
403         msg = ldb_msg_new(mem_ctx);
404
405         msg->dn = reg_path_to_ldb(msg, parent, name, NULL);
406
407         ldb_msg_add_string(msg, "key", talloc_strdup(mem_ctx, name));
408         if (classname != NULL)
409                 ldb_msg_add_string(msg, "classname",
410                                    talloc_strdup(mem_ctx, classname));
411
412         ret = ldb_add(parentkd->ldb, msg);
413         if (ret != LDB_SUCCESS) {
414                 DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parentkd->ldb)));
415                 return WERR_FOOBAR;
416         }
417
418         DEBUG(2, ("key added: %s\n", ldb_dn_get_linearized(msg->dn)));
419
420         newkd = talloc_zero(mem_ctx, struct ldb_key_data);
421         newkd->ldb = talloc_reference(newkd, parentkd->ldb);
422         newkd->key.ops = &reg_backend_ldb;
423         newkd->dn = talloc_steal(newkd, msg->dn);
424
425         *newkey = (struct hive_key *)newkd;
426
427         return WERR_OK;
428 }
429
430 static WERROR ldb_del_key(const struct hive_key *key, const char *child)
431 {
432         int ret;
433         struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data);
434         struct ldb_dn *childdn;
435
436         childdn = ldb_dn_copy(parentkd->ldb, parentkd->dn);
437         ldb_dn_add_child_fmt(childdn, "key=%s", child);
438
439         ret = ldb_delete(parentkd->ldb, childdn);
440
441         talloc_free(childdn);
442
443         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
444                 return WERR_NOT_FOUND;
445         } else if (ret != LDB_SUCCESS) {
446                 DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(parentkd->ldb)));
447                 return WERR_FOOBAR;
448         }
449
450         return WERR_OK;
451 }
452
453 static WERROR ldb_del_value (struct hive_key *key, const char *child)
454 {
455         int ret;
456         struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data);
457         struct ldb_dn *childdn;
458
459         childdn = ldb_dn_copy(kd->ldb, kd->dn);
460         if (!ldb_dn_add_child_fmt(childdn, "value=%s",
461                                   reg_ldb_escape(childdn, child)))
462         {
463                 talloc_free(childdn);
464                 return WERR_FOOBAR;
465         }
466
467         ret = ldb_delete(kd->ldb, childdn);
468
469         talloc_free(childdn);
470
471         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
472                 return WERR_NOT_FOUND;
473         } else if (ret != LDB_SUCCESS) {
474                 DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(kd->ldb)));
475                 return WERR_FOOBAR;
476         }
477
478         return WERR_OK;
479 }
480
481 static WERROR ldb_set_value(struct hive_key *parent,
482                             const char *name, uint32_t type,
483                             const DATA_BLOB data)
484 {
485         struct ldb_message *msg;
486         struct ldb_key_data *kd = talloc_get_type(parent, struct ldb_key_data);
487         int ret;
488         TALLOC_CTX *mem_ctx = talloc_init("ldb_set_value");
489
490         msg = reg_ldb_pack_value(kd->ldb, mem_ctx, name, type, data);
491
492         msg->dn = ldb_dn_copy(msg, kd->dn);
493         if (!ldb_dn_add_child_fmt(msg->dn, "value=%s",
494                                   reg_ldb_escape(mem_ctx, name)))
495         {
496                 talloc_free(mem_ctx);
497                 return WERR_FOOBAR;
498         }
499
500         ret = ldb_add(kd->ldb, msg);
501         if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
502                 int i;
503                 for (i = 0; i < msg->num_elements; i++) {
504                         msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
505                 }
506                 ret = ldb_modify(kd->ldb, msg);
507         }
508
509         if (ret != LDB_SUCCESS) {
510                 DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(kd->ldb)));
511                 talloc_free(mem_ctx);
512                 return WERR_FOOBAR;
513         }
514
515         talloc_free(mem_ctx);
516         return WERR_OK;
517 }
518
519 static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx,
520                                const struct hive_key *key,
521                                const char **classname,
522                                uint32_t *num_subkeys,
523                                uint32_t *num_values,
524                                NTTIME *last_change_time,
525                                uint32_t *max_subkeynamelen,
526                                uint32_t *max_valnamelen,
527                                uint32_t *max_valbufsize)
528 {
529         struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data);
530
531         /* FIXME */
532         if (classname != NULL)
533                 *classname = NULL;
534
535         if (num_subkeys != NULL) {
536                 W_ERROR_NOT_OK_RETURN(cache_subkeys(kd));
537                 *num_subkeys = kd->subkey_count;
538         }
539
540         if (num_values != NULL) {
541                 W_ERROR_NOT_OK_RETURN(cache_values(kd));
542                 *num_values = kd->value_count;
543         }
544
545         if (last_change_time != NULL)
546                 *last_change_time = 0;
547
548         if (max_subkeynamelen != NULL) {
549                 int i;
550                 struct ldb_message_element *el;
551                 W_ERROR_NOT_OK_RETURN(cache_subkeys(kd));
552
553                 *max_subkeynamelen = 0;
554
555                 for (i = 0; i < kd->subkey_count; i++) {
556                         el = ldb_msg_find_element(kd->subkeys[i], "key");
557                         *max_subkeynamelen = MAX(*max_subkeynamelen, el->values[0].length);
558                 }
559         }
560
561         if (max_valnamelen != NULL || max_valbufsize != NULL) {
562                 int i;
563                 struct ldb_message_element *el;
564                 W_ERROR_NOT_OK_RETURN(cache_values(kd));
565
566                 if (max_valbufsize != NULL)
567                         *max_valbufsize = 0;
568
569                 if (max_valnamelen != NULL)
570                         *max_valnamelen = 0;
571
572                 for (i = 0; i < kd->value_count; i++) {
573                         if (max_valnamelen != NULL) {
574                                 el = ldb_msg_find_element(kd->values[i], "value");
575                                 *max_valnamelen = MAX(*max_valnamelen, el->values[0].length);
576                         }
577
578                         if (max_valbufsize != NULL) {
579                                 DATA_BLOB data;
580                                 reg_ldb_unpack_value(mem_ctx, kd->values[i], NULL, 
581                                                      NULL, &data);
582                                 *max_valbufsize = MAX(*max_valbufsize, data.length);
583                                 talloc_free(data.data);
584                         }
585                 }
586         }
587
588         return WERR_OK;
589 }
590
591 static struct hive_operations reg_backend_ldb = {
592         .name = "ldb",
593         .add_key = ldb_add_key,
594         .del_key = ldb_del_key,
595         .get_key_by_name = ldb_open_key,
596         .enum_value = ldb_get_value_by_id,
597         .enum_key = ldb_get_subkey_by_id,
598         .set_value = ldb_set_value,
599         .get_value_by_name = ldb_get_value,
600         .delete_value = ldb_del_value,
601         .get_key_info = ldb_get_key_info,
602 };