LCOV - code coverage report
Current view: top level - source3/registry - reg_import.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 59 118 50.0 %
Date: 2024-04-21 15:09:00 Functions: 5 11 45.5 %

          Line data    Source code
       1             : /*
       2             :  * Samba Unix/Linux SMB client library
       3             :  * Adapter to use reg_parse with the registry api
       4             :  *
       5             :  * Copyright (C) Gregor Beck 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             : #include "includes.h"
      22             : #include "reg_parse.h"
      23             : #include "reg_import.h"
      24             : #include "registry.h"
      25             : #include "registry/reg_objects.h"
      26             : #include <assert.h>
      27             : 
      28             : /* Debuglevel for tracing */
      29             : static const int TL = 2;
      30             : 
      31             : struct reg_import {
      32             :         struct reg_parse_callback reg_parse_callback;
      33             :         struct reg_import_callback call;
      34             :         void *open_key;
      35             : };
      36             : 
      37             : static int reg_parse_callback_key(struct reg_import *cb_private,
      38             :                                   const char *key[], size_t n, bool del);
      39             : 
      40             : static int reg_parse_callback_val(struct reg_import *cb_private,
      41             :                                   const char *name, uint32_t type,
      42             :                                   const uint8_t *data, size_t len);
      43             : 
      44             : static int reg_parse_callback_val_registry_value(struct reg_import *cb_private,
      45             :                                                  const char *name,
      46             :                                                  uint32_t type,
      47             :                                                  const uint8_t *data,
      48             :                                                  size_t len);
      49             : 
      50             : static int reg_parse_callback_val_regval_blob(struct reg_import *cb_private,
      51             :                                               const char *name, uint32_t type,
      52             :                                               const uint8_t *data,
      53             :                                               size_t len);
      54             : 
      55             : static int reg_parse_callback_val_del(struct reg_import *cb_private,
      56             :                                       const char *name);
      57             : 
      58             : static int reg_parse_callback_comment(struct reg_import *cb_private,
      59             :                                       const char *txt);
      60             : 
      61             : 
      62             : /*******************************************************************************/
      63             : 
      64         250 : int reg_parse_callback_key(struct reg_import *p,
      65             :                            const char *key[], size_t n, bool del)
      66             : {
      67         250 :         WERROR werr = WERR_OK;
      68             : 
      69         250 :         DEBUG(TL, ("%s: %s\n", __FUNCTION__, key[0]));
      70             : 
      71         250 :         if (p->open_key != NULL) {
      72         244 :                 werr = p->call.closekey(p->call.data, p->open_key);
      73         244 :                 p->open_key = NULL;
      74         244 :                 if (!W_ERROR_IS_OK(werr)) {
      75           0 :                         DEBUG(0, ("closekey failed: %s\n", win_errstr(werr)));
      76             :                 }
      77             :         }
      78             : 
      79         250 :         if (del) {
      80           0 :                 werr = p->call.deletekey(p->call.data, NULL, key[0]);
      81           0 :                 if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
      82             :                         /* the key didn't exist, treat as success */
      83           0 :                         werr = WERR_OK;
      84             :                 }
      85           0 :                 if (!W_ERROR_IS_OK(werr)) {
      86           0 :                         DEBUG(0, ("deletekey %s failed: %s\n",
      87             :                                   key[0], win_errstr(werr)));
      88             :                 }
      89             :         } else {
      90           0 :                 bool existing;
      91         250 :                 werr = p->call.createkey(p->call.data, NULL, key[0],
      92             :                                          &p->open_key, &existing);
      93         250 :                 if (W_ERROR_IS_OK(werr)) {
      94         250 :                         DEBUG(TL, ("createkey %s %s\n",
      95             :                                   existing ? "opened" : "created", key[0]));
      96             :                 } else {
      97           0 :                         DEBUG(0, ("createkey %s failed: %s\n",
      98             :                                   key[0], win_errstr(werr)));
      99             :                 }
     100             :         }
     101             : 
     102         250 :         return W_ERROR_IS_OK(werr) ? 0 : -1;
     103             : }
     104             : 
     105             : #define DEBUG_ADD_HEX(LEV, PTR, LEN)                                    \
     106             :         do {                                                            \
     107             :                 int i;                                                  \
     108             :                 const unsigned char* ptr = (const unsigned char*)PTR;   \
     109             :                 for (i=0; i<LEN; i++) {                                      \
     110             :                         DEBUGADD(LEV, ("'%c'(%02x)%s",                        \
     111             :                                        isprint(ptr[i]) ? ptr[i] : '.',  \
     112             :                                        (unsigned)ptr[i],                \
     113             :                                        ((i+1 < LEN) && (i+1)%8)              \
     114             :                                        ? ",  " : "\n"));            \
     115             :                 }                                                       \
     116             :         } while(0)
     117             : 
     118             : /*----------------------------------------------------------------------------*/
     119          50 : int reg_parse_callback_val(struct reg_import *p,
     120             :                            const char *name, uint32_t type,
     121             :                            const uint8_t *data, size_t len)
     122             : {
     123          50 :         WERROR werr = WERR_OK;
     124             : 
     125          50 :         DEBUG(TL, ("%s(%x): >%s< = [%zx]\n",  __FUNCTION__, type, name, len));
     126        3818 :         DEBUG_ADD_HEX(TL, data, len);
     127             : 
     128          50 :         werr = p->call.setval.blob(p->call.data, p->open_key, name, type,
     129             :                                    data, len);
     130          50 :         if (!W_ERROR_IS_OK(werr)) {
     131           2 :                 DEBUG(0, ("setval %s failed: %s\n",
     132             :                           name, win_errstr(werr)));
     133             :         }
     134             : 
     135          50 :         return W_ERROR_IS_OK(werr) ? 0 : -1;
     136             : }
     137             : 
     138             : /*----------------------------------------------------------------------------*/
     139        1086 : int reg_parse_callback_val_registry_value(struct reg_import *p,
     140             :                                           const char *name, uint32_t type,
     141             :                                           const uint8_t *data, size_t len)
     142             : {
     143        1086 :         WERROR werr = WERR_OK;
     144        1086 :         struct registry_value val = {
     145             :                 .type = type,
     146        1086 :                 .data = data_blob_talloc(p, data, len),
     147             :         };
     148             : 
     149        1086 :         DEBUG(TL, ("%s(%x): >%s< = [%zx]\n", __FUNCTION__, type, name, len));
     150       66472 :         DEBUG_ADD_HEX(TL, data, len);
     151             : 
     152        1086 :         werr = p->call.setval.registry_value(p->call.data, p->open_key,
     153             :                                              name, &val);
     154        1086 :         if (!W_ERROR_IS_OK(werr)) {
     155           0 :                 DEBUG(0, ("setval %s failed: %s\n",
     156             :                           name, win_errstr(werr)));
     157             :         }
     158             : 
     159        1086 :         data_blob_free(&val.data);
     160        1086 :         return W_ERROR_IS_OK(werr) ? 0 : -1;
     161             : }
     162             : 
     163             : /*----------------------------------------------------------------------------*/
     164           0 : int reg_parse_callback_val_regval_blob(struct reg_import *p,
     165             :                                        const char *name, uint32_t type,
     166             :                                        const uint8_t *data, size_t len)
     167             : {
     168           0 :         WERROR werr = WERR_OK;
     169           0 :         void* mem_ctx = talloc_new(p);
     170           0 :         struct regval_blob *v = NULL;
     171             : 
     172           0 :         DEBUG(TL, ("%s(%x): >%s< = [%zx]\n", __FUNCTION__, type, name, len));
     173           0 :         DEBUG_ADD_HEX(TL, data, len);
     174             : 
     175           0 :         v = regval_compose(mem_ctx, name, type, data, len);
     176           0 :         if (v == NULL) {
     177           0 :                 DEBUG(0, ("regval_compose %s failed\n", name));
     178           0 :                 werr = WERR_NOT_ENOUGH_MEMORY;
     179           0 :                 goto done;
     180             :         }
     181             : 
     182           0 :         werr = p->call.setval.regval_blob(p->call.data, p->open_key, v);
     183           0 :         if (!W_ERROR_IS_OK(werr)) {
     184           0 :                 DEBUG(0, ("setval %s failed: %s\n",
     185             :                           name, win_errstr(werr)));
     186             :         }
     187             : 
     188           0 : done:
     189           0 :         talloc_free(mem_ctx);
     190             : 
     191           0 :         return W_ERROR_IS_OK(werr) ? 0 : -1;
     192             : }
     193             : 
     194             : 
     195             : /*----------------------------------------------------------------------------*/
     196             : 
     197           0 : int reg_parse_callback_val_del(struct reg_import *p,
     198             :                                const char *name)
     199             : {
     200           0 :         WERROR werr = WERR_OK;
     201             : 
     202           0 :         DEBUG(TL, ("%s: %s\n", __FUNCTION__, name));
     203             : 
     204           0 :         werr = p->call.deleteval(p->call.data, p->open_key, name);
     205           0 :         if (!W_ERROR_IS_OK(werr)) {
     206           0 :                 DEBUG(0, ("deleteval %s failed: %s\n",
     207             :                           name, win_errstr(werr)));
     208             :         }
     209             : 
     210           0 :         return W_ERROR_IS_OK(werr) ? 0 : -1;
     211             : }
     212             : 
     213             : 
     214           8 : int reg_parse_callback_comment(struct reg_import *cb_private,
     215             :                                const char *txt)
     216             : {
     217           8 :         DEBUG(TL, ("%s: %s\n", __FUNCTION__, txt));
     218           8 :         return 0;
     219             : }
     220             : 
     221             : /******************************************************************************/
     222           0 : static WERROR nop_callback_open(void* private_data,
     223             :                 void* parent,
     224             :                 const char* name,
     225             :                 void** key)
     226             : {
     227           0 :         return WERR_OK;
     228             : }
     229             : 
     230           0 : static WERROR nop_callback_close(void* private_data, void* key)
     231             : {
     232           0 :         return WERR_OK;
     233             : }
     234             : 
     235           0 : static WERROR nop_callback_create(void* private_data,
     236             :                 void* parent,
     237             :                 const char* name,
     238             :                 void** key,
     239             :                 bool* existing)
     240             : {
     241           0 :         return WERR_OK;
     242             : }
     243             : 
     244             : 
     245           0 : static WERROR nop_callback_del(void* private_data,
     246             :                 void* parent,
     247             :                 const char* name)
     248             : {
     249           0 :         return WERR_OK;
     250             : }
     251             : 
     252          10 : struct reg_parse_callback *reg_import_adapter(TALLOC_CTX *talloc_ctx,
     253             :                                               struct reg_import_callback cb)
     254             : {
     255           0 :         struct reg_parse_callback *ret;
     256          10 :         struct reg_import *p = talloc_zero(talloc_ctx, struct reg_import);
     257          10 :         if (p == NULL) {
     258           0 :                 goto fail;
     259             :         }
     260          10 :         if (cb.openkey == NULL) {
     261          10 :                 cb.openkey = (reg_import_callback_openkey_t)&nop_callback_open;
     262             :         }
     263          10 :         if (cb.closekey == NULL) {
     264           0 :                 cb.closekey =
     265             :                         (reg_import_callback_closekey_t)&nop_callback_close;
     266             :         }
     267          10 :         if (cb.createkey == NULL) {
     268           0 :                 cb.createkey =
     269             :                         (reg_import_callback_createkey_t)&nop_callback_create;
     270             :         }
     271          10 :         if (cb.deletekey == NULL) {
     272           0 :                 cb.deletekey =
     273             :                         (reg_import_callback_deletekey_t)&nop_callback_del;
     274             : 
     275             :         }
     276          10 :         if (cb.deleteval == NULL) {
     277           0 :                 cb.deleteval =
     278             :                         (reg_import_callback_deleteval_t)&nop_callback_del;
     279             :         }
     280             : 
     281          10 :         p->call = cb;
     282             : 
     283          10 :         ret = &p->reg_parse_callback;
     284          10 :         ret->key     = (reg_parse_callback_key_t)     &reg_parse_callback_key;
     285          10 :         ret->val_del = (reg_parse_callback_val_del_t) &reg_parse_callback_val_del;
     286          10 :         ret->comment = (reg_parse_callback_comment_t) &reg_parse_callback_comment;
     287          10 :         ret->data = p;
     288             : 
     289          10 :         switch (cb.setval_type) {
     290           8 :         case BLOB:
     291           8 :                 assert(cb.setval.blob != NULL);
     292           8 :                 ret->val = (reg_parse_callback_val_t) &reg_parse_callback_val;
     293           8 :                 break;
     294           2 :         case REGISTRY_VALUE:
     295           2 :                 assert(cb.setval.registry_value != NULL);
     296           2 :                 ret->val = (reg_parse_callback_val_t) &reg_parse_callback_val_registry_value;
     297           2 :                 break;
     298           0 :         case REGVAL_BLOB:
     299           0 :                 assert(cb.setval.regval_blob != NULL);
     300           0 :                 ret->val = (reg_parse_callback_val_t) &reg_parse_callback_val_regval_blob;
     301           0 :                 break;
     302           0 :         case NONE:
     303           0 :                 ret->val = NULL;
     304           0 :                 break;
     305           0 :         default:
     306           0 :                 assert(false);
     307             :         }
     308             : 
     309          10 :         assert((struct reg_parse_callback *)p == ret);
     310          10 :         return ret;
     311           0 : fail:
     312           0 :         talloc_free(p);
     313           0 :         return NULL;
     314             : }

Generated by: LCOV version 1.14