From f0c650a38286c07b9f3e83139c15bfbadc70ad5f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 23 May 2005 16:25:31 +0000 Subject: r6942: * merging the registry changes back to the 3.0 tree * removing the testprns tool (This used to be commit 81ffb0dbbbd244623507880c323a3c37e2b8dc4d) --- source3/rpc_client/cli_reg.c | 999 +++++++++++++++++++------------------------ 1 file changed, 441 insertions(+), 558 deletions(-) (limited to 'source3/rpc_client') diff --git a/source3/rpc_client/cli_reg.c b/source3/rpc_client/cli_reg.c index 87b41d248e..164bdd3129 100644 --- a/source3/rpc_client/cli_reg.c +++ b/source3/rpc_client/cli_reg.c @@ -8,6 +8,7 @@ Copyright (C) Jeremy Allison 1999. Copyright (C) Simo Sorce 2001 Copyright (C) Jeremy Cooper 2004 + Copyright (C) Gerald (Jerry) Carter 2005 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 @@ -25,130 +26,46 @@ */ #include "includes.h" +#include "rpc_client.h" /* Shutdown a server */ -/* internal connect to a registry hive root (open a registry policy) */ +/******************************************************************* + internal connect to a registry hive root (open a registry policy) +*******************************************************************/ static WERROR cli_reg_open_hive_int(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint16 op_code, const char *op_name, uint32 access_mask, POLICY_HND *hnd) { - prs_struct rbuf; - prs_struct qbuf; - REG_Q_OPEN_HIVE q_o; - REG_R_OPEN_HIVE r_o; - WERROR result = WERR_GENERAL_FAILURE; + REG_Q_OPEN_HIVE in; + REG_R_OPEN_HIVE out; + prs_struct qbuf, rbuf; - ZERO_STRUCT(q_o); - ZERO_STRUCT(r_o); + ZERO_STRUCT(in); + ZERO_STRUCT(out); - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + init_reg_q_open_hive(&in, access_mask); - init_reg_q_open_hive(&q_o, access_mask); + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, op_code, + in, out, + qbuf, rbuf, + reg_io_q_open_hive, + reg_io_r_open_hive, + WERR_GENERAL_FAILURE ); - /* Marshall the query parameters */ - if (!reg_io_q_open_hive("", &q_o, &qbuf, 0)) - goto done; + if ( !W_ERROR_IS_OK( out.status ) ) + return out.status; - /* Send the request, receive the response */ - if (!rpc_api_pipe_req(cli, PI_WINREG, op_code, &qbuf, &rbuf)) - goto done; + memcpy( hnd, &out.pol, sizeof(POLICY_HND) ); - /* Unmarshall the response */ - if (!reg_io_r_open_hive("", &r_o, &rbuf, 0)) - goto done; - - result = r_o.status; - if (NT_STATUS_IS_OK(result)) - *hnd = r_o.pol; - -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); - - return result; -} - - -WERROR cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx, - const char *msg, uint32 timeout, BOOL do_reboot, - BOOL force) -{ - prs_struct qbuf; - prs_struct rbuf; - REG_Q_SHUTDOWN q_s; - REG_R_SHUTDOWN r_s; - WERROR result = WERR_GENERAL_FAILURE; - - if (msg == NULL) return WERR_INVALID_PARAM; - - ZERO_STRUCT (q_s); - ZERO_STRUCT (r_s); - - prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_reg_q_shutdown(&q_s, msg, timeout, do_reboot, force); - - if (!reg_io_q_shutdown("", &q_s, &qbuf, 0) || - !rpc_api_pipe_req(cli, PI_WINREG, REG_SHUTDOWN, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if(reg_io_r_shutdown("", &r_s, &rbuf, 0)) - result = r_s.status; - -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); - - return result; -} - - -/* Abort a server shutdown */ - -WERROR cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx) -{ - prs_struct rbuf; - prs_struct qbuf; - REG_Q_ABORT_SHUTDOWN q_s; - REG_R_ABORT_SHUTDOWN r_s; - WERROR result = WERR_GENERAL_FAILURE; - - ZERO_STRUCT (q_s); - ZERO_STRUCT (r_s); - - prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_reg_q_abort_shutdown(&q_s); - - if (!reg_io_q_abort_shutdown("", &q_s, &qbuf, 0) || - !rpc_api_pipe_req(cli, PI_WINREG, REG_ABORT_SHUTDOWN, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (reg_io_r_abort_shutdown("", &r_s, &rbuf, 0)) - result = r_s.status; - -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf ); - - return result; + return out.status; } -/* connect to a registry hive root (open a registry policy) */ +/******************************************************************* + connect to a registry hive root (open a registry policy) +*******************************************************************/ WERROR cli_reg_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 reg_type, uint32 access_mask, @@ -184,43 +101,86 @@ WERROR cli_reg_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, access_mask, reg_hnd); } -/**************************************************************************** -do a REG Unknown 0xB command. sent after a create key or create value. -this might be some sort of "sync" or "refresh" command, sent after -modification of the registry... -****************************************************************************/ -WERROR cli_reg_flush_key(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd) + +/******************************************************************* +*******************************************************************/ + +WERROR cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx, + const char *msg, uint32 timeout, BOOL do_reboot, + BOOL force) { - prs_struct rbuf; - prs_struct qbuf; - REG_Q_FLUSH_KEY q_o; - REG_R_FLUSH_KEY r_o; - WERROR result = WERR_GENERAL_FAILURE; + REG_Q_SHUTDOWN in; + REG_R_SHUTDOWN out; + prs_struct qbuf, rbuf; - prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + if (msg == NULL) + return WERR_INVALID_PARAM; + + ZERO_STRUCT (in); + ZERO_STRUCT (out); /* Marshall data and send request */ - init_reg_q_flush_key(&q_o, hnd); + init_reg_q_shutdown(&in, msg, timeout, do_reboot, force); - if (!reg_io_q_flush_key("", &q_o, &qbuf, 0) || - !rpc_api_pipe_req(cli, PI_WINREG, REG_FLUSH_KEY, &qbuf, &rbuf)) - goto done; + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_SHUTDOWN, + in, out, + qbuf, rbuf, + reg_io_q_shutdown, + reg_io_r_shutdown, + WERR_GENERAL_FAILURE ); - ZERO_STRUCT(r_o); + return out.status; +} - /* Unmarshall response */ +/******************************************************************* +*******************************************************************/ + +WERROR cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx) +{ + REG_Q_ABORT_SHUTDOWN in; + REG_R_ABORT_SHUTDOWN out; + prs_struct qbuf, rbuf; + + ZERO_STRUCT (in); + ZERO_STRUCT (out); + + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_ABORT_SHUTDOWN, + in, out, + qbuf, rbuf, + reg_io_q_abort_shutdown, + reg_io_r_abort_shutdown, + WERR_GENERAL_FAILURE ); + + return out.status; +} - if (reg_io_r_flush_key("", &r_o, &rbuf, 0)) - result = r_o.status; -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); +/**************************************************************************** +do a REG Unknown 0xB command. sent after a create key or create value. +this might be some sort of "sync" or "refresh" command, sent after +modification of the registry... +****************************************************************************/ +WERROR cli_reg_flush_key(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd) +{ + REG_Q_FLUSH_KEY in; + REG_R_FLUSH_KEY out; + prs_struct qbuf, rbuf; - return result; + ZERO_STRUCT (in); + ZERO_STRUCT (out); + + init_reg_q_flush_key(&in, hnd); + + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_FLUSH_KEY, + in, out, + qbuf, rbuf, + reg_io_q_flush_key, + reg_io_r_flush_key, + WERR_GENERAL_FAILURE ); + + return out.status; } /**************************************************************************** @@ -234,96 +194,93 @@ WERROR cli_reg_query_key(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 *max_valnamelen, uint32 *max_valbufsize, uint32 *sec_desc, NTTIME *mod_time) { - prs_struct rbuf; - prs_struct qbuf; - REG_Q_QUERY_KEY q_o; - REG_R_QUERY_KEY r_o; + REG_Q_QUERY_KEY in; + REG_R_QUERY_KEY out; + prs_struct qbuf, rbuf; uint32 saved_class_len = *class_len; - WERROR result = WERR_GENERAL_FAILURE; - - prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_reg_q_query_key( &q_o, hnd, key_class ); - if (!reg_io_q_query_key("", &q_o, &qbuf, 0) || - !rpc_api_pipe_req(cli, PI_WINREG, REG_QUERY_KEY, &qbuf, &rbuf)) - goto done; + ZERO_STRUCT (in); + ZERO_STRUCT (out); - ZERO_STRUCT(r_o); + init_reg_q_query_key( &in, hnd, key_class ); - /* Unmarshall response */ + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_QUERY_KEY, + in, out, + qbuf, rbuf, + reg_io_q_query_key, + reg_io_r_query_key, + WERR_GENERAL_FAILURE ); - if (!reg_io_r_query_key("", &r_o, &rbuf, 0)) - goto done; + if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) { + ZERO_STRUCT (in); - result = r_o.status; - if (NT_STATUS_EQUAL(result, ERROR_INSUFFICIENT_BUFFER)) { - *class_len = r_o.class.string->uni_max_len; - goto done; - } else if (!NT_STATUS_IS_OK(result)) - goto done; + *class_len = out.class.string->uni_max_len; + if ( *class_len > saved_class_len ) + return out.status; + + /* set a string of spaces and NULL terminate */ - *class_len = r_o.class.string->uni_max_len; - unistr2_to_ascii(key_class, r_o.class.string, saved_class_len-1); - *num_subkeys = r_o.num_subkeys ; - *max_subkeylen = r_o.max_subkeylen ; - *num_values = r_o.num_values ; - *max_valnamelen = r_o.max_valnamelen; - *max_valbufsize = r_o.max_valbufsize; - *sec_desc = r_o.sec_desc ; - *mod_time = r_o.mod_time ; - /* Maybe: *max_classlen = r_o.reserved; */ + memset( key_class, (int)' ', *class_len ); + key_class[*class_len] = '\0'; + + init_reg_q_query_key( &in, hnd, key_class ); -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); + ZERO_STRUCT (out); - return result; + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_QUERY_KEY, + in, out, + qbuf, rbuf, + reg_io_q_query_key, + reg_io_r_query_key, + WERR_GENERAL_FAILURE ); + } + + if ( !W_ERROR_IS_OK( out.status ) ) + return out.status; + + *class_len = out.class.string->uni_max_len; + unistr2_to_ascii(key_class, out.class.string, saved_class_len-1); + *num_subkeys = out.num_subkeys ; + *max_subkeylen = out.max_subkeylen ; + *num_values = out.num_values ; + *max_valnamelen = out.max_valnamelen; + *max_valbufsize = out.max_valbufsize; + *sec_desc = out.sec_desc ; + *mod_time = out.mod_time ; + /* Maybe: *max_classlen = out.reserved; */ + + return out.status; } /**************************************************************************** -do a REG Unknown 1A ****************************************************************************/ + WERROR cli_reg_getversion(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, uint32 *unk) { - prs_struct rbuf; - prs_struct qbuf; - REG_Q_GETVERSION q_o; - REG_R_GETVERSION r_o; - WERROR result = WERR_GENERAL_FAILURE; - - prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ + REG_Q_GETVERSION in; + REG_R_GETVERSION out; + prs_struct qbuf, rbuf; - init_reg_q_getversion(&q_o, hnd); - - if (!reg_io_q_getversion("", &q_o, &qbuf, 0) || - !rpc_api_pipe_req(cli, PI_WINREG, REG_GETVERSION, &qbuf, &rbuf)) - goto done; - - ZERO_STRUCT(r_o); - - /* Unmarshall response */ - - if (!reg_io_r_getversion("", &r_o, &rbuf, 0)) - goto done; - - result = r_o.status; - if (NT_STATUS_IS_OK(result)) - if (unk != NULL) - *unk = r_o.unknown; - -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); - - return result; + ZERO_STRUCT (in); + ZERO_STRUCT (out); + + init_reg_q_getversion(&in, hnd); + + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_GETVERSION, + in, out, + qbuf, rbuf, + reg_io_q_getversion, + reg_io_r_getversion, + WERR_GENERAL_FAILURE ); + + + if ( !W_ERROR_IS_OK( out.status ) ) + return out.status; + + *unk = out.unknown; + + return out.status; } /**************************************************************************** @@ -333,41 +290,30 @@ WERROR cli_reg_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, const char *val_name, uint32 *type, REGVAL_BUFFER *buffer) { - prs_struct rbuf; - prs_struct qbuf; - REG_Q_INFO q_o; - REG_R_INFO r_o; - WERROR result = WERR_GENERAL_FAILURE; - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_reg_q_info(&q_o, hnd, val_name, buffer); - - if (!reg_io_q_info("", &q_o, &qbuf, 0) || - !rpc_api_pipe_req(cli, PI_WINREG, REG_INFO, &qbuf, &rbuf)) - goto done; + REG_Q_INFO in; + REG_R_INFO out; + prs_struct qbuf, rbuf; - ZERO_STRUCT(r_o); - - /* Unmarshall response */ - - if (!reg_io_r_info("", &r_o, &rbuf, 0)) - goto done; - - result = r_o.status; - if (NT_STATUS_IS_OK(result)) { - *type = *r_o.type; - *buffer = *r_o.value; - } - -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); - - return result; + ZERO_STRUCT (in); + ZERO_STRUCT (out); + + init_reg_q_info(&in, hnd, val_name, buffer); + + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_QUERY_KEY, + in, out, + qbuf, rbuf, + reg_io_q_info, + reg_io_r_info, + WERR_GENERAL_FAILURE ); + + + if ( !W_ERROR_IS_OK( out.status ) ) + return out.status; + + *type = *out.type; + *buffer = *out.value; + + return out.status; } /**************************************************************************** @@ -377,43 +323,30 @@ WERROR cli_reg_set_key_sec(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, uint32 sec_info, size_t secdesc_size, SEC_DESC *sec_desc) { - prs_struct rbuf; - prs_struct qbuf; - REG_Q_SET_KEY_SEC q_o; - REG_R_SET_KEY_SEC r_o; + REG_Q_SET_KEY_SEC in; + REG_R_SET_KEY_SEC out; + prs_struct qbuf, rbuf; SEC_DESC_BUF *sec_desc_buf; - WERROR result = WERR_GENERAL_FAILURE; - - /* - * Flatten the security descriptor. - */ - sec_desc_buf = make_sec_desc_buf(mem_ctx, secdesc_size, sec_desc); - if (sec_desc_buf == NULL) - goto done; - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_reg_q_set_key_sec(&q_o, hnd, sec_info, sec_desc_buf); - if (!reg_io_q_set_key_sec("", &q_o, &qbuf, 0) || - !rpc_api_pipe_req(cli, PI_WINREG, REG_SET_KEY_SEC, &qbuf, &rbuf)) - goto done; - - ZERO_STRUCT(r_o); - - /* Unmarshall response */ - - if (reg_io_r_set_key_sec("", &r_o, &rbuf, 0)) - result = r_o.status; - -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); - - return result; + ZERO_STRUCT (in); + ZERO_STRUCT (out); + + /* Flatten the security descriptor */ + + if ( !(sec_desc_buf = make_sec_desc_buf(mem_ctx, secdesc_size, sec_desc)) ) + return WERR_GENERAL_FAILURE; + + init_reg_q_set_key_sec(&in, hnd, sec_info, sec_desc_buf); + + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_SET_KEY_SEC, + in, out, + qbuf, rbuf, + reg_io_q_set_key_sec, + reg_io_r_set_key_sec, + WERR_GENERAL_FAILURE ); + + + return out.status; } @@ -424,53 +357,32 @@ WERROR cli_reg_get_key_sec(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, uint32 sec_info, uint32 *sec_buf_size, SEC_DESC_BUF *sec_buf) { - prs_struct rbuf; - prs_struct qbuf; - REG_Q_GET_KEY_SEC q_o; - REG_R_GET_KEY_SEC r_o; - WERROR result = WERR_GENERAL_FAILURE; - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_reg_q_get_key_sec(&q_o, hnd, sec_info, *sec_buf_size, sec_buf); - - if (!reg_io_q_get_key_sec("", &q_o, &qbuf, 0) || - !rpc_api_pipe_req(cli, PI_WINREG, REG_GET_KEY_SEC, &qbuf, &rbuf)) - goto done; - - ZERO_STRUCT(r_o); + REG_Q_GET_KEY_SEC in; + REG_R_GET_KEY_SEC out; + prs_struct qbuf, rbuf; - /* Unmarshall response */ - - r_o.data = sec_buf; - - if (*sec_buf_size != 0) - { - sec_buf->sec = TALLOC(mem_ctx, *sec_buf_size); - } - - if (!reg_io_r_get_key_sec("", &r_o, &rbuf, 0)) - goto done; - - result = r_o.status; - if (NT_STATUS_IS_OK(result)) - (*sec_buf_size) = r_o.data->len; - else if (NT_STATUS_EQUAL(result, ERROR_INSUFFICIENT_BUFFER)) - { - /* - * get the maximum buffer size: it was too small - */ - (*sec_buf_size) = r_o.hdr_sec.buf_max_len; - } + ZERO_STRUCT (in); + ZERO_STRUCT (out); + + init_reg_q_get_key_sec(&in, hnd, sec_info, *sec_buf_size, sec_buf); -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_GET_KEY_SEC, + in, out, + qbuf, rbuf, + reg_io_q_get_key_sec, + reg_io_r_get_key_sec, + WERR_GENERAL_FAILURE ); + - return result; + /* this might be able to return WERR_MORE_DATA, I'm not sure */ + + if ( !W_ERROR_IS_OK( out.status ) ) + return out.status; + + sec_buf = out.data; + *sec_buf_size = out.data->len; + + return out.status; } /**************************************************************************** @@ -479,35 +391,23 @@ do a REG Delete Value WERROR cli_reg_delete_val(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, char *val_name) { - prs_struct rbuf; - prs_struct qbuf; - REG_Q_DELETE_VALUE q_o; - REG_R_DELETE_VALUE r_o; - WERROR result = WERR_GENERAL_FAILURE; - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_reg_q_delete_val(&q_o, hnd, val_name); - - if (!reg_io_q_delete_val("", &q_o, &qbuf, 0) || - !rpc_api_pipe_req(cli, PI_WINREG, REG_DELETE_VALUE, &qbuf, &rbuf)) - goto done; - - ZERO_STRUCT(r_o); - - /* Unmarshall response */ - - if (reg_io_r_delete_val("", &r_o, &rbuf, 0)) - result = r_o.status; - -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); + REG_Q_DELETE_VALUE in; + REG_R_DELETE_VALUE out; + prs_struct qbuf, rbuf; - return result; + ZERO_STRUCT (in); + ZERO_STRUCT (out); + + init_reg_q_delete_val(&in, hnd, val_name); + + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_DELETE_VALUE, + in, out, + qbuf, rbuf, + reg_io_q_delete_val, + reg_io_r_delete_val, + WERR_GENERAL_FAILURE ); + + return out.status; } /**************************************************************************** @@ -516,35 +416,23 @@ do a REG Delete Key WERROR cli_reg_delete_key(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, char *key_name) { - prs_struct rbuf; - prs_struct qbuf; - REG_Q_DELETE_KEY q_o; - REG_R_DELETE_KEY r_o; - WERROR result = WERR_GENERAL_FAILURE; - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_reg_q_delete_key(&q_o, hnd, key_name); + REG_Q_DELETE_KEY in; + REG_R_DELETE_KEY out; + prs_struct qbuf, rbuf; - if (!reg_io_q_delete_key("", &q_o, &qbuf, 0) || - !rpc_api_pipe_req(cli, PI_WINREG, REG_DELETE_KEY, &qbuf, &rbuf)) - goto done; - - ZERO_STRUCT(r_o); - - /* Unmarshall response */ - - if (reg_io_r_delete_key("", &r_o, &rbuf, 0)) - result = r_o.status; - -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); - - return result; + ZERO_STRUCT (in); + ZERO_STRUCT (out); + + init_reg_q_delete_key(&in, hnd, key_name); + + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_DELETE_KEY, + in, out, + qbuf, rbuf, + reg_io_q_delete_key, + reg_io_r_delete_key, + WERR_GENERAL_FAILURE ); + + return out.status; } /**************************************************************************** @@ -554,51 +442,41 @@ WERROR cli_reg_create_key(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, char *key_name, char *key_class, uint32 access_desired, POLICY_HND *key) { - prs_struct rbuf; - prs_struct qbuf; - REG_Q_CREATE_KEY q_o; - REG_R_CREATE_KEY r_o; + REG_Q_CREATE_KEY in; + REG_R_CREATE_KEY out; + prs_struct qbuf, rbuf; SEC_DESC *sec; SEC_DESC_BUF *sec_buf; size_t sec_len; - WERROR result = WERR_GENERAL_FAILURE; - - ZERO_STRUCT(q_o); - - if ((sec = make_sec_desc(mem_ctx, 1, SEC_DESC_SELF_RELATIVE, - NULL, NULL, NULL, NULL, &sec_len)) == NULL) - goto done; - - if ((sec_buf = make_sec_desc_buf(mem_ctx, sec_len, sec)) == NULL) - goto done; - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - init_reg_q_create_key(&q_o, hnd, key_name, key_class, access_desired, sec_buf); - - if (!reg_io_q_create_key("", &q_o, &qbuf, 0) || - !rpc_api_pipe_req(cli, PI_WINREG, REG_CREATE_KEY, &qbuf, &rbuf)) - goto done; - - ZERO_STRUCT(r_o); - - /* Unmarshall response */ - - if (!reg_io_r_create_key("", &r_o, &rbuf, 0)) - goto done; - - result = r_o.status; - if (NT_STATUS_IS_OK(result)) - *key = r_o.key_pol; - -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); - - return result; + ZERO_STRUCT (in); + ZERO_STRUCT (out); + + if ( !(sec = make_sec_desc(mem_ctx, 1, SEC_DESC_SELF_RELATIVE, + NULL, NULL, NULL, NULL, &sec_len)) ) + { + return WERR_GENERAL_FAILURE; + } + + if ( !(sec_buf = make_sec_desc_buf(mem_ctx, sec_len, sec)) ) + return WERR_GENERAL_FAILURE; + + init_reg_q_create_key(&in, hnd, key_name, key_class, access_desired, sec_buf); + + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_CREATE_KEY, + in, out, + qbuf, rbuf, + reg_io_q_create_key, + reg_io_r_create_key, + WERR_GENERAL_FAILURE ); + + + if ( !W_ERROR_IS_OK( out.status ) ) + return out.status; + + memcpy( key, &out.key_pol, sizeof(POLICY_HND) ); + + return out.status; } /**************************************************************************** @@ -606,46 +484,40 @@ do a REG Enum Key ****************************************************************************/ WERROR cli_reg_enum_key(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, int key_index, fstring key_name, - uint32 *unk_1, uint32 *unk_2, time_t *mod_time) + fstring class_name, time_t *mod_time) { - prs_struct rbuf; - prs_struct qbuf; - REG_Q_ENUM_KEY q_o; - REG_R_ENUM_KEY r_o; - WERROR result = WERR_GENERAL_FAILURE; - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + REG_Q_ENUM_KEY in; + REG_R_ENUM_KEY out; + prs_struct qbuf, rbuf; - /* Marshall data and send request */ - - init_reg_q_enum_key(&q_o, hnd, key_index); + ZERO_STRUCT (in); + ZERO_STRUCT (out); + + init_reg_q_enum_key(&in, hnd, key_index); - if (!reg_io_q_enum_key("", &q_o, &qbuf, 0) || - !rpc_api_pipe_req(cli, PI_WINREG, REG_ENUM_KEY, &qbuf, &rbuf)) - goto done; + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_ENUM_KEY, + in, out, + qbuf, rbuf, + reg_io_q_enum_key, + reg_io_r_enum_key, + WERR_GENERAL_FAILURE ); - ZERO_STRUCT(r_o); + if ( !W_ERROR_IS_OK(out.status) ) + return out.status; - /* Unmarshall response */ + if ( out.keyname.string ) + rpcstr_pull( key_name, out.keyname.string->buffer, sizeof(fstring), -1, STR_TERMINATE ); + else + fstrcpy( key_name, "(Default)" ); - if (!reg_io_r_enum_key("", &r_o, &rbuf, 0)) - goto done; + if ( out.classname && out.classname->string ) + rpcstr_pull( class_name, out.classname->string->buffer, sizeof(fstring), -1, STR_TERMINATE ); + else + fstrcpy( class_name, "" ); - result = r_o.status; - if (NT_STATUS_IS_OK(result)) { - (*unk_1) = r_o.unknown_1; - (*unk_2) = r_o.unknown_2; - unistr3_to_ascii(key_name, &r_o.key_name, - sizeof(fstring)-1); - (*mod_time) = nt_time_to_unix(&r_o.time); - } + *mod_time = nt_time_to_unix(out.time); -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); - - return result; + return out.status; } /**************************************************************************** @@ -655,162 +527,173 @@ WERROR cli_reg_set_val(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, char *val_name, uint32 type, RPC_DATA_BLOB *data) { - prs_struct rbuf; - prs_struct qbuf; - REG_Q_SET_VALUE q_o; - REG_R_SET_VALUE r_o; - WERROR result = WERR_GENERAL_FAILURE; - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + REG_Q_SET_VALUE in; + REG_R_SET_VALUE out; + prs_struct qbuf, rbuf; - /* Marshall data and send request */ - - init_reg_q_set_val(&q_o, hnd, val_name, type, data); - - if (!reg_io_q_set_val("", &q_o, &qbuf, 0) || - !rpc_api_pipe_req(cli, PI_WINREG, REG_SET_VALUE, &qbuf, &rbuf)) - goto done; - - ZERO_STRUCT(r_o); - - /* Unmarshal response */ - - if (reg_io_r_set_val("", &r_o, &rbuf, 0)) - result = r_o.status; + ZERO_STRUCT (in); + ZERO_STRUCT (out); + + init_reg_q_set_val(&in, hnd, val_name, type, data); -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_SET_VALUE, + in, out, + qbuf, rbuf, + reg_io_q_set_val, + reg_io_r_set_val, + WERR_GENERAL_FAILURE ); - return result; + return out.status; } /**************************************************************************** do a REG Enum Value ****************************************************************************/ WERROR cli_reg_enum_val(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, int val_index, int max_valnamelen, - int max_valbufsize, fstring val_name, - uint32 *val_type, REGVAL_BUFFER *value) + POLICY_HND *hnd, int idx, + fstring val_name, uint32 *type, REGVAL_BUFFER *value) { - prs_struct rbuf; - prs_struct qbuf; - REG_Q_ENUM_VALUE q_o; - REG_R_ENUM_VALUE r_o; - WERROR result = WERR_GENERAL_FAILURE; + REG_Q_ENUM_VALUE in; + REG_R_ENUM_VALUE out; + prs_struct qbuf, rbuf; - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ + ZERO_STRUCT (in); + ZERO_STRUCT (out); + + init_reg_q_enum_val(&in, hnd, idx, 0x0100, 0x1000); - init_reg_q_enum_val(&q_o, hnd, val_index, val_name, max_valbufsize); + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_ENUM_VALUE, + in, out, + qbuf, rbuf, + reg_io_q_enum_val, + reg_io_r_enum_val, + WERR_GENERAL_FAILURE ); - if (!reg_io_q_enum_val("", &q_o, &qbuf, 0) || - !rpc_api_pipe_req(cli, PI_WINREG, REG_ENUM_VALUE, &qbuf, &rbuf)) - goto done; + if ( W_ERROR_EQUAL(out.status, WERR_MORE_DATA) ) { - ZERO_STRUCT(r_o); + ZERO_STRUCT (in); - /* Unmarshall response */ + init_reg_q_enum_val(&in, hnd, idx, 0x0100, *out.buffer_len1); - if (!reg_io_r_enum_val("", &r_o, &rbuf, 0)) - goto done; + ZERO_STRUCT (out); - result = r_o.status; - if (NT_STATUS_IS_OK(result) || - NT_STATUS_EQUAL(result, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - (*val_type) = *r_o.type; - unistr2_to_ascii(val_name, r_o.name.string, sizeof(fstring)-1); - *value = *r_o.value; + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_ENUM_VALUE, + in, out, + qbuf, rbuf, + reg_io_q_enum_val, + reg_io_r_enum_val, + WERR_GENERAL_FAILURE ); } -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); + if ( !W_ERROR_IS_OK(out.status) ) + return out.status; - return result; + unistr2_to_ascii(val_name, out.name.string, sizeof(fstring)-1); + *type = *out.type; + *value = *out.value; + + return out.status; } /**************************************************************************** -do a REG Open Key ****************************************************************************/ + WERROR cli_reg_open_entry(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, char *key_name, uint32 access_desired, POLICY_HND *key_hnd) { - prs_struct rbuf; - prs_struct qbuf; - REG_Q_OPEN_ENTRY q_o; - REG_R_OPEN_ENTRY r_o; - WERROR result = WERR_GENERAL_FAILURE; - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + REG_Q_OPEN_ENTRY in; + REG_R_OPEN_ENTRY out; + prs_struct qbuf, rbuf; - /* Marshall data and send request */ - - init_reg_q_open_entry(&q_o, hnd, key_name, access_desired); - - /* turn parameters into data stream */ - if (!reg_io_q_open_entry("", &q_o, &qbuf, 0) || - !rpc_api_pipe_req(cli, PI_WINREG, REG_OPEN_ENTRY, &qbuf, &rbuf)) - goto done; - - ZERO_STRUCT(r_o); - - /* Unmarsall response */ - - if (!reg_io_r_open_entry("", &r_o, &rbuf, 0)) - goto done; + ZERO_STRUCT (in); + ZERO_STRUCT (out); + + init_reg_q_open_entry(&in, hnd, key_name, access_desired); - result = r_o.status; - if (NT_STATUS_IS_OK(result)) - *key_hnd = r_o.pol; + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_OPEN_ENTRY, + in, out, + qbuf, rbuf, + reg_io_q_open_entry, + reg_io_r_open_entry, + WERR_GENERAL_FAILURE ); -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); + if ( !W_ERROR_IS_OK( out.status ) ) + return out.status; - return result; + memcpy( key_hnd, &out.pol, sizeof(POLICY_HND) ); + + return out.status; } /**************************************************************************** -do a REG Close ****************************************************************************/ + WERROR cli_reg_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd) { - prs_struct rbuf; - prs_struct qbuf; - REG_Q_CLOSE q_c; - REG_R_CLOSE r_c; - WERROR result = WERR_GENERAL_FAILURE; - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + REG_Q_CLOSE in; + REG_R_CLOSE out; + prs_struct qbuf, rbuf; - /* Marshall data and send request */ - - init_reg_q_close(&q_c, hnd); + ZERO_STRUCT (in); + ZERO_STRUCT (out); + + init_reg_q_close(&in, hnd); + + CLI_DO_RPC( cli, mem_ctx, PI_WINREG, REG_CLOSE, + in, out, + qbuf, rbuf, + reg_io_q_close, + reg_io_r_close, + WERR_GENERAL_FAILURE ); + + return out.status; +} - if (!reg_io_q_close("", &q_c, &qbuf, 0) || - !rpc_api_pipe_req(cli, PI_WINREG, REG_CLOSE, &qbuf, &rbuf)) - goto done; - ZERO_STRUCT(r_c); +/* + ################################################################# + Utility functions + ################################################################# + */ - /* Unmarshall response */ +/***************************************************************** + Splits out the start of the key (HKLM or HKU) and the rest of the key. +*****************************************************************/ - if (reg_io_r_close("", &r_c, &rbuf, 0)) - result = r_c.status; +BOOL reg_split_hive(const char *full_keyname, uint32 *reg_type, pstring key_name) +{ + pstring tmp; + + if (!next_token(&full_keyname, tmp, "\\", sizeof(tmp))) + return False; + + (*reg_type) = 0; + + DEBUG(10, ("reg_split_key: hive %s\n", tmp)); + + if (strequal(tmp, "HKLM") || strequal(tmp, "HKEY_LOCAL_MACHINE")) + (*reg_type) = HKEY_LOCAL_MACHINE; + else if (strequal(tmp, "HKCR") || strequal(tmp, "HKEY_CLASSES_ROOT")) + (*reg_type) = HKEY_CLASSES_ROOT; + else if (strequal(tmp, "HKU") || strequal(tmp, "HKEY_USERS")) + (*reg_type) = HKEY_USERS; + else if (strequal(tmp, "HKPD")||strequal(tmp, "HKEY_PERFORMANCE_DATA")) + (*reg_type) = HKEY_PERFORMANCE_DATA; + else { + DEBUG(10,("reg_split_key: unrecognised hive key %s\n", tmp)); + return False; + } + + if (next_token(&full_keyname, tmp, "\n\r", sizeof(tmp))) + pstrcpy(key_name, tmp); + else + key_name[0] = 0; -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); + DEBUG(10, ("reg_split_key: name %s\n", key_name)); - return result; + return True; } -- cgit