/** * delete all values from a key */ static sbcErr smbconf_reg_delete_values(struct registry_key *key) { WERROR werr; sbcErr err; char *valname; struct registry_value *valvalue; uint32_t count; TALLOC_CTX *mem_ctx = talloc_stackframe(); for (count = 0; werr = reg_enumvalue(mem_ctx, key, count, &valname, &valvalue), W_ERROR_IS_OK(werr); count++) { werr = reg_deletevalue(key, valname); if (!W_ERROR_IS_OK(werr)) { err = SBC_ERR_ACCESS_DENIED; goto done; } } if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) { DEBUG(1, ("smbconf_reg_delete_values: " "Error enumerating values of %s: %s\n", key->key->name, win_errstr(werr))); err = SBC_ERR_ACCESS_DENIED; goto done; } err = SBC_ERR_OK; done: talloc_free(mem_ctx); return err; }
static int net_registry_enumerate(struct net_context *c, int argc, const char **argv) { WERROR werr; struct registry_key *key = NULL; TALLOC_CTX *ctx = talloc_stackframe(); char *subkey_name; NTTIME modtime; uint32_t count; char *valname = NULL; struct registry_value *valvalue = NULL; int ret = -1; if (argc != 1 || c->display_usage) { d_printf("Usage: net registry enumerate <path>\n"); d_printf("Example: net registry enumerate " "'HKLM\\Software\\Samba'\n"); goto done; } werr = open_key(ctx, argv[0], REG_KEY_READ, &key); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr)); goto done; } for (count = 0; werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime), W_ERROR_IS_OK(werr); count++) { print_registry_key(subkey_name, &modtime); } if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) { goto done; } for (count = 0; werr = reg_enumvalue(ctx, key, count, &valname, &valvalue), W_ERROR_IS_OK(werr); count++) { print_registry_value_with_name(valname, valvalue); } if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) { goto done; } ret = 0; done: TALLOC_FREE(ctx); return ret; }
static int net_registry_getvaluesraw(struct net_context *c, int argc, const char **argv) { WERROR werr; int ret = -1; struct registry_key *key = NULL; TALLOC_CTX *ctx = talloc_stackframe(); uint32_t idx; if (argc != 1 || c->display_usage) { d_fprintf(stderr, "usage: net rpc registry getvaluesraw " "<key>\n"); goto done; } werr = open_key(ctx, argv[0], REG_KEY_READ, &key); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr)); goto done; } idx = 0; while (true) { struct registry_value *val; werr = reg_enumvalue(talloc_tos(), key, idx, NULL, &val); if (W_ERROR_EQUAL(werr, WERR_NO_MORE_ITEMS)) { ret = 0; break; } if (!W_ERROR_IS_OK(werr)) { break; } print_registry_value(val, true); TALLOC_FREE(val); idx += 1; } done: TALLOC_FREE(ctx); return ret; }
static WERROR registry_enumkey(struct registry_key* parent, const char* keyname, bool recursive) { WERROR werr; TALLOC_CTX *ctx = talloc_stackframe(); char* subkey_name; NTTIME modtime; uint32_t count; char* valname = NULL; struct registry_value *valvalue = NULL; struct registry_key* key = NULL; werr = reg_openkey(ctx, parent, keyname, REG_KEY_READ, &key); if (!W_ERROR_IS_OK(werr)) { goto done; } if (recursive) { printf("[%s]\n\n", key->key->name); } else { for (count = 0; werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime), W_ERROR_IS_OK(werr); count++) { print_registry_key(subkey_name, &modtime); } if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) { goto done; } } for (count = 0; werr = reg_enumvalue(ctx, key, count, &valname, &valvalue), W_ERROR_IS_OK(werr); count++) { print_registry_value_with_name(valname, valvalue); } if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) { goto done; } if (!recursive) { werr = WERR_OK; goto done; } for (count = 0; werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime), W_ERROR_IS_OK(werr); count++) { werr = registry_enumkey(key, subkey_name, recursive); if (!W_ERROR_IS_OK(werr)) { goto done; } } if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) { goto done; } werr = WERR_OK; done: TALLOC_FREE(ctx); return werr; }
/** * Get the values of a key as a list of value names * and a list of value strings (ordered) */ static sbcErr smbconf_reg_get_values(TALLOC_CTX *mem_ctx, struct registry_key *key, uint32_t *num_values, char ***value_names, char ***value_strings) { TALLOC_CTX *tmp_ctx = NULL; WERROR werr = WERR_OK; sbcErr err; uint32_t count; struct registry_value *valvalue = NULL; char *valname = NULL; uint32_t tmp_num_values = 0; char **tmp_valnames = NULL; char **tmp_valstrings = NULL; uint32_t num_includes = 0; char **includes = NULL; if ((num_values == NULL) || (value_names == NULL) || (value_strings == NULL)) { err = SBC_ERR_INVALID_PARAM; goto done; } tmp_ctx = talloc_stackframe(); for (count = 0; werr = reg_enumvalue(tmp_ctx, key, count, &valname, &valvalue), W_ERROR_IS_OK(werr); count++) { char *valstring; if (!smbconf_reg_valname_valid(valname)) { continue; } err = smbconf_add_string_to_array(tmp_ctx, &tmp_valnames, tmp_num_values, valname); if (!SBC_ERROR_IS_OK(err)) { goto done; } valstring = smbconf_format_registry_value(tmp_ctx, valvalue); err = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings, tmp_num_values, valstring); if (!SBC_ERROR_IS_OK(err)) { goto done; } tmp_num_values++; } if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) { err = SBC_ERR_NOMEM; goto done; } /* now add the includes at the end */ err = smbconf_reg_get_includes_internal(tmp_ctx, key, &num_includes, &includes); if (!SBC_ERROR_IS_OK(err)) { goto done; } for (count = 0; count < num_includes; count++) { err = smbconf_add_string_to_array(tmp_ctx, &tmp_valnames, tmp_num_values, "include"); if (!SBC_ERROR_IS_OK(err)) { goto done; } err = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings, tmp_num_values, includes[count]); if (!SBC_ERROR_IS_OK(err)) { goto done; } tmp_num_values++; } *num_values = tmp_num_values; if (tmp_num_values > 0) { *value_names = talloc_move(mem_ctx, &tmp_valnames); *value_strings = talloc_move(mem_ctx, &tmp_valstrings); } else { *value_names = NULL; *value_strings = NULL; } done: talloc_free(tmp_ctx); return err; }
static int load_registry_service(const char *servicename) { struct registry_key *key; char *path; WERROR err; uint32 i; char *value_name; struct registry_value *value; int res = -1; if (!lp_registry_shares()) { return -1; } if ((servicename == NULL) || (*servicename == '\0')) { return -1; } if (strequal(servicename, GLOBAL_NAME)) { return -2; } if (asprintf(&path, "%s\\%s", KEY_SMBCONF, servicename) == -1) { return -1; } err = reg_open_path(NULL, path, REG_KEY_READ, get_root_nt_token(), &key); SAFE_FREE(path); if (!W_ERROR_IS_OK(err)) { return -1; } res = lp_add_service(servicename, -1); if (res == -1) { goto error; } for (i=0; W_ERROR_IS_OK(reg_enumvalue(key, key, i, &value_name, &value)); i++) { switch (value->type) { case REG_DWORD: { char *tmp; if (asprintf(&tmp, "%d", value->v.dword) == -1) { continue; } lp_do_parameter(res, value_name, tmp); SAFE_FREE(tmp); break; } case REG_SZ: { lp_do_parameter(res, value_name, value->v.sz.str); break; } default: /* Ignore all the rest */ break; } TALLOC_FREE(value_name); TALLOC_FREE(value); } error: TALLOC_FREE(key); return res; }