static WERROR cmd_ls(struct regshell_context *ctx, int argc, char **argv) { unsigned int i; WERROR error; uint32_t valuetype; DATA_BLOB valuedata; const char *name = NULL; for (i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(ctx, ctx->current, i, &name, NULL, NULL)); i++) { printf("K %s\n", name); } if (!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { fprintf(stderr, "Error occurred while browsing through keys: %s\n", win_errstr(error)); return error; } for (i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(ctx, ctx->current, i, &name, &valuetype, &valuedata)); i++) printf("V \"%s\" %s %s\n", name, str_regtype(valuetype), reg_val_data_string(ctx, valuetype, valuedata)); return WERR_OK; }
/* winreg_EnumKey */ static WERROR dcesrv_winreg_EnumKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_EnumKey *r) { struct dcesrv_handle *h; struct registry_key *key; const char *name, *classname; NTTIME last_mod; WERROR result; DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY); key = h->data; result = reg_key_get_subkey_by_index(mem_ctx, key, r->in.enum_index, &name, &classname, &last_mod); if (2*strlen_m_term(name) > r->in.name->size) { return WERR_MORE_DATA; } if (name != NULL) { r->out.name->name = name; r->out.name->length = 2*strlen_m_term(name); } else { r->out.name->name = r->in.name->name; r->out.name->length = r->in.name->length; } r->out.name->size = r->in.name->size; r->out.keyclass = r->in.keyclass; if (classname != NULL) { r->out.keyclass->name = classname; r->out.keyclass->length = 2*strlen_m_term(classname); } else { r->out.keyclass->name = r->in.keyclass->name; r->out.keyclass->length = r->in.keyclass->length; } r->out.keyclass->size = r->in.keyclass->size; if (r->in.last_changed_time != NULL) r->out.last_changed_time = &last_mod; return result; }
/** * Print a registry key recursively * * @param level Level at which to print * @param p Key to print * @param fullpath Whether the full pat hshould be printed or just the last bit * @param novals Whether values should not be printed */ static void print_tree(unsigned int level, struct registry_key *p, const char *name, bool fullpath, bool novals) { struct registry_key *subkey; const char *valuename, *keyname; uint32_t valuetype; DATA_BLOB valuedata; struct security_descriptor *sec_desc; WERROR error; unsigned int i; TALLOC_CTX *mem_ctx; for(i = 0; i < level; i++) putchar(' '); puts(name); mem_ctx = talloc_init("print_tree"); for (i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(mem_ctx, p, i, &keyname, NULL, NULL)); i++) { SMB_ASSERT(strlen(keyname) > 0); if (!W_ERROR_IS_OK(reg_open_key(mem_ctx, p, keyname, &subkey))) continue; print_tree(level+1, subkey, (fullpath && strlen(name))? talloc_asprintf(mem_ctx, "%s\\%s", name, keyname): keyname, fullpath, novals); talloc_free(subkey); } talloc_free(mem_ctx); if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { DEBUG(0, ("Error occurred while fetching subkeys for '%s': %s\n", name, win_errstr(error))); } if (!novals) { mem_ctx = talloc_init("print_tree"); for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index( mem_ctx, p, i, &valuename, &valuetype, &valuedata)); i++) { unsigned int j; for(j = 0; j < level+1; j++) putchar(' '); printf("%s\n", reg_val_description(mem_ctx, valuename, valuetype, valuedata)); } talloc_free(mem_ctx); if(!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) { DEBUG(0, ("Error occurred while fetching values for '%s': %s\n", name, win_errstr(error))); } } mem_ctx = talloc_init("sec_desc"); if (!W_ERROR_IS_OK(reg_get_sec_desc(mem_ctx, p, &sec_desc))) { DEBUG(0, ("Error getting security descriptor\n")); } talloc_free(mem_ctx); }
/* * Generate difference between two keys */ WERROR reg_generate_diff_key(struct registry_key *oldkey, struct registry_key *newkey, const char *path, const struct reg_diff_callbacks *callbacks, void *callback_data) { int i; struct registry_key *t1 = NULL, *t2 = NULL; char *tmppath; const char *keyname1; WERROR error, error1, error2; TALLOC_CTX *mem_ctx = talloc_init("writediff"); uint32_t old_num_subkeys, old_num_values, new_num_subkeys, new_num_values; if (oldkey != NULL) { error = reg_key_get_info(mem_ctx, oldkey, NULL, &old_num_subkeys, &old_num_values, NULL, NULL, NULL, NULL); if (!W_ERROR_IS_OK(error)) { DEBUG(0, ("Error occurred while getting key info: %s\n", win_errstr(error))); talloc_free(mem_ctx); return error; } } else { old_num_subkeys = 0; old_num_values = 0; } /* Subkeys that were changed or deleted */ for (i = 0; i < old_num_subkeys; i++) { error1 = reg_key_get_subkey_by_index(mem_ctx, oldkey, i, &keyname1, NULL, NULL); if (!W_ERROR_IS_OK(error1)) { DEBUG(0, ("Error occurred while getting subkey by index: %s\n", win_errstr(error1))); continue; } if (newkey != NULL) { error2 = reg_open_key(mem_ctx, newkey, keyname1, &t2); } else { error2 = WERR_BADFILE; t2 = NULL; } if (!W_ERROR_IS_OK(error2) && !W_ERROR_EQUAL(error2, WERR_BADFILE)) { DEBUG(0, ("Error occured while getting subkey by name: %s\n", win_errstr(error2))); talloc_free(mem_ctx); return error2; } /* if "error2" is going to be "WERR_BADFILE", then newkey */ /* didn't have such a subkey and therefore add a del diff */ tmppath = talloc_asprintf(mem_ctx, "%s\\%s", path, keyname1); if (!W_ERROR_IS_OK(error2)) callbacks->del_key(callback_data, tmppath); /* perform here also the recursive invocation */ error1 = reg_open_key(mem_ctx, oldkey, keyname1, &t1); if (!W_ERROR_IS_OK(error1)) { DEBUG(0, ("Error occured while getting subkey by name: %s\n", win_errstr(error1))); talloc_free(mem_ctx); return error1; } reg_generate_diff_key(t1, t2, tmppath, callbacks, callback_data); talloc_free(tmppath); } if (newkey != NULL) { error = reg_key_get_info(mem_ctx, newkey, NULL, &new_num_subkeys, &new_num_values, NULL, NULL, NULL, NULL); if (!W_ERROR_IS_OK(error)) { DEBUG(0, ("Error occurred while getting key info: %s\n", win_errstr(error))); talloc_free(mem_ctx); return error; } } else { new_num_subkeys = 0; new_num_values = 0; } /* Subkeys that were added */ for(i = 0; i < new_num_subkeys; i++) { error1 = reg_key_get_subkey_by_index(mem_ctx, newkey, i, &keyname1, NULL, NULL); if (!W_ERROR_IS_OK(error1)) { DEBUG(0, ("Error occurred while getting subkey by index: %s\n", win_errstr(error1))); talloc_free(mem_ctx); return error1; } if (oldkey != NULL) { error2 = reg_open_key(mem_ctx, oldkey, keyname1, &t1); if (W_ERROR_IS_OK(error2)) continue; } else { error2 = WERR_BADFILE; t1 = NULL; } if (!W_ERROR_EQUAL(error2, WERR_BADFILE)) { DEBUG(0, ("Error occurred while getting subkey by name: %s\n", win_errstr(error2))); talloc_free(mem_ctx); return error2; } /* oldkey didn't have such a subkey, add add diff */ tmppath = talloc_asprintf(mem_ctx, "%s\\%s", path, keyname1); callbacks->add_key(callback_data, tmppath); /* perform here also the recursive invocation */ error1 = reg_open_key(mem_ctx, newkey, keyname1, &t2); if (!W_ERROR_IS_OK(error1)) { DEBUG(0, ("Error occured while getting subkey by name: %s\n", win_errstr(error1))); talloc_free(mem_ctx); return error1; } reg_generate_diff_key(t1, t2, tmppath, callbacks, callback_data); talloc_free(tmppath); } /* Values that were added or changed */ for(i = 0; i < new_num_values; i++) { const char *name; uint32_t type1, type2; DATA_BLOB contents1, contents2; error1 = reg_key_get_value_by_index(mem_ctx, newkey, i, &name, &type1, &contents1); if (!W_ERROR_IS_OK(error1)) { DEBUG(0, ("Unable to get value by index: %s\n", win_errstr(error1))); talloc_free(mem_ctx); return error1; } if (oldkey != NULL) { error2 = reg_key_get_value_by_name(mem_ctx, oldkey, name, &type2, &contents2); } else error2 = WERR_BADFILE; if (!W_ERROR_IS_OK(error2) && !W_ERROR_EQUAL(error2, WERR_BADFILE)) { DEBUG(0, ("Error occurred while getting value by name: %s\n", win_errstr(error2))); talloc_free(mem_ctx); return error2; } if (W_ERROR_IS_OK(error2) && (data_blob_cmp(&contents1, &contents2) == 0) && (type1 == type2)) continue; callbacks->set_value(callback_data, path, name, type1, contents1); } /* Values that were deleted */ for (i = 0; i < old_num_values; i++) { const char *name; uint32_t type; DATA_BLOB contents; error1 = reg_key_get_value_by_index(mem_ctx, oldkey, i, &name, &type, &contents); if (!W_ERROR_IS_OK(error1)) { DEBUG(0, ("Unable to get value by index: %s\n", win_errstr(error1))); talloc_free(mem_ctx); return error1; } if (newkey != NULL) error2 = reg_key_get_value_by_name(mem_ctx, newkey, name, &type, &contents); else error2 = WERR_BADFILE; if (W_ERROR_IS_OK(error2)) continue; if (!W_ERROR_EQUAL(error2, WERR_BADFILE)) { DEBUG(0, ("Error occurred while getting value by name: %s\n", win_errstr(error2))); talloc_free(mem_ctx); return error2; } callbacks->del_value(callback_data, path, name); } talloc_free(mem_ctx); return WERR_OK; }