summaryrefslogtreecommitdiff
path: root/source3/libmsrpc/cac_winreg.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libmsrpc/cac_winreg.c')
-rw-r--r--source3/libmsrpc/cac_winreg.c1177
1 files changed, 0 insertions, 1177 deletions
diff --git a/source3/libmsrpc/cac_winreg.c b/source3/libmsrpc/cac_winreg.c
deleted file mode 100644
index 0470d2a80f..0000000000
--- a/source3/libmsrpc/cac_winreg.c
+++ /dev/null
@@ -1,1177 +0,0 @@
-
-/*
- * Unix SMB/CIFS implementation.
- * MS-RPC client library implementation (WINREG pipe)
- * Copyright (C) Chris Nicholls 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
- * 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,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include "libmsrpc.h"
-#include "libmsrpc_internal.h"
-
-NTSTATUS cac_delete_subkeys_recursive(struct rpc_pipe_client * pipe_hnd,
- TALLOC_CTX * mem_ctx, POLICY_HND * key);
-
-int cac_RegConnect( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
- struct RegConnect *op )
-{
- SMBCSRV *srv = NULL;
- struct rpc_pipe_client *pipe_hnd = NULL;
- POLICY_HND *key = NULL;
-
- if ( !hnd )
- return CAC_FAILURE;
-
- if ( !hnd->_internal.ctx ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if ( !op || !op->in.root || !mem_ctx ) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- srv = cac_GetServer( hnd );
- if ( !srv ) {
- hnd->status = NT_STATUS_INVALID_CONNECTION;
- return CAC_FAILURE;
- }
-
- /*initialize for winreg pipe if we have to */
- if ( !hnd->_internal.pipes[PI_WINREG] ) {
- if ( !
- ( pipe_hnd =
- cli_rpc_pipe_open_noauth( srv->cli, PI_WINREG,
- &hnd->status ) ) ) {
- return CAC_FAILURE;
- }
-
- hnd->_internal.pipes[PI_WINREG] = True;
- }
-
- pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
- if ( !pipe_hnd ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- key = talloc( mem_ctx, POLICY_HND );
- if ( !key ) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- hnd->status =
- rpccli_winreg_Connect( pipe_hnd, mem_ctx, op->in.root,
- op->in.access, key );
-
- if ( !NT_STATUS_IS_OK( hnd->status ) ) {
- return CAC_FAILURE;
- }
-
- op->out.key = key;
-
- return CAC_SUCCESS;
-}
-
-int cac_RegClose( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
- POLICY_HND * key )
-{
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- if ( !hnd )
- return CAC_FAILURE;
-
- if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if ( !key || !mem_ctx ) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
- if ( !pipe_hnd ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- hnd->status = rpccli_winreg_CloseKey( pipe_hnd, mem_ctx, key );
-
- if ( !NT_STATUS_IS_OK( hnd->status ) ) {
- return CAC_FAILURE;
- }
-
- return CAC_SUCCESS;
-}
-
-int cac_RegOpenKey( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
- struct RegOpenKey *op )
-{
- struct rpc_pipe_client *pipe_hnd = NULL;
- struct winreg_String key_string;
-
- POLICY_HND *key_out;
- POLICY_HND *parent_key;
-
- char *key_name = NULL;
- uint32 reg_type = 0;
-
- struct RegConnect rc;
-
- if ( !hnd )
- return CAC_FAILURE;
-
- if ( !hnd->_internal.ctx ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if ( !op || !op->in.name || !mem_ctx ) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
-
- key_out = talloc( mem_ctx, POLICY_HND );
- if ( !key_out ) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- if ( !op->in.parent_key ) {
- /*then we need to connect to the registry */
- if ( !cac_ParseRegPath( op->in.name, &reg_type, &key_name ) ) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- /*use cac_RegConnect because it handles the session setup */
- ZERO_STRUCT( rc );
-
- rc.in.access = op->in.access;
- rc.in.root = reg_type;
-
- if ( !cac_RegConnect( hnd, mem_ctx, &rc ) ) {
- return CAC_FAILURE;
- }
-
- /**if they only specified the root key, return the key we just opened*/
- if ( key_name == NULL ) {
- op->out.key = rc.out.key;
- return CAC_SUCCESS;
- }
-
- parent_key = rc.out.key;
- } else {
- parent_key = op->in.parent_key;
- key_name = op->in.name;
- }
-
- pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
- if ( !pipe_hnd ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- key_string.name = key_name;
- hnd->status =
- rpccli_winreg_OpenKey( pipe_hnd, mem_ctx, parent_key,
- key_string, 0, op->in.access,
- key_out );
-
- if ( !NT_STATUS_IS_OK( hnd->status ) ) {
- return CAC_FAILURE;
- }
-
- if ( !op->in.parent_key ) {
- /*then close the one that we opened above */
- hnd->status =
- rpccli_winreg_CloseKey( pipe_hnd, mem_ctx,
- parent_key );
-
- if ( !NT_STATUS_IS_OK( hnd->status ) ) {
- return CAC_FAILURE;
- }
- }
-
- op->out.key = key_out;
-
- return CAC_SUCCESS;
-}
-
-int cac_RegEnumKeys( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
- struct RegEnumKeys *op )
-{
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- /*buffers for rpccli_reg_enum_key call */
- fstring key_name_in;
- fstring class_name_in;
-
- /*output buffers */
- char **key_names_out = NULL;
- char **class_names_out = NULL;
- time_t *mod_times_out = NULL;
- uint32 num_keys_out = 0;
- uint32 resume_idx = 0;
-
- if ( !hnd )
- return CAC_FAILURE;
-
- /* This is to avoid useless rpc calls, if the last call
- exhausted all the keys, then we don't need to go
- through everything again */
-
- if ( NT_STATUS_V( hnd->status ) ==
- NT_STATUS_V( NT_STATUS_GUIDS_EXHAUSTED ) )
- return CAC_FAILURE;
-
- if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if ( !op || op->in.max_keys == 0 || !mem_ctx ) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
- if ( !pipe_hnd ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- /* The only way to know how many keys to expect is to
- assume max_keys keys will be found */
-
- key_names_out = TALLOC_ARRAY( mem_ctx, char *, op->in.max_keys );
- if ( !key_names_out ) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- class_names_out = TALLOC_ARRAY( mem_ctx, char *, op->in.max_keys );
- if ( !class_names_out ) {
- hnd->status = NT_STATUS_NO_MEMORY;
- TALLOC_FREE( key_names_out );
- return CAC_FAILURE;
- }
-
- mod_times_out = TALLOC_ARRAY( mem_ctx, time_t, op->in.max_keys );
- if ( !mod_times_out ) {
- hnd->status = NT_STATUS_NO_MEMORY;
- TALLOC_FREE( key_names_out );
- TALLOC_FREE( class_names_out );
-
- return CAC_FAILURE;
- }
-
- resume_idx = op->out.resume_idx;
-
- do {
-#if 0
- hnd->status =
- rpccli_winreg_EnumKey( pipe_hnd, mem_ctx, op->in.key,
- resume_idx, key_name_in,
- class_name_in,
- &mod_times_out );
-#endif
-
- if ( !NT_STATUS_IS_OK( hnd->status ) ) {
- /*don't increment any values */
- break;
- }
-
- key_names_out[num_keys_out] =
- talloc_strdup( mem_ctx, key_name_in );
-
- class_names_out[num_keys_out] =
- talloc_strdup( mem_ctx, class_name_in );
-
- if ( !key_names_out[num_keys_out]
- || !class_names_out[num_keys_out] ) {
- hnd->status = NT_STATUS_NO_MEMORY;
- break;
- }
-
- resume_idx++;
- num_keys_out++;
- } while ( num_keys_out < op->in.max_keys );
-
- if ( CAC_OP_FAILED( hnd->status ) ) {
- op->out.num_keys = 0;
- return CAC_FAILURE;
- }
-
- op->out.resume_idx = resume_idx;
- op->out.num_keys = num_keys_out;
- op->out.key_names = key_names_out;
- op->out.class_names = class_names_out;
- op->out.mod_times = mod_times_out;
-
- return CAC_SUCCESS;
-}
-
-int cac_RegCreateKey( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
- struct RegCreateKey *op )
-{
- struct rpc_pipe_client *pipe_hnd = NULL;
- POLICY_HND *key_out;
- struct RegOpenKey rok;
- struct winreg_String key_string, class_string;
- enum winreg_CreateAction action = 0;
-
- if ( !hnd )
- return CAC_FAILURE;
-
- if ( !hnd->_internal.ctx ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if ( !op || !op->in.parent_key || !op->in.key_name || !mem_ctx ) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- /*first try to open the key - we use cac_RegOpenKey(). this doubles as a way to ensure the winreg pipe is initialized */
- ZERO_STRUCT( rok );
-
- rok.in.name = op->in.key_name;
- rok.in.access = op->in.access;
- rok.in.parent_key = op->in.parent_key;
-
- if ( cac_RegOpenKey( hnd, mem_ctx, &rok ) ) {
- /*then we got the key, return */
- op->out.key = rok.out.key;
- return CAC_SUCCESS;
- }
-
- /*just be ultra-safe */
- pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
- if ( !pipe_hnd ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- key_out = talloc( mem_ctx, POLICY_HND );
- if ( !key_out ) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- key_string.name = op->in.key_name;
- class_string.name = op->in.class_name;
- hnd->status =
- rpccli_winreg_CreateKey( pipe_hnd, mem_ctx, op->in.parent_key,
- key_string, class_string, 0,
- op->in.access, NULL, key_out,
- &action );
-
- if ( !NT_STATUS_IS_OK( hnd->status ) ) {
- return CAC_FAILURE;
- }
-
- op->out.key = key_out;
-
- return CAC_SUCCESS;
-
-}
-
-NTSTATUS cac_delete_subkeys_recursive( struct rpc_pipe_client * pipe_hnd,
- TALLOC_CTX * mem_ctx, POLICY_HND * key )
-{
- POLICY_HND subkey;
- fstring subkey_name;
- int cur_key = 0;
- NTSTATUS status;
- uint32 num_subkeys, max_subkeylen, max_classlen;
- uint32 num_values, max_valnamelen, maxvalbufsize;
- char *name_buffer;
- struct winreg_String class_string;
-
- NTTIME modtime;
- uint32 secdescsize;
-
- /* First get the max subkey name length */
-
- class_string.name = NULL;
- status = rpccli_winreg_QueryInfoKey( pipe_hnd, mem_ctx, key,
- &class_string, &num_subkeys,
- &max_subkeylen, &max_classlen,
- &num_values, &max_valnamelen,
- &maxvalbufsize, &secdescsize,
- &modtime );
-
-
- if ( !NT_STATUS_IS_OK( status ) ) {
- return status;
- }
-
- if ( (name_buffer = TALLOC_ARRAY( mem_ctx, char, max_subkeylen )) == NULL ) {
- d_fprintf(stderr, "Memory allocation error.\n");
- return NT_STATUS_NO_MEMORY;
- }
-
-
- while ( NT_STATUS_IS_OK( status ) ) {
- struct winreg_String key_string;
- struct winreg_StringBuf subkey_string;
- fstring subkeyname;
-
- memset( name_buffer, 0x0, max_subkeylen );
- subkey_string.name = name_buffer;
- subkey_string.length = 0;
- subkey_string.size = max_subkeylen;
-
- status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key, cur_key,
- &subkey_string, NULL, NULL);
-
- if ( !NT_STATUS_IS_OK( status ) )
- break;
-
- /* copy the keyname and add the terminating NULL */
-
- StrnCpy( subkeyname, subkey_string.name,
- MIN(subkey_string.length, sizeof(subkeyname)-1) );
- subkeyname[MIN(subkey_string.length, sizeof(subkeyname)-1)] = '\0';
-
- /*try to open the key with full access */
-
- key_string.name = subkeyname;
- status = rpccli_winreg_OpenKey( pipe_hnd, mem_ctx, key,
- key_string, 0, REG_KEY_ALL,
- &subkey );
-
- if ( !NT_STATUS_IS_OK( status ) )
- break;
-
- status = cac_delete_subkeys_recursive( pipe_hnd, mem_ctx,
- &subkey );
-
- if ( !W_ERROR_EQUAL( ntstatus_to_werror(status), WERR_NO_MORE_ITEMS )
- && !NT_STATUS_IS_OK( status ) )
- break;
-
- /*flush the key just to be safe */
- rpccli_winreg_FlushKey( pipe_hnd, mem_ctx, key );
-
- /*close the key that we opened */
- rpccli_winreg_CloseKey( pipe_hnd, mem_ctx, &subkey );
-
- /*now we delete the subkey */
- key_string.name = subkey_name;
- status = rpccli_winreg_DeleteKey( pipe_hnd, mem_ctx, key,
- key_string );
-
- cur_key++;
- }
-
-
- return status;
-}
-
-
-
-int cac_RegDeleteKey( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
- struct RegDeleteKey *op )
-{
- struct rpc_pipe_client *pipe_hnd = NULL;
- struct winreg_String key_string;
-
- if ( !hnd )
- return CAC_FAILURE;
-
- if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if ( !op || !op->in.parent_key || !op->in.name || !mem_ctx ) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
- if ( !pipe_hnd ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if ( op->in.recursive ) {
-
- /* first open the key, and then delete all of
- it's subkeys recursively */
-
- struct RegOpenKey rok;
-
- ZERO_STRUCT( rok );
-
- rok.in.parent_key = op->in.parent_key;
- rok.in.name = op->in.name;
- rok.in.access = REG_KEY_ALL;
-
- if ( !cac_RegOpenKey( hnd, mem_ctx, &rok ) )
- return CAC_FAILURE;
-
- hnd->status = cac_delete_subkeys_recursive( pipe_hnd, mem_ctx,
- rok.out.key );
-
- /*close the key that we opened */
- cac_RegClose( hnd, mem_ctx, rok.out.key );
-
- if ( NT_STATUS_V( hnd->status ) !=
- NT_STATUS_V( NT_STATUS_GUIDS_EXHAUSTED )
- && !NT_STATUS_IS_OK( hnd->status ) )
- return CAC_FAILURE;
-
- /*now go on to actually delete the key */
- }
-
- key_string.name = op->in.name;
- hnd->status =
- rpccli_winreg_DeleteKey( pipe_hnd, mem_ctx, op->in.parent_key,
- key_string );
-
- if ( !NT_STATUS_IS_OK( hnd->status ) ) {
- return CAC_FAILURE;
- }
-
- return CAC_SUCCESS;
-}
-
-int cac_RegDeleteValue( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
- struct RegDeleteValue *op )
-{
- struct rpc_pipe_client *pipe_hnd = NULL;
- struct winreg_String value_string;
-
- if ( !hnd )
- return CAC_FAILURE;
-
- if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if ( !op || !op->in.parent_key || !op->in.name || !mem_ctx ) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
- if ( !pipe_hnd ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- value_string.name = op->in.name;
- hnd->status =
- rpccli_winreg_DeleteValue( pipe_hnd, mem_ctx,
- op->in.parent_key, value_string );
-
- if ( !NT_STATUS_IS_OK( hnd->status ) ) {
- return CAC_FAILURE;
- }
-
- return CAC_SUCCESS;
-}
-
-int cac_RegQueryKeyInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
- struct RegQueryKeyInfo *op )
-{
- struct rpc_pipe_client *pipe_hnd = NULL;
- uint32 num_subkeys_out = 0;
- uint32 long_subkey_out = 0;
- uint32 long_class_out = 0;
- uint32 num_values_out = 0;
- uint32 long_value_out = 0;
- uint32 long_data_out = 0;
- uint32 secdesc_size = 0;
- NTTIME mod_time;
- struct winreg_String class_string;
-
- if ( !hnd )
- return CAC_FAILURE;
-
- if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if ( !op || !op->in.key || !mem_ctx ) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
- if ( !pipe_hnd ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- hnd->status = rpccli_winreg_QueryInfoKey( pipe_hnd, mem_ctx,
- op->in.key,
- &class_string,
- &num_subkeys_out,
- &long_subkey_out,
- &long_class_out,
- &num_values_out,
- &long_value_out,
- &long_data_out,
- &secdesc_size, &mod_time );
-
- if ( !NT_STATUS_IS_OK( hnd->status ) )
- return CAC_FAILURE;
-
- if ( !class_string.name ) {
- op->out.class_name = talloc_strdup( mem_ctx, "" );
- } else {
- op->out.class_name = talloc_strdup( mem_ctx, class_string.name );
- }
-
- if ( !op->out.class_name ) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- op->out.num_subkeys = num_subkeys_out;
- op->out.longest_subkey = long_subkey_out;
- op->out.longest_class = long_class_out;
- op->out.num_values = num_values_out;
- op->out.longest_value_name = long_value_out;
- op->out.longest_value_data = long_data_out;
- op->out.security_desc_size = secdesc_size;
- op->out.last_write_time = nt_time_to_unix( mod_time );
-
- return CAC_FAILURE;
-}
-
-int cac_RegQueryValue( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
- struct RegQueryValue *op )
-{
- struct rpc_pipe_client *pipe_hnd = NULL;
- struct winreg_String value_string;
- REGVAL_BUFFER buffer;
- REG_VALUE_DATA *data_out = NULL;
- enum winreg_Type val_type;
- uint8 *buf;
- uint32 buf_size = 4096;
- uint32 length = 0;
-
- if ( !hnd )
- return CAC_FAILURE;
-
- if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if ( !op || !op->in.key || !op->in.val_name || !mem_ctx ) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
- if ( !pipe_hnd ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- value_string.name = op->in.val_name;
-
- if ( ( buf = TALLOC_ARRAY( mem_ctx, uint8, buf_size ) ) == NULL ) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- hnd->status = rpccli_winreg_QueryValue( pipe_hnd, mem_ctx, op->in.key,
- value_string, &val_type, buf,
- &buf_size, &length );
-
- if ( !NT_STATUS_IS_OK( hnd->status ) )
- return CAC_FAILURE;
-
- init_regval_buffer( &buffer, buf, length );
-
- data_out = cac_MakeRegValueData( mem_ctx, val_type, buffer );
- if ( !data_out ) {
- if ( errno == ENOMEM )
- hnd->status = NT_STATUS_NO_MEMORY;
- else
- hnd->status = NT_STATUS_INVALID_PARAMETER;
-
- return CAC_FAILURE;
- }
-
- op->out.type = val_type;
- op->out.data = data_out;
-
- return CAC_SUCCESS;
-}
-
-
-int cac_RegEnumValues( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
- struct RegEnumValues *op )
-{
- struct rpc_pipe_client *pipe_hnd = NULL;
- char *name_buffer;
- REGVAL_BUFFER val_buf;
- uint32 *types_out = NULL;
- REG_VALUE_DATA **values_out = NULL;
- char **val_names_out = NULL;
- uint32 num_values_out = 0;
- uint32 resume_idx = 0;
- uint32 num_subkeys, max_subkeylen, max_classlen;
- uint32 num_values, max_valnamelen, maxvalbufsize;
- struct winreg_String class_string;
- NTTIME modtime;
- uint32 secdescsize;
- uint8 *buffer;
-
- if ( !hnd )
- return CAC_FAILURE;
-
- /* This is to avoid useless rpc calls, if the last
- call exhausted all the keys, then we don't need
- to go through everything again */
-
- if ( NT_STATUS_V( hnd->status ) ==
- NT_STATUS_V( NT_STATUS_GUIDS_EXHAUSTED ) )
- return CAC_FAILURE;
-
- if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if ( !op || !op->in.key || op->in.max_values == 0 || !mem_ctx ) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
- if ( !pipe_hnd ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- /*we need to assume that the max number of values will be enumerated */
- types_out = TALLOC_ARRAY( mem_ctx, uint32, op->in.max_values );
-
- if ( !types_out ) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- values_out = TALLOC_ARRAY( mem_ctx, REG_VALUE_DATA *,
- op->in.max_values );
-
- if ( !values_out ) {
- TALLOC_FREE( types_out );
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- val_names_out = TALLOC_ARRAY( mem_ctx, char *, op->in.max_values );
-
- if ( !val_names_out ) {
- TALLOC_FREE( types_out );
- TALLOC_FREE( values_out );
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- resume_idx = op->out.resume_idx;
-
- class_string.name = NULL;
- hnd->status = rpccli_winreg_QueryInfoKey( pipe_hnd, mem_ctx, op->in.key,
- &class_string, &num_subkeys,
- &max_subkeylen, &max_classlen,
- &num_values, &max_valnamelen,
- &maxvalbufsize, &secdescsize,
- &modtime );
-
- if ( !NT_STATUS_IS_OK(hnd->status) ) {
- TALLOC_FREE( types_out );
- TALLOC_FREE( values_out );
-
- return CAC_FAILURE;
- }
-
- if ( (buffer = TALLOC_ARRAY( mem_ctx, uint8, maxvalbufsize )) == NULL ) {
- TALLOC_FREE( types_out );
- TALLOC_FREE( values_out );
- hnd->status = NT_STATUS_NO_MEMORY;
-
- return CAC_FAILURE;
- }
-
- if ( (name_buffer = TALLOC_ARRAY(mem_ctx, char, max_valnamelen)) == NULL ) {
- TALLOC_FREE( types_out );
- TALLOC_FREE( values_out );
- TALLOC_FREE( buffer );
- hnd->status = NT_STATUS_NO_MEMORY;
-
- return CAC_FAILURE;
- }
-
- do {
- uint32 data_size = maxvalbufsize;
- uint32 data_length = 0;
- struct winreg_ValNameBuf name_buf;
-
- memset( name_buffer, 0x0, max_valnamelen );
- name_buf.name = name_buffer;
- name_buf.size = max_valnamelen;
- name_buf.length = 0;
-
- hnd->status = rpccli_winreg_EnumValue( pipe_hnd, mem_ctx,
- op->in.key,
- resume_idx, &name_buf,
- &types_out[num_values_out], buffer,
- &data_size,
- &data_length );
-
- if ( !NT_STATUS_IS_OK( hnd->status ) )
- break;
-
- ZERO_STRUCT( val_buf );
- init_regval_buffer( &val_buf, buffer, data_length );
-
- values_out[num_values_out] = cac_MakeRegValueData( mem_ctx,
- types_out[num_values_out],
- val_buf );
- val_names_out[num_values_out] = TALLOC_ARRAY( mem_ctx, char, name_buf.length+1 );
-
- if ( !val_names_out[num_values_out]
- || !values_out[num_values_out] ) {
- hnd->status = NT_STATUS_NO_MEMORY;
- break;
- }
-
- StrnCpy( val_names_out[num_values_out], name_buf.name, name_buf.length );
- (val_names_out[num_values_out])[name_buf.length] = '\0';
-
- num_values_out++;
- resume_idx++;
- } while ( num_values_out < op->in.max_values );
-
- if ( CAC_OP_FAILED( hnd->status ) )
- return CAC_FAILURE;
-
- op->out.types = types_out;
- op->out.num_values = num_values_out;
- op->out.value_names = val_names_out;
- op->out.values = values_out;
- op->out.resume_idx = resume_idx;
-
- return CAC_SUCCESS;
-}
-
-int cac_RegSetValue( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
- struct RegSetValue *op )
-{
- struct rpc_pipe_client *pipe_hnd = NULL;
- struct winreg_String value_string;
-
- RPC_DATA_BLOB *buffer;
-
- if ( !hnd )
- return CAC_FAILURE;
-
- if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if ( !op || !op->in.key || !op->in.val_name || !mem_ctx ) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
- if ( !pipe_hnd ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- buffer = cac_MakeRpcDataBlob( mem_ctx, op->in.type, op->in.value );
-
- if ( !buffer ) {
- if ( errno == ENOMEM )
- hnd->status = NT_STATUS_NO_MEMORY;
- else
- hnd->status = NT_STATUS_INVALID_PARAMETER;
-
- return CAC_FAILURE;
- }
-
- value_string.name = op->in.val_name;
- hnd->status =
- rpccli_winreg_SetValue( pipe_hnd, mem_ctx, op->in.key,
- value_string, op->in.type,
- buffer->buffer, buffer->buf_len );
-
- if ( !NT_STATUS_IS_OK( hnd->status ) )
- return CAC_FAILURE;
-
- /*flush */
- hnd->status = rpccli_winreg_FlushKey( pipe_hnd, mem_ctx, op->in.key );
-
- if ( !NT_STATUS_IS_OK( hnd->status ) )
- return CAC_FAILURE;
-
- return CAC_SUCCESS;
-}
-
-
-
-int cac_RegGetVersion( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
- struct RegGetVersion *op )
-{
- struct rpc_pipe_client *pipe_hnd = NULL;
- uint32 version_out;
-
- if ( !hnd )
- return CAC_FAILURE;
-
- if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if ( !op || !op->in.key || !mem_ctx ) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
- if ( !pipe_hnd ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- hnd->status =
- rpccli_winreg_GetVersion( pipe_hnd, mem_ctx, op->in.key,
- &version_out );
-
- if ( !NT_STATUS_IS_OK( hnd->status ) )
- return CAC_FAILURE;
-
- op->out.version = version_out;
-
- return CAC_SUCCESS;
-}
-
-int cac_RegGetKeySecurity( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
- struct RegGetKeySecurity *op )
-{
- struct rpc_pipe_client *pipe_hnd = NULL;
- struct KeySecurityData keysec;
-
- ZERO_STRUCT( keysec );
-
- if ( !hnd )
- return CAC_FAILURE;
-
- if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if ( !op || !op->in.key || op->in.info_type == 0 || !mem_ctx ) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
- if ( !pipe_hnd ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- hnd->status =
- rpccli_winreg_GetKeySecurity( pipe_hnd, mem_ctx, op->in.key,
- op->in.info_type, &keysec );
-
- if ( !NT_STATUS_IS_OK( hnd->status ) ) {
- return CAC_FAILURE;
- }
-
-#if 0 /* FIX ME!!!! unmarshall the security descriptor */
- op->out.size = buf.sd_size;
- op->out.descriptor = dup_sec_desc( mem_ctx, buf.sd );
-#endif
-
- if ( op->out.descriptor == NULL ) {
- return CAC_FAILURE;
- }
-
- return CAC_SUCCESS;
-}
-
-int cac_RegSetKeySecurity( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
- struct RegSetKeySecurity *op )
-{
- struct rpc_pipe_client *pipe_hnd = NULL;
- struct KeySecurityData keysec;
-
- ZERO_STRUCT( keysec );
-
- if ( !hnd )
- return CAC_FAILURE;
-
- if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if ( !op || !op->in.key || op->in.info_type == 0 || op->in.size == 0
- || !op->in.descriptor || !mem_ctx ) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
- if ( !pipe_hnd ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- /* FIXME!!! Marshall in the input sec_desc to struct KeySecurityData */
- hnd->status =
- rpccli_winreg_SetKeySecurity( pipe_hnd, mem_ctx, op->in.key,
- op->in.info_type, &keysec );
-
- if ( !NT_STATUS_IS_OK( hnd->status ) ) {
- return CAC_FAILURE;
- }
-
- return CAC_SUCCESS;
-}
-
-int cac_Shutdown( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
- struct Shutdown *op )
-{
- SMBCSRV *srv = NULL;
- struct rpc_pipe_client *pipe_hnd = NULL;
- struct initshutdown_String msg_string;
- struct initshutdown_String_sub s;
-
- char *msg;
-
- if ( !hnd )
- return CAC_FAILURE;
-
- if ( !hnd->_internal.ctx ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if ( !op || !mem_ctx ) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- srv = cac_GetServer( hnd );
- if ( !srv ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- /*initialize for winreg pipe if we have to */
- if ( !hnd->_internal.pipes[PI_INITSHUTDOWN] ) {
- if ( !
- ( pipe_hnd =
- cli_rpc_pipe_open_noauth( srv->cli, PI_INITSHUTDOWN,
- &( hnd->status ) ) ) ) {
- return CAC_FAILURE;
- }
-
- hnd->_internal.pipes[PI_INITSHUTDOWN] = True;
- }
-
- pipe_hnd = cac_GetPipe( hnd, PI_INITSHUTDOWN );
- if ( !pipe_hnd ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- msg = ( op->in.message !=
- NULL ) ? op->in.message : talloc_strdup( mem_ctx, "" );
- msg_string.name = &s;
- msg_string.name->name = msg;
-
- hnd->status = NT_STATUS_OK;
-
- if ( hnd->_internal.srv_level > SRV_WIN_NT4 ) {
- hnd->status =
- rpccli_initshutdown_InitEx( pipe_hnd, mem_ctx, NULL,
- &msg_string,
- op->in.timeout,
- op->in.reboot,
- op->in.force,
- op->in.reason );
- }
-
- if ( hnd->_internal.srv_level < SRV_WIN_2K
- || !NT_STATUS_IS_OK( hnd->status ) ) {
- hnd->status =
- rpccli_initshutdown_Init( pipe_hnd, mem_ctx, NULL,
- &msg_string, op->in.timeout,
- op->in.reboot,
- op->in.force );
-
- hnd->_internal.srv_level = SRV_WIN_NT4;
- }
-
- if ( !NT_STATUS_IS_OK( hnd->status ) ) {
- return CAC_FAILURE;
- }
-
- return CAC_SUCCESS;
-}
-
-int cac_AbortShutdown( CacServerHandle * hnd, TALLOC_CTX * mem_ctx )
-{
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- if ( !hnd )
- return CAC_FAILURE;
-
- if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_INITSHUTDOWN] ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe( hnd, PI_INITSHUTDOWN );
- if ( !pipe_hnd ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- hnd->status = rpccli_initshutdown_Abort( pipe_hnd, mem_ctx, NULL );
-
- if ( !NT_STATUS_IS_OK( hnd->status ) )
- return CAC_FAILURE;
-
- return CAC_SUCCESS;
-}