LCOV - code coverage report
Current view: top level - source4/lib/registry - local.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 158 174 90.8 %
Date: 2024-04-21 15:09:00 Functions: 15 16 93.8 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Transparent registry backend handling
       4             :    Copyright (C) Jelmer Vernooij                        2003-2007.
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program; if not, write to the Free Software
      18             :    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "../lib/util/dlinklist.h"
      23             : #include "lib/registry/registry.h"
      24             : #include "system/filesys.h"
      25             : 
      26             : struct reg_key_path {
      27             :         uint32_t predefined_key;
      28             :         const char **elements;
      29             : };
      30             : 
      31             : struct registry_local {
      32             :         const struct registry_operations *ops;
      33             : 
      34             :         struct mountpoint {
      35             :                 struct reg_key_path path;
      36             :                 struct hive_key *key;
      37             :                 struct mountpoint *prev, *next;
      38             :         } *mountpoints;
      39             : };
      40             : 
      41             : struct local_key {
      42             :         struct registry_key global;
      43             :         struct reg_key_path path;
      44             :         struct hive_key *hive_key;
      45             : };
      46             : 
      47             : 
      48       32304 : struct registry_key *reg_import_hive_key(struct registry_context *ctx,
      49             :                                          struct hive_key *hive,
      50             :                                          uint32_t predefined_key,
      51             :                                          const char **elements)
      52             : {
      53        3511 :         struct local_key *local_key;
      54        3511 :         struct reg_key_path parent_path;
      55             : 
      56       32304 :         parent_path.predefined_key = predefined_key;
      57       32304 :         parent_path.elements = elements;
      58             : 
      59       32304 :         local_key = talloc(ctx, struct local_key);
      60       32304 :         if (local_key != NULL) {
      61       32304 :                 local_key->hive_key = talloc_reference(local_key, hive);
      62       32304 :                 local_key->global.context = talloc_reference(local_key, ctx);
      63       32304 :                 local_key->path = parent_path;
      64             :         }
      65             : 
      66       32304 :         return (struct registry_key *)local_key;
      67             : }
      68             : 
      69             : 
      70        8569 : static WERROR local_open_key(TALLOC_CTX *mem_ctx,
      71             :                              struct registry_key *parent,
      72             :                              const char *path,
      73             :                              struct registry_key **result)
      74             : {
      75         933 :         char *orig, *curbegin, *curend;
      76        8569 :         struct local_key *local_parent = talloc_get_type(parent,
      77             :                                                          struct local_key);
      78        8569 :         struct hive_key *curkey = local_parent->hive_key;
      79         933 :         WERROR error;
      80        8569 :         const char **elements = NULL;
      81         933 :         int el;
      82             : 
      83        8569 :         if (path == NULL || path[0] == '\0') {
      84           0 :                 return WERR_INVALID_PARAMETER;
      85             :         }
      86             : 
      87        8569 :         orig = talloc_strdup(mem_ctx, path);
      88        8569 :         W_ERROR_HAVE_NO_MEMORY(orig);
      89        8569 :         curbegin = orig;
      90        8569 :         curend = strchr(orig, '\\');
      91             : 
      92        8569 :         if (local_parent->path.elements != NULL) {
      93          22 :                 elements = talloc_array(mem_ctx, const char *,
      94             :                                         str_list_length(local_parent->path.elements) + 1);
      95          22 :                 W_ERROR_HAVE_NO_MEMORY(elements);
      96          84 :                 for (el = 0; local_parent->path.elements[el] != NULL; el++) {
      97          62 :                         elements[el] = talloc_reference(elements,
      98             :                                                         local_parent->path.elements[el]);
      99             :                 }
     100          22 :                 elements[el] = NULL;
     101             :         } else {
     102        7636 :                 elements = NULL;
     103        7636 :                 el = 0;
     104             :         }
     105             : 
     106        1963 :         do {
     107       18625 :                 if (curend != NULL)
     108       10056 :                         *curend = '\0';
     109       18625 :                 elements = talloc_realloc(mem_ctx, elements, const char *, el+2);
     110       18625 :                 W_ERROR_HAVE_NO_MEMORY(elements);
     111       18625 :                 elements[el] = talloc_strdup(elements, curbegin);
     112       18625 :                 W_ERROR_HAVE_NO_MEMORY(elements[el]);
     113       18625 :                 el++;
     114       18625 :                 elements[el] = NULL;
     115       18625 :                 error = hive_get_key_by_name(mem_ctx, curkey,
     116             :                                              curbegin, &curkey);
     117       18625 :                 if (!W_ERROR_IS_OK(error)) {
     118         326 :                         DEBUG(2, ("Opening key %s failed: %s\n", curbegin,
     119             :                                 win_errstr(error)));
     120         326 :                         talloc_free(orig);
     121         326 :                         return error;
     122             :                 }
     123       18299 :                 if (curend == NULL)
     124        7316 :                         break;
     125       10056 :                 curbegin = curend + 1;
     126       10056 :                 curend = strchr(curbegin, '\\');
     127       10056 :         } while (curbegin[0] != '\0');
     128        8243 :         talloc_free(orig);
     129             : 
     130       17413 :         *result = reg_import_hive_key(local_parent->global.context, curkey,
     131             :                                       local_parent->path.predefined_key,
     132        8243 :                                       talloc_steal(curkey, elements));
     133             : 
     134        8243 :         return WERR_OK;
     135             : }
     136             : 
     137       11692 : WERROR local_get_predefined_key(struct registry_context *ctx,
     138             :                                 uint32_t key_id, struct registry_key **key)
     139             : {
     140       11692 :         struct registry_local *rctx = talloc_get_type(ctx,
     141             :                                                       struct registry_local);
     142        1359 :         struct mountpoint *mp;
     143             : 
     144       12275 :         for (mp = rctx->mountpoints; mp != NULL; mp = mp->next) {
     145       12246 :                 if (mp->path.predefined_key == key_id &&
     146       11663 :                         mp->path.elements == NULL)
     147       10333 :                         break;
     148             :         }
     149             : 
     150       11692 :         if (mp == NULL)
     151          29 :                 return WERR_FILE_NOT_FOUND;
     152             : 
     153       11663 :         *key = reg_import_hive_key(ctx, mp->key,
     154             :                                    mp->path.predefined_key,
     155             :                                    mp->path.elements);
     156             : 
     157       11663 :         return WERR_OK;
     158             : }
     159             : 
     160         260 : static WERROR local_enum_key(TALLOC_CTX *mem_ctx,
     161             :                              const struct registry_key *key, uint32_t idx,
     162             :                              const char **name,
     163             :                              const char **keyclass,
     164             :                              NTTIME *last_changed_time)
     165             : {
     166         260 :         const struct local_key *local = (const struct local_key *)key;
     167             : 
     168         260 :         return hive_enum_key(mem_ctx, local->hive_key, idx, name, keyclass,
     169             :                              last_changed_time);
     170             : }
     171             : 
     172       12398 : static WERROR local_create_key(TALLOC_CTX *mem_ctx,
     173             :                                struct registry_key *parent,
     174             :                                const char *path,
     175             :                                const char *key_class,
     176             :                                struct security_descriptor *security,
     177             :                                struct registry_key **result)
     178             : {
     179        1254 :         char *orig, *curbegin, *curend;
     180       12398 :         struct local_key *local_parent = talloc_get_type(parent,
     181             :                                                          struct local_key);
     182       12398 :         struct hive_key *curkey = local_parent->hive_key;
     183        1254 :         WERROR error;
     184       12398 :         const char **elements = NULL;
     185        1254 :         int el;
     186             : 
     187       12398 :         if (path == NULL || path[0] == '\0') {
     188           0 :                 return WERR_INVALID_PARAMETER;
     189             :         }
     190             : 
     191       12398 :         orig = talloc_strdup(mem_ctx, path);
     192       12398 :         W_ERROR_HAVE_NO_MEMORY(orig);
     193       12398 :         curbegin = orig;
     194       12398 :         curend = strchr(orig, '\\');
     195             : 
     196       12398 :         if (local_parent->path.elements != NULL) {
     197        7609 :                 elements = talloc_array(mem_ctx, const char *,
     198             :                                         str_list_length(local_parent->path.elements) + 1);
     199        7609 :                 W_ERROR_HAVE_NO_MEMORY(elements);
     200       22433 :                 for (el = 0; local_parent->path.elements[el] != NULL; el++) {
     201       14824 :                         elements[el] = talloc_reference(elements,
     202             :                                                         local_parent->path.elements[el]);
     203             :                 }
     204        7609 :                 elements[el] = NULL;
     205             :         } else {
     206        4374 :                 elements = NULL;
     207        4374 :                 el = 0;
     208             :         }
     209             : 
     210        1255 :         do {
     211       14399 :                 if (curend != NULL)
     212        2001 :                         *curend = '\0';
     213       14399 :                 elements = talloc_realloc(mem_ctx, elements, const char *, el+2);
     214       14399 :                 W_ERROR_HAVE_NO_MEMORY(elements);
     215       14399 :                 elements[el] = talloc_strdup(elements, curbegin);
     216       14399 :                 W_ERROR_HAVE_NO_MEMORY(elements[el]);
     217       14399 :                 el++;
     218       14399 :                 elements[el] = NULL;
     219       14399 :                 error = hive_get_key_by_name(mem_ctx, curkey,
     220             :                                              curbegin, &curkey);
     221       14399 :                 if (W_ERROR_EQUAL(error, WERR_FILE_NOT_FOUND)) {
     222        4872 :                         error = hive_key_add_name(mem_ctx, curkey, curbegin,
     223             :                                                   key_class, security,
     224             :                                                   &curkey);
     225             :                 }
     226       14399 :                 if (!W_ERROR_IS_OK(error)) {
     227           0 :                         DEBUG(2, ("Open/Creation of key %s failed: %s\n",
     228             :                                 curbegin, win_errstr(error)));
     229           0 :                         talloc_free(orig);
     230           0 :                         return error;
     231             :                 }
     232       14399 :                 if (curend == NULL)
     233       11144 :                         break;
     234        2001 :                 curbegin = curend + 1;
     235        2001 :                 curend = strchr(curbegin, '\\');
     236        2001 :         } while (curbegin[0] != '\0');
     237       12398 :         talloc_free(orig);
     238             : 
     239       26050 :         *result = reg_import_hive_key(local_parent->global.context, curkey,
     240             :                                       local_parent->path.predefined_key,
     241       12398 :                                       talloc_steal(curkey, elements));
     242             : 
     243       12398 :         return WERR_OK;
     244             : }
     245             : 
     246        3028 : static WERROR local_set_value(struct registry_key *key, const char *name,
     247             :                               uint32_t type, const DATA_BLOB data)
     248             : {
     249        3028 :         struct local_key *local = (struct local_key *)key;
     250             : 
     251        3028 :         if (name == NULL) {
     252           0 :                 return WERR_INVALID_PARAMETER;
     253             :         }
     254             : 
     255        3028 :         return hive_key_set_value(local->hive_key, name, type, data);
     256             : }
     257             : 
     258        8165 : static WERROR local_get_value(TALLOC_CTX *mem_ctx,
     259             :                               const struct registry_key *key,
     260             :                               const char *name, uint32_t *type, DATA_BLOB *data)
     261             : {
     262        8165 :         const struct local_key *local = (const struct local_key *)key;
     263             : 
     264        8165 :         if (name == NULL) {
     265         240 :                 return WERR_INVALID_PARAMETER;
     266             :         }
     267             : 
     268        7925 :         return hive_get_value(mem_ctx, local->hive_key, name, type, data);
     269             : }
     270             : 
     271        2885 : static WERROR local_enum_value(TALLOC_CTX *mem_ctx,
     272             :                                const struct registry_key *key, uint32_t idx,
     273             :                                const char **name,
     274             :                                uint32_t *type,
     275             :                                DATA_BLOB *data)
     276             : {
     277        2885 :         const struct local_key *local = (const struct local_key *)key;
     278             : 
     279        2885 :         return hive_get_value_by_index(mem_ctx, local->hive_key, idx,
     280             :                                        name, type, data);
     281             : }
     282             : 
     283        2564 : static WERROR local_delete_key(TALLOC_CTX *mem_ctx, struct registry_key *key,
     284             :                                const char *name)
     285             : {
     286        2564 :         const struct local_key *local = (const struct local_key *)key;
     287             : 
     288        2564 :         if (name == NULL) {
     289           0 :                 return WERR_INVALID_PARAMETER;
     290             :         }
     291             : 
     292        2564 :         return hive_key_del(mem_ctx, local->hive_key, name);
     293             : }
     294             : 
     295        2403 : static WERROR local_delete_value(TALLOC_CTX *mem_ctx, struct registry_key *key,
     296             :                                  const char *name)
     297             : {
     298        2403 :         const struct local_key *local = (const struct local_key *)key;
     299             : 
     300        2403 :         if (name == NULL) {
     301           0 :                 return WERR_INVALID_PARAMETER;
     302             :         }
     303             : 
     304        2403 :         return hive_key_del_value(mem_ctx, local->hive_key, name);
     305             : }
     306             : 
     307         641 : static WERROR local_flush_key(struct registry_key *key)
     308             : {
     309         641 :         const struct local_key *local = (const struct local_key *)key;
     310             : 
     311         641 :         return hive_key_flush(local->hive_key);
     312             : }
     313             : 
     314         268 : static WERROR local_get_key_info(TALLOC_CTX *mem_ctx,
     315             :                                  const struct registry_key *key,
     316             :                                  const char **classname,
     317             :                                  uint32_t *num_subkeys,
     318             :                                  uint32_t *num_values,
     319             :                                  NTTIME *last_change_time,
     320             :                                  uint32_t *max_subkeynamelen,
     321             :                                  uint32_t *max_valnamelen,
     322             :                                  uint32_t *max_valbufsize)
     323             : {
     324         268 :         const struct local_key *local = (const struct local_key *)key;
     325             : 
     326         268 :         return hive_key_get_info(mem_ctx, local->hive_key,
     327             :                                  classname, num_subkeys, num_values,
     328             :                                  last_change_time, max_subkeynamelen, 
     329             :                                  max_valnamelen, max_valbufsize);
     330             : }
     331           0 : static WERROR local_get_sec_desc(TALLOC_CTX *mem_ctx, 
     332             :                                  const struct registry_key *key, 
     333             :                                  struct security_descriptor **security)
     334             : {
     335           0 :         const struct local_key *local = (const struct local_key *)key;
     336             : 
     337           0 :         return hive_get_sec_desc(mem_ctx, local->hive_key, security);
     338             : }
     339           1 : static WERROR local_set_sec_desc(struct registry_key *key, 
     340             :                                  const struct security_descriptor *security)
     341             : {
     342           1 :         const struct local_key *local = (const struct local_key *)key;
     343             : 
     344           1 :         return hive_set_sec_desc(local->hive_key, security);
     345             : }
     346             : const static struct registry_operations local_ops = {
     347             :         .name = "local",
     348             :         .open_key = local_open_key,
     349             :         .get_predefined_key = local_get_predefined_key,
     350             :         .enum_key = local_enum_key,
     351             :         .create_key = local_create_key,
     352             :         .set_value = local_set_value,
     353             :         .get_value = local_get_value,
     354             :         .enum_value = local_enum_value,
     355             :         .delete_key = local_delete_key,
     356             :         .delete_value = local_delete_value,
     357             :         .flush_key = local_flush_key,
     358             :         .get_key_info = local_get_key_info,
     359             :         .get_sec_desc = local_get_sec_desc,
     360             :         .set_sec_desc = local_set_sec_desc,
     361             : };
     362             : 
     363         534 : WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx)
     364             : {
     365         534 :         struct registry_local *ret = talloc_zero(mem_ctx,
     366             :                                                  struct registry_local);
     367             : 
     368         534 :         W_ERROR_HAVE_NO_MEMORY(ret);
     369             : 
     370         534 :         ret->ops = &local_ops;
     371             : 
     372         534 :         *ctx = (struct registry_context *)ret;
     373             : 
     374         534 :         return WERR_OK;
     375             : }
     376             : 
     377        1506 : WERROR reg_mount_hive(struct registry_context *rctx,
     378             :                       struct hive_key *hive_key,
     379             :                       uint32_t key_id,
     380             :                       const char **elements)
     381             : {
     382        1506 :         struct registry_local *reg_local = talloc_get_type(rctx,
     383             :                                                            struct registry_local);
     384          32 :         struct mountpoint *mp;
     385        1506 :         unsigned int i = 0;
     386             : 
     387        1506 :         mp = talloc(rctx, struct mountpoint);
     388        1506 :         W_ERROR_HAVE_NO_MEMORY(mp);
     389        1506 :         mp->path.predefined_key = key_id;
     390        1506 :         mp->prev = mp->next = NULL;
     391        1506 :         mp->key = hive_key;
     392        1506 :         if (elements != NULL && elements[0] != NULL) {
     393           0 :                 mp->path.elements = talloc_array(mp, const char *,
     394             :                                                  str_list_length(elements));
     395           0 :                 W_ERROR_HAVE_NO_MEMORY(mp->path.elements);
     396           0 :                 for (i = 0; elements[i] != NULL; i++) {
     397           0 :                         mp->path.elements[i] = talloc_reference(mp->path.elements,
     398             :                                                                 elements[i]);
     399             :                 }
     400           0 :                 mp->path.elements[i] = NULL;
     401             :         } else {
     402        1506 :                 mp->path.elements = NULL;
     403             :         }
     404             : 
     405        1506 :         DLIST_ADD(reg_local->mountpoints, mp);
     406             : 
     407        1506 :         return WERR_OK;
     408             : }

Generated by: LCOV version 1.14