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