static sbcErr smbconf_reg_set_multi_sz_value(struct registry_key *key, const char *valname, const uint32_t num_strings, const char **strings) { WERROR werr; sbcErr err = SBC_ERR_OK; struct registry_value *value; uint32_t count; TALLOC_CTX *tmp_ctx = talloc_stackframe(); const char **array; if (strings == NULL) { err = SBC_ERR_INVALID_PARAM; goto done; } array = talloc_zero_array(tmp_ctx, const char *, num_strings + 1); if (array == NULL) { err = SBC_ERR_NOMEM; goto done; } value = talloc_zero(tmp_ctx, struct registry_value); if (value == NULL) { err = SBC_ERR_NOMEM; goto done; } value->type = REG_MULTI_SZ; for (count = 0; count < num_strings; count++) { array[count] = talloc_strdup(value, strings[count]); if (array[count] == NULL) { err = SBC_ERR_NOMEM; goto done; } } if (!push_reg_multi_sz(value, &value->data, array)) { err = SBC_ERR_NOMEM; goto done; } werr = reg_setvalue(key, valname, value); if (!W_ERROR_IS_OK(werr)) { DEBUG(5, ("Error adding value '%s' to key '%s': %s\n", valname, key->key->name, win_errstr(werr))); err = SBC_ERR_ACCESS_DENIED; } done: talloc_free(tmp_ctx); return err; }
static int net_registry_setvalue(struct net_context *c, int argc, const char **argv) { WERROR werr; struct registry_value value; struct registry_key *key = NULL; int ret = -1; TALLOC_CTX *ctx = talloc_stackframe(); if (argc < 4 || c->display_usage) { d_fprintf(stderr, "%s\n%s", _("Usage:"), _("net registry setvalue <key> <valuename> " "<type> [<val>]+\n")); goto done; } if (!strequal(argv[2], "multi_sz") && (argc != 4)) { d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]); goto done; } if (strequal(argv[2], "dword")) { uint32_t v = strtoul(argv[3], NULL, 10); value.type = REG_DWORD; value.data = data_blob_talloc(ctx, NULL, 4); SIVAL(value.data.data, 0, v); } else if (strequal(argv[2], "sz")) { value.type = REG_SZ; if (!push_reg_sz(ctx, &value.data, argv[3])) { goto done; } } else if (strequal(argv[2], "multi_sz")) { const char **array; int count = argc - 3; int i; value.type = REG_MULTI_SZ; array = talloc_zero_array(ctx, const char *, count + 1); if (array == NULL) { goto done; } for (i=0; i < count; i++) { array[i] = talloc_strdup(array, argv[count+i]); if (array[i] == NULL) { goto done; } } if (!push_reg_multi_sz(ctx, &value.data, array)) { goto done; } } else {
struct registry_value *registry_value_multi_sz(TALLOC_CTX *mem_ctx, const char **str) { struct registry_value *ret; ret = talloc_zero(mem_ctx, struct registry_value); if (ret == NULL) { return NULL; } if (!push_reg_multi_sz(ret, &ret->data, str)) { talloc_free(ret); return NULL; } ret->type = REG_MULTI_SZ; return ret; }
WERROR _PNP_GetDeviceList(struct pipes_struct *p, struct PNP_GetDeviceList *r) { char *devicepath; uint32_t size = 0; const char **multi_sz = NULL; DATA_BLOB blob; if ((r->in.flags & CM_GETIDLIST_FILTER_SERVICE) && (!r->in.filter)) { return WERR_CM_INVALID_POINTER; } if (!(devicepath = get_device_path(p->mem_ctx, r->in.filter))) { return WERR_NOT_ENOUGH_MEMORY; } size = strlen(devicepath) + 2; if (*r->in.length < size) { return WERR_CM_BUFFER_SMALL; } multi_sz = talloc_zero_array(p->mem_ctx, const char *, 2); if (!multi_sz) { return WERR_NOT_ENOUGH_MEMORY; } multi_sz[0] = devicepath; if (!push_reg_multi_sz(multi_sz, &blob, multi_sz)) { return WERR_NOT_ENOUGH_MEMORY; } if (*r->in.length < blob.length/2) { return WERR_CM_BUFFER_SMALL; } memcpy(r->out.buffer, blob.data, blob.length); return WERR_OK; }
NTSTATUS dcerpc_winreg_set_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 = { 0, }; DATA_BLOB blob; WERROR result = WERR_OK; NTSTATUS status; wvalue.name = value; if (!push_reg_multi_sz(mem_ctx, &blob, data)) { DEBUG(2, ("dcerpc_winreg_set_multi_sz: Could not marshall " "string multi sz for %s\n", wvalue.name)); *pwerr = WERR_NOMEM; return NT_STATUS_OK; } status = dcerpc_winreg_SetValue(h, mem_ctx, key_handle, wvalue, REG_MULTI_SZ, blob.data, blob.length, &result); if (!NT_STATUS_IS_OK(status)) { return status; } if (!W_ERROR_IS_OK(result)) { *pwerr = result; } return status; }
/********************************************************************* 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 {