root/source4/lib/registry/util.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. str_regtype
  2. reg_val_data_string
  3. reg_val_description
  4. reg_string_to_val
  5. reg_open_key_abs
  6. get_abs_parent
  7. reg_key_del_abs
  8. reg_key_add_abs

   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, see <http://www.gnu.org/licenses/>.
  18 */
  19 
  20 #include "includes.h"
  21 #include "lib/registry/registry.h"
  22 #include "librpc/gen_ndr/winreg.h"
  23 
  24 /**
  25  * @file
  26  * @brief Registry utility functions
  27  */
  28 
  29 static const struct {
  30         uint32_t id;
  31         const char *name;
  32 } reg_value_types[] = {
  33         { REG_SZ, "REG_SZ" },
  34         { REG_DWORD, "REG_DWORD" },
  35         { REG_BINARY, "REG_BINARY" },
  36         { REG_EXPAND_SZ, "REG_EXPAND_SZ" },
  37         { REG_NONE, "REG_NONE" },
  38         { 0, NULL }
  39 };
  40 
  41 /** Return string description of registry value type */
  42 _PUBLIC_ const char *str_regtype(int type)
     /* [<][>][^][v][top][bottom][index][help] */
  43 {
  44         int i;
  45         for (i = 0; reg_value_types[i].name; i++) {
  46                 if (reg_value_types[i].id == type)
  47                         return reg_value_types[i].name;
  48         }
  49 
  50         return "Unknown";
  51 }
  52 
  53 _PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, 
     /* [<][>][^][v][top][bottom][index][help] */
  54                                    struct smb_iconv_convenience *iconv_convenience,
  55                                    uint32_t type,
  56                                    const DATA_BLOB data)
  57 {
  58         char *ret = NULL;
  59 
  60         if (data.length == 0)
  61                 return talloc_strdup(mem_ctx, "");
  62 
  63         switch (type) {
  64                 case REG_EXPAND_SZ:
  65                 case REG_SZ:
  66                         convert_string_talloc_convenience(mem_ctx, iconv_convenience, CH_UTF16, CH_UNIX,
  67                                               data.data, data.length,
  68                                               (void **)&ret, NULL, false);
  69                         return ret;
  70                 case REG_BINARY:
  71                         ret = data_blob_hex_string(mem_ctx, &data);
  72                         return ret;
  73                 case REG_DWORD:
  74                         if (*(int *)data.data == 0)
  75                                 return talloc_strdup(mem_ctx, "0");
  76                         return talloc_asprintf(mem_ctx, "0x%x",
  77                                                *(int *)data.data);
  78                 case REG_MULTI_SZ:
  79                         /* FIXME */
  80                         break;
  81                 default:
  82                         break;
  83         }
  84 
  85         return ret;
  86 }
  87 
  88 /** Generate a string that describes a registry value */
  89 _PUBLIC_ char *reg_val_description(TALLOC_CTX *mem_ctx, 
     /* [<][>][^][v][top][bottom][index][help] */
  90                                    struct smb_iconv_convenience *iconv_convenience, 
  91                                    const char *name,
  92                                    uint32_t data_type,
  93                                    const DATA_BLOB data)
  94 {
  95         return talloc_asprintf(mem_ctx, "%s = %s : %s", name?name:"<No Name>",
  96                                str_regtype(data_type),
  97                                reg_val_data_string(mem_ctx, iconv_convenience, data_type, data));
  98 }
  99 
 100 _PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, 
     /* [<][>][^][v][top][bottom][index][help] */
 101                                 struct smb_iconv_convenience *iconv_convenience,
 102                                 const char *type_str,
 103                                 const char *data_str, uint32_t *type,
 104                                 DATA_BLOB *data)
 105 {
 106         int i;
 107         *type = -1;
 108 
 109         /* Find the correct type */
 110         for (i = 0; reg_value_types[i].name; i++) {
 111                 if (!strcmp(reg_value_types[i].name, type_str)) {
 112                         *type = reg_value_types[i].id;
 113                         break;
 114                 }
 115         }
 116 
 117         if (*type == -1)
 118                 return false;
 119 
 120         /* Convert data appropriately */
 121 
 122         switch (*type)
 123         {
 124                 case REG_SZ:
 125                 case REG_EXPAND_SZ:
 126                 convert_string_talloc_convenience(mem_ctx, iconv_convenience, CH_UNIX, CH_UTF16,
 127                                                      data_str, strlen(data_str),
 128                                                      (void **)&data->data, &data->length, false);
 129                         break;
 130 
 131                 case REG_DWORD: {
 132                         uint32_t tmp = strtol(data_str, NULL, 0);
 133                         *data = data_blob_talloc(mem_ctx, &tmp, 4);
 134                         }
 135                         break;
 136 
 137                 case REG_NONE:
 138                         ZERO_STRUCTP(data);
 139                         break;
 140 
 141                 case REG_BINARY:
 142                         *data = strhex_to_data_blob(mem_ctx, data_str);
 143                         break;
 144 
 145                 default:
 146                         /* FIXME */
 147                         return false;
 148         }
 149         return true;
 150 }
 151 
 152 /** Open a key by name (including the predefined key name!) */
 153 WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle,
     /* [<][>][^][v][top][bottom][index][help] */
 154                         const char *name, struct registry_key **result)
 155 {
 156         struct registry_key *predef;
 157         WERROR error;
 158         int predeflength;
 159         char *predefname;
 160 
 161         if (strchr(name, '\\') != NULL)
 162                 predeflength = strchr(name, '\\')-name;
 163         else
 164                 predeflength = strlen(name);
 165 
 166         predefname = talloc_strndup(mem_ctx, name, predeflength);
 167         error = reg_get_predefined_key_by_name(handle, predefname, &predef);
 168         talloc_free(predefname);
 169 
 170         if (!W_ERROR_IS_OK(error)) {
 171                 return error;
 172         }
 173 
 174         if (strchr(name, '\\')) {
 175                 return reg_open_key(mem_ctx, predef, strchr(name, '\\')+1,
 176                                     result);
 177         } else {
 178                 *result = predef;
 179                 return WERR_OK;
 180         }
 181 }
 182 
 183 static WERROR get_abs_parent(TALLOC_CTX *mem_ctx, struct registry_context *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 184                              const char *path, struct registry_key **parent,
 185                              const char **name)
 186 {
 187         char *parent_name;
 188         WERROR error;
 189 
 190         if (strchr(path, '\\') == NULL) {
 191                 return WERR_FOOBAR;
 192         }
 193 
 194         parent_name = talloc_strndup(mem_ctx, path, strrchr(path, '\\')-path);
 195 
 196         error = reg_open_key_abs(mem_ctx, ctx, parent_name, parent);
 197         if (!W_ERROR_IS_OK(error)) {
 198                 return error;
 199         }
 200 
 201         *name = talloc_strdup(mem_ctx, strrchr(path, '\\')+1);
 202 
 203         return WERR_OK;
 204 }
 205 
 206 WERROR reg_key_del_abs(struct registry_context *ctx, const char *path)
     /* [<][>][^][v][top][bottom][index][help] */
 207 {
 208         struct registry_key *parent;
 209         const char *n;
 210         TALLOC_CTX *mem_ctx = talloc_init("reg_key_del_abs");
 211         WERROR error;
 212 
 213         if (!strchr(path, '\\')) {
 214                 return WERR_FOOBAR;
 215         }
 216 
 217         error = get_abs_parent(mem_ctx, ctx, path, &parent, &n);
 218         if (W_ERROR_IS_OK(error)) {
 219                 error = reg_key_del(parent, n);
 220         }
 221 
 222         talloc_free(mem_ctx);
 223 
 224         return error;
 225 }
 226 
 227 WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 228                        const char *path, uint32_t access_mask,
 229                        struct security_descriptor *sec_desc,
 230                        struct registry_key **result)
 231 {
 232         struct registry_key *parent;
 233         const char *n;
 234         WERROR error;
 235 
 236         if (!strchr(path, '\\')) {
 237                 return WERR_ALREADY_EXISTS;
 238         }
 239 
 240         error = get_abs_parent(mem_ctx, ctx, path, &parent, &n);
 241         if (!W_ERROR_IS_OK(error)) {
 242                 DEBUG(2, ("Opening parent of %s failed with %s\n", path,
 243                                   win_errstr(error)));
 244                 return error;
 245         }
 246 
 247         error = reg_key_add_name(mem_ctx, parent, n, NULL, sec_desc, result);
 248 
 249         return error;
 250 }

/* [<][>][^][v][top][bottom][index][help] */