s3:winbindd: use wb_sids2xids instead of wb_sid2gid in winbindd_sid_to_gid
[kai/samba.git] / source3 / registry / reg_objects.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-2010
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 registry frontend view functions. */
22
23 #include "includes.h"
24 #include "registry.h"
25 #include "reg_objects.h"
26 #include "util_tdb.h"
27 #include "dbwrap/dbwrap.h"
28 #include "dbwrap/dbwrap_rbt.h"
29 #include "../libcli/registry/util_reg.h"
30
31 #undef DBGC_CLASS
32 #define DBGC_CLASS DBGC_REGISTRY
33
34 /* low level structure to contain registry values */
35
36 struct regval_blob {
37         fstring         valuename;
38         uint32_t        type;
39         /* this should be encapsulated in an RPC_DATA_BLOB */
40         uint32_t        size;   /* in bytes */
41         uint8_t         *data_p;
42 };
43
44 /* container for registry values */
45
46 struct regval_ctr {
47         uint32_t num_values;
48         struct regval_blob **values;
49         int seqnum;
50 };
51
52 struct regsubkey_ctr {
53         uint32_t        num_subkeys;
54         char            **subkeys;
55         struct db_context *subkeys_hash;
56         int seqnum;
57 };
58
59 /**********************************************************************
60
61  Note that the struct regsubkey_ctr and struct regval_ctr objects *must* be
62  talloc()'d since the methods use the object pointer as the talloc
63  context for internal private data.
64
65  There is no longer a regval_ctr_intit() and regval_ctr_destroy()
66  pair of functions.  Simply talloc_zero() and TALLOC_FREE() the
67  object.
68
69  **********************************************************************/
70
71 WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr)
72 {
73         if (ctr == NULL) {
74                 return WERR_INVALID_PARAM;
75         }
76
77         *ctr = talloc_zero(mem_ctx, struct regsubkey_ctr);
78         if (*ctr == NULL) {
79                 return WERR_NOMEM;
80         }
81
82         (*ctr)->subkeys_hash = db_open_rbt(*ctr);
83         if ((*ctr)->subkeys_hash == NULL) {
84                 talloc_free(*ctr);
85                 return WERR_NOMEM;
86         }
87
88         return WERR_OK;
89 }
90
91 /**
92  * re-initialize the list of subkeys (to the emtpy list)
93  * in an already allocated regsubkey_ctr
94  */
95
96 WERROR regsubkey_ctr_reinit(struct regsubkey_ctr *ctr)
97 {
98         if (ctr == NULL) {
99                 return WERR_INVALID_PARAM;
100         }
101
102         talloc_free(ctr->subkeys_hash);
103         ctr->subkeys_hash = db_open_rbt(ctr);
104         W_ERROR_HAVE_NO_MEMORY(ctr->subkeys_hash);
105
106         TALLOC_FREE(ctr->subkeys);
107
108         ctr->num_subkeys = 0;
109         ctr->seqnum = 0;
110
111         return WERR_OK;
112 }
113
114 WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum)
115 {
116         if (ctr == NULL) {
117                 return WERR_INVALID_PARAM;
118         }
119
120         ctr->seqnum = seqnum;
121
122         return WERR_OK;
123 }
124
125 int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr)
126 {
127         if (ctr == NULL) {
128                 return -1;
129         }
130
131         return ctr->seqnum;
132 }
133
134 static WERROR regsubkey_ctr_hash_keyname(struct regsubkey_ctr *ctr,
135                                          const char *keyname,
136                                          uint32_t idx)
137 {
138         WERROR werr;
139
140         werr = ntstatus_to_werror(dbwrap_store_bystring_upper(ctr->subkeys_hash,
141                                                 keyname,
142                                                 make_tdb_data((uint8_t *)&idx,
143                                                               sizeof(idx)),
144                                                 TDB_REPLACE));
145         if (!W_ERROR_IS_OK(werr)) {
146                 DEBUG(1, ("error hashing new key '%s' in container: %s\n",
147                           keyname, win_errstr(werr)));
148         }
149
150         return werr;
151 }
152
153 static WERROR regsubkey_ctr_unhash_keyname(struct regsubkey_ctr *ctr,
154                                            const char *keyname)
155 {
156         WERROR werr;
157
158         werr = ntstatus_to_werror(dbwrap_delete_bystring_upper(ctr->subkeys_hash,
159                                   keyname));
160         if (!W_ERROR_IS_OK(werr)) {
161                 DEBUG(1, ("error unhashing key '%s' in container: %s\n",
162                           keyname, win_errstr(werr)));
163         }
164
165         return werr;
166 }
167
168 static WERROR regsubkey_ctr_index_for_keyname(struct regsubkey_ctr *ctr,
169                                               const char *keyname,
170                                               uint32_t *idx)
171 {
172         TDB_DATA data;
173         NTSTATUS status;
174
175         if ((ctr == NULL) || (keyname == NULL)) {
176                 return WERR_INVALID_PARAM;
177         }
178
179         status = dbwrap_fetch_bystring_upper(ctr->subkeys_hash, ctr, keyname,
180                                              &data);
181         if (!NT_STATUS_IS_OK(status)) {
182                 return WERR_NOT_FOUND;
183         }
184
185         if (data.dsize != sizeof(*idx)) {
186                 talloc_free(data.dptr);
187                 return WERR_INVALID_DATATYPE;
188         }
189
190         if (idx != NULL) {
191                 *idx = *(uint32_t *)data.dptr;
192         }
193
194         talloc_free(data.dptr);
195         return WERR_OK;
196 }
197
198 /***********************************************************************
199  Add a new key to the array
200  **********************************************************************/
201
202 WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname )
203 {
204         char **newkeys;
205         WERROR werr;
206
207         if ( !keyname ) {
208                 return WERR_OK;
209         }
210
211         /* make sure the keyname is not already there */
212
213         if ( regsubkey_ctr_key_exists( ctr, keyname ) ) {
214                 return WERR_OK;
215         }
216
217         if (!(newkeys = talloc_realloc(ctr, ctr->subkeys, char *,
218                                              ctr->num_subkeys+1))) {
219                 return WERR_NOMEM;
220         }
221
222         ctr->subkeys = newkeys;
223
224         if (!(ctr->subkeys[ctr->num_subkeys] = talloc_strdup(ctr->subkeys,
225                                                              keyname ))) {
226                 /*
227                  * Don't shrink the new array again, this wastes a pointer
228                  */
229                 return WERR_NOMEM;
230         }
231
232         werr = regsubkey_ctr_hash_keyname(ctr, keyname, ctr->num_subkeys);
233         W_ERROR_NOT_OK_RETURN(werr);
234
235         ctr->num_subkeys++;
236
237         return WERR_OK;
238 }
239
240  /***********************************************************************
241  Delete a key from the array
242  **********************************************************************/
243
244 WERROR regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname )
245 {
246         WERROR werr;
247         uint32_t idx, j;
248
249         if (keyname == NULL) {
250                 return WERR_INVALID_PARAM;
251         }
252
253         /* make sure the keyname is actually already there */
254
255         werr = regsubkey_ctr_index_for_keyname(ctr, keyname, &idx);
256         W_ERROR_NOT_OK_RETURN(werr);
257
258         werr = regsubkey_ctr_unhash_keyname(ctr, keyname);
259         W_ERROR_NOT_OK_RETURN(werr);
260
261         /* update if we have any keys left */
262         ctr->num_subkeys--;
263         if (idx < ctr->num_subkeys) {
264                 memmove(&ctr->subkeys[idx], &ctr->subkeys[idx+1],
265                         sizeof(char *) * (ctr->num_subkeys - idx));
266
267                 /* we have to re-hash rest of the array...  :-( */
268                 for (j = idx; j < ctr->num_subkeys; j++) {
269                         werr = regsubkey_ctr_hash_keyname(ctr, ctr->subkeys[j], j);
270                         W_ERROR_NOT_OK_RETURN(werr);
271                 }
272         }
273
274         return WERR_OK;
275 }
276
277 /***********************************************************************
278  Check for the existance of a key
279  **********************************************************************/
280
281 bool regsubkey_ctr_key_exists( struct regsubkey_ctr *ctr, const char *keyname )
282 {
283         WERROR werr;
284
285         if (!ctr->subkeys) {
286                 return False;
287         }
288
289         werr = regsubkey_ctr_index_for_keyname(ctr, keyname, NULL);
290         if (!W_ERROR_IS_OK(werr)) {
291                 return false;
292         }
293
294         return true;
295 }
296
297 /***********************************************************************
298  How many keys does the container hold ?
299  **********************************************************************/
300
301 int regsubkey_ctr_numkeys( struct regsubkey_ctr *ctr )
302 {
303         return ctr->num_subkeys;
304 }
305
306 /***********************************************************************
307  Retreive a specific key string
308  **********************************************************************/
309
310 char* regsubkey_ctr_specific_key( struct regsubkey_ctr *ctr, uint32_t key_index )
311 {
312         if ( ! (key_index < ctr->num_subkeys) )
313                 return NULL;
314
315         return ctr->subkeys[key_index];
316 }
317
318 /*
319  * Utility functions for struct regval_ctr
320  */
321
322 /**
323  * allocate a regval_ctr structure.
324  */
325 WERROR regval_ctr_init(TALLOC_CTX *mem_ctx, struct regval_ctr **ctr)
326 {
327         if (ctr == NULL) {
328                 return WERR_INVALID_PARAM;
329         }
330
331         *ctr = talloc_zero(mem_ctx, struct regval_ctr);
332         if (*ctr == NULL) {
333                 return WERR_NOMEM;
334         }
335
336         return WERR_OK;
337 }
338
339 /***********************************************************************
340  How many keys does the container hold ?
341  **********************************************************************/
342
343 int regval_ctr_numvals(struct regval_ctr *ctr)
344 {
345         return ctr->num_values;
346 }
347
348 /**********************************************************************
349  *********************************************************************/
350
351 uint8_t* regval_data_p(struct regval_blob *val)
352 {
353         return val->data_p;
354 }
355
356 /**********************************************************************
357  *********************************************************************/
358
359 uint32_t regval_size(struct regval_blob *val)
360 {
361         return val->size;
362 }
363
364 /**********************************************************************
365  *********************************************************************/
366
367 char* regval_name(struct regval_blob *val)
368 {
369         return val->valuename;
370 }
371
372 /**********************************************************************
373  *********************************************************************/
374
375 uint32_t regval_type(struct regval_blob *val)
376 {
377         return val->type;
378 }
379
380 /***********************************************************************
381  Retreive a pointer to a specific value.  Caller shoud dup the structure
382  since this memory will go away when the ctr is free()'d
383  **********************************************************************/
384
385 struct regval_blob *regval_ctr_specific_value(struct regval_ctr *ctr,
386                                               uint32_t idx)
387 {
388         if ( !(idx < ctr->num_values) )
389                 return NULL;
390
391         return ctr->values[idx];
392 }
393
394 /***********************************************************************
395  Check for the existance of a value
396  **********************************************************************/
397
398 bool regval_ctr_value_exists(struct regval_ctr *ctr, const char *value)
399 {
400         int     i;
401
402         for ( i=0; i<ctr->num_values; i++ ) {
403                 if ( strequal( ctr->values[i]->valuename, value) )
404                         return True;
405         }
406
407         return False;
408 }
409
410 /**
411  * Get a value by its name
412  */
413 struct regval_blob *regval_ctr_value_byname(struct regval_ctr *ctr,
414                                             const char *value)
415 {
416         int i;
417
418         for (i = 0; i < ctr->num_values; i++) {
419                 if (strequal(ctr->values[i]->valuename, value)) {
420                         return ctr->values[i];
421                 }
422         }
423
424         return NULL;
425 }
426
427
428 /***********************************************************************
429  * compose a struct regval_blob from input data
430  **********************************************************************/
431
432 struct regval_blob *regval_compose(TALLOC_CTX *ctx, const char *name,
433                                    uint32_t type,
434                                    const uint8_t *data_p, size_t size)
435 {
436         struct regval_blob *regval = talloc(ctx, struct regval_blob);
437
438         if (regval == NULL) {
439                 return NULL;
440         }
441
442         fstrcpy(regval->valuename, name);
443         regval->type = type;
444         if (size) {
445                 regval->data_p = (uint8_t *)talloc_memdup(regval, data_p, size);
446                 if (!regval->data_p) {
447                         TALLOC_FREE(regval);
448                         return NULL;
449                 }
450         } else {
451                 regval->data_p = NULL;
452         }
453         regval->size = size;
454
455         return regval;
456 }
457
458 /***********************************************************************
459  Add a new registry value to the array
460  **********************************************************************/
461
462 int regval_ctr_addvalue(struct regval_ctr *ctr, const char *name, uint32_t type,
463                         const uint8_t *data_p, size_t size)
464 {
465         if ( !name )
466                 return ctr->num_values;
467
468         /* Delete the current value (if it exists) and add the new one */
469
470         regval_ctr_delvalue( ctr, name );
471
472         /* allocate a slot in the array of pointers */
473
474         if (  ctr->num_values == 0 ) {
475                 ctr->values = talloc( ctr, struct regval_blob *);
476         } else {
477                 ctr->values = talloc_realloc(ctr, ctr->values,
478                                                    struct regval_blob *,
479                                                    ctr->num_values+1);
480         }
481
482         if (!ctr->values) {
483                 ctr->num_values = 0;
484                 return 0;
485         }
486
487         /* allocate a new value and store the pointer in the arrya */
488
489         ctr->values[ctr->num_values] = regval_compose(ctr, name, type, data_p,
490                                                       size);
491         if (ctr->values[ctr->num_values] == NULL) {
492                 ctr->num_values = 0;
493                 return 0;
494         }
495         ctr->num_values++;
496
497         return ctr->num_values;
498 }
499
500 /***********************************************************************
501  Add a new registry SZ value to the array
502  **********************************************************************/
503
504 int regval_ctr_addvalue_sz(struct regval_ctr *ctr, const char *name, const char *data)
505 {
506         DATA_BLOB blob;
507
508         if (!push_reg_sz(ctr, &blob, data)) {
509                 return -1;
510         }
511
512         return regval_ctr_addvalue(ctr, name, REG_SZ,
513                                    (const uint8_t *)blob.data,
514                                    blob.length);
515 }
516
517 /***********************************************************************
518  Add a new registry MULTI_SZ value to the array
519  **********************************************************************/
520
521 int regval_ctr_addvalue_multi_sz(struct regval_ctr *ctr, const char *name, const char **data)
522 {
523         DATA_BLOB blob;
524
525         if (!push_reg_multi_sz(ctr, &blob, data)) {
526                 return -1;
527         }
528
529         return regval_ctr_addvalue(ctr, name, REG_MULTI_SZ,
530                                    (const uint8_t *)blob.data,
531                                    blob.length);
532 }
533
534 /***********************************************************************
535  Add a new registry value to the array
536  **********************************************************************/
537
538 int regval_ctr_copyvalue(struct regval_ctr *ctr, struct regval_blob *val)
539 {
540         if ( val ) {
541                 regval_ctr_addvalue(ctr, val->valuename, val->type,
542                                     (uint8_t *)val->data_p, val->size);
543         }
544
545         return ctr->num_values;
546 }
547
548 /***********************************************************************
549  Delete a single value from the registry container.
550  No need to free memory since it is talloc'd.
551  **********************************************************************/
552
553 int regval_ctr_delvalue(struct regval_ctr *ctr, const char *name)
554 {
555         int     i;
556
557         for ( i=0; i<ctr->num_values; i++ ) {
558                 if ( strequal( ctr->values[i]->valuename, name ) )
559                         break;
560         }
561
562         /* just return if we don't find it */
563
564         if ( i == ctr->num_values )
565                 return ctr->num_values;
566
567         /* If 'i' was not the last element, just shift everything down one */
568         ctr->num_values--;
569         if ( i < ctr->num_values )
570                 memmove(&ctr->values[i], &ctr->values[i+1],
571                         sizeof(struct regval_blob*)*(ctr->num_values-i));
572
573         return ctr->num_values;
574 }
575
576 /***********************************************************************
577  Retrieve single value from the registry container.
578  No need to free memory since it is talloc'd.
579  **********************************************************************/
580
581 struct regval_blob* regval_ctr_getvalue(struct regval_ctr *ctr,
582                                         const char *name)
583 {
584         int     i;
585
586         /* search for the value */
587
588         for ( i=0; i<ctr->num_values; i++ ) {
589                 if ( strequal( ctr->values[i]->valuename, name ) )
590                         return ctr->values[i];
591         }
592
593         return NULL;
594 }
595
596 int regval_ctr_get_seqnum(struct regval_ctr *ctr)
597 {
598         if (ctr == NULL) {
599                 return -1;
600         }
601
602         return ctr->seqnum;
603 }
604
605 WERROR regval_ctr_set_seqnum(struct regval_ctr *ctr, int seqnum)
606 {
607         if (ctr == NULL) {
608                 return WERR_INVALID_PARAM;
609         }
610
611         ctr->seqnum = seqnum;
612
613         return WERR_OK;
614 }
615
616 /***********************************************************************
617  return the data_p as a uint32_t
618  **********************************************************************/
619
620 uint32_t regval_dword(struct regval_blob *val)
621 {
622         uint32_t data;
623
624         data = IVAL( regval_data_p(val), 0 );
625
626         return data;
627 }
628
629 /***********************************************************************
630  return the data_p as a character string
631  **********************************************************************/
632
633 const char *regval_sz(struct regval_blob *val)
634 {
635         const char *data = NULL;
636         DATA_BLOB blob = data_blob_const(regval_data_p(val), regval_size(val));
637
638         pull_reg_sz(talloc_tos(), &blob, &data);
639
640         return data;
641 }