/* winreg_QueryValue */ static WERROR dcesrv_winreg_QueryValue(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_QueryValue *r) { struct dcesrv_handle *h; struct registry_key *key; uint32_t value_type; DATA_BLOB value_data; 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_value_by_name(mem_ctx, key, r->in.value_name->name, &value_type, &value_data); if (!W_ERROR_IS_OK(result)) { /* if the lookup wasn't successful, send client query back */ value_type = *r->in.type; value_data.data = r->in.data; value_data.length = *r->in.data_length; } r->out.type = talloc(mem_ctx, uint32_t); if (!r->out.type) { return WERR_NOMEM; } *r->out.type = value_type; r->out.data_length = talloc(mem_ctx, uint32_t); if (!r->out.data_length) { return WERR_NOMEM; } *r->out.data_length = value_data.length; r->out.data_size = talloc(mem_ctx, uint32_t); if (!r->out.data_size) { return WERR_NOMEM; } *r->out.data_size = value_data.length; r->out.data = value_data.data; return result; default: return WERR_ACCESS_DENIED; } }
static WERROR cmd_print(struct regshell_context *ctx, int argc, char **argv) { uint32_t value_type; DATA_BLOB value_data; WERROR error; if (argc != 2) { fprintf(stderr, "Usage: print <valuename>\n"); return WERR_INVALID_PARAM; } error = reg_key_get_value_by_name(ctx, ctx->current, argv[1], &value_type, &value_data); if (!W_ERROR_IS_OK(error)) { fprintf(stderr, "No such value '%s'\n", argv[1]); return error; } printf("%s\n%s\n", str_regtype(value_type), reg_val_data_string(ctx, value_type, value_data)); return WERR_OK; }
/* * 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; }