Changeset 745 for trunk/server/source3/libgpo/gpext/registry.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/libgpo/gpext/registry.c
r414 r745 2 2 * Unix SMB/CIFS implementation. 3 3 * Group Policy Support 4 * Copyright (C) Guenther Deschner 2007-2008 4 * Copyright (C) Guenther Deschner 2007-2008,2010 5 5 * 6 6 * This program is free software; you can redistribute it and/or modify … … 20 20 #include "includes.h" 21 21 #include "../libgpo/gpo_ini.h" 22 #include "../libgpo/gpo.h" 23 #include "libgpo/gpo_proto.h" 24 #include "registry.h" 25 #include "../librpc/gen_ndr/ndr_preg.h" 22 26 23 27 #define GP_EXT_NAME "registry" … … 33 37 static TALLOC_CTX *ctx = NULL; 34 38 35 struct gp_registry_file_header {36 uint32_t signature;37 uint32_t version;38 };39 40 struct gp_registry_file_entry {41 UNISTR key;42 UNISTR value;43 enum winreg_Type type;44 size_t size;45 uint8_t *data;46 };47 48 struct gp_registry_file {49 struct gp_registry_file_header header;50 size_t num_entries;51 struct gp_registry_entry *entries;52 };53 54 /****************************************************************55 ****************************************************************/56 57 static bool reg_parse_header(const char *desc,58 struct gp_registry_file_header *header,59 prs_struct *ps,60 int depth)61 {62 if (!header)63 return false;64 65 prs_debug(ps, depth, desc, "reg_parse_header");66 depth++;67 68 if (!prs_uint32("signature", ps, depth, &header->signature))69 return false;70 71 if (!prs_uint32("version", ps, depth, &header->version))72 return false;73 74 return true;75 }76 77 /****************************************************************78 ****************************************************************/79 80 static bool reg_parse_and_verify_ucs2_char(const char *desc,81 char character,82 prs_struct *ps,83 int depth)84 {85 uint16_t tmp;86 87 if (!prs_uint16(desc, ps, depth, &tmp))88 return false;89 90 if (tmp != UCS2_CHAR(character))91 return false;92 93 return true;94 }95 96 /****************************************************************97 ****************************************************************/98 99 static bool reg_parse_init(prs_struct *ps, int depth)100 {101 return reg_parse_and_verify_ucs2_char("initiator '['", '[',102 ps, depth);103 }104 105 /****************************************************************106 ****************************************************************/107 108 static bool reg_parse_sep(prs_struct *ps, int depth)109 {110 return reg_parse_and_verify_ucs2_char("separator ';'", ';',111 ps, depth);112 }113 114 /****************************************************************115 ****************************************************************/116 117 static bool reg_parse_term(prs_struct *ps, int depth)118 {119 return reg_parse_and_verify_ucs2_char("terminator ']'", ']',120 ps, depth);121 }122 123 124 /****************************************************************125 * [key;value;type;size;data]126 ****************************************************************/127 128 static bool reg_parse_entry(TALLOC_CTX *mem_ctx,129 const char *desc,130 struct gp_registry_file_entry *entry,131 prs_struct *ps,132 int depth)133 {134 uint32_t size = 0;135 136 if (!entry)137 return false;138 139 prs_debug(ps, depth, desc, "reg_parse_entry");140 depth++;141 142 ZERO_STRUCTP(entry);143 144 if (!reg_parse_init(ps, depth))145 return false;146 147 if (!prs_unistr("key", ps, depth, &entry->key))148 return false;149 150 if (!reg_parse_sep(ps, depth))151 return false;152 153 if (!prs_unistr("value", ps, depth, &entry->value))154 return false;155 156 if (!reg_parse_sep(ps, depth))157 return false;158 159 if (!prs_uint32("type", ps, depth, &entry->type))160 return false;161 162 if (!reg_parse_sep(ps, depth))163 return false;164 165 if (!prs_uint32("size", ps, depth, &size))166 return false;167 168 entry->size = size;169 170 if (!reg_parse_sep(ps, depth))171 return false;172 173 if (entry->size) {174 entry->data = TALLOC_ZERO_ARRAY(mem_ctx, uint8, entry->size);175 if (!entry->data)176 return false;177 }178 179 if (!prs_uint8s(false, "data", ps, depth, entry->data, entry->size))180 return false;181 182 if (!reg_parse_term(ps, depth))183 return false;184 185 return true;186 }187 188 39 /**************************************************************** 189 40 ****************************************************************/ 190 41 191 42 static bool reg_parse_value(TALLOC_CTX *mem_ctx, 192 c har **value,43 const char **value, 193 44 enum gp_reg_action *action) 194 45 { … … 252 103 253 104 static bool gp_reg_entry_from_file_entry(TALLOC_CTX *mem_ctx, 254 struct gp_registry_file_entry *file_entry,105 struct preg_entry *r, 255 106 struct gp_registry_entry **reg_entry) 256 107 { 257 108 struct registry_value *data = NULL; 258 109 struct gp_registry_entry *entry = NULL; 259 char *key = NULL;260 char *value = NULL;261 110 enum gp_reg_action action = GP_REG_ACTION_NONE; 262 size_t converted_size;263 111 264 112 ZERO_STRUCTP(*reg_entry); … … 268 116 return false; 269 117 270 if (strlen_w((const smb_ucs2_t *)file_entry->key.buffer) <= 0) 271 return false; 272 273 if (!pull_ucs2_talloc(mem_ctx, &key, file_entry->key.buffer, 274 &converted_size)) 275 { 276 return false; 277 } 278 279 if (strlen_w((const smb_ucs2_t *)file_entry->value.buffer) > 0 && 280 !pull_ucs2_talloc(mem_ctx, &value, file_entry->value.buffer, 281 &converted_size)) 282 { 283 return false; 284 } 285 286 if (!reg_parse_value(mem_ctx, &value, &action)) 287 return false; 288 289 data->type = file_entry->type; 290 291 switch (data->type) { 292 case REG_DWORD: 293 data->v.dword = atoi((char *)file_entry->data); 294 break; 295 case REG_BINARY: 296 data->v.binary = data_blob_talloc(mem_ctx, 297 file_entry->data, 298 file_entry->size); 299 break; 300 case REG_NONE: 301 break; 302 case REG_SZ: 303 if (!pull_ucs2_talloc(mem_ctx, &data->v.sz.str, 304 (const smb_ucs2_t *) 305 file_entry->data, 306 &data->v.sz.len)) { 307 data->v.sz.len = -1; 308 } 309 310 break; 311 case REG_DWORD_BIG_ENDIAN: 312 case REG_EXPAND_SZ: 313 case REG_LINK: 314 case REG_MULTI_SZ: 315 case REG_QWORD: 316 /* case REG_DWORD_LITTLE_ENDIAN: */ 317 /* case REG_QWORD_LITTLE_ENDIAN: */ 318 printf("not yet implemented: %d\n", data->type); 319 return false; 320 default: 321 printf("invalid reg type defined: %d\n", data->type); 322 return false; 323 324 } 118 data->type = r->type; 119 data->data = data_blob_talloc(data, r->data, r->size); 325 120 326 121 entry = TALLOC_ZERO_P(mem_ctx, struct gp_registry_entry); … … 328 123 return false; 329 124 330 entry->key = key; 331 entry->value = value; 125 if (!reg_parse_value(mem_ctx, &r->valuename, &action)) 126 return false; 127 128 entry->key = talloc_strdup(entry, r->keyname); 129 entry->value = talloc_strdup(entry, r->valuename); 332 130 entry->data = data; 333 131 entry->action = action; 334 132 335 133 *reg_entry = entry; 336 337 return true;338 }339 340 /****************************************************************341 * [key;value;type;size;data][key;value;type;size;data]...342 ****************************************************************/343 344 static bool reg_parse_entries(TALLOC_CTX *mem_ctx,345 const char *desc,346 struct gp_registry_entry **entries,347 size_t *num_entries,348 prs_struct *ps,349 int depth)350 {351 352 if (!entries || !num_entries)353 return false;354 355 prs_debug(ps, depth, desc, "reg_parse_entries");356 depth++;357 358 *entries = NULL;359 *num_entries = 0;360 361 while (ps->buffer_size > ps->data_offset) {362 363 struct gp_registry_file_entry f_entry;364 struct gp_registry_entry *r_entry = NULL;365 366 if (!reg_parse_entry(mem_ctx, desc, &f_entry,367 ps, depth))368 return false;369 370 if (!gp_reg_entry_from_file_entry(mem_ctx,371 &f_entry,372 &r_entry))373 return false;374 375 if (!add_gp_registry_entry_to_array(mem_ctx,376 r_entry,377 entries,378 num_entries))379 return false;380 }381 134 382 135 return true; … … 389 142 uint32_t flags, 390 143 const char *filename, 391 struct gp_registry_entry **entries, 392 size_t *num_entries) 393 { 394 uint16_t *buf = NULL; 395 size_t n = 0; 396 NTSTATUS status; 397 prs_struct ps; 398 struct gp_registry_file *reg_file; 144 struct gp_registry_entry **entries_p, 145 size_t *num_entries_p) 146 { 147 DATA_BLOB blob; 148 NTSTATUS status; 149 enum ndr_err_code ndr_err; 399 150 const char *real_filename = NULL; 400 401 reg_file = TALLOC_ZERO_P(mem_ctx, struct gp_registry_file); 402 NT_STATUS_HAVE_NO_MEMORY(reg_file); 151 struct preg_file r; 152 struct gp_registry_entry *entries = NULL; 153 size_t num_entries = 0; 154 int i; 403 155 404 156 status = gp_find_file(mem_ctx, … … 408 160 &real_filename); 409 161 if (!NT_STATUS_IS_OK(status)) { 410 TALLOC_FREE(reg_file);411 162 return status; 412 163 } 413 164 414 buf = (uint16 *)file_load(real_filename, &n, 0, NULL); 415 if (!buf) { 416 TALLOC_FREE(reg_file); 165 blob.data = (uint8_t *)file_load(real_filename, &blob.length, 0, NULL); 166 if (!blob.data) { 417 167 return NT_STATUS_CANNOT_LOAD_REGISTRY_FILE; 418 168 } 419 169 420 if (!prs_init(&ps, n, mem_ctx, UNMARSHALL)) { 421 status = NT_STATUS_NO_MEMORY; 170 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r, 171 (ndr_pull_flags_fn_t)ndr_pull_preg_file); 172 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 173 status = ndr_map_error2ntstatus(ndr_err); 422 174 goto out; 423 175 } 424 176 425 if (!prs_copy_data_in(&ps, (char *)buf, n)) { 426 status = NT_STATUS_NO_MEMORY; 427 goto out; 428 } 429 430 prs_set_offset(&ps, 0); 431 432 if (!reg_parse_header("header", ®_file->header, &ps, 0)) { 433 status = NT_STATUS_REGISTRY_IO_FAILED; 434 goto out; 435 } 436 437 if (reg_file->header.signature != GP_REGPOL_FILE_SIGNATURE) { 177 if (!strequal(r.header.signature, "PReg")) { 438 178 status = NT_STATUS_INVALID_PARAMETER; 439 179 goto out; 440 180 } 441 181 442 if (r eg_file->header.version != GP_REGPOL_FILE_VERSION) {182 if (r.header.version != GP_REGPOL_FILE_VERSION) { 443 183 status = NT_STATUS_INVALID_PARAMETER; 444 184 goto out; 445 185 } 446 186 447 if (!reg_parse_entries(mem_ctx, "entries", ®_file->entries, 448 ®_file->num_entries, &ps, 0)) { 449 status = NT_STATUS_REGISTRY_IO_FAILED; 450 goto out; 451 } 452 453 *entries = reg_file->entries; 454 *num_entries = reg_file->num_entries; 187 for (i=0; i < r.num_entries; i++) { 188 189 struct gp_registry_entry *r_entry = NULL; 190 191 if (!gp_reg_entry_from_file_entry(mem_ctx, 192 &r.entries[i], 193 &r_entry)) { 194 status = NT_STATUS_NO_MEMORY; 195 goto out; 196 } 197 198 if (!add_gp_registry_entry_to_array(mem_ctx, 199 r_entry, 200 &entries, 201 &num_entries)) { 202 status = NT_STATUS_NO_MEMORY; 203 goto out; 204 } 205 } 206 207 *entries_p = entries; 208 *num_entries_p = num_entries; 455 209 456 210 status = NT_STATUS_OK; 457 211 458 212 out: 459 TALLOC_FREE(buf); 460 prs_mem_free(&ps); 461 213 data_blob_free(&blob); 462 214 return status; 463 215 } … … 467 219 468 220 static WERROR reg_apply_registry(TALLOC_CTX *mem_ctx, 469 const struct nt_user_token *token,221 const struct security_token *token, 470 222 struct registry_key *root_key, 471 223 uint32_t flags, … … 522 274 uint32_t flags, 523 275 struct registry_key *root_key, 524 const struct nt_user_token *token,276 const struct security_token *token, 525 277 struct GROUP_POLICY_OBJECT *gpo, 526 278 const char *extension_guid,
Note:
See TracChangeset
for help on using the changeset viewer.