3 * Unix SMB/CIFS implementation.
4 * MS-RPC client library implementation (WINREG pipe)
5 * Copyright (C) Chris Nicholls 2005.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "libmsrpc_internal.h"
26 int cac_RegConnect( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
27 struct RegConnect *op )
30 struct rpc_pipe_client *pipe_hnd = NULL;
31 POLICY_HND *key = NULL;
36 if ( !hnd->_internal.ctx ) {
37 hnd->status = NT_STATUS_INVALID_HANDLE;
41 if ( !op || !op->in.root || !mem_ctx ) {
42 hnd->status = NT_STATUS_INVALID_PARAMETER;
46 srv = cac_GetServer( hnd );
48 hnd->status = NT_STATUS_INVALID_CONNECTION;
52 /*initialize for winreg pipe if we have to */
53 if ( !hnd->_internal.pipes[PI_WINREG] ) {
56 cli_rpc_pipe_open_noauth( srv->cli, PI_WINREG,
61 hnd->_internal.pipes[PI_WINREG] = True;
64 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
66 hnd->status = NT_STATUS_INVALID_HANDLE;
70 key = talloc( mem_ctx, POLICY_HND );
72 hnd->status = NT_STATUS_NO_MEMORY;
77 rpccli_winreg_Connect( pipe_hnd, mem_ctx, op->in.root,
80 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
89 int cac_RegClose( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
92 struct rpc_pipe_client *pipe_hnd = NULL;
97 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
98 hnd->status = NT_STATUS_INVALID_HANDLE;
102 if ( !key || !mem_ctx ) {
103 hnd->status = NT_STATUS_INVALID_PARAMETER;
107 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
109 hnd->status = NT_STATUS_INVALID_HANDLE;
113 hnd->status = rpccli_winreg_CloseKey( pipe_hnd, mem_ctx, key );
115 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
122 int cac_RegOpenKey( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
123 struct RegOpenKey *op )
125 struct rpc_pipe_client *pipe_hnd = NULL;
126 struct winreg_String key_string;
129 POLICY_HND *parent_key;
131 char *key_name = NULL;
134 struct RegConnect rc;
139 if ( !hnd->_internal.ctx ) {
140 hnd->status = NT_STATUS_INVALID_HANDLE;
144 if ( !op || !op->in.name || !mem_ctx ) {
145 hnd->status = NT_STATUS_INVALID_PARAMETER;
150 key_out = talloc( mem_ctx, POLICY_HND );
152 hnd->status = NT_STATUS_NO_MEMORY;
156 if ( !op->in.parent_key ) {
157 /*then we need to connect to the registry */
158 if ( !cac_ParseRegPath( op->in.name, ®_type, &key_name ) ) {
159 hnd->status = NT_STATUS_INVALID_PARAMETER;
163 /*use cac_RegConnect because it handles the session setup */
166 rc.in.access = op->in.access;
167 rc.in.root = reg_type;
169 if ( !cac_RegConnect( hnd, mem_ctx, &rc ) ) {
173 /**if they only specified the root key, return the key we just opened*/
174 if ( key_name == NULL ) {
175 op->out.key = rc.out.key;
179 parent_key = rc.out.key;
181 parent_key = op->in.parent_key;
182 key_name = op->in.name;
185 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
187 hnd->status = NT_STATUS_INVALID_HANDLE;
191 key_string.name = key_name;
193 rpccli_winreg_OpenKey( pipe_hnd, mem_ctx, parent_key,
194 key_string, 0, op->in.access,
197 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
201 if ( !op->in.parent_key ) {
202 /*then close the one that we opened above */
204 rpccli_winreg_CloseKey( pipe_hnd, mem_ctx,
207 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
212 op->out.key = key_out;
217 int cac_RegEnumKeys( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
218 struct RegEnumKeys *op )
220 struct rpc_pipe_client *pipe_hnd = NULL;
222 /*buffers for rpccli_reg_enum_key call */
224 fstring class_name_in;
227 char **key_names_out = NULL;
228 char **class_names_out = NULL;
229 time_t *mod_times_out = NULL;
230 uint32 num_keys_out = 0;
231 uint32 resume_idx = 0;
236 /*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 */
237 if ( NT_STATUS_V( hnd->status ) ==
238 NT_STATUS_V( NT_STATUS_GUIDS_EXHAUSTED ) )
241 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
242 hnd->status = NT_STATUS_INVALID_HANDLE;
246 if ( !op || op->in.max_keys == 0 || !mem_ctx ) {
247 hnd->status = NT_STATUS_INVALID_PARAMETER;
251 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
253 hnd->status = NT_STATUS_INVALID_HANDLE;
257 /**the only way to know how many keys to expect is to assume max_keys keys will be found*/
258 key_names_out = TALLOC_ARRAY( mem_ctx, char *, op->in.max_keys );
259 if ( !key_names_out ) {
260 hnd->status = NT_STATUS_NO_MEMORY;
264 class_names_out = TALLOC_ARRAY( mem_ctx, char *, op->in.max_keys );
265 if ( !class_names_out ) {
266 hnd->status = NT_STATUS_NO_MEMORY;
267 TALLOC_FREE( key_names_out );
271 mod_times_out = TALLOC_ARRAY( mem_ctx, time_t, op->in.max_keys );
272 if ( !mod_times_out ) {
273 hnd->status = NT_STATUS_NO_MEMORY;
274 TALLOC_FREE( key_names_out );
275 TALLOC_FREE( class_names_out );
280 resume_idx = op->out.resume_idx;
286 rpccli_winreg_EnumKey( pipe_hnd, mem_ctx, op->in.key,
287 resume_idx, key_name_in,
293 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
294 /*don't increment any values */
298 key_names_out[num_keys_out] =
299 talloc_strdup( mem_ctx, key_name_in );
301 class_names_out[num_keys_out] =
302 talloc_strdup( mem_ctx, class_name_in );
304 if ( !key_names_out[num_keys_out]
305 || !class_names_out[num_keys_out] ) {
306 hnd->status = NT_STATUS_NO_MEMORY;
312 } while ( num_keys_out < op->in.max_keys );
314 if ( CAC_OP_FAILED( hnd->status ) ) {
315 op->out.num_keys = 0;
319 op->out.resume_idx = resume_idx;
320 op->out.num_keys = num_keys_out;
321 op->out.key_names = key_names_out;
322 op->out.class_names = class_names_out;
323 op->out.mod_times = mod_times_out;
328 int cac_RegCreateKey( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
329 struct RegCreateKey *op )
331 struct rpc_pipe_client *pipe_hnd = NULL;
333 struct RegOpenKey rok;
334 struct winreg_String key_string, class_string;
335 enum winreg_CreateAction action = 0;
340 if ( !hnd->_internal.ctx ) {
341 hnd->status = NT_STATUS_INVALID_HANDLE;
345 if ( !op || !op->in.parent_key || !op->in.key_name || !mem_ctx ) {
346 hnd->status = NT_STATUS_INVALID_PARAMETER;
350 /*first try to open the key - we use cac_RegOpenKey(). this doubles as a way to ensure the winreg pipe is initialized */
353 rok.in.name = op->in.key_name;
354 rok.in.access = op->in.access;
355 rok.in.parent_key = op->in.parent_key;
357 if ( cac_RegOpenKey( hnd, mem_ctx, &rok ) ) {
358 /*then we got the key, return */
359 op->out.key = rok.out.key;
363 /*just be ultra-safe */
364 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
366 hnd->status = NT_STATUS_INVALID_HANDLE;
370 key_out = talloc( mem_ctx, POLICY_HND );
372 hnd->status = NT_STATUS_NO_MEMORY;
376 key_string.name = op->in.key_name;
377 class_string.name = op->in.class_name;
379 rpccli_winreg_CreateKey( pipe_hnd, mem_ctx, op->in.parent_key,
380 key_string, class_string, 0,
381 op->in.access, NULL, key_out,
384 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
388 op->out.key = key_out;
394 WERROR cac_delete_subkeys_recursive( struct rpc_pipe_client * pipe_hnd,
395 TALLOC_CTX * mem_ctx, POLICY_HND * key )
397 /*NOTE: using cac functions might result in a big(ger) memory bloat, and would probably be far less efficient
398 * so we use the cli_reg functions directly*/
400 WERROR err = WERR_OK;
409 while ( W_ERROR_IS_OK( err ) ) {
410 struct winreg_String key_string;
414 status = rpccli_winreg_enum_key( pipe_hnd, mem_ctx, key,
415 cur_key, subkey_name,
416 class_buf, &mod_time_buf );
419 if ( !NT_STATUS_IS_OK( status ) )
422 /*try to open the key with full access */
423 key_string.name = subkey_name;
424 status = rpccli_winreg_OpenKey( pipe_hnd, mem_ctx, key,
425 key_string, 0, REG_KEY_ALL,
428 if ( !NT_STATUS_IS_OK( status ) )
431 err = cac_delete_subkeys_recursive( pipe_hnd, mem_ctx,
434 if ( !W_ERROR_EQUAL( err, WERR_NO_MORE_ITEMS )
435 && !W_ERROR_IS_OK( err ) )
438 /*flush the key just to be safe */
439 rpccli_winreg_FlushKey( pipe_hnd, mem_ctx, key );
441 /*close the key that we opened */
442 rpccli_winreg_CloseKey( pipe_hnd, mem_ctx, &subkey );
444 /*now we delete the subkey */
445 key_string.name = subkey_name;
446 status = rpccli_winreg_DeleteKey( pipe_hnd, mem_ctx, key,
448 err = ntstatus_to_werror( status );
460 int cac_RegDeleteKey( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
461 struct RegDeleteKey *op )
463 struct rpc_pipe_client *pipe_hnd = NULL;
465 struct winreg_String key_string;
470 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
471 hnd->status = NT_STATUS_INVALID_HANDLE;
475 if ( !op || !op->in.parent_key || !op->in.name || !mem_ctx ) {
476 hnd->status = NT_STATUS_INVALID_PARAMETER;
480 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
482 hnd->status = NT_STATUS_INVALID_HANDLE;
486 if ( op->in.recursive ) {
487 /*first open the key, and then delete all of it's subkeys recursively */
488 struct RegOpenKey rok;
492 rok.in.parent_key = op->in.parent_key;
493 rok.in.name = op->in.name;
494 rok.in.access = REG_KEY_ALL;
496 if ( !cac_RegOpenKey( hnd, mem_ctx, &rok ) )
499 err = cac_delete_subkeys_recursive( pipe_hnd, mem_ctx,
502 /*close the key that we opened */
503 cac_RegClose( hnd, mem_ctx, rok.out.key );
505 hnd->status = werror_to_ntstatus( err );
507 if ( NT_STATUS_V( hnd->status ) !=
508 NT_STATUS_V( NT_STATUS_GUIDS_EXHAUSTED )
509 && !NT_STATUS_IS_OK( hnd->status ) )
512 /*now go on to actually delete the key */
515 key_string.name = op->in.name;
517 rpccli_winreg_DeleteKey( pipe_hnd, mem_ctx, op->in.parent_key,
520 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
527 int cac_RegDeleteValue( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
528 struct RegDeleteValue *op )
530 struct rpc_pipe_client *pipe_hnd = NULL;
531 struct winreg_String value_string;
536 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
537 hnd->status = NT_STATUS_INVALID_HANDLE;
541 if ( !op || !op->in.parent_key || !op->in.name || !mem_ctx ) {
542 hnd->status = NT_STATUS_INVALID_PARAMETER;
546 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
548 hnd->status = NT_STATUS_INVALID_HANDLE;
552 value_string.name = op->in.name;
554 rpccli_winreg_DeleteValue( pipe_hnd, mem_ctx,
555 op->in.parent_key, value_string );
557 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
566 /* JRA - disabled until fix. */
568 /* This code is currently broken so disable it - it needs to handle the ERROR_MORE_DATA
569 cleanly and resubmit the query. */
571 int cac_RegQueryKeyInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
572 struct RegQueryKeyInfo *op )
574 struct rpc_pipe_client *pipe_hnd = NULL;
577 char *class_name_out = NULL;
578 uint32 class_len = 0;
579 uint32 num_subkeys_out = 0;
580 uint32 long_subkey_out = 0;
581 uint32 long_class_out = 0;
582 uint32 num_values_out = 0;
583 uint32 long_value_out = 0;
584 uint32 long_data_out = 0;
585 uint32 secdesc_size = 0;
591 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
592 hnd->status = NT_STATUS_INVALID_HANDLE;
596 if ( !op || !op->in.key || !mem_ctx ) {
597 hnd->status = NT_STATUS_INVALID_PARAMETER;
601 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
603 hnd->status = NT_STATUS_INVALID_HANDLE;
607 err = rpccli_reg_query_key( pipe_hnd, mem_ctx, op->in.key,
616 &secdesc_size, &mod_time );
618 hnd->status = werror_to_ntstatus( err );
620 if ( !NT_STATUS_IS_OK( hnd->status ) )
623 if ( !class_name_out ) {
624 op->out.class_name = talloc_strdup( mem_ctx, "" );
625 } else if ( class_len != 0 && class_name_out[class_len - 1] != '\0' ) {
626 /*then we need to add a '\0' */
628 talloc_size( mem_ctx,
629 sizeof( char ) * ( class_len + 1 ) );
631 memcpy( op->out.class_name, class_name_out, class_len );
633 op->out.class_name[class_len] = '\0';
634 } else { /*then everything worked out fine in the function */
635 op->out.class_name = talloc_strdup( mem_ctx, class_name_out );
638 if ( !op->out.class_name ) {
639 hnd->status = NT_STATUS_NO_MEMORY;
643 op->out.num_subkeys = num_subkeys_out;
644 op->out.longest_subkey = long_subkey_out;
645 op->out.longest_class = long_class_out;
646 op->out.num_values = num_values_out;
647 op->out.longest_value_name = long_value_out;
648 op->out.longest_value_data = long_data_out;
649 op->out.security_desc_size = secdesc_size;
650 op->out.last_write_time = nt_time_to_unix( &mod_time );
656 int cac_RegQueryValue( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
657 struct RegQueryValue *op )
659 struct rpc_pipe_client *pipe_hnd = NULL;
660 struct winreg_String value_string;
661 REGVAL_BUFFER buffer;
662 REG_VALUE_DATA *data_out = NULL;
663 enum winreg_Type val_type;
665 uint32 buf_size = 4096;
671 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
672 hnd->status = NT_STATUS_INVALID_HANDLE;
676 if ( !op || !op->in.key || !op->in.val_name || !mem_ctx ) {
677 hnd->status = NT_STATUS_INVALID_PARAMETER;
681 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
683 hnd->status = NT_STATUS_INVALID_HANDLE;
687 value_string.name = op->in.val_name;
689 if ( ( buf = TALLOC_ARRAY( mem_ctx, uint8, buf_size ) ) == NULL ) {
690 hnd->status = NT_STATUS_NO_MEMORY;
694 hnd->status = rpccli_winreg_QueryValue( pipe_hnd, mem_ctx, op->in.key,
695 value_string, &val_type, buf,
696 &buf_size, &length );
698 if ( !NT_STATUS_IS_OK( hnd->status ) )
701 init_regval_buffer( &buffer, buf, length );
703 data_out = cac_MakeRegValueData( mem_ctx, val_type, buffer );
705 if ( errno == ENOMEM )
706 hnd->status = NT_STATUS_NO_MEMORY;
708 hnd->status = NT_STATUS_INVALID_PARAMETER;
713 op->out.type = val_type;
714 op->out.data = data_out;
720 int cac_RegEnumValues( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
721 struct RegEnumValues *op )
723 struct rpc_pipe_client *pipe_hnd = NULL;
725 /*buffers for rpccli_reg_enum_key call */
726 fstring val_name_buf;
727 REGVAL_BUFFER val_buf;
730 uint32 *types_out = NULL;
731 REG_VALUE_DATA **values_out = NULL;
732 char **val_names_out = NULL;
733 uint32 num_values_out = 0;
734 uint32 resume_idx = 0;
739 /*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 */
740 if ( NT_STATUS_V( hnd->status ) ==
741 NT_STATUS_V( NT_STATUS_GUIDS_EXHAUSTED ) )
744 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
745 hnd->status = NT_STATUS_INVALID_HANDLE;
749 if ( !op || !op->in.key || op->in.max_values == 0 || !mem_ctx ) {
750 hnd->status = NT_STATUS_INVALID_PARAMETER;
754 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
756 hnd->status = NT_STATUS_INVALID_HANDLE;
760 /*we need to assume that the max number of values will be enumerated */
762 ( uint32 * ) talloc_array( mem_ctx, int, op->in.max_values );
764 hnd->status = NT_STATUS_NO_MEMORY;
769 talloc_array( mem_ctx, REG_VALUE_DATA *, op->in.max_values );
771 TALLOC_FREE( types_out );
772 hnd->status = NT_STATUS_NO_MEMORY;
776 val_names_out = talloc_array( mem_ctx, char *, op->in.max_values );
777 if ( !val_names_out ) {
778 TALLOC_FREE( types_out );
779 TALLOC_FREE( values_out );
780 hnd->status = NT_STATUS_NO_MEMORY;
784 resume_idx = op->out.resume_idx;
786 ZERO_STRUCT( val_buf );
790 rpccli_winreg_enum_val( pipe_hnd, mem_ctx, op->in.key,
791 resume_idx, val_name_buf,
792 &types_out[num_values_out],
796 if ( !NT_STATUS_IS_OK( hnd->status ) )
799 values_out[num_values_out] =
800 cac_MakeRegValueData( mem_ctx,
801 types_out[num_values_out],
803 val_names_out[num_values_out] =
804 talloc_strdup( mem_ctx, val_name_buf );
806 if ( !val_names_out[num_values_out]
807 || !values_out[num_values_out] ) {
808 hnd->status = NT_STATUS_NO_MEMORY;
814 } while ( num_values_out < op->in.max_values );
816 if ( CAC_OP_FAILED( hnd->status ) )
819 op->out.types = types_out;
820 op->out.num_values = num_values_out;
821 op->out.value_names = val_names_out;
822 op->out.values = values_out;
823 op->out.resume_idx = resume_idx;
828 int cac_RegSetValue( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
829 struct RegSetValue *op )
831 struct rpc_pipe_client *pipe_hnd = NULL;
832 struct winreg_String value_string;
834 RPC_DATA_BLOB *buffer;
839 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
840 hnd->status = NT_STATUS_INVALID_HANDLE;
844 if ( !op || !op->in.key || !op->in.val_name || !mem_ctx ) {
845 hnd->status = NT_STATUS_INVALID_PARAMETER;
849 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
851 hnd->status = NT_STATUS_INVALID_HANDLE;
855 buffer = cac_MakeRpcDataBlob( mem_ctx, op->in.type, op->in.value );
858 if ( errno == ENOMEM )
859 hnd->status = NT_STATUS_NO_MEMORY;
861 hnd->status = NT_STATUS_INVALID_PARAMETER;
866 value_string.name = op->in.val_name;
868 rpccli_winreg_SetValue( pipe_hnd, mem_ctx, op->in.key,
869 value_string, op->in.type,
870 buffer->buffer, buffer->buf_len );
872 if ( !NT_STATUS_IS_OK( hnd->status ) )
876 hnd->status = rpccli_winreg_FlushKey( pipe_hnd, mem_ctx, op->in.key );
878 if ( !NT_STATUS_IS_OK( hnd->status ) )
886 int cac_RegGetVersion( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
887 struct RegGetVersion *op )
889 struct rpc_pipe_client *pipe_hnd = NULL;
895 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
896 hnd->status = NT_STATUS_INVALID_HANDLE;
900 if ( !op || !op->in.key || !mem_ctx ) {
901 hnd->status = NT_STATUS_INVALID_PARAMETER;
905 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
907 hnd->status = NT_STATUS_INVALID_HANDLE;
912 rpccli_winreg_GetVersion( pipe_hnd, mem_ctx, op->in.key,
915 if ( !NT_STATUS_IS_OK( hnd->status ) )
918 op->out.version = version_out;
923 int cac_RegGetKeySecurity( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
924 struct RegGetKeySecurity *op )
926 struct rpc_pipe_client *pipe_hnd = NULL;
927 struct KeySecurityData keysec;
929 ZERO_STRUCT( keysec );
934 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
935 hnd->status = NT_STATUS_INVALID_HANDLE;
939 if ( !op || !op->in.key || op->in.info_type == 0 || !mem_ctx ) {
940 hnd->status = NT_STATUS_INVALID_PARAMETER;
944 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
946 hnd->status = NT_STATUS_INVALID_HANDLE;
951 rpccli_winreg_GetKeySecurity( pipe_hnd, mem_ctx, op->in.key,
952 op->in.info_type, &keysec );
954 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
957 #if 0 /* FIX ME!!!! unmarshall the security descriptor */
958 op->out.size = buf.sd_size;
959 op->out.descriptor = dup_sec_desc( mem_ctx, buf.sd );
962 if ( op->out.descriptor == NULL ) {
969 int cac_RegSetKeySecurity( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
970 struct RegSetKeySecurity *op )
972 struct rpc_pipe_client *pipe_hnd = NULL;
973 struct KeySecurityData keysec;
975 ZERO_STRUCT( keysec );
980 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
981 hnd->status = NT_STATUS_INVALID_HANDLE;
985 if ( !op || !op->in.key || op->in.info_type == 0 || op->in.size == 0
986 || !op->in.descriptor || !mem_ctx ) {
987 hnd->status = NT_STATUS_INVALID_PARAMETER;
991 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
993 hnd->status = NT_STATUS_INVALID_HANDLE;
997 /* FIXME!!! Marshall in the input sec_desc to struct KeySecurityData */
999 rpccli_winreg_SetKeySecurity( pipe_hnd, mem_ctx, op->in.key,
1000 op->in.info_type, &keysec );
1002 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1009 int cac_Shutdown( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1010 struct Shutdown *op )
1012 SMBCSRV *srv = NULL;
1013 struct rpc_pipe_client *pipe_hnd = NULL;
1014 struct initshutdown_String msg_string;
1015 struct initshutdown_String_sub s;
1022 if ( !hnd->_internal.ctx ) {
1023 hnd->status = NT_STATUS_INVALID_HANDLE;
1027 if ( !op || !mem_ctx ) {
1028 hnd->status = NT_STATUS_INVALID_PARAMETER;
1032 srv = cac_GetServer( hnd );
1034 hnd->status = NT_STATUS_INVALID_HANDLE;
1038 /*initialize for winreg pipe if we have to */
1039 if ( !hnd->_internal.pipes[PI_INITSHUTDOWN] ) {
1042 cli_rpc_pipe_open_noauth( srv->cli, PI_INITSHUTDOWN,
1043 &( hnd->status ) ) ) ) {
1047 hnd->_internal.pipes[PI_INITSHUTDOWN] = True;
1050 pipe_hnd = cac_GetPipe( hnd, PI_INITSHUTDOWN );
1052 hnd->status = NT_STATUS_INVALID_HANDLE;
1056 msg = ( op->in.message !=
1057 NULL ) ? op->in.message : talloc_strdup( mem_ctx, "" );
1058 msg_string.name = &s;
1059 msg_string.name->name = msg;
1061 hnd->status = NT_STATUS_OK;
1063 if ( hnd->_internal.srv_level > SRV_WIN_NT4 ) {
1065 rpccli_initshutdown_InitEx( pipe_hnd, mem_ctx, NULL,
1073 if ( hnd->_internal.srv_level < SRV_WIN_2K
1074 || !NT_STATUS_IS_OK( hnd->status ) ) {
1076 rpccli_initshutdown_Init( pipe_hnd, mem_ctx, NULL,
1077 &msg_string, op->in.timeout,
1081 hnd->_internal.srv_level = SRV_WIN_NT4;
1084 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1091 int cac_AbortShutdown( CacServerHandle * hnd, TALLOC_CTX * mem_ctx )
1093 struct rpc_pipe_client *pipe_hnd = NULL;
1098 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_INITSHUTDOWN] ) {
1099 hnd->status = NT_STATUS_INVALID_HANDLE;
1103 pipe_hnd = cac_GetPipe( hnd, PI_INITSHUTDOWN );
1105 hnd->status = NT_STATUS_INVALID_HANDLE;
1109 hnd->status = rpccli_initshutdown_Abort( pipe_hnd, mem_ctx, NULL );
1111 if ( !NT_STATUS_IS_OK( hnd->status ) )