static WERROR open_key(TALLOC_CTX *ctx, const char *path, uint32 desired_access, struct registry_key **key) { WERROR werr; char *subkey_name = NULL; struct registry_key *hive = NULL; TALLOC_CTX *tmp_ctx = talloc_stackframe(); if ((path == NULL) || (key == NULL)) { return WERR_INVALID_PARAM; } werr = open_hive(tmp_ctx, path, desired_access, &hive, &subkey_name); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, _("open_hive failed: %s\n"), win_errstr(werr)); goto done; } werr = reg_openkey(ctx, hive, subkey_name, desired_access, key); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, _("reg_openkey failed: %s\n"), win_errstr(werr)); goto done; } werr = WERR_OK; done: TALLOC_FREE(tmp_ctx); return werr; }
/** * Utility function to open a complete registry path including the hive prefix. */ WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path, uint32 desired_access, const struct security_token *token, struct registry_key **pkey) { struct registry_key *hive, *key; char *path, *p; WERROR err; if (!(path = SMB_STRDUP(orig_path))) { return WERR_NOMEM; } p = strchr(path, '\\'); if ((p == NULL) || (p[1] == '\0')) { /* * No key behind the hive, just return the hive */ err = reg_openhive(mem_ctx, path, desired_access, token, &hive); if (!W_ERROR_IS_OK(err)) { SAFE_FREE(path); return err; } SAFE_FREE(path); *pkey = hive; return WERR_OK; } *p = '\0'; err = reg_openhive(mem_ctx, path, KEY_ENUMERATE_SUB_KEYS, token, &hive); if (!W_ERROR_IS_OK(err)) { SAFE_FREE(path); return err; } err = reg_openkey(mem_ctx, hive, p+1, desired_access, &key); TALLOC_FREE(hive); SAFE_FREE(path); if (!W_ERROR_IS_OK(err)) { return err; } *pkey = key; return WERR_OK; }
/** * Open a subkey of the base key (i.e a service) */ static sbcErr smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx, struct smbconf_ctx *ctx, const char *servicename, uint32 desired_access, struct registry_key **key) { WERROR werr; if (servicename == NULL) { *key = rpd(ctx)->base_key; return SBC_ERR_OK; } werr = reg_openkey(mem_ctx, rpd(ctx)->base_key, servicename, desired_access, key); if (W_ERROR_EQUAL(werr, WERR_BADFILE)) { return SBC_ERR_NO_SUCH_SERVICE; } if (!W_ERROR_IS_OK(werr)) { return SBC_ERR_NOMEM; } return SBC_ERR_OK; }
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; }
/********************************************************************* for an eventlog, add in a source name. If the eventlog doesn't exist (not in the list) do nothing. If a source for the log already exists, change the information (remove, replace) *********************************************************************/ static bool eventlog_add_source( const char *eventlog, const char *sourcename, const char *messagefile ) { /* Find all of the eventlogs, add keys for each of them */ /* need to add to the value KEY_EVENTLOG/<eventlog>/Sources string (Creating if necessary) need to add KEY of source to KEY_EVENTLOG/<eventlog>/<source> */ const char **elogs = lp_eventlog_list( ); const char **wrklist, **wp; char *evtlogpath = NULL; int ii = 0; bool already_in; int i; int numsources = 0; TALLOC_CTX *ctx = talloc_stackframe(); WERROR werr; struct registry_key *key_hive, *key_eventlog, *key_source; struct security_token *token = NULL; const char *hive_name, *relpath; enum winreg_CreateAction action; struct registry_value *value; static const uint32_t ACCESS = REG_KEY_READ | REG_KEY_WRITE; bool ret = false; if (!elogs) { d_printf("No Eventlogs configured\n"); goto done; } for ( i = 0; elogs[i]; i++ ) { if ( strequal( elogs[i], eventlog ) ) break; } if ( !elogs[i] ) { d_printf("Eventlog [%s] not found in list of valid event logs\n", eventlog); goto done; } /* have to assume that the evenlog key itself exists at this point */ /* add in a key of [sourcename] under the eventlog key */ /* todo add to Sources */ evtlogpath = talloc_asprintf(ctx, "%s\\%s", KEY_EVENTLOG, eventlog); if (!evtlogpath) { d_printf("Out of memory\n"); goto done; } relpath = evtlogpath + sizeof(KEY_EVENTLOG); hive_name = talloc_strndup(ctx, evtlogpath, relpath - evtlogpath); if (!hive_name) { d_printf("Out of memory\n"); goto done; } relpath++; werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token)); if (!W_ERROR_IS_OK(werr)) { d_printf("Failed to create admin token: %s\n", win_errstr(werr)); goto done; } werr = reg_openhive(ctx, hive_name, ACCESS, token, &key_hive); if (!W_ERROR_IS_OK(werr)) { d_printf("Failed to open hive [%s]: %s\n", hive_name, win_errstr(werr)); goto done; } werr = reg_openkey(ctx, key_hive, relpath, ACCESS, &key_eventlog); if (!W_ERROR_IS_OK(werr)) { d_printf("Failed to open key [%s]: %s\n", evtlogpath, win_errstr(werr)); goto done; } werr = reg_queryvalue(ctx, key_eventlog, "Sources", &value); if (!W_ERROR_IS_OK(werr)) { d_printf("Failed to get value \"Sources\" for [%s]: %s\n", evtlogpath, win_errstr(werr)); goto done; } /* perhaps this adding a new string to a multi_sz should be a fn? */ /* check to see if it's there already */ if ( value->type != REG_MULTI_SZ ) { d_printf("Wrong type for \"Sources\", should be REG_MULTI_SZ\n"); goto done; } /* convert to a 'regulah' chars to do some comparisons */ already_in = false; wrklist = NULL; dump_data(1, value->data.data, value->data.length); if (!pull_reg_multi_sz(ctx, &value->data, &wrklist)) { d_printf("Failed to pull REG_MULTI_SZ from \"Sources\"\n"); goto done; } for (ii=0; wrklist[ii]; ii++) { numsources++; } if (numsources > 0) { /* see if it's in there already */ wp = wrklist; while (wp && *wp ) { if ( strequal( *wp, sourcename ) ) { d_printf("Source name [%s] already in list for [%s] \n", sourcename, eventlog); already_in = true; break; } wp++; } } else { d_printf("Nothing in the sources list, this might be a problem\n"); } if ( !already_in ) { /* make a new list with an additional entry; copy values, add another */ wp = talloc_realloc(ctx, wrklist, const char *, numsources + 2 ); if ( !wp ) { d_printf("Out of memory\n"); goto done; } wp[numsources] = sourcename; wp[numsources+1] = NULL; if (!push_reg_multi_sz(ctx, &value->data, wp)) { d_printf("Failed to push Sources\n"); goto done; } dump_data( 1, value->data.data, value->data.length); werr = reg_setvalue(key_eventlog, "Sources", value); if (!W_ERROR_IS_OK(werr)) { d_printf("Failed to set value Sources: %s\n", win_errstr(werr)); goto done; } } else {