static WERROR reg_diff_apply_del_all_values(void *_ctx, const char *key_name) { struct registry_context *ctx = (struct registry_context *)_ctx; struct registry_key *key; WERROR error; const char* value_name; error = reg_open_key_abs(ctx, ctx, key_name, &key); if (!W_ERROR_IS_OK(error)) { DEBUG(0, ("Error opening key '%s'\n", key_name)); return error; } W_ERROR_NOT_OK_RETURN(reg_key_get_info(ctx, key, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); while (W_ERROR_IS_OK(reg_key_get_value_by_index( ctx, key, 0, &value_name, NULL, NULL))) { error = reg_del_value(key, value_name); if (!W_ERROR_IS_OK(error)) { DEBUG(0, ("Error deleting value '%s'\n", value_name)); return error; } } return WERR_OK; }
static WERROR cmd_info(struct regshell_context *ctx, int argc, char **argv) { struct security_descriptor *sec_desc = NULL; time_t last_mod; WERROR error; const char *classname = NULL; NTTIME last_change; uint32_t max_subkeynamelen; uint32_t max_valnamelen; uint32_t max_valbufsize; uint32_t num_subkeys; uint32_t num_values; error = reg_key_get_info(ctx, ctx->current, &classname, &num_subkeys, &num_values, &last_change, &max_subkeynamelen, &max_valnamelen, &max_valbufsize); if (!W_ERROR_IS_OK(error)) { printf("Error getting key info: %s\n", win_errstr(error)); return error; } printf("Name: %s\n", strchr(ctx->path, '\\')?strrchr(ctx->path, '\\')+1: ctx->path); printf("Full path: %s\n", ctx->path); if (classname != NULL) printf("Key Class: %s\n", classname); last_mod = nt_time_to_unix(last_change); printf("Time Last Modified: %s", ctime(&last_mod)); printf("Number of subkeys: %d\n", num_subkeys); printf("Number of values: %d\n", num_values); if (max_valnamelen > 0) printf("Maximum value name length: %d\n", max_valnamelen); if (max_valbufsize > 0) printf("Maximum value data length: %d\n", max_valbufsize); if (max_subkeynamelen > 0) printf("Maximum sub key name length: %d\n", max_subkeynamelen); error = reg_get_sec_desc(ctx, ctx->current, &sec_desc); if (!W_ERROR_IS_OK(error)) { printf("Error getting security descriptor: %s\n", win_errstr(error)); return WERR_OK; } ndr_print_debug((ndr_print_fn_t)ndr_print_security_descriptor, "Security", sec_desc); talloc_free(sec_desc); return WERR_OK; }
static uint32_t get_num_values(TALLOC_CTX *ctx, const struct registry_key *key) { const char *classname; uint32_t num_subkeys; uint32_t num_values; NTTIME last_change_time; uint32_t max_subkeynamelen; uint32_t max_valnamelen; uint32_t max_valbufsize; WERROR rv; rv = reg_key_get_info(ctx, key, &classname, &num_subkeys, &num_values, &last_change_time, &max_subkeynamelen, &max_valnamelen, &max_valbufsize); if (W_ERROR_IS_OK(rv)) { return num_values; } return 0; }
/* winreg_QueryInfoKey */ static WERROR dcesrv_winreg_QueryInfoKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_QueryInfoKey *r) { struct dcesrv_handle *h; struct registry_key *key; const char *classname = NULL; WERROR result; DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY); key = h->data; switch (security_session_user_level(dce_call->conn->auth_state.session_info)) { case SECURITY_SYSTEM: case SECURITY_ADMINISTRATOR: case SECURITY_USER: result = reg_key_get_info(mem_ctx, key, &classname, r->out.num_subkeys, r->out.num_values, r->out.last_changed_time, r->out.max_subkeylen, r->out.max_valnamelen, r->out.max_valbufsize); if (classname != NULL) { r->out.classname->name = classname; r->out.classname->name_len = 2*strlen_m_term(classname); } else { r->out.classname->name = r->in.classname->name; r->out.classname->name_len = r->in.classname->name_len; } r->out.classname->name_size = r->in.classname->name_size; return result; default: return WERR_ACCESS_DENIED; } }
/* * 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; }