This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "includes.h"
#include "utils/net.h"
#include "regfio.h"
#include "reg_objects.h"
-static BOOL reg_hive_key(const char *fullname, uint32 *reg_type,
+static bool reg_hive_key(const char *fullname, uint32 *reg_type,
const char **key_name)
{
const char *sep;
else if (strnequal(fullname, "HKU", len) ||
strnequal(fullname, "HKEY_USERS", len))
(*reg_type) = HKEY_USERS;
+ else if (strnequal(fullname, "HKCU", len) ||
+ strnequal(fullname, "HKEY_CURRENT_USER", len))
+ (*reg_type) = HKEY_CURRENT_USER;
else if (strnequal(fullname, "HKPD", len) ||
strnequal(fullname, "HKEY_PERFORMANCE_DATA", len))
(*reg_type) = HKEY_PERFORMANCE_DATA;
NTSTATUS status;
struct winreg_String key;
+ ZERO_STRUCT(key);
+
if (!reg_hive_key(name, &hive, &key.name)) {
return NT_STATUS_INVALID_PARAMETER;
}
for (i=0; i<num_subkeys; i++) {
char c, n;
struct winreg_StringBuf class_buf;
- struct winreg_StringBuf *pclass_buf = &class_buf;
struct winreg_StringBuf name_buf;
NTTIME modtime;
- NTTIME *pmodtime = &modtime;
c = '\0';
class_buf.name = &c;
ZERO_STRUCT(modtime);
status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key_hnd,
- i, &name_buf, &pclass_buf,
- &pmodtime);
+ i, &name_buf, &class_buf,
+ &modtime);
if (W_ERROR_EQUAL(ntstatus_to_werror(status),
WERR_NO_MORE_ITEMS) ) {
classes[i] = NULL;
- if (pclass_buf && pclass_buf->name &&
- (!(classes[i] = talloc_strdup(classes,
- pclass_buf->name)))) {
+ if (class_buf.name &&
+ (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
status = NT_STATUS_NO_MEMORY;
goto error;
}
goto error;
}
- if ((pmodtime) &&
- (!(modtimes[i] = (NTTIME *)talloc_memdup(
- modtimes, pmodtime, sizeof(*pmodtime))))) {
+ if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
+ modtimes, &modtime, sizeof(modtime))))) {
status = NT_STATUS_NO_MEMORY;
goto error;
}
for (i=0; i<num_values; i++) {
enum winreg_Type type = REG_NONE;
- enum winreg_Type *ptype = &type;
- uint8 d = 0;
- uint8 *data = &d;
-
+ uint8 *data = NULL;
uint32 data_size;
- uint32 *pdata_size = &data_size;
-
uint32 value_length;
- uint32 *pvalue_length = &value_length;
char n;
struct winreg_ValNameBuf name_buf;
+ WERROR err;
n = '\0';
name_buf.name = &n;
name_buf.size = max_valnamelen + 2;
data_size = max_valbufsize;
+ data = (uint8 *)TALLOC(mem_ctx, data_size);
value_length = 0;
status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
- i, &name_buf, &ptype,
- &data, &pdata_size,
- &pvalue_length );
+ i, &name_buf, &type,
+ data, &data_size,
+ &value_length );
if ( W_ERROR_EQUAL(ntstatus_to_werror(status),
WERR_NO_MORE_ITEMS) ) {
goto error;
}
- if ((name_buf.name == NULL) || (ptype == NULL) ||
- (data == NULL) || (pdata_size == 0) ||
- (pvalue_length == NULL)) {
+ if (name_buf.name == NULL) {
status = NT_STATUS_INVALID_PARAMETER;
goto error;
}
goto error;
}
- status = registry_pull_value(values, &values[i], *ptype, data,
- *pdata_size, *pvalue_length);
- if (!(NT_STATUS_IS_OK(status))) {
+ err = registry_pull_value(values, &values[i], type, data,
+ data_size, value_length);
+ if (!W_ERROR_IS_OK(err)) {
+ status = werror_to_ntstatus(err);
goto error;
}
}
return status;
}
+static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
+ struct rpc_pipe_client *pipe_hnd,
+ struct policy_handle *key_hnd,
+ uint32_t sec_info,
+ struct KeySecurityData *sd)
+{
+ return rpccli_winreg_GetKeySecurity(pipe_hnd, mem_ctx, key_hnd,
+ sec_info, sd);
+}
+
+
static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
struct rpc_pipe_client *pipe_hnd,
struct policy_handle *key_hnd,
struct winreg_String name_string;
DATA_BLOB blob;
NTSTATUS result;
+ WERROR err;
- result = registry_push_value(mem_ctx, value, &blob);
- if (!NT_STATUS_IS_OK(result)) {
- return result;
+ err = registry_push_value(mem_ctx, value, &blob);
+ if (!W_ERROR_IS_OK(err)) {
+ return werror_to_ntstatus(err);
}
+ ZERO_STRUCT(name_string);
+
name_string.name = name;
result = rpccli_winreg_SetValue(pipe_hnd, blob.data, key_hnd,
name_string, value->type,
NTSTATUS status;
struct registry_value value;
- status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_WRITE,
+ status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
&hive_hnd, &key_hnd);
if (!NT_STATUS_IS_OK(status)) {
d_fprintf(stderr, "registry_openkey failed: %s\n",
value.v.sz.str = CONST_DISCARD(char *, argv[3]);
}
else {
- d_fprintf(stderr, "type \"%s\" not implemented\n", argv[3]);
+ d_fprintf(stderr, "type \"%s\" not implemented\n", argv[2]);
status = NT_STATUS_NOT_IMPLEMENTED;
goto error;
}
NTSTATUS status;
struct winreg_String valuename;
- status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_WRITE,
+ ZERO_STRUCT(valuename);
+
+ status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
&hive_hnd, &key_hnd);
if (!NT_STATUS_IS_OK(status)) {
d_fprintf(stderr, "registry_openkey failed: %s\n",
struct policy_handle hive_hnd, key_hnd;
struct winreg_String key, keyclass;
enum winreg_CreateAction action;
- enum winreg_CreateAction *paction = &action;
NTSTATUS status;
+ ZERO_STRUCT(key);
+ ZERO_STRUCT(keyclass);
+
if (!reg_hive_key(argv[0], &hive, &key.name)) {
return NT_STATUS_INVALID_PARAMETER;
}
status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
- REG_KEY_READ|REG_KEY_WRITE,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
&hive_hnd);
if (!(NT_STATUS_IS_OK(status))) {
return status;
status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
keyclass, 0, REG_KEY_READ, NULL,
- &key_hnd, &paction);
+ &key_hnd, &action);
if (!NT_STATUS_IS_OK(status)) {
d_fprintf(stderr, "createkey returned %s\n",
nt_errstr(status));
return status;
}
- if (paction) {
- switch (*paction) {
+ switch (action) {
case REG_ACTION_NONE:
d_printf("createkey did nothing -- huh?\n");
break;
case REG_OPENED_EXISTING_KEY:
d_printf("createkey opened existing %s\n", argv[0]);
break;
- }
}
rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd);
struct winreg_String key;
NTSTATUS status;
+ ZERO_STRUCT(key);
+
if (!reg_hive_key(argv[0], &hive, &key.name)) {
return NT_STATUS_INVALID_PARAMETER;
}
- status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, REG_KEY_WRITE,
+ status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
&hive_hnd);
if (!(NT_STATUS_IS_OK(status))) {
return status;
{
POLICY_HND pol_hive, pol_key;
NTSTATUS status;
- uint32 num_subkeys;
- uint32 num_values;
- char **names, **classes;
- NTTIME **modtimes;
+ uint32 num_subkeys = 0;
+ uint32 num_values = 0;
+ char **names = NULL, **classes = NULL;
+ NTTIME **modtimes = NULL;
uint32 i;
- struct registry_value **values;
+ struct registry_value **values = NULL;
if (argc != 1 ) {
- d_printf("Usage: net rpc enumerate <path> [recurse]\n");
- d_printf("Example: net rpc enumerate 'HKLM\\Software\\Samba'\n");
+ d_printf("Usage: net rpc registry enumerate <path> [recurse]\n");
+ d_printf("Example: net rpc registry enumerate 'HKLM\\Software\\Samba'\n");
return NT_STATUS_OK;
}
}
case REG_BINARY:
d_printf("Value = %d bytes\n",
- v->v.binary.length);
+ (int)v->v.binary.length);
break;
default:
d_printf("Value = <unprintable>\n");
struct winreg_String filename;
if (argc != 2 ) {
- d_printf("Usage: net rpc backup <path> <file> \n");
+ d_printf("Usage: net rpc registry backup <path> <file> \n");
return NT_STATUS_OK;
}
/********************************************************************
********************************************************************/
-static BOOL dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
+static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
{
REGF_NK_REC *key;
pstring regpath;
/********************************************************************
********************************************************************/
-static BOOL write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
+static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
REGF_NK_REC *parent, REGF_FILE *outfile,
const char *parentpath )
{
REGF_NK_REC *nk;
if (argc != 1 ) {
- d_printf("Usage: net rpc dump <file> \n");
+ d_printf("Usage: net rpc registry dump <file> \n");
return 0;
}
int result = 1;
if (argc != 2 ) {
- d_printf("Usage: net rpc copy <srcfile> <newfile>\n");
+ d_printf("Usage: net rpc registry copy <srcfile> <newfile>\n");
return 0;
}
/********************************************************************
********************************************************************/
+static NTSTATUS rpc_registry_getsd_internal(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
+{
+ POLICY_HND pol_hive, pol_key;
+ NTSTATUS status;
+ struct KeySecurityData *sd = NULL;
+ uint32_t sec_info;
+ DATA_BLOB blob;
+ struct security_descriptor sec_desc;
+ uint32_t access_mask = REG_KEY_READ |
+ SEC_RIGHT_MAXIMUM_ALLOWED |
+ SEC_RIGHT_SYSTEM_SECURITY;
+
+ if (argc <1 || argc > 2) {
+ d_printf("Usage: net rpc registry getsd <path> <secinfo>\n");
+ d_printf("Example: net rpc registry getsd 'HKLM\\Software\\Samba'\n");
+ return NT_STATUS_OK;
+ }
+
+ status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
+ access_mask,
+ &pol_hive, &pol_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "registry_openkey failed: %s\n",
+ nt_errstr(status));
+ return status;
+ }
+
+ sd = TALLOC_ZERO_P(mem_ctx, struct KeySecurityData);
+ if (!sd) {
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
+ sd->size = 0x1000;
+
+ if (argc >= 2) {
+ sscanf(argv[1], "%x", &sec_info);
+ } else {
+ sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
+ }
+
+ status = registry_getsd(mem_ctx, pipe_hnd, &pol_key, sec_info, sd);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr, "getting sd failed: %s\n",
+ nt_errstr(status));
+ goto out;
+ }
+
+ blob.data = sd->data;
+ blob.length = sd->size;
+
+ status = ndr_pull_struct_blob(&blob, mem_ctx, &sec_desc,
+ (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+
+ display_sec_desc(&sec_desc);
+
+ out:
+ rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key);
+ rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive);
+
+ return status;
+}
+
+
+static int rpc_registry_getsd(int argc, const char **argv)
+{
+ return run_rpc_command(NULL, PI_WINREG, 0,
+ rpc_registry_getsd_internal, argc, argv);
+}
+
+/********************************************************************
+********************************************************************/
+
int net_rpc_registry(int argc, const char **argv)
{
struct functable2 func[] = {
"Dump a registry file" },
{ "copy", rpc_registry_copy,
"Copy a registry file" },
+ { "getsd", rpc_registry_getsd,
+ "Get security descriptor" },
{NULL, NULL, NULL}
};