/** * 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_SZ to an ldap mod */ static bool map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, const char *name, struct registry_value *value) { const char *str_value = NULL; ADS_STATUS status; if (value->type != REG_SZ) return false; if (value->data.length && value->data.data) { if (!pull_reg_sz(ctx, &value->data, &str_value)) { return false; } status = ads_mod_str(ctx, mods, name, str_value); return ADS_ERR_OK(status); } return true; }
WERROR gp_read_reg_val_sz(TALLOC_CTX *mem_ctx, struct registry_key *key, const char *val_name, const char **val) { WERROR werr; struct registry_value *reg_val = NULL; werr = reg_queryvalue(mem_ctx, key, val_name, ®_val); W_ERROR_NOT_OK_RETURN(werr); if (reg_val->type != REG_SZ) { return WERR_INVALID_DATATYPE; } if (!pull_reg_sz(mem_ctx, ®_val->data, val)) { return WERR_NOMEM; } return WERR_OK; }
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; }
WERROR nt_printer_guid_get(TALLOC_CTX *mem_ctx, const struct auth_session_info *session_info, struct messaging_context *msg_ctx, const char *printer, struct GUID *guid) { TALLOC_CTX *tmp_ctx; enum winreg_Type type; DATA_BLOB blob; uint32_t len; NTSTATUS status; WERROR result; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) { DEBUG(0, ("out of memory?!\n")); return WERR_NOMEM; } result = winreg_get_printer_dataex_internal(tmp_ctx, session_info, msg_ctx, printer, SPOOL_DSSPOOLER_KEY, "objectGUID", &type, &blob.data, &len); if (!W_ERROR_IS_OK(result)) { DEBUG(0, ("Failed to get GUID for printer %s\n", printer)); goto out_ctx_free; } blob.length = (size_t)len; /* We used to store the guid as REG_BINARY, then swapped to REG_SZ for Vista compatibility so check for both */ switch (type) { case REG_SZ: { bool ok; const char *guid_str; ok = pull_reg_sz(tmp_ctx, &blob, &guid_str); if (!ok) { DEBUG(0, ("Failed to unmarshall GUID for printer %s\n", printer)); result = WERR_REG_CORRUPT; goto out_ctx_free; } status = GUID_from_string(guid_str, guid); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("bad GUID for printer %s\n", printer)); result = ntstatus_to_werror(status); goto out_ctx_free; } break; } case REG_BINARY: if (blob.length != sizeof(struct GUID)) { DEBUG(0, ("bad GUID for printer %s\n", printer)); result = WERR_REG_CORRUPT; goto out_ctx_free; } memcpy(guid, blob.data, sizeof(struct GUID)); break; default: DEBUG(0,("GUID value stored as invalid type (%d)\n", type)); result = WERR_REG_CORRUPT; goto out_ctx_free; break; } result = WERR_OK; out_ctx_free: talloc_free(tmp_ctx); return result; }
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; } }
NTSTATUS dcerpc_winreg_query_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_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_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; } }