diff options
Diffstat (limited to 'source3/libmsrpc/cac_winreg.c')
-rw-r--r-- | source3/libmsrpc/cac_winreg.c | 1177 |
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, ®_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; -} |