s3:registry: introduce a define REGDB_CODE_VERSION and use it in regdb code.
[abartlet/samba.git/.git] / source3 / registry / reg_backend_db.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  Virtual Windows Registry Layer
4  *  Copyright (C) Gerald Carter                     2002-2005
5  *  Copyright (C) Michael Adam                      2007-2011
6  *  Copyright (C) Gregor Beck                       2011
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 /* Implementation of internal registry database functions. */
23
24 #include "includes.h"
25 #include "system/filesys.h"
26 #include "registry.h"
27 #include "reg_db.h"
28 #include "reg_util_internal.h"
29 #include "reg_backend_db.h"
30 #include "reg_objects.h"
31 #include "nt_printing.h"
32 #include "util_tdb.h"
33 #include "dbwrap/dbwrap.h"
34 #include "dbwrap/dbwrap_open.h"
35 #include "../libcli/security/secdesc.h"
36
37 #undef DBGC_CLASS
38 #define DBGC_CLASS DBGC_REGISTRY
39
40 #define REGDB_VERSION_KEYNAME "INFO/version"
41
42 static struct db_context *regdb = NULL;
43 static int regdb_refcount;
44
45 static bool regdb_key_exists(struct db_context *db, const char *key);
46 static WERROR regdb_fetch_keys_internal(struct db_context *db, const char *key,
47                                         struct regsubkey_ctr *ctr);
48 static bool regdb_store_keys_internal(struct db_context *db, const char *key,
49                                       struct regsubkey_ctr *ctr);
50 static int regdb_fetch_values_internal(struct db_context *db, const char* key,
51                                        struct regval_ctr *values);
52 static NTSTATUS regdb_store_values_internal(struct db_context *db, const char *key,
53                                             struct regval_ctr *values);
54 static WERROR regdb_store_subkey_list(struct db_context *db, const char *parent,
55                                       const char *key);
56
57 static WERROR regdb_create_basekey(struct db_context *db, const char *key);
58 static WERROR regdb_create_subkey_internal(struct db_context *db,
59                                            const char *key,
60                                            const char *subkey);
61
62
63 struct regdb_trans_ctx {
64         NTSTATUS (*action)(struct db_context *, void *);
65         void *private_data;
66 };
67
68 static NTSTATUS regdb_trans_do_action(struct db_context *db, void *private_data)
69 {
70         NTSTATUS status;
71         int32_t version_id;
72         struct regdb_trans_ctx *ctx = (struct regdb_trans_ctx *)private_data;
73
74         version_id = dbwrap_fetch_int32(db, REGDB_VERSION_KEYNAME);
75
76         if (version_id != REGDB_CODE_VERSION) {
77                 DEBUG(0, ("ERROR: changed registry version %d found while "
78                           "trying to write to the registry. Version %d "
79                           "expected.  Denying access.\n",
80                           version_id, REGDB_CODE_VERSION));
81                 return NT_STATUS_ACCESS_DENIED;
82         }
83
84         status = ctx->action(db,  ctx->private_data);
85         return status;
86 }
87
88 static WERROR regdb_trans_do(struct db_context *db,
89                              NTSTATUS (*action)(struct db_context *, void *),
90                              void *private_data)
91 {
92         NTSTATUS status;
93         struct regdb_trans_ctx ctx;
94
95
96         ctx.action = action;
97         ctx.private_data = private_data;
98
99         status = dbwrap_trans_do(db, regdb_trans_do_action, &ctx);
100
101         return ntstatus_to_werror(status);
102 }
103
104 /* List the deepest path into the registry.  All part components will be created.*/
105
106 /* If you want to have a part of the path controlled by the tdb and part by
107    a virtual registry db (e.g. printing), then you have to list the deepest path.
108    For example,"HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Print" 
109    allows the reg_db backend to handle everything up to 
110    "HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion" and then we'll hook 
111    the reg_printing backend onto the last component of the path (see 
112    KEY_PRINTING_2K in include/rpc_reg.h)   --jerry */
113
114 static const char *builtin_registry_paths[] = {
115         KEY_PRINTING_2K,
116         KEY_PRINTING_PORTS,
117         KEY_PRINTING,
118         KEY_PRINTING "\\Forms",
119         KEY_PRINTING "\\Printers",
120         KEY_PRINTING "\\Environments\\Windows NT x86\\Print Processors\\winprint",
121         KEY_SHARES,
122         KEY_EVENTLOG,
123         KEY_SMBCONF,
124         KEY_PERFLIB,
125         KEY_PERFLIB_009,
126         KEY_GROUP_POLICY,
127         KEY_SAMBA_GROUP_POLICY,
128         KEY_GP_MACHINE_POLICY,
129         KEY_GP_MACHINE_WIN_POLICY,
130         KEY_HKCU,
131         KEY_GP_USER_POLICY,
132         KEY_GP_USER_WIN_POLICY,
133         "HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\GPExtensions",
134         "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors",
135         KEY_PROD_OPTIONS,
136         "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration",
137         KEY_TCPIP_PARAMS,
138         KEY_NETLOGON_PARAMS,
139         KEY_HKU,
140         KEY_HKCR,
141         KEY_HKPD,
142         KEY_HKPT,
143          NULL };
144
145 struct builtin_regkey_value {
146         const char *path;
147         const char *valuename;
148         uint32 type;
149         union {
150                 const char *string;
151                 uint32 dw_value;
152         } data;
153 };
154
155 static struct builtin_regkey_value builtin_registry_values[] = {
156         { KEY_PRINTING_PORTS,
157                 SAMBA_PRINTER_PORT_NAME, REG_SZ, { "" } },
158         { KEY_PRINTING_2K,
159                 "DefaultSpoolDirectory", REG_SZ, { "C:\\Windows\\System32\\Spool\\Printers" } },
160         { KEY_EVENTLOG,
161                 "DisplayName", REG_SZ, { "Event Log" } },
162         { KEY_EVENTLOG,
163                 "ErrorControl", REG_DWORD, { (char*)0x00000001 } },
164         { NULL, NULL, 0, { NULL } }
165 };
166
167 static WERROR create_key_recursive(struct db_context *db,
168                                    char *path,
169                                    const char *subkey)
170 {
171         WERROR werr;
172         char *p;
173
174         if (subkey == NULL) {
175                 return WERR_INVALID_PARAM;
176         }
177
178         if (path == NULL) {
179                 return regdb_create_basekey(db, subkey);
180         }
181
182         p = strrchr_m(path, '\\');
183
184         if (p == NULL) {
185                 werr = create_key_recursive(db, NULL, path);
186         } else {
187                 *p = '\0';
188                 werr = create_key_recursive(db, path, p+1);
189                 *p = '\\';
190         }
191
192         if (!W_ERROR_IS_OK(werr)) {
193                 goto done;
194         }
195
196         werr = regdb_create_subkey_internal(db, path, subkey);
197
198 done:
199         return werr;
200 }
201
202 /**
203  * Initialize a key in the registry:
204  * create each component key of the specified path.
205  */
206 static WERROR init_registry_key_internal(struct db_context *db,
207                                          const char *add_path)
208 {
209         char *subkey, *key;
210         WERROR werr;
211         TALLOC_CTX *frame = talloc_stackframe();
212
213         if (add_path == NULL) {
214                 werr = WERR_INVALID_PARAM;
215                 goto done;
216         }
217
218         key = talloc_strdup(frame, add_path);
219
220         subkey = strrchr_m(key, '\\');
221         if (subkey == NULL) {
222                 subkey = key;
223                 key = NULL;
224         } else {
225                 *subkey = '\0';
226                 subkey++;
227         }
228
229         werr = create_key_recursive(db, key, subkey);
230
231 done:
232         talloc_free(frame);
233         return werr;
234 }
235
236 struct init_registry_key_context {
237         const char *add_path;
238 };
239
240 static NTSTATUS init_registry_key_action(struct db_context *db,
241                                          void *private_data)
242 {
243         struct init_registry_key_context *init_ctx =
244                 (struct init_registry_key_context *)private_data;
245
246         return werror_to_ntstatus(init_registry_key_internal(
247                                         db, init_ctx->add_path));
248 }
249
250 /**
251  * Initialize a key in the registry:
252  * create each component key of the specified path,
253  * wrapped in one db transaction.
254  */
255 WERROR init_registry_key(const char *add_path)
256 {
257         struct init_registry_key_context init_ctx;
258
259         if (regdb_key_exists(regdb, add_path)) {
260                 return WERR_OK;
261         }
262
263         init_ctx.add_path = add_path;
264
265         return regdb_trans_do(regdb,
266                               init_registry_key_action,
267                               &init_ctx);
268 }
269
270 /***********************************************************************
271  Open the registry data in the tdb
272  ***********************************************************************/
273
274 static void regdb_ctr_add_value(struct regval_ctr *ctr,
275                                 struct builtin_regkey_value *value)
276 {
277         switch(value->type) {
278         case REG_DWORD:
279                 regval_ctr_addvalue(ctr, value->valuename, REG_DWORD,
280                                     (uint8_t *)&value->data.dw_value,
281                                     sizeof(uint32));
282                 break;
283
284         case REG_SZ:
285                 regval_ctr_addvalue_sz(ctr, value->valuename,
286                                        value->data.string);
287                 break;
288
289         default:
290                 DEBUG(0, ("regdb_ctr_add_value: invalid value type in "
291                           "registry values [%d]\n", value->type));
292         }
293 }
294
295 static NTSTATUS init_registry_data_action(struct db_context *db,
296                                           void *private_data)
297 {
298         NTSTATUS status;
299         TALLOC_CTX *frame = talloc_stackframe();
300         struct regval_ctr *values;
301         int i;
302
303         /* loop over all of the predefined paths and add each component */
304
305         for (i=0; builtin_registry_paths[i] != NULL; i++) {
306                 if (regdb_key_exists(db, builtin_registry_paths[i])) {
307                         continue;
308                 }
309                 status = werror_to_ntstatus(init_registry_key_internal(db,
310                                                   builtin_registry_paths[i]));
311                 if (!NT_STATUS_IS_OK(status)) {
312                         goto done;
313                 }
314         }
315
316         /* loop over all of the predefined values and add each component */
317
318         for (i=0; builtin_registry_values[i].path != NULL; i++) {
319                 WERROR werr;
320
321                 werr = regval_ctr_init(frame, &values);
322                 if (!W_ERROR_IS_OK(werr)) {
323                         status = werror_to_ntstatus(werr);
324                         goto done;
325                 }
326
327                 regdb_fetch_values_internal(db,
328                                             builtin_registry_values[i].path,
329                                             values);
330
331                 /* preserve existing values across restarts. Only add new ones */
332
333                 if (!regval_ctr_key_exists(values,
334                                         builtin_registry_values[i].valuename))
335                 {
336                         regdb_ctr_add_value(values,
337                                             &builtin_registry_values[i]);
338                         status = regdb_store_values_internal(db,
339                                         builtin_registry_values[i].path,
340                                         values);
341                         if (!NT_STATUS_IS_OK(status)) {
342                                 goto done;
343                         }
344                 }
345                 TALLOC_FREE(values);
346         }
347
348         status = NT_STATUS_OK;
349
350 done:
351
352         TALLOC_FREE(frame);
353         return status;
354 }
355
356 WERROR init_registry_data(void)
357 {
358         WERROR werr;
359         TALLOC_CTX *frame = talloc_stackframe();
360         struct regval_ctr *values;
361         int i;
362
363         /*
364          * First, check for the existence of the needed keys and values.
365          * If all do already exist, we can save the writes.
366          */
367         for (i=0; builtin_registry_paths[i] != NULL; i++) {
368                 if (!regdb_key_exists(regdb, builtin_registry_paths[i])) {
369                         goto do_init;
370                 }
371         }
372
373         for (i=0; builtin_registry_values[i].path != NULL; i++) {
374                 werr = regval_ctr_init(frame, &values);
375                 W_ERROR_NOT_OK_GOTO_DONE(werr);
376
377                 regdb_fetch_values_internal(regdb,
378                                             builtin_registry_values[i].path,
379                                             values);
380                 if (!regval_ctr_key_exists(values,
381                                         builtin_registry_values[i].valuename))
382                 {
383                         TALLOC_FREE(values);
384                         goto do_init;
385                 }
386
387                 TALLOC_FREE(values);
388         }
389
390         werr = WERR_OK;
391         goto done;
392
393 do_init:
394
395         /*
396          * There are potentially quite a few store operations which are all
397          * indiviually wrapped in tdb transactions. Wrapping them in a single
398          * transaction gives just a single transaction_commit() to actually do
399          * its fsync()s. See tdb/common/transaction.c for info about nested
400          * transaction behaviour.
401          */
402
403         werr = regdb_trans_do(regdb,
404                               init_registry_data_action,
405                               NULL);
406
407 done:
408         TALLOC_FREE(frame);
409         return werr;
410 }
411
412 static int regdb_normalize_keynames_fn(struct db_record *rec,
413                                        void *private_data)
414 {
415         TALLOC_CTX *mem_ctx = talloc_tos();
416         const char *keyname;
417         NTSTATUS status;
418         struct db_context *db = (struct db_context *)private_data;
419
420         if (rec->key.dptr == NULL || rec->key.dsize == 0) {
421                 return 0;
422         }
423
424         if (db == NULL) {
425                 DEBUG(0, ("regdb_normalize_keynames_fn: ERROR: "
426                           "NULL db context handed in via private_data\n"));
427                 return 1;
428         }
429
430         if (strncmp((const char *)rec->key.dptr, REGDB_VERSION_KEYNAME,
431             strlen(REGDB_VERSION_KEYNAME)) == 0)
432         {
433                 return 0;
434         }
435
436         keyname = strchr((const char *) rec->key.dptr, '/');
437         if (keyname) {
438                 keyname = talloc_string_sub(mem_ctx,
439                                             (const char *) rec->key.dptr,
440                                             "/",
441                                             "\\");
442
443                 DEBUG(2, ("regdb_normalize_keynames_fn: Convert %s to %s\n",
444                           (const char *) rec->key.dptr,
445                           keyname));
446
447                 /* Delete the original record and store the normalized key */
448                 status = rec->delete_rec(rec);
449                 if (!NT_STATUS_IS_OK(status)) {
450                         DEBUG(0,("regdb_normalize_keynames_fn: "
451                                  "tdb_delete for [%s] failed!\n",
452                                  rec->key.dptr));
453                         return 1;
454                 }
455
456                 status = dbwrap_store_bystring(db, keyname, rec->value,
457                                                TDB_REPLACE);
458                 if (!NT_STATUS_IS_OK(status)) {
459                         DEBUG(0,("regdb_normalize_keynames_fn: "
460                                  "failed to store new record for [%s]!\n",
461                                  keyname));
462                         return 1;
463                 }
464         }
465
466         return 0;
467 }
468
469 static WERROR regdb_store_regdb_version(struct db_context *db, uint32_t version)
470 {
471         NTSTATUS status;
472         if (db == NULL) {
473                 return WERR_CAN_NOT_COMPLETE;
474         }
475
476         status = dbwrap_trans_store_int32(db, REGDB_VERSION_KEYNAME, version);
477         if (!NT_STATUS_IS_OK(status)) {
478                 DEBUG(1, ("regdb_store_regdb_version: error storing %s = %d: %s\n",
479                           REGDB_VERSION_KEYNAME, version, nt_errstr(status)));
480                 return ntstatus_to_werror(status);
481         } else {
482                 DEBUG(10, ("regdb_store_regdb_version: stored %s = %d\n",
483                           REGDB_VERSION_KEYNAME, version));
484                 return WERR_OK;
485         }
486 }
487
488 static WERROR regdb_upgrade_v1_to_v2(struct db_context *db)
489 {
490         TALLOC_CTX *mem_ctx;
491         int rc;
492         WERROR werr;
493
494         mem_ctx = talloc_stackframe();
495
496         rc = db->traverse(db, regdb_normalize_keynames_fn, db);
497
498         talloc_free(mem_ctx);
499
500         if (rc < 0) {
501                 return WERR_REG_IO_FAILURE;
502         }
503
504         werr = regdb_store_regdb_version(db, REGDB_VERSION_V2);
505         return werr;
506 }
507
508 static int regdb_upgrade_v2_to_v3_fn(struct db_record *rec, void *private_data)
509 {
510         const char *keyname;
511         fstring subkeyname;
512         NTSTATUS status;
513         WERROR werr;
514         uint8_t *buf;
515         uint32_t buflen, len;
516         uint32_t num_items;
517         uint32_t i;
518         struct db_context *db = (struct db_context *)private_data;
519
520         if (rec->key.dptr == NULL || rec->key.dsize == 0) {
521                 return 0;
522         }
523
524         if (db == NULL) {
525                 DEBUG(0, ("regdb_normalize_keynames_fn: ERROR: "
526                           "NULL db context handed in via private_data\n"));
527                 return 1;
528         }
529
530         keyname = (const char *)rec->key.dptr;
531
532         if (strncmp(keyname, REGDB_VERSION_KEYNAME,
533                     strlen(REGDB_VERSION_KEYNAME)) == 0)
534         {
535                 return 0;
536         }
537
538         if (strncmp(keyname, REG_SORTED_SUBKEYS_PREFIX,
539                     strlen(REG_SORTED_SUBKEYS_PREFIX)) == 0)
540         {
541                 /* Delete the deprecated sorted subkeys cache. */
542
543                 DEBUG(10, ("regdb_upgrade_v2_to_v3: deleting [%s]\n", keyname));
544
545                 status = rec->delete_rec(rec);
546                 if (!NT_STATUS_IS_OK(status)) {
547                         DEBUG(0, ("regdb_upgrade_v2_to_v3: tdb_delete for [%s] "
548                                   "failed!\n", keyname));
549                         return 1;
550                 }
551
552                 return 0;
553         }
554
555         if (strncmp(keyname, REG_VALUE_PREFIX, strlen(REG_VALUE_PREFIX)) == 0) {
556                 DEBUG(10, ("regdb_upgrade_v2_to_v3: skipping [%s]\n", keyname));
557                 return 0;
558         }
559
560         if (strncmp(keyname, REG_SECDESC_PREFIX,
561                     strlen(REG_SECDESC_PREFIX)) == 0)
562         {
563                 DEBUG(10, ("regdb_upgrade_v2_to_v3: skipping [%s]\n", keyname));
564                 return 0;
565         }
566
567         /*
568          * Found a regular subkey list record.
569          * Walk the list and create the list record for those
570          * subkeys that don't already have one.
571          */
572         DEBUG(10, ("regdb_upgrade_v2_to_v3: scanning subkey list of [%s]\n",
573                    keyname));
574
575         buf = rec->value.dptr;
576         buflen = rec->value.dsize;
577
578         len = tdb_unpack(buf, buflen, "d", &num_items);
579         if (len == (uint32_t)-1) {
580                 /* invalid or empty - skip */
581                 return 0;
582         }
583
584         for (i=0; i<num_items; i++) {
585                 len += tdb_unpack(buf+len, buflen-len, "f", subkeyname);
586                 DEBUG(10, ("regdb_upgrade_v2_to_v3: "
587                            "writing subkey list for [%s\\%s]\n",
588                            keyname, subkeyname));
589                 werr = regdb_store_subkey_list(db, keyname, subkeyname);
590                 if (!W_ERROR_IS_OK(werr)) {
591                         return 1;
592                 }
593         }
594
595         return 0;
596 }
597
598 static WERROR regdb_upgrade_v2_to_v3(struct db_context *db)
599 {
600         int rc;
601         WERROR werr;
602
603         rc = regdb->traverse(db, regdb_upgrade_v2_to_v3_fn, db);
604         if (rc < 0) {
605                 werr = WERR_REG_IO_FAILURE;
606                 goto done;
607         }
608
609         werr = regdb_store_regdb_version(db, REGDB_VERSION_V3);
610
611 done:
612         return werr;
613 }
614
615 /***********************************************************************
616  Open the registry database
617  ***********************************************************************/
618
619 WERROR regdb_init(void)
620 {
621         uint32 vers_id;
622         WERROR werr;
623
624         if (regdb) {
625                 DEBUG(10, ("regdb_init: incrementing refcount (%d->%d)\n",
626                            regdb_refcount, regdb_refcount+1));
627                 regdb_refcount++;
628                 return WERR_OK;
629         }
630
631         regdb = db_open(NULL, state_path("registry.tdb"), 0,
632                               REG_TDB_FLAGS, O_RDWR, 0600);
633         if (!regdb) {
634                 regdb = db_open(NULL, state_path("registry.tdb"), 0,
635                                       REG_TDB_FLAGS, O_RDWR|O_CREAT, 0600);
636                 if (!regdb) {
637                         werr = ntstatus_to_werror(map_nt_error_from_unix(errno));
638                         DEBUG(1,("regdb_init: Failed to open registry %s (%s)\n",
639                                 state_path("registry.tdb"), strerror(errno) ));
640                         return werr;
641                 }
642
643                 DEBUG(10,("regdb_init: Successfully created registry tdb\n"));
644         }
645
646         regdb_refcount = 1;
647         DEBUG(10, ("regdb_init: registry db openend. refcount reset (%d)\n",
648                    regdb_refcount));
649
650         vers_id = dbwrap_fetch_int32(regdb, REGDB_VERSION_KEYNAME);
651         if (vers_id == -1) {
652                 DEBUG(10, ("regdb_init: registry version uninitialized "
653                            "(got %d), initializing to version %d\n",
654                            vers_id, REGDB_CODE_VERSION));
655
656                 werr = regdb_store_regdb_version(regdb, REGDB_CODE_VERSION);
657                 return werr;
658         }
659
660         if (vers_id > REGDB_CODE_VERSION || vers_id == 0) {
661                 DEBUG(0, ("regdb_init: unknown registry version %d "
662                           "(code version = %d), refusing initialization\n",
663                           vers_id, REGDB_CODE_VERSION));
664                 return WERR_CAN_NOT_COMPLETE;
665         }
666
667         if (regdb->transaction_start(regdb) != 0) {
668                 return WERR_REG_IO_FAILURE;
669         }
670
671         if (vers_id == REGDB_VERSION_V1) {
672                 DEBUG(10, ("regdb_init: upgrading registry fromversion %d "
673                            "to %d\n", REGDB_VERSION_V1, REGDB_VERSION_V2));
674
675                 werr = regdb_upgrade_v1_to_v2(regdb);
676                 if (!W_ERROR_IS_OK(werr)) {
677                         regdb->transaction_cancel(regdb);
678                         return werr;
679                 }
680
681                 vers_id = REGDB_VERSION_V2;
682         }
683
684         if (vers_id == REGDB_VERSION_V2) {
685                 DEBUG(10, ("regdb_init: upgrading registry from version %d "
686                            "to %d\n", REGDB_VERSION_V2, REGDB_VERSION_V3));
687
688                 werr = regdb_upgrade_v2_to_v3(regdb);
689                 if (!W_ERROR_IS_OK(werr)) {
690                         regdb->transaction_cancel(regdb);
691                         return werr;
692                 }
693
694                 vers_id = REGDB_VERSION_V3;
695         }
696
697         /* future upgrade code should go here */
698
699         if (regdb->transaction_commit(regdb) != 0) {
700                 return WERR_REG_IO_FAILURE;
701         }
702
703         return WERR_OK;
704 }
705
706 /***********************************************************************
707  Open the registry.  Must already have been initialized by regdb_init()
708  ***********************************************************************/
709
710 WERROR regdb_open( void )
711 {
712         WERROR result = WERR_OK;
713
714         if ( regdb ) {
715                 DEBUG(10, ("regdb_open: incrementing refcount (%d->%d)\n",
716                            regdb_refcount, regdb_refcount+1));
717                 regdb_refcount++;
718                 return WERR_OK;
719         }
720
721         become_root();
722
723         regdb = db_open(NULL, state_path("registry.tdb"), 0,
724                               REG_TDB_FLAGS, O_RDWR, 0600);
725         if ( !regdb ) {
726                 result = ntstatus_to_werror( map_nt_error_from_unix( errno ) );
727                 DEBUG(0,("regdb_open: Failed to open %s! (%s)\n",
728                         state_path("registry.tdb"), strerror(errno) ));
729         }
730
731         unbecome_root();
732
733         regdb_refcount = 1;
734         DEBUG(10, ("regdb_open: registry db opened. refcount reset (%d)\n",
735                    regdb_refcount));
736
737         return result;
738 }
739
740 /***********************************************************************
741  ***********************************************************************/
742
743 int regdb_close( void )
744 {
745         if (regdb_refcount == 0) {
746                 return 0;
747         }
748
749         regdb_refcount--;
750
751         DEBUG(10, ("regdb_close: decrementing refcount (%d->%d)\n",
752                    regdb_refcount+1, regdb_refcount));
753
754         if ( regdb_refcount > 0 )
755                 return 0;
756
757         SMB_ASSERT( regdb_refcount >= 0 );
758
759         TALLOC_FREE(regdb);
760         return 0;
761 }
762
763 WERROR regdb_transaction_start(void)
764 {
765         return (regdb->transaction_start(regdb) == 0) ?
766                 WERR_OK : WERR_REG_IO_FAILURE;
767 }
768
769 WERROR regdb_transaction_commit(void)
770 {
771         return (regdb->transaction_commit(regdb) == 0) ?
772                 WERR_OK : WERR_REG_IO_FAILURE;
773 }
774
775 WERROR regdb_transaction_cancel(void)
776 {
777         return (regdb->transaction_cancel(regdb) == 0) ?
778                 WERR_OK : WERR_REG_IO_FAILURE;
779 }
780
781 /***********************************************************************
782  return the tdb sequence number of the registry tdb.
783  this is an indicator for the content of the registry
784  having changed. it will change upon regdb_init, too, though.
785  ***********************************************************************/
786 int regdb_get_seqnum(void)
787 {
788         return regdb->get_seqnum(regdb);
789 }
790
791
792 static WERROR regdb_delete_key_with_prefix(struct db_context *db,
793                                            const char *keyname,
794                                            const char *prefix)
795 {
796         char *path;
797         WERROR werr = WERR_NOMEM;
798         TALLOC_CTX *mem_ctx = talloc_stackframe();
799
800         if (keyname == NULL) {
801                 werr = WERR_INVALID_PARAM;
802                 goto done;
803         }
804
805         if (prefix == NULL) {
806                 path = discard_const_p(char, keyname);
807         } else {
808                 path = talloc_asprintf(mem_ctx, "%s\\%s", prefix, keyname);
809                 if (path == NULL) {
810                         goto done;
811                 }
812         }
813
814         path = normalize_reg_path(mem_ctx, path);
815         if (path == NULL) {
816                 goto done;
817         }
818
819         werr = ntstatus_to_werror(dbwrap_delete_bystring(db, path));
820
821         /* treat "not found" as ok */
822         if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) {
823                 werr = WERR_OK;
824         }
825
826 done:
827         talloc_free(mem_ctx);
828         return werr;
829 }
830
831
832 static WERROR regdb_delete_values(struct db_context *db, const char *keyname)
833 {
834         return regdb_delete_key_with_prefix(db, keyname, REG_VALUE_PREFIX);
835 }
836
837 static WERROR regdb_delete_secdesc(struct db_context *db, const char *keyname)
838 {
839         return regdb_delete_key_with_prefix(db, keyname, REG_SECDESC_PREFIX);
840 }
841
842 static WERROR regdb_delete_subkeylist(struct db_context *db, const char *keyname)
843 {
844         return regdb_delete_key_with_prefix(db, keyname, NULL);
845 }
846
847
848 static WERROR regdb_delete_key_lists(struct db_context *db, const char *keyname)
849 {
850         WERROR werr;
851
852         werr = regdb_delete_values(db, keyname);
853         if (!W_ERROR_IS_OK(werr)) {
854                 DEBUG(1, (__location__ " Deleting %s\\%s failed: %s\n",
855                           REG_VALUE_PREFIX, keyname, win_errstr(werr)));
856                 goto done;
857         }
858
859         werr = regdb_delete_secdesc(db, keyname);
860         if (!W_ERROR_IS_OK(werr)) {
861                 DEBUG(1, (__location__ " Deleting %s\\%s failed: %s\n",
862                           REG_SECDESC_PREFIX, keyname, win_errstr(werr)));
863                 goto done;
864         }
865
866         werr = regdb_delete_subkeylist(db, keyname);
867         if (!W_ERROR_IS_OK(werr)) {
868                 DEBUG(1, (__location__ " Deleting %s failed: %s\n",
869                           keyname, win_errstr(werr)));
870                 goto done;
871         }
872
873 done:
874         return werr;
875 }
876
877 /***********************************************************************
878  Add subkey strings to the registry tdb under a defined key
879  fmt is the same format as tdb_pack except this function only supports
880  fstrings
881  ***********************************************************************/
882
883 static WERROR regdb_store_keys_internal2(struct db_context *db,
884                                          const char *key,
885                                          struct regsubkey_ctr *ctr)
886 {
887         TDB_DATA dbuf;
888         uint8 *buffer = NULL;
889         int i = 0;
890         uint32 len, buflen;
891         uint32 num_subkeys = regsubkey_ctr_numkeys(ctr);
892         char *keyname = NULL;
893         TALLOC_CTX *ctx = talloc_stackframe();
894         WERROR werr;
895
896         if (!key) {
897                 werr = WERR_INVALID_PARAM;
898                 goto done;
899         }
900
901         keyname = talloc_strdup(ctx, key);
902         if (!keyname) {
903                 werr = WERR_NOMEM;
904                 goto done;
905         }
906
907         keyname = normalize_reg_path(ctx, keyname);
908         if (!keyname) {
909                 werr = WERR_NOMEM;
910                 goto done;
911         }
912
913         /* allocate some initial memory */
914
915         buffer = (uint8 *)SMB_MALLOC(1024);
916         if (buffer == NULL) {
917                 werr = WERR_NOMEM;
918                 goto done;
919         }
920         buflen = 1024;
921         len = 0;
922
923         /* store the number of subkeys */
924
925         len += tdb_pack(buffer+len, buflen-len, "d", num_subkeys);
926
927         /* pack all the strings */
928
929         for (i=0; i<num_subkeys; i++) {
930                 size_t thistime;
931
932                 thistime = tdb_pack(buffer+len, buflen-len, "f",
933                                     regsubkey_ctr_specific_key(ctr, i));
934                 if (len+thistime > buflen) {
935                         size_t thistime2;
936                         /*
937                          * tdb_pack hasn't done anything because of the short
938                          * buffer, allocate extra space.
939                          */
940                         buffer = SMB_REALLOC_ARRAY(buffer, uint8_t,
941                                                    (len+thistime)*2);
942                         if(buffer == NULL) {
943                                 DEBUG(0, ("regdb_store_keys: Failed to realloc "
944                                           "memory of size [%u]\n",
945                                           (unsigned int)(len+thistime)*2));
946                                 werr = WERR_NOMEM;
947                                 goto done;
948                         }
949                         buflen = (len+thistime)*2;
950                         thistime2 = tdb_pack(
951                                 buffer+len, buflen-len, "f",
952                                 regsubkey_ctr_specific_key(ctr, i));
953                         if (thistime2 != thistime) {
954                                 DEBUG(0, ("tdb_pack failed\n"));
955                                 werr = WERR_CAN_NOT_COMPLETE;
956                                 goto done;
957                         }
958                 }
959                 len += thistime;
960         }
961
962         /* finally write out the data */
963
964         dbuf.dptr = buffer;
965         dbuf.dsize = len;
966         werr = ntstatus_to_werror(dbwrap_store_bystring(db, keyname, dbuf,
967                                                         TDB_REPLACE));
968
969 done:
970         TALLOC_FREE(ctx);
971         SAFE_FREE(buffer);
972         return werr;
973 }
974
975 /**
976  * Utility function to store a new empty list of
977  * subkeys of given key specified as parent and subkey name
978  * (thereby creating the key).
979  * If the parent keyname is NULL, then the "subkey" is
980  * interpreted as a base key.
981  * If the subkey list does already exist, it is not modified.
982  *
983  * Must be called from within a transaction.
984  */
985 static WERROR regdb_store_subkey_list(struct db_context *db, const char *parent,
986                                       const char *key)
987 {
988         WERROR werr;
989         char *path = NULL;
990         struct regsubkey_ctr *subkeys = NULL;
991         TALLOC_CTX *frame = talloc_stackframe();
992
993         if (parent == NULL) {
994                 path = talloc_strdup(frame, key);
995         } else {
996                 path = talloc_asprintf(frame, "%s\\%s", parent, key);
997         }
998         if (!path) {
999                 werr = WERR_NOMEM;
1000                 goto done;
1001         }
1002
1003         werr = regsubkey_ctr_init(frame, &subkeys);
1004         W_ERROR_NOT_OK_GOTO_DONE(werr);
1005
1006         werr = regdb_fetch_keys_internal(db, path, subkeys);
1007         if (W_ERROR_IS_OK(werr)) {
1008                 /* subkey list exists already - don't modify */
1009                 goto done;
1010         }
1011
1012         werr = regsubkey_ctr_reinit(subkeys);
1013         W_ERROR_NOT_OK_GOTO_DONE(werr);
1014
1015         /* create a record with 0 subkeys */
1016         werr = regdb_store_keys_internal2(db, path, subkeys);
1017         if (!W_ERROR_IS_OK(werr)) {
1018                 DEBUG(0, ("regdb_store_keys: Failed to store new record for "
1019                           "key [%s]: %s\n", path, win_errstr(werr)));
1020                 goto done;
1021         }
1022
1023 done:
1024         talloc_free(frame);
1025         return werr;
1026 }
1027
1028 /***********************************************************************
1029  Store the new subkey record and create any child key records that
1030  do not currently exist
1031  ***********************************************************************/
1032
1033 struct regdb_store_keys_context {
1034         const char *key;
1035         struct regsubkey_ctr *ctr;
1036 };
1037
1038 static NTSTATUS regdb_store_keys_action(struct db_context *db,
1039                                         void *private_data)
1040 {
1041         struct regdb_store_keys_context *store_ctx;
1042         WERROR werr;
1043         int num_subkeys, i;
1044         char *path = NULL;
1045         struct regsubkey_ctr *old_subkeys = NULL;
1046         char *oldkeyname = NULL;
1047         TALLOC_CTX *mem_ctx = talloc_stackframe();
1048
1049         store_ctx = (struct regdb_store_keys_context *)private_data;
1050
1051         /*
1052          * Re-fetch the old keys inside the transaction
1053          */
1054
1055         werr = regsubkey_ctr_init(mem_ctx, &old_subkeys);
1056         W_ERROR_NOT_OK_GOTO_DONE(werr);
1057
1058         werr = regdb_fetch_keys_internal(db, store_ctx->key, old_subkeys);
1059         if (!W_ERROR_IS_OK(werr) &&
1060             !W_ERROR_EQUAL(werr, WERR_NOT_FOUND))
1061         {
1062                 goto done;
1063         }
1064
1065         /*
1066          * Make the store operation as safe as possible without transactions:
1067          *
1068          * (1) For each subkey removed from ctr compared with old_subkeys:
1069          *
1070          *     (a) First delete the value db entry.
1071          *
1072          *     (b) Next delete the secdesc db record.
1073          *
1074          *     (c) Then delete the subkey list entry.
1075          *
1076          * (2) Now write the list of subkeys of the parent key,
1077          *     deleting removed entries and adding new ones.
1078          *
1079          * (3) Finally create the subkey list entries for the added keys.
1080          *
1081          * This way if we crash half-way in between deleting the subkeys
1082          * and storing the parent's list of subkeys, no old data can pop up
1083          * out of the blue when re-adding keys later on.
1084          */
1085
1086         /* (1) delete removed keys' lists (values/secdesc/subkeys) */
1087
1088         num_subkeys = regsubkey_ctr_numkeys(old_subkeys);
1089         for (i=0; i<num_subkeys; i++) {
1090                 oldkeyname = regsubkey_ctr_specific_key(old_subkeys, i);
1091
1092                 if (regsubkey_ctr_key_exists(store_ctx->ctr, oldkeyname)) {
1093                         /*
1094                          * It's still around, don't delete
1095                          */
1096                         continue;
1097                 }
1098
1099                 path = talloc_asprintf(mem_ctx, "%s\\%s", store_ctx->key,
1100                                        oldkeyname);
1101                 if (!path) {
1102                         werr = WERR_NOMEM;
1103                         goto done;
1104                 }
1105
1106                 werr = regdb_delete_key_lists(db, path);
1107                 W_ERROR_NOT_OK_GOTO_DONE(werr);
1108
1109                 TALLOC_FREE(path);
1110         }
1111
1112         TALLOC_FREE(old_subkeys);
1113
1114         /* (2) store the subkey list for the parent */
1115
1116         werr = regdb_store_keys_internal2(db, store_ctx->key, store_ctx->ctr);
1117         if (!W_ERROR_IS_OK(werr)) {
1118                 DEBUG(0,("regdb_store_keys: Failed to store new subkey list "
1119                          "for parent [%s]: %s\n", store_ctx->key,
1120                          win_errstr(werr)));
1121                 goto done;
1122         }
1123
1124         /* (3) now create records for any subkeys that don't already exist */
1125
1126         num_subkeys = regsubkey_ctr_numkeys(store_ctx->ctr);
1127
1128         for (i=0; i<num_subkeys; i++) {
1129                 const char *subkey;
1130
1131                 subkey = regsubkey_ctr_specific_key(store_ctx->ctr, i);
1132
1133                 werr = regdb_store_subkey_list(db, store_ctx->key, subkey);
1134                 W_ERROR_NOT_OK_GOTO_DONE(werr);
1135         }
1136
1137         werr = WERR_OK;
1138
1139 done:
1140         talloc_free(mem_ctx);
1141         return werror_to_ntstatus(werr);
1142 }
1143
1144 static bool regdb_store_keys_internal(struct db_context *db, const char *key,
1145                                       struct regsubkey_ctr *ctr)
1146 {
1147         int num_subkeys, old_num_subkeys, i;
1148         struct regsubkey_ctr *old_subkeys = NULL;
1149         TALLOC_CTX *ctx = talloc_stackframe();
1150         WERROR werr;
1151         bool ret = false;
1152         struct regdb_store_keys_context store_ctx;
1153
1154         if (!regdb_key_exists(db, key)) {
1155                 goto done;
1156         }
1157
1158         /*
1159          * fetch a list of the old subkeys so we can determine if anything has
1160          * changed
1161          */
1162
1163         werr = regsubkey_ctr_init(ctx, &old_subkeys);
1164         if (!W_ERROR_IS_OK(werr)) {
1165                 DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
1166                 goto done;
1167         }
1168
1169         werr = regdb_fetch_keys_internal(db, key, old_subkeys);
1170         if (!W_ERROR_IS_OK(werr) &&
1171             !W_ERROR_EQUAL(werr, WERR_NOT_FOUND))
1172         {
1173                 goto done;
1174         }
1175
1176         num_subkeys = regsubkey_ctr_numkeys(ctr);
1177         old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys);
1178         if ((num_subkeys && old_num_subkeys) &&
1179             (num_subkeys == old_num_subkeys)) {
1180
1181                 for (i = 0; i < num_subkeys; i++) {
1182                         if (strcmp(regsubkey_ctr_specific_key(ctr, i),
1183                                    regsubkey_ctr_specific_key(old_subkeys, i))
1184                             != 0)
1185                         {
1186                                 break;
1187                         }
1188                 }
1189                 if (i == num_subkeys) {
1190                         /*
1191                          * Nothing changed, no point to even start a tdb
1192                          * transaction
1193                          */
1194
1195                         ret = true;
1196                         goto done;
1197                 }
1198         }
1199
1200         TALLOC_FREE(old_subkeys);
1201
1202         store_ctx.key = key;
1203         store_ctx.ctr = ctr;
1204
1205         werr = regdb_trans_do(db,
1206                               regdb_store_keys_action,
1207                               &store_ctx);
1208
1209         ret = W_ERROR_IS_OK(werr);
1210
1211 done:
1212         TALLOC_FREE(ctx);
1213
1214         return ret;
1215 }
1216
1217 bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
1218 {
1219         return regdb_store_keys_internal(regdb, key, ctr);
1220 }
1221
1222 /**
1223  * create a subkey of a given key
1224  */
1225
1226 struct regdb_create_subkey_context {
1227         const char *key;
1228         const char *subkey;
1229 };
1230
1231 static NTSTATUS regdb_create_subkey_action(struct db_context *db,
1232                                            void *private_data)
1233 {
1234         WERROR werr;
1235         struct regdb_create_subkey_context *create_ctx;
1236         struct regsubkey_ctr *subkeys;
1237         TALLOC_CTX *mem_ctx = talloc_stackframe();
1238
1239         create_ctx = (struct regdb_create_subkey_context *)private_data;
1240
1241         werr = regsubkey_ctr_init(mem_ctx, &subkeys);
1242         W_ERROR_NOT_OK_GOTO_DONE(werr);
1243
1244         werr = regdb_fetch_keys_internal(db, create_ctx->key, subkeys);
1245         W_ERROR_NOT_OK_GOTO_DONE(werr);
1246
1247         werr = regsubkey_ctr_addkey(subkeys, create_ctx->subkey);
1248         W_ERROR_NOT_OK_GOTO_DONE(werr);
1249
1250         werr = regdb_store_keys_internal2(db, create_ctx->key, subkeys);
1251         if (!W_ERROR_IS_OK(werr)) {
1252                 DEBUG(0, (__location__ " failed to store new subkey list for "
1253                          "parent key %s: %s\n", create_ctx->key,
1254                          win_errstr(werr)));
1255         }
1256
1257         werr = regdb_store_subkey_list(db, create_ctx->key, create_ctx->subkey);
1258
1259 done:
1260         talloc_free(mem_ctx);
1261         return werror_to_ntstatus(werr);
1262 }
1263
1264 static WERROR regdb_create_subkey_internal(struct db_context *db,
1265                                            const char *key,
1266                                            const char *subkey)
1267 {
1268         WERROR werr;
1269         struct regsubkey_ctr *subkeys;
1270         TALLOC_CTX *mem_ctx = talloc_stackframe();
1271         struct regdb_create_subkey_context create_ctx;
1272
1273         if (!regdb_key_exists(db, key)) {
1274                 werr = WERR_NOT_FOUND;
1275                 goto done;
1276         }
1277
1278         werr = regsubkey_ctr_init(mem_ctx, &subkeys);
1279         W_ERROR_NOT_OK_GOTO_DONE(werr);
1280
1281         werr = regdb_fetch_keys_internal(db, key, subkeys);
1282         W_ERROR_NOT_OK_GOTO_DONE(werr);
1283
1284         if (regsubkey_ctr_key_exists(subkeys, subkey)) {
1285                 werr = WERR_OK;
1286                 goto done;
1287         }
1288
1289         talloc_free(subkeys);
1290
1291         create_ctx.key = key;
1292         create_ctx.subkey = subkey;
1293
1294         werr = regdb_trans_do(db,
1295                               regdb_create_subkey_action,
1296                               &create_ctx);
1297
1298 done:
1299         talloc_free(mem_ctx);
1300         return werr;
1301 }
1302
1303 static WERROR regdb_create_subkey(const char *key, const char *subkey)
1304 {
1305         return regdb_create_subkey_internal(regdb, key, subkey);
1306 }
1307
1308 /**
1309  * create a base key
1310  */
1311
1312 struct regdb_create_basekey_context {
1313         const char *key;
1314 };
1315
1316 static NTSTATUS regdb_create_basekey_action(struct db_context *db,
1317                                             void *private_data)
1318 {
1319         WERROR werr;
1320         struct regdb_create_basekey_context *create_ctx;
1321
1322         create_ctx = (struct regdb_create_basekey_context *)private_data;
1323
1324         werr = regdb_store_subkey_list(db, NULL, create_ctx->key);
1325
1326         return werror_to_ntstatus(werr);
1327 }
1328
1329 static WERROR regdb_create_basekey(struct db_context *db, const char *key)
1330 {
1331         WERROR werr;
1332         struct regdb_create_subkey_context create_ctx;
1333
1334         create_ctx.key = key;
1335
1336         werr = regdb_trans_do(db,
1337                               regdb_create_basekey_action,
1338                               &create_ctx);
1339
1340         return werr;
1341 }
1342
1343 /**
1344  * create a subkey of a given key
1345  */
1346
1347 struct regdb_delete_subkey_context {
1348         const char *key;
1349         const char *subkey;
1350         const char *path;
1351         bool lazy;
1352 };
1353
1354 static NTSTATUS regdb_delete_subkey_action(struct db_context *db,
1355                                            void *private_data)
1356 {
1357         WERROR werr;
1358         struct regdb_delete_subkey_context *delete_ctx;
1359         struct regsubkey_ctr *subkeys;
1360         TALLOC_CTX *mem_ctx = talloc_stackframe();
1361
1362         delete_ctx = (struct regdb_delete_subkey_context *)private_data;
1363
1364         werr = regdb_delete_key_lists(db, delete_ctx->path);
1365         W_ERROR_NOT_OK_GOTO_DONE(werr);
1366
1367         if (delete_ctx->lazy) {
1368                 goto done;
1369         }
1370
1371         werr = regsubkey_ctr_init(mem_ctx, &subkeys);
1372         W_ERROR_NOT_OK_GOTO_DONE(werr);
1373
1374         werr = regdb_fetch_keys_internal(db, delete_ctx->key, subkeys);
1375         W_ERROR_NOT_OK_GOTO_DONE(werr);
1376
1377         werr = regsubkey_ctr_delkey(subkeys, delete_ctx->subkey);
1378         W_ERROR_NOT_OK_GOTO_DONE(werr);
1379
1380         werr = regdb_store_keys_internal2(db, delete_ctx->key, subkeys);
1381         if (!W_ERROR_IS_OK(werr)) {
1382                 DEBUG(0, (__location__ " failed to store new subkey_list for "
1383                          "parent key %s: %s\n", delete_ctx->key,
1384                          win_errstr(werr)));
1385         }
1386
1387 done:
1388         talloc_free(mem_ctx);
1389         return werror_to_ntstatus(werr);
1390 }
1391
1392 static WERROR regdb_delete_subkey(const char *key, const char *subkey, bool lazy)
1393 {
1394         WERROR werr;
1395         char *path;
1396         struct regdb_delete_subkey_context delete_ctx;
1397         TALLOC_CTX *mem_ctx = talloc_stackframe();
1398
1399         if (!regdb_key_exists(regdb, key)) {
1400                 werr = WERR_NOT_FOUND;
1401                 goto done;
1402         }
1403
1404         path = talloc_asprintf(mem_ctx, "%s\\%s", key, subkey);
1405         if (path == NULL) {
1406                 werr = WERR_NOMEM;
1407                 goto done;
1408         }
1409
1410         if (!regdb_key_exists(regdb, path)) {
1411                 werr = WERR_OK;
1412                 goto done;
1413         }
1414
1415         delete_ctx.key = key;
1416         delete_ctx.subkey = subkey;
1417         delete_ctx.path = path;
1418         delete_ctx.lazy = lazy;
1419
1420         werr = regdb_trans_do(regdb,
1421                               regdb_delete_subkey_action,
1422                               &delete_ctx);
1423
1424 done:
1425         talloc_free(mem_ctx);
1426         return werr;
1427 }
1428
1429 static TDB_DATA regdb_fetch_key_internal(struct db_context *db,
1430                                          TALLOC_CTX *mem_ctx, const char *key)
1431 {
1432         char *path = NULL;
1433         TDB_DATA data;
1434
1435         path = normalize_reg_path(mem_ctx, key);
1436         if (!path) {
1437                 return make_tdb_data(NULL, 0);
1438         }
1439
1440         data = dbwrap_fetch_bystring(db, mem_ctx, path);
1441
1442         TALLOC_FREE(path);
1443         return data;
1444 }
1445
1446
1447 /**
1448  * Check for the existence of a key.
1449  *
1450  * Existence of a key is authoritatively defined by
1451  * the existence of the record that contains the list
1452  * of its subkeys.
1453  *
1454  * Return false, if the record does not match the correct
1455  * structure of an initial 4-byte counter and then a
1456  * list of the corresponding number of zero-terminated
1457  * strings.
1458  */
1459 static bool regdb_key_exists(struct db_context *db, const char *key)
1460 {
1461         TALLOC_CTX *mem_ctx = talloc_stackframe();
1462         TDB_DATA value;
1463         bool ret = false;
1464         char *path;
1465         uint32_t buflen;
1466         const char *buf;
1467         uint32_t num_items, i;
1468         int32_t len;
1469
1470         if (key == NULL) {
1471                 goto done;
1472         }
1473
1474         path = normalize_reg_path(mem_ctx, key);
1475         if (path == NULL) {
1476                 DEBUG(0, ("out of memory! (talloc failed)\n"));
1477                 goto done;
1478         }
1479
1480         if (*path == '\0') {
1481                 goto done;
1482         }
1483
1484         value = regdb_fetch_key_internal(db, mem_ctx, path);
1485         if (value.dptr == NULL) {
1486                 goto done;
1487         }
1488
1489         if (value.dsize == 0) {
1490                 DEBUG(10, ("regdb_key_exists: subkeylist-record for key "
1491                           "[%s] is empty: Could be a deleted record in a "
1492                           "clustered (ctdb) environment?\n",
1493                           path));
1494                 goto done;
1495         }
1496
1497         len = tdb_unpack(value.dptr, value.dsize, "d", &num_items);
1498         if (len == (int32_t)-1) {
1499                 DEBUG(1, ("regdb_key_exists: ERROR: subkeylist-record for key "
1500                           "[%s] is invalid: Could not parse initial 4-byte "
1501                           "counter. record data length is %u.\n",
1502                           path, (unsigned int)value.dsize));
1503                 goto done;
1504         }
1505
1506         /*
1507          * Note: the tdb_unpack check above implies that len <= value.dsize
1508          */
1509         buflen = value.dsize - len;
1510         buf = (const char *)value.dptr + len;
1511
1512         len = 0;
1513
1514         for (i = 0; i < num_items; i++) {
1515                 if (buflen == 0) {
1516                         break;
1517                 }
1518                 len = strnlen(buf, buflen) + 1;
1519                 if (buflen < len) {
1520                         DEBUG(1, ("regdb_key_exists: ERROR: subkeylist-record "
1521                                   "for key [%s] is corrupt: %u items expected, "
1522                                   "item number %u is not zero terminated.\n",
1523                                   path, num_items, i+1));
1524                         goto done;
1525                 }
1526
1527                 buf += len;
1528                 buflen -= len;
1529         }
1530
1531         if (buflen > 0) {
1532                 DEBUG(1, ("regdb_key_exists: ERROR: subkeylist-record for key "
1533                           "[%s] is corrupt: %u items expected and found, but "
1534                           "the record contains additional %u bytes\n",
1535                           path, num_items, buflen));
1536                 goto done;
1537         }
1538
1539         if (i < num_items) {
1540                 DEBUG(1, ("regdb_key_exists: ERROR: subkeylist-record for key "
1541                           "[%s] is corrupt: %u items expected, but only %u "
1542                           "items found.\n",
1543                           path, num_items, i+1));
1544                 goto done;
1545         }
1546
1547         ret = true;
1548
1549 done:
1550         TALLOC_FREE(mem_ctx);
1551         return ret;
1552 }
1553
1554
1555 /***********************************************************************
1556  Retrieve an array of strings containing subkeys.  Memory should be
1557  released by the caller.
1558  ***********************************************************************/
1559
1560 static WERROR regdb_fetch_keys_internal(struct db_context *db, const char *key,
1561                                         struct regsubkey_ctr *ctr)
1562 {
1563         WERROR werr;
1564         uint32_t num_items;
1565         uint8 *buf;
1566         uint32 buflen, len;
1567         int i;
1568         fstring subkeyname;
1569         TALLOC_CTX *frame = talloc_stackframe();
1570         TDB_DATA value;
1571
1572         DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL"));
1573
1574         if (!regdb_key_exists(db, key)) {
1575                 DEBUG(10, ("key [%s] not found\n", key));
1576                 werr = WERR_NOT_FOUND;
1577                 goto done;
1578         }
1579
1580         werr = regsubkey_ctr_reinit(ctr);
1581         W_ERROR_NOT_OK_GOTO_DONE(werr);
1582
1583         werr = regsubkey_ctr_set_seqnum(ctr, db->get_seqnum(db));
1584         W_ERROR_NOT_OK_GOTO_DONE(werr);
1585
1586         value = regdb_fetch_key_internal(db, frame, key);
1587
1588         if (value.dsize == 0 || value.dptr == NULL) {
1589                 DEBUG(10, ("regdb_fetch_keys: no subkeys found for key [%s]\n",
1590                            key));
1591                 goto done;
1592         }
1593
1594         buf = value.dptr;
1595         buflen = value.dsize;
1596         len = tdb_unpack( buf, buflen, "d", &num_items);
1597         if (len == (uint32_t)-1) {
1598                 werr = WERR_NOT_FOUND;
1599                 goto done;
1600         }
1601
1602         for (i=0; i<num_items; i++) {
1603                 len += tdb_unpack(buf+len, buflen-len, "f", subkeyname);
1604                 werr = regsubkey_ctr_addkey(ctr, subkeyname);
1605                 if (!W_ERROR_IS_OK(werr)) {
1606                         DEBUG(5, ("regdb_fetch_keys: regsubkey_ctr_addkey "
1607                                   "failed: %s\n", win_errstr(werr)));
1608                         num_items = 0;
1609                         goto done;
1610                 }
1611         }
1612
1613         DEBUG(11,("regdb_fetch_keys: Exit [%d] items\n", num_items));
1614
1615 done:
1616         TALLOC_FREE(frame);
1617         return werr;
1618 }
1619
1620 int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr)
1621 {
1622         WERROR werr;
1623
1624         werr = regdb_fetch_keys_internal(regdb, key, ctr);
1625         if (!W_ERROR_IS_OK(werr)) {
1626                 return -1;
1627         }
1628
1629         return regsubkey_ctr_numkeys(ctr);
1630 }
1631
1632 /****************************************************************************
1633  Unpack a list of registry values frem the TDB
1634  ***************************************************************************/
1635
1636 static int regdb_unpack_values(struct regval_ctr *values, uint8 *buf, int buflen)
1637 {
1638         int             len = 0;
1639         uint32          type;
1640         fstring valuename;
1641         uint32          size;
1642         uint8           *data_p;
1643         uint32          num_values = 0;
1644         int             i;
1645
1646         /* loop and unpack the rest of the registry values */
1647
1648         len += tdb_unpack(buf+len, buflen-len, "d", &num_values);
1649
1650         for ( i=0; i<num_values; i++ ) {
1651                 /* unpack the next regval */
1652
1653                 type = REG_NONE;
1654                 size = 0;
1655                 data_p = NULL;
1656                 valuename[0] = '\0';
1657                 len += tdb_unpack(buf+len, buflen-len, "fdB",
1658                                   valuename,
1659                                   &type,
1660                                   &size,
1661                                   &data_p);
1662
1663                 regval_ctr_addvalue(values, valuename, type,
1664                                 (uint8_t *)data_p, size);
1665                 SAFE_FREE(data_p); /* 'B' option to tdb_unpack does a malloc() */
1666
1667                 DEBUG(8,("specific: [%s], len: %d\n", valuename, size));
1668         }
1669
1670         return len;
1671 }
1672
1673 /****************************************************************************
1674  Pack all values in all printer keys
1675  ***************************************************************************/
1676
1677 static int regdb_pack_values(struct regval_ctr *values, uint8 *buf, int buflen)
1678 {
1679         int             len = 0;
1680         int             i;
1681         struct regval_blob      *val;
1682         int             num_values;
1683
1684         if ( !values )
1685                 return 0;
1686
1687         num_values = regval_ctr_numvals( values );
1688
1689         /* pack the number of values first */
1690
1691         len += tdb_pack( buf+len, buflen-len, "d", num_values );
1692
1693         /* loop over all values */
1694
1695         for ( i=0; i<num_values; i++ ) {
1696                 val = regval_ctr_specific_value( values, i );
1697                 len += tdb_pack(buf+len, buflen-len, "fdB",
1698                                 regval_name(val),
1699                                 regval_type(val),
1700                                 regval_size(val),
1701                                 regval_data_p(val) );
1702         }
1703
1704         return len;
1705 }
1706
1707 /***********************************************************************
1708  Retrieve an array of strings containing subkeys.  Memory should be
1709  released by the caller.
1710  ***********************************************************************/
1711
1712 static int regdb_fetch_values_internal(struct db_context *db, const char* key,
1713                                        struct regval_ctr *values)
1714 {
1715         char *keystr = NULL;
1716         TALLOC_CTX *ctx = talloc_stackframe();
1717         int ret = 0;
1718         TDB_DATA value;
1719         WERROR werr;
1720
1721         DEBUG(10,("regdb_fetch_values: Looking for value of key [%s] \n", key));
1722
1723         if (!regdb_key_exists(db, key)) {
1724                 goto done;
1725         }
1726
1727         keystr = talloc_asprintf(ctx, "%s\\%s", REG_VALUE_PREFIX, key);
1728         if (!keystr) {
1729                 goto done;
1730         }
1731
1732         werr = regval_ctr_set_seqnum(values, db->get_seqnum(db));
1733         W_ERROR_NOT_OK_GOTO_DONE(werr);
1734
1735         value = regdb_fetch_key_internal(db, ctx, keystr);
1736
1737         if (!value.dptr) {
1738                 /* all keys have zero values by default */
1739                 goto done;
1740         }
1741
1742         regdb_unpack_values(values, value.dptr, value.dsize);
1743         ret = regval_ctr_numvals(values);
1744
1745 done:
1746         TALLOC_FREE(ctx);
1747         return ret;
1748 }
1749
1750 int regdb_fetch_values(const char* key, struct regval_ctr *values)
1751 {
1752         return regdb_fetch_values_internal(regdb, key, values);
1753 }
1754
1755 static NTSTATUS regdb_store_values_internal(struct db_context *db,
1756                                             const char *key,
1757                                             struct regval_ctr *values)
1758 {
1759         TDB_DATA old_data, data;
1760         char *keystr = NULL;
1761         TALLOC_CTX *ctx = talloc_stackframe();
1762         int len;
1763         NTSTATUS status;
1764
1765         DEBUG(10,("regdb_store_values: Looking for value of key [%s] \n", key));
1766
1767         if (!regdb_key_exists(db, key)) {
1768                 status = NT_STATUS_NOT_FOUND;
1769                 goto done;
1770         }
1771
1772         ZERO_STRUCT(data);
1773
1774         len = regdb_pack_values(values, data.dptr, data.dsize);
1775         if (len <= 0) {
1776                 DEBUG(0,("regdb_store_values: unable to pack values. len <= 0\n"));
1777                 status = NT_STATUS_UNSUCCESSFUL;
1778                 goto done;
1779         }
1780
1781         data.dptr = talloc_array(ctx, uint8, len);
1782         data.dsize = len;
1783
1784         len = regdb_pack_values(values, data.dptr, data.dsize);
1785
1786         SMB_ASSERT( len == data.dsize );
1787
1788         keystr = talloc_asprintf(ctx, "%s\\%s", REG_VALUE_PREFIX, key );
1789         if (!keystr) {
1790                 status = NT_STATUS_NO_MEMORY;
1791                 goto done;
1792         }
1793         keystr = normalize_reg_path(ctx, keystr);
1794         if (!keystr) {
1795                 goto done;
1796         }
1797
1798         old_data = dbwrap_fetch_bystring(db, ctx, keystr);
1799
1800         if ((old_data.dptr != NULL)
1801             && (old_data.dsize == data.dsize)
1802             && (memcmp(old_data.dptr, data.dptr, data.dsize) == 0))
1803         {
1804                 status = NT_STATUS_OK;
1805                 goto done;
1806         }
1807
1808         status = dbwrap_trans_store_bystring(db, keystr, data, TDB_REPLACE);
1809
1810 done:
1811         TALLOC_FREE(ctx);
1812         return status;
1813 }
1814
1815 struct regdb_store_values_ctx {
1816         const char *key;
1817         struct regval_ctr *values;
1818 };
1819
1820 static NTSTATUS regdb_store_values_action(struct db_context *db,
1821                                           void *private_data)
1822 {
1823         NTSTATUS status;
1824         struct regdb_store_values_ctx *ctx =
1825                 (struct regdb_store_values_ctx *)private_data;
1826
1827         status = regdb_store_values_internal(db, ctx->key, ctx->values);
1828
1829         return status;
1830 }
1831
1832 bool regdb_store_values(const char *key, struct regval_ctr *values)
1833 {
1834         WERROR werr;
1835         struct regdb_store_values_ctx ctx;
1836
1837         ctx.key = key;
1838         ctx.values = values;
1839
1840         werr = regdb_trans_do(regdb, regdb_store_values_action, &ctx);
1841
1842         return W_ERROR_IS_OK(werr);
1843 }
1844
1845 static WERROR regdb_get_secdesc(TALLOC_CTX *mem_ctx, const char *key,
1846                                 struct security_descriptor **psecdesc)
1847 {
1848         char *tdbkey;
1849         TDB_DATA data;
1850         NTSTATUS status;
1851         TALLOC_CTX *tmp_ctx = talloc_stackframe();
1852         WERROR err = WERR_OK;
1853
1854         DEBUG(10, ("regdb_get_secdesc: Getting secdesc of key [%s]\n", key));
1855
1856         if (!regdb_key_exists(regdb, key)) {
1857                 err = WERR_BADFILE;
1858                 goto done;
1859         }
1860
1861         tdbkey = talloc_asprintf(tmp_ctx, "%s\\%s", REG_SECDESC_PREFIX, key);
1862         if (tdbkey == NULL) {
1863                 err = WERR_NOMEM;
1864                 goto done;
1865         }
1866
1867         tdbkey = normalize_reg_path(tmp_ctx, tdbkey);
1868         if (tdbkey == NULL) {
1869                 err = WERR_NOMEM;
1870                 goto done;
1871         }
1872
1873         data = dbwrap_fetch_bystring(regdb, tmp_ctx, tdbkey);
1874         if (data.dptr == NULL) {
1875                 err = WERR_BADFILE;
1876                 goto done;
1877         }
1878
1879         status = unmarshall_sec_desc(mem_ctx, (uint8 *)data.dptr, data.dsize,
1880                                      psecdesc);
1881
1882         if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MEMORY)) {
1883                 err = WERR_NOMEM;
1884         } else if (!NT_STATUS_IS_OK(status)) {
1885                 err = WERR_REG_CORRUPT;
1886         }
1887
1888 done:
1889         TALLOC_FREE(tmp_ctx);
1890         return err;
1891 }
1892
1893 struct regdb_set_secdesc_ctx {
1894         const char *key;
1895         struct security_descriptor *secdesc;
1896 };
1897
1898 static NTSTATUS regdb_set_secdesc_action(struct db_context *db,
1899                                          void *private_data)
1900 {
1901         char *tdbkey;
1902         NTSTATUS status;
1903         TDB_DATA tdbdata;
1904         struct regdb_set_secdesc_ctx *ctx =
1905                 (struct regdb_set_secdesc_ctx *)private_data;
1906         TALLOC_CTX *frame = talloc_stackframe();
1907
1908         tdbkey = talloc_asprintf(frame, "%s\\%s", REG_SECDESC_PREFIX, ctx->key);
1909         if (tdbkey == NULL) {
1910                 goto done;
1911         }
1912
1913         tdbkey = normalize_reg_path(frame, tdbkey);
1914         if (tdbkey == NULL) {
1915                 status = NT_STATUS_NO_MEMORY;
1916                 goto done;
1917         }
1918
1919         if (ctx->secdesc == NULL) {
1920                 /* assuming a delete */
1921                 status = dbwrap_delete_bystring(db, tdbkey);
1922                 goto done;
1923         }
1924
1925         status = marshall_sec_desc(frame, ctx->secdesc, &tdbdata.dptr,
1926                                    &tdbdata.dsize);
1927         if (!NT_STATUS_IS_OK(status)) {
1928                 goto done;
1929         }
1930
1931         status = dbwrap_store_bystring(db, tdbkey, tdbdata, 0);
1932
1933 done:
1934         TALLOC_FREE(frame);
1935         return status;
1936 }
1937
1938 static WERROR regdb_set_secdesc(const char *key,
1939                                 struct security_descriptor *secdesc)
1940 {
1941         WERROR err;
1942         struct regdb_set_secdesc_ctx ctx;
1943
1944         if (!regdb_key_exists(regdb, key)) {
1945                 err = WERR_BADFILE;
1946                 goto done;
1947         }
1948
1949         ctx.key = key;
1950         ctx.secdesc = secdesc;
1951
1952         err = regdb_trans_do(regdb, regdb_set_secdesc_action, &ctx);
1953
1954 done:
1955         return err;
1956 }
1957
1958 bool regdb_subkeys_need_update(struct regsubkey_ctr *subkeys)
1959 {
1960         return (regdb_get_seqnum() != regsubkey_ctr_get_seqnum(subkeys));
1961 }
1962
1963 bool regdb_values_need_update(struct regval_ctr *values)
1964 {
1965         return (regdb_get_seqnum() != regval_ctr_get_seqnum(values));
1966 }
1967
1968 /*
1969  * Table of function pointers for default access
1970  */
1971
1972 struct registry_ops regdb_ops = {
1973         .fetch_subkeys = regdb_fetch_keys,
1974         .fetch_values = regdb_fetch_values,
1975         .store_subkeys = regdb_store_keys,
1976         .store_values = regdb_store_values,
1977         .create_subkey = regdb_create_subkey,
1978         .delete_subkey = regdb_delete_subkey,
1979         .get_secdesc = regdb_get_secdesc,
1980         .set_secdesc = regdb_set_secdesc,
1981         .subkeys_need_update = regdb_subkeys_need_update,
1982         .values_need_update = regdb_values_need_update
1983 };