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 26struct reg_key_path { 27 uint32_t predefined_key; 28 const char **elements; 29}; 30 31struct 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 41struct local_key { 42 struct registry_key global; 43 struct reg_key_path path; 44 struct hive_key *hive_key; 45}; 46 47 48struct 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 struct local_key *local_key; 54 struct reg_key_path parent_path; 55 56 parent_path.predefined_key = predefined_key; 57 parent_path.elements = elements; 58 59 local_key = talloc(ctx, struct local_key); 60 local_key->hive_key = talloc_steal(local_key, hive); 61 local_key->global.context = talloc_reference(local_key, ctx); 62 local_key->path = parent_path; 63 64 return (struct registry_key *)local_key; 65} 66 67 68static WERROR local_open_key(TALLOC_CTX *mem_ctx, 69 struct registry_key *parent, 70 const char *path, 71 struct registry_key **result) 72{ 73 char *orig = talloc_strdup(mem_ctx, path), 74 *curbegin = orig, 75 *curend = strchr(orig, '\\'); 76 struct local_key *local_parent = talloc_get_type(parent, 77 struct local_key); 78 struct hive_key *curkey = local_parent->hive_key; 79 WERROR error; 80 const char **elements = NULL; 81 int el; 82 83 if (local_parent->path.elements != NULL) { 84 elements = talloc_array(mem_ctx, const char *, 85 str_list_length(local_parent->path.elements) + 1); 86 for (el = 0; local_parent->path.elements[el] != NULL; el++) { 87 elements[el] = talloc_reference(elements, 88 local_parent->path.elements[el]); 89 } 90 elements[el] = NULL; 91 } else { 92 elements = NULL; 93 el = 0; 94 } 95 96 while (curbegin != NULL && *curbegin) { 97 if (curend != NULL) 98 *curend = '\0'; 99 elements = talloc_realloc(mem_ctx, elements, const char *, el+2); 100 elements[el] = talloc_strdup(elements, curbegin); 101 el++; 102 elements[el] = NULL; 103 error = hive_get_key_by_name(mem_ctx, curkey, 104 curbegin, &curkey); 105 if (!W_ERROR_IS_OK(error)) { 106 DEBUG(2, ("Opening key %s failed: %s\n", curbegin, 107 win_errstr(error))); 108 talloc_free(orig); 109 return error; 110 } 111 if (curend == NULL) 112 break; 113 curbegin = curend + 1; 114 curend = strchr(curbegin, '\\'); 115 } 116 talloc_free(orig); 117 118 *result = reg_import_hive_key(local_parent->global.context, curkey, 119 local_parent->path.predefined_key, 120 talloc_steal(curkey, elements)); 121 122 return WERR_OK; 123} 124 125WERROR local_get_predefined_key(struct registry_context *ctx, 126 uint32_t key_id, struct registry_key **key) 127{ 128 struct registry_local *rctx = talloc_get_type(ctx, 129 struct registry_local); 130 struct mountpoint *mp; 131 132 for (mp = rctx->mountpoints; mp != NULL; mp = mp->next) { 133 if (mp->path.predefined_key == key_id && 134 mp->path.elements == NULL) 135 break; 136 } 137 138 if (mp == NULL) 139 return WERR_BADFILE; 140 141 *key = reg_import_hive_key(ctx, mp->key, 142 mp->path.predefined_key, 143 mp->path.elements); 144 145 return WERR_OK; 146} 147 148static WERROR local_enum_key(TALLOC_CTX *mem_ctx, 149 const struct registry_key *key, uint32_t idx, 150 const char **name, 151 const char **keyclass, 152 NTTIME *last_changed_time) 153{ 154 const struct local_key *local = (const struct local_key *)key; 155 156 return hive_enum_key(mem_ctx, local->hive_key, idx, name, keyclass, 157 last_changed_time); 158} 159 160static WERROR local_create_key(TALLOC_CTX *mem_ctx, 161 struct registry_key *parent_key, 162 const char *name, 163 const char *key_class, 164 struct security_descriptor *security, 165 struct registry_key **key) 166{ 167 struct local_key *local_parent; 168 struct hive_key *hivekey; 169 const char **elements; 170 int i; 171 const char *last_part; 172 173 last_part = strrchr(name, '\\'); 174 if (last_part == NULL) { 175 last_part = name; 176 local_parent = (struct local_key *)parent_key; 177 } else { 178 W_ERROR_NOT_OK_RETURN(reg_open_key(mem_ctx, parent_key, 179 talloc_strndup(mem_ctx, name, last_part-name), 180 (struct registry_key **)&local_parent)); 181 last_part++; 182 } 183 184 W_ERROR_NOT_OK_RETURN(hive_key_add_name(mem_ctx, local_parent->hive_key, 185 last_part, key_class, security, 186 &hivekey)); 187 188 if (local_parent->path.elements != NULL) { 189 elements = talloc_array(hivekey, const char *, 190 str_list_length(local_parent->path.elements)+2); 191 for (i = 0; local_parent->path.elements[i] != NULL; i++) { 192 elements[i] = talloc_reference(elements, 193 local_parent->path.elements[i]); 194 } 195 } else { 196 elements = talloc_array(hivekey, const char *, 2); 197 i = 0; 198 } 199 200 elements[i] = talloc_strdup(elements, name); 201 elements[i+1] = NULL; 202 203 *key = reg_import_hive_key(local_parent->global.context, hivekey, 204 local_parent->path.predefined_key, 205 elements); 206 207 return WERR_OK; 208} 209 210static WERROR local_set_value(struct registry_key *key, const char *name, 211 uint32_t type, const DATA_BLOB data) 212{ 213 struct local_key *local = (struct local_key *)key; 214 215 return hive_key_set_value(local->hive_key, name, type, data); 216} 217 218static WERROR local_get_value(TALLOC_CTX *mem_ctx, 219 const struct registry_key *key, 220 const char *name, uint32_t *type, DATA_BLOB *data) 221{ 222 const struct local_key *local = (const struct local_key *)key; 223 224 return hive_get_value(mem_ctx, local->hive_key, name, type, data); 225} 226 227static WERROR local_enum_value(TALLOC_CTX *mem_ctx, 228 const struct registry_key *key, uint32_t idx, 229 const char **name, 230 uint32_t *type, 231 DATA_BLOB *data) 232{ 233 const struct local_key *local = (const struct local_key *)key; 234 235 return hive_get_value_by_index(mem_ctx, local->hive_key, idx, 236 name, type, data); 237} 238 239static WERROR local_delete_key(struct registry_key *key, const char *name) 240{ 241 const struct local_key *local = (const struct local_key *)key; 242 243 return hive_key_del(local->hive_key, name); 244} 245 246static WERROR local_delete_value(struct registry_key *key, const char *name) 247{ 248 const struct local_key *local = (const struct local_key *)key; 249 250 return hive_key_del_value(local->hive_key, name); 251} 252 253static WERROR local_flush_key(struct registry_key *key) 254{ 255 const struct local_key *local = (const struct local_key *)key; 256 257 return hive_key_flush(local->hive_key); 258} 259 260static WERROR local_get_key_info(TALLOC_CTX *mem_ctx, 261 const struct registry_key *key, 262 const char **classname, 263 uint32_t *num_subkeys, 264 uint32_t *num_values, 265 NTTIME *last_change_time, 266 uint32_t *max_subkeynamelen, 267 uint32_t *max_valnamelen, 268 uint32_t *max_valbufsize) 269{ 270 const struct local_key *local = (const struct local_key *)key; 271 272 return hive_key_get_info(mem_ctx, local->hive_key, 273 classname, num_subkeys, num_values, 274 last_change_time, max_subkeynamelen, 275 max_valnamelen, max_valbufsize); 276} 277static WERROR local_get_sec_desc(TALLOC_CTX *mem_ctx, 278 const struct registry_key *key, 279 struct security_descriptor **security) 280{ 281 const struct local_key *local = (const struct local_key *)key; 282 283 return hive_get_sec_desc(mem_ctx, local->hive_key, security); 284} 285static WERROR local_set_sec_desc(struct registry_key *key, 286 const struct security_descriptor *security) 287{ 288 const struct local_key *local = (const struct local_key *)key; 289 290 return hive_set_sec_desc(local->hive_key, security); 291} 292const static struct registry_operations local_ops = { 293 .name = "local", 294 .open_key = local_open_key, 295 .get_predefined_key = local_get_predefined_key, 296 .enum_key = local_enum_key, 297 .create_key = local_create_key, 298 .set_value = local_set_value, 299 .get_value = local_get_value, 300 .enum_value = local_enum_value, 301 .delete_key = local_delete_key, 302 .delete_value = local_delete_value, 303 .flush_key = local_flush_key, 304 .get_key_info = local_get_key_info, 305 .get_sec_desc = local_get_sec_desc, 306 .set_sec_desc = local_set_sec_desc, 307}; 308 309WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx) 310{ 311 struct registry_local *ret = talloc_zero(mem_ctx, 312 struct registry_local); 313 314 W_ERROR_HAVE_NO_MEMORY(ret); 315 316 ret->ops = &local_ops; 317 318 *ctx = (struct registry_context *)ret; 319 320 return WERR_OK; 321} 322 323WERROR reg_mount_hive(struct registry_context *rctx, 324 struct hive_key *hive_key, 325 uint32_t key_id, 326 const char **elements) 327{ 328 struct registry_local *reg_local = talloc_get_type(rctx, 329 struct registry_local); 330 struct mountpoint *mp = talloc(rctx, struct mountpoint); 331 int i = 0; 332 333 mp->path.predefined_key = key_id; 334 mp->prev = mp->next = NULL; 335 mp->key = hive_key; 336 if (elements != NULL && str_list_length(elements) != 0) { 337 mp->path.elements = talloc_array(mp, const char *, 338 str_list_length(elements)); 339 for (i = 0; elements[i] != NULL; i++) { 340 mp->path.elements[i] = talloc_reference(mp->path.elements, 341 elements[i]); 342 } 343 mp->path.elements[i] = NULL; 344 } else { 345 mp->path.elements = NULL; 346 } 347 348 DLIST_ADD(reg_local->mountpoints, mp); 349 350 return WERR_OK; 351} 352