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