/** * format a registry_value into a string. * * This is intended to be used for smbconf registry values, * which are ar stored as REG_SZ values, so the incomplete * handling should be ok. */ static char *smbconf_format_registry_value(TALLOC_CTX *mem_ctx, struct registry_value *value) { char *result = NULL; /* alternatively, create a new talloc context? */ if (mem_ctx == NULL) { return result; } switch (value->type) { case REG_DWORD: if (value->data.length >= 4) { uint32_t v = IVAL(value->data.data, 0); result = talloc_asprintf(mem_ctx, "%d", v); } break; case REG_SZ: case REG_EXPAND_SZ: { const char *s; if (!pull_reg_sz(mem_ctx, &value->data, &s)) { break; } result = talloc_strdup(mem_ctx, s); break; } case REG_MULTI_SZ: { uint32 j; const char **a = NULL; if (!pull_reg_multi_sz(mem_ctx, &value->data, &a)) { break; } for (j = 0; a[j] != NULL; j++) { result = talloc_asprintf(mem_ctx, "%s\"%s\" ", result ? result : "" , a[j]); if (result == NULL) { break; } } break; } case REG_BINARY: result = talloc_asprintf(mem_ctx, "binary (%d bytes)", (int)value->data.length); break; default: result = talloc_asprintf(mem_ctx, "<unprintable>"); break; } return result; }
/* map a REG_MULTI_SZ to an ldap mod */ static bool map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, struct registry_value *value) { const char **str_values = NULL; ADS_STATUS status; if (value->type != REG_MULTI_SZ) { return false; } if (value->data.length && value->data.data) { if (!pull_reg_multi_sz(ctx, &value->data, &str_values)) { return false; } status = ads_mod_strlist(ctx, mods, name, str_values); return ADS_ERR_OK(status); } return true; }
static WERROR append_data_summary(TALLOC_CTX *ctx, struct value_item *vitem) { char *tmp = NULL; /* This is adapted from print_registry_value() in net_registry_util.c */ switch(vitem->type) { case REG_DWORD: { uint32_t v = 0; if (vitem->data.length >= 4) { v = IVAL(vitem->data.data, 0); } tmp = talloc_asprintf(ctx, "0x%08x (%u)", v, v); break; } case REG_SZ: case REG_EXPAND_SZ: { const char *s; if (!pull_reg_sz(ctx, &vitem->data, &s)) { break; } vitem->unprintable = !string_is_printable(s); if (vitem->unprintable) { tmp = talloc_asprintf(ctx, "(unprintable)"); } else { tmp = talloc_asprintf(ctx, "%s", s); } break; } case REG_MULTI_SZ: { size_t i, len; const char **a; const char *val; if (!pull_reg_multi_sz(ctx, &vitem->data, &a)) { break; } for (len = 0; a[len] != NULL; ++len) { } tmp = talloc_asprintf(ctx, "(%u) ", (unsigned)len); if (tmp == NULL) { return WERR_NOMEM; } for (i = 0; i < len; ++i) { if (!string_is_printable(a[i])) { val = "(unprintable)"; vitem->unprintable = true; } else { val = a[i]; } if (i == len - 1) { tmp = talloc_asprintf_append(tmp, "[%u]=\"%s\"", (unsigned)i, val); } else { tmp = talloc_asprintf_append(tmp, "[%u]=\"%s\", ", (unsigned)i, val); } if (tmp == NULL) { return WERR_NOMEM; } } break; } case REG_BINARY: tmp = talloc_asprintf(ctx, "(%d bytes)", (int)vitem->data.length); break; default: tmp = talloc_asprintf(ctx, "(unknown)"); break; } if (tmp == NULL) { return WERR_NOMEM; } vitem->value = tmp; return WERR_OK; }
static sbcErr smbconf_reg_get_includes_internal(TALLOC_CTX *mem_ctx, struct registry_key *key, uint32_t *num_includes, char ***includes) { WERROR werr; sbcErr err; uint32_t count; struct registry_value *value = NULL; char **tmp_includes = NULL; const char **array = NULL; TALLOC_CTX *tmp_ctx = talloc_stackframe(); if (!smbconf_value_exists(key, INCLUDES_VALNAME)) { /* no includes */ *num_includes = 0; *includes = NULL; err = SBC_ERR_OK; goto done; } werr = reg_queryvalue(tmp_ctx, key, INCLUDES_VALNAME, &value); if (!W_ERROR_IS_OK(werr)) { err = SBC_ERR_ACCESS_DENIED; goto done; } if (value->type != REG_MULTI_SZ) { /* wrong type -- ignore */ err = SBC_ERR_OK; goto done; } if (!pull_reg_multi_sz(tmp_ctx, &value->data, &array)) { err = SBC_ERR_NOMEM; goto done; } for (count = 0; array[count] != NULL; count++) { err = smbconf_add_string_to_array(tmp_ctx, &tmp_includes, count, array[count]); if (!SBC_ERROR_IS_OK(err)) { goto done; } } if (count > 0) { *includes = talloc_move(mem_ctx, &tmp_includes); if (*includes == NULL) { err = SBC_ERR_NOMEM; goto done; } *num_includes = count; } else { *num_includes = 0; *includes = NULL; } err = SBC_ERR_OK; done: talloc_free(tmp_ctx); return err; }
void dump_reg_val(int lvl, const char *direction, const char *key, const char *subkey, struct registry_value *val) { int i = 0; const char *type_str = NULL; if (!val) { DEBUG(lvl,("no val!\n")); return; } type_str = str_regtype(val->type); DEBUG(lvl,("\tdump_reg_val:\t%s '%s'\n\t\t\t'%s' %s: ", direction, key, subkey, type_str)); switch (val->type) { case REG_DWORD: { uint32_t v; if (val->data.length < 4) { break; } v = IVAL(val->data.data, 0); DEBUG(lvl,("%d (0x%08x)\n", (int)v, v)); break; } case REG_QWORD: { uint64_t v; if (val->data.length < 8) { break; } v = BVAL(val->data.data, 0); DEBUG(lvl,("%d (0x%016llx)\n", (int)v, (unsigned long long)v)); break; } case REG_SZ: { const char *s; if (!pull_reg_sz(talloc_tos(), &val->data, &s)) { break; } DEBUG(lvl,("%s (length: %d)\n", s, (int)strlen_m(s))); break; } case REG_MULTI_SZ: { const char **a; if (!pull_reg_multi_sz(talloc_tos(), &val->data, &a)) { break; } for (i=0; a[i] != NULL; i++) { ;; } DEBUG(lvl,("(num_strings: %d)\n", i)); for (i=0; a[i] != NULL; i++) { DEBUGADD(lvl,("\t%s\n", a[i])); } break; } case REG_NONE: DEBUG(lvl,("\n")); break; case REG_BINARY: dump_data(lvl, val->data.data, val->data.length); break; default: DEBUG(lvl,("unsupported type: %d\n", val->type)); break; } }
/********************************************************************* 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 {
NTSTATUS dcerpc_winreg_query_multi_sz(TALLOC_CTX *mem_ctx, struct dcerpc_binding_handle *h, struct policy_handle *key_handle, const char *value, const char ***data, WERROR *pwerr) { struct winreg_String wvalue; enum winreg_Type type = REG_NONE; WERROR result = WERR_OK; uint32_t value_len = 0; uint32_t data_size = 0; NTSTATUS status; DATA_BLOB blob; wvalue.name = value; status = dcerpc_winreg_QueryValue(h, mem_ctx, key_handle, &wvalue, &type, NULL, &data_size, &value_len, &result); if (!NT_STATUS_IS_OK(status)) { return status; } if (!W_ERROR_IS_OK(result)) { *pwerr = result; return status; } if (type != REG_MULTI_SZ) { *pwerr = WERR_INVALID_DATATYPE; return status; } blob = data_blob_talloc_zero(mem_ctx, data_size); if (blob.data == NULL) { *pwerr = WERR_NOMEM; return status; } value_len = 0; status = dcerpc_winreg_QueryValue(h, mem_ctx, key_handle, &wvalue, &type, blob.data, &data_size, &value_len, &result); if (!NT_STATUS_IS_OK(status)) { return status; } if (!W_ERROR_IS_OK(result)) { *pwerr = result; return status; } if (data) { bool ok; ok = pull_reg_multi_sz(mem_ctx, &blob, data); if (!ok) { *pwerr = WERR_NOMEM; } } return status; }
void print_registry_value(const struct registry_value *valvalue, bool raw) { if (!raw) { d_printf(_("Type = %s\n"), str_regtype(valvalue->type)); } switch(valvalue->type) { case REG_DWORD: { uint32_t v = 0; if (valvalue->data.length >= 4) { v = IVAL(valvalue->data.data, 0); } if (!raw) { d_printf(_("Value = ")); } d_printf("%d\n", v); break; } case REG_SZ: case REG_EXPAND_SZ: { const char *s; if (!pull_reg_sz(talloc_tos(), &valvalue->data, &s)) { break; } if (!raw) { d_printf(_("Value = \"")); } d_printf("%s", s); if (!raw) { d_printf("\""); } d_printf("\n"); break; } case REG_MULTI_SZ: { uint32 j; const char **a; if (!pull_reg_multi_sz(talloc_tos(), &valvalue->data, &a)) { break; } for (j = 0; a[j] != NULL; j++) { if (!raw) { d_printf(_("Value[%3.3d] = \""), j); } d_printf("%s", a[j]); if (!raw) { d_printf("\""); } d_printf("\n"); } break; } case REG_BINARY: if (!raw) { d_printf(_("Value = ")); } d_printf(_("%d bytes\n"), (int)valvalue->data.length); break; default: if (!raw) { d_printf(_("Value = ")); } d_printf(_("<unprintable>\n")); break; } }