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
237 exhausted all the keys, then we don't need to go
238 through everything again */
240 if ( NT_STATUS_V( hnd->status ) ==
241 NT_STATUS_V( NT_STATUS_GUIDS_EXHAUSTED ) )
244 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
245 hnd->status = NT_STATUS_INVALID_HANDLE;
249 if ( !op || op->in.max_keys == 0 || !mem_ctx ) {
250 hnd->status = NT_STATUS_INVALID_PARAMETER;
254 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
256 hnd->status = NT_STATUS_INVALID_HANDLE;
260 /* The only way to know how many keys to expect is to
261 assume max_keys keys will be found */
263 key_names_out = TALLOC_ARRAY( mem_ctx, char *, op->in.max_keys );
264 if ( !key_names_out ) {
265 hnd->status = NT_STATUS_NO_MEMORY;
269 class_names_out = TALLOC_ARRAY( mem_ctx, char *, op->in.max_keys );
270 if ( !class_names_out ) {
271 hnd->status = NT_STATUS_NO_MEMORY;
272 TALLOC_FREE( key_names_out );
276 mod_times_out = TALLOC_ARRAY( mem_ctx, time_t, op->in.max_keys );
277 if ( !mod_times_out ) {
278 hnd->status = NT_STATUS_NO_MEMORY;
279 TALLOC_FREE( key_names_out );
280 TALLOC_FREE( class_names_out );
285 resume_idx = op->out.resume_idx;
290 rpccli_winreg_EnumKey( pipe_hnd, mem_ctx, op->in.key,
291 resume_idx, key_name_in,
296 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
297 /*don't increment any values */
301 key_names_out[num_keys_out] =
302 talloc_strdup( mem_ctx, key_name_in );
304 class_names_out[num_keys_out] =
305 talloc_strdup( mem_ctx, class_name_in );
307 if ( !key_names_out[num_keys_out]
308 || !class_names_out[num_keys_out] ) {
309 hnd->status = NT_STATUS_NO_MEMORY;
315 } while ( num_keys_out < op->in.max_keys );
317 if ( CAC_OP_FAILED( hnd->status ) ) {
318 op->out.num_keys = 0;
322 op->out.resume_idx = resume_idx;
323 op->out.num_keys = num_keys_out;
324 op->out.key_names = key_names_out;
325 op->out.class_names = class_names_out;
326 op->out.mod_times = mod_times_out;
331 int cac_RegCreateKey( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
332 struct RegCreateKey *op )
334 struct rpc_pipe_client *pipe_hnd = NULL;
336 struct RegOpenKey rok;
337 struct winreg_String key_string, class_string;
338 enum winreg_CreateAction action = 0;
339 enum winreg_CreateAction *paction = &action;
344 if ( !hnd->_internal.ctx ) {
345 hnd->status = NT_STATUS_INVALID_HANDLE;
349 if ( !op || !op->in.parent_key || !op->in.key_name || !mem_ctx ) {
350 hnd->status = NT_STATUS_INVALID_PARAMETER;
354 /*first try to open the key - we use cac_RegOpenKey(). this doubles as a way to ensure the winreg pipe is initialized */
357 rok.in.name = op->in.key_name;
358 rok.in.access = op->in.access;
359 rok.in.parent_key = op->in.parent_key;
361 if ( cac_RegOpenKey( hnd, mem_ctx, &rok ) ) {
362 /*then we got the key, return */
363 op->out.key = rok.out.key;
367 /*just be ultra-safe */
368 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
370 hnd->status = NT_STATUS_INVALID_HANDLE;
374 key_out = talloc( mem_ctx, POLICY_HND );
376 hnd->status = NT_STATUS_NO_MEMORY;
380 key_string.name = op->in.key_name;
381 class_string.name = op->in.class_name;
383 rpccli_winreg_CreateKey( pipe_hnd, mem_ctx, op->in.parent_key,
384 key_string, class_string, 0,
385 op->in.access, NULL, key_out,
388 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
392 op->out.key = key_out;
398 NTSTATUS cac_delete_subkeys_recursive( struct rpc_pipe_client * pipe_hnd,
399 TALLOC_CTX * mem_ctx, POLICY_HND * key )
405 uint32 num_subkeys, max_subkeylen, max_classlen;
406 uint32 num_values, max_valnamelen, maxvalbufsize;
408 struct winreg_String class_string;
413 /* First get the max subkey name length */
415 class_string.name = NULL;
416 status = rpccli_winreg_QueryInfoKey( pipe_hnd, mem_ctx, key,
417 &class_string, &num_subkeys,
418 &max_subkeylen, &max_classlen,
419 &num_values, &max_valnamelen,
420 &maxvalbufsize, &secdescsize,
424 if ( !NT_STATUS_IS_OK( status ) ) {
428 if ( (name_buffer = TALLOC_ARRAY( mem_ctx, char, max_subkeylen )) == NULL ) {
429 d_fprintf(stderr, "Memory allocation error.\n");
430 return NT_STATUS_NO_MEMORY;
434 while ( NT_STATUS_IS_OK( status ) ) {
435 struct winreg_String key_string;
436 struct winreg_StringBuf subkey_string;
439 memset( name_buffer, 0x0, max_subkeylen );
440 subkey_string.name = name_buffer;
441 subkey_string.length = 0;
442 subkey_string.size = max_subkeylen;
444 status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key, cur_key,
445 &subkey_string, NULL, NULL);
447 if ( !NT_STATUS_IS_OK( status ) )
450 /* copy the keyname and add the terminating NULL */
452 StrnCpy( subkeyname, subkey_string.name,
453 MIN(subkey_string.length, sizeof(subkeyname)-1) );
454 subkeyname[MIN(subkey_string.length, sizeof(subkeyname)-1)] = '\0';
456 /*try to open the key with full access */
458 key_string.name = subkeyname;
459 status = rpccli_winreg_OpenKey( pipe_hnd, mem_ctx, key,
460 key_string, 0, REG_KEY_ALL,
463 if ( !NT_STATUS_IS_OK( status ) )
466 status = cac_delete_subkeys_recursive( pipe_hnd, mem_ctx,
469 if ( !W_ERROR_EQUAL( ntstatus_to_werror(status), WERR_NO_MORE_ITEMS )
470 && !NT_STATUS_IS_OK( status ) )
473 /*flush the key just to be safe */
474 rpccli_winreg_FlushKey( pipe_hnd, mem_ctx, key );
476 /*close the key that we opened */
477 rpccli_winreg_CloseKey( pipe_hnd, mem_ctx, &subkey );
479 /*now we delete the subkey */
480 key_string.name = subkey_name;
481 status = rpccli_winreg_DeleteKey( pipe_hnd, mem_ctx, key,
493 int cac_RegDeleteKey( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
494 struct RegDeleteKey *op )
496 struct rpc_pipe_client *pipe_hnd = NULL;
497 struct winreg_String key_string;
502 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
503 hnd->status = NT_STATUS_INVALID_HANDLE;
507 if ( !op || !op->in.parent_key || !op->in.name || !mem_ctx ) {
508 hnd->status = NT_STATUS_INVALID_PARAMETER;
512 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
514 hnd->status = NT_STATUS_INVALID_HANDLE;
518 if ( op->in.recursive ) {
520 /* first open the key, and then delete all of
521 it's subkeys recursively */
523 struct RegOpenKey rok;
527 rok.in.parent_key = op->in.parent_key;
528 rok.in.name = op->in.name;
529 rok.in.access = REG_KEY_ALL;
531 if ( !cac_RegOpenKey( hnd, mem_ctx, &rok ) )
534 hnd->status = cac_delete_subkeys_recursive( pipe_hnd, mem_ctx,
537 /*close the key that we opened */
538 cac_RegClose( hnd, mem_ctx, rok.out.key );
540 if ( NT_STATUS_V( hnd->status ) !=
541 NT_STATUS_V( NT_STATUS_GUIDS_EXHAUSTED )
542 && !NT_STATUS_IS_OK( hnd->status ) )
545 /*now go on to actually delete the key */
548 key_string.name = op->in.name;
550 rpccli_winreg_DeleteKey( pipe_hnd, mem_ctx, op->in.parent_key,
553 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
560 int cac_RegDeleteValue( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
561 struct RegDeleteValue *op )
563 struct rpc_pipe_client *pipe_hnd = NULL;
564 struct winreg_String value_string;
569 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
570 hnd->status = NT_STATUS_INVALID_HANDLE;
574 if ( !op || !op->in.parent_key || !op->in.name || !mem_ctx ) {
575 hnd->status = NT_STATUS_INVALID_PARAMETER;
579 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
581 hnd->status = NT_STATUS_INVALID_HANDLE;
585 value_string.name = op->in.name;
587 rpccli_winreg_DeleteValue( pipe_hnd, mem_ctx,
588 op->in.parent_key, value_string );
590 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
597 int cac_RegQueryKeyInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
598 struct RegQueryKeyInfo *op )
600 struct rpc_pipe_client *pipe_hnd = NULL;
601 uint32 num_subkeys_out = 0;
602 uint32 long_subkey_out = 0;
603 uint32 long_class_out = 0;
604 uint32 num_values_out = 0;
605 uint32 long_value_out = 0;
606 uint32 long_data_out = 0;
607 uint32 secdesc_size = 0;
609 struct winreg_String class_string;
614 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
615 hnd->status = NT_STATUS_INVALID_HANDLE;
619 if ( !op || !op->in.key || !mem_ctx ) {
620 hnd->status = NT_STATUS_INVALID_PARAMETER;
624 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
626 hnd->status = NT_STATUS_INVALID_HANDLE;
630 hnd->status = rpccli_winreg_QueryInfoKey( pipe_hnd, mem_ctx,
639 &secdesc_size, &mod_time );
641 if ( !NT_STATUS_IS_OK( hnd->status ) )
644 if ( !class_string.name ) {
645 op->out.class_name = talloc_strdup( mem_ctx, "" );
647 op->out.class_name = talloc_strdup( mem_ctx, class_string.name );
650 if ( !op->out.class_name ) {
651 hnd->status = NT_STATUS_NO_MEMORY;
655 op->out.num_subkeys = num_subkeys_out;
656 op->out.longest_subkey = long_subkey_out;
657 op->out.longest_class = long_class_out;
658 op->out.num_values = num_values_out;
659 op->out.longest_value_name = long_value_out;
660 op->out.longest_value_data = long_data_out;
661 op->out.security_desc_size = secdesc_size;
662 op->out.last_write_time = nt_time_to_unix( mod_time );
667 int cac_RegQueryValue( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
668 struct RegQueryValue *op )
670 struct rpc_pipe_client *pipe_hnd = NULL;
671 struct winreg_String value_string;
672 REGVAL_BUFFER buffer;
673 REG_VALUE_DATA *data_out = NULL;
674 enum winreg_Type val_type;
675 enum winreg_Type *pval_type = &val_type;
677 uint32 buf_size = 4096;
678 uint32 *pbuf_size = &buf_size;
680 uint32 *plength = &length;
685 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
686 hnd->status = NT_STATUS_INVALID_HANDLE;
690 if ( !op || !op->in.key || !op->in.val_name || !mem_ctx ) {
691 hnd->status = NT_STATUS_INVALID_PARAMETER;
695 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
697 hnd->status = NT_STATUS_INVALID_HANDLE;
701 value_string.name = op->in.val_name;
703 if ( ( buf = TALLOC_ARRAY( mem_ctx, uint8, buf_size ) ) == NULL ) {
704 hnd->status = NT_STATUS_NO_MEMORY;
708 hnd->status = rpccli_winreg_QueryValue( pipe_hnd, mem_ctx, op->in.key,
709 value_string, &pval_type, &buf,
710 &pbuf_size, &plength );
712 if ( !NT_STATUS_IS_OK( hnd->status ) )
715 init_regval_buffer( &buffer, buf, length );
717 data_out = cac_MakeRegValueData( mem_ctx, val_type, buffer );
719 if ( errno == ENOMEM )
720 hnd->status = NT_STATUS_NO_MEMORY;
722 hnd->status = NT_STATUS_INVALID_PARAMETER;
727 op->out.type = val_type;
728 op->out.data = data_out;
734 int cac_RegEnumValues( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
735 struct RegEnumValues *op )
737 struct rpc_pipe_client *pipe_hnd = NULL;
739 REGVAL_BUFFER val_buf;
740 uint32 *types_out = NULL;
741 REG_VALUE_DATA **values_out = NULL;
742 char **val_names_out = NULL;
743 uint32 num_values_out = 0;
744 uint32 resume_idx = 0;
745 uint32 num_subkeys, max_subkeylen, max_classlen;
746 uint32 num_values, max_valnamelen, maxvalbufsize;
747 struct winreg_String class_string;
755 /* This is to avoid useless rpc calls, if the last
756 call exhausted all the keys, then we don't need
757 to go through everything again */
759 if ( NT_STATUS_V( hnd->status ) ==
760 NT_STATUS_V( NT_STATUS_GUIDS_EXHAUSTED ) )
763 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
764 hnd->status = NT_STATUS_INVALID_HANDLE;
768 if ( !op || !op->in.key || op->in.max_values == 0 || !mem_ctx ) {
769 hnd->status = NT_STATUS_INVALID_PARAMETER;
773 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
775 hnd->status = NT_STATUS_INVALID_HANDLE;
779 /*we need to assume that the max number of values will be enumerated */
780 types_out = talloc_array( mem_ctx, uint32, op->in.max_values );
783 hnd->status = NT_STATUS_NO_MEMORY;
787 values_out = talloc_array( mem_ctx, REG_VALUE_DATA *,
791 TALLOC_FREE( types_out );
792 hnd->status = NT_STATUS_NO_MEMORY;
796 val_names_out = talloc_array( mem_ctx, char *, op->in.max_values );
798 if ( !val_names_out ) {
799 TALLOC_FREE( types_out );
800 TALLOC_FREE( values_out );
801 hnd->status = NT_STATUS_NO_MEMORY;
805 resume_idx = op->out.resume_idx;
807 class_string.name = NULL;
808 hnd->status = rpccli_winreg_QueryInfoKey( pipe_hnd, mem_ctx, op->in.key,
809 &class_string, &num_subkeys,
810 &max_subkeylen, &max_classlen,
811 &num_values, &max_valnamelen,
812 &maxvalbufsize, &secdescsize,
815 if ( !NT_STATUS_IS_OK(hnd->status) ) {
816 TALLOC_FREE( types_out );
817 TALLOC_FREE( values_out );
822 if ( (buffer = TALLOC_ARRAY( mem_ctx, uint8, maxvalbufsize )) == NULL ) {
823 TALLOC_FREE( types_out );
824 TALLOC_FREE( values_out );
825 hnd->status = NT_STATUS_NO_MEMORY;
830 if ( (name_buffer = TALLOC_ARRAY(mem_ctx, char, max_valnamelen)) == NULL ) {
831 TALLOC_FREE( types_out );
832 TALLOC_FREE( values_out );
833 TALLOC_FREE( buffer );
834 hnd->status = NT_STATUS_NO_MEMORY;
840 uint32 data_size = maxvalbufsize;
841 uint32 *pdata_size = &data_size;
842 uint32 data_length = 0;
843 uint32 *pdata_length = &data_length;
844 struct winreg_StringBuf name_buf;
845 enum winreg_Type *ptype = &types_out[num_values_out];
847 memset( name_buffer, 0x0, max_valnamelen );
848 name_buf.name = name_buffer;
849 name_buf.size = max_valnamelen;
852 hnd->status = rpccli_winreg_EnumValue( pipe_hnd, mem_ctx,
854 resume_idx, &name_buf,
859 if ( !NT_STATUS_IS_OK( hnd->status ) )
862 ZERO_STRUCT( val_buf );
863 init_regval_buffer( &val_buf, buffer, data_length );
865 values_out[num_values_out] = cac_MakeRegValueData( mem_ctx,
866 types_out[num_values_out],
868 val_names_out[num_values_out] = TALLOC_ARRAY( mem_ctx, char, name_buf.length+1 );
870 if ( !val_names_out[num_values_out]
871 || !values_out[num_values_out] ) {
872 hnd->status = NT_STATUS_NO_MEMORY;
876 StrnCpy( val_names_out[num_values_out], name_buf.name, name_buf.length );
877 (val_names_out[num_values_out])[name_buf.length] = '\0';
881 } while ( num_values_out < op->in.max_values );
883 if ( CAC_OP_FAILED( hnd->status ) )
886 op->out.types = types_out;
887 op->out.num_values = num_values_out;
888 op->out.value_names = val_names_out;
889 op->out.values = values_out;
890 op->out.resume_idx = resume_idx;
895 int cac_RegSetValue( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
896 struct RegSetValue *op )
898 struct rpc_pipe_client *pipe_hnd = NULL;
899 struct winreg_String value_string;
901 RPC_DATA_BLOB *buffer;
906 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
907 hnd->status = NT_STATUS_INVALID_HANDLE;
911 if ( !op || !op->in.key || !op->in.val_name || !mem_ctx ) {
912 hnd->status = NT_STATUS_INVALID_PARAMETER;
916 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
918 hnd->status = NT_STATUS_INVALID_HANDLE;
922 buffer = cac_MakeRpcDataBlob( mem_ctx, op->in.type, op->in.value );
925 if ( errno == ENOMEM )
926 hnd->status = NT_STATUS_NO_MEMORY;
928 hnd->status = NT_STATUS_INVALID_PARAMETER;
933 value_string.name = op->in.val_name;
935 rpccli_winreg_SetValue( pipe_hnd, mem_ctx, op->in.key,
936 value_string, op->in.type,
937 buffer->buffer, buffer->buf_len );
939 if ( !NT_STATUS_IS_OK( hnd->status ) )
943 hnd->status = rpccli_winreg_FlushKey( pipe_hnd, mem_ctx, op->in.key );
945 if ( !NT_STATUS_IS_OK( hnd->status ) )
953 int cac_RegGetVersion( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
954 struct RegGetVersion *op )
956 struct rpc_pipe_client *pipe_hnd = NULL;
962 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
963 hnd->status = NT_STATUS_INVALID_HANDLE;
967 if ( !op || !op->in.key || !mem_ctx ) {
968 hnd->status = NT_STATUS_INVALID_PARAMETER;
972 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
974 hnd->status = NT_STATUS_INVALID_HANDLE;
979 rpccli_winreg_GetVersion( pipe_hnd, mem_ctx, op->in.key,
982 if ( !NT_STATUS_IS_OK( hnd->status ) )
985 op->out.version = version_out;
990 int cac_RegGetKeySecurity( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
991 struct RegGetKeySecurity *op )
993 struct rpc_pipe_client *pipe_hnd = NULL;
994 struct KeySecurityData keysec;
996 ZERO_STRUCT( keysec );
1001 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
1002 hnd->status = NT_STATUS_INVALID_HANDLE;
1006 if ( !op || !op->in.key || op->in.info_type == 0 || !mem_ctx ) {
1007 hnd->status = NT_STATUS_INVALID_PARAMETER;
1011 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
1013 hnd->status = NT_STATUS_INVALID_HANDLE;
1018 rpccli_winreg_GetKeySecurity( pipe_hnd, mem_ctx, op->in.key,
1019 op->in.info_type, &keysec );
1021 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1025 #if 0 /* FIX ME!!!! unmarshall the security descriptor */
1026 op->out.size = buf.sd_size;
1027 op->out.descriptor = dup_sec_desc( mem_ctx, buf.sd );
1030 if ( op->out.descriptor == NULL ) {
1037 int cac_RegSetKeySecurity( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1038 struct RegSetKeySecurity *op )
1040 struct rpc_pipe_client *pipe_hnd = NULL;
1041 struct KeySecurityData keysec;
1043 ZERO_STRUCT( keysec );
1048 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_WINREG] ) {
1049 hnd->status = NT_STATUS_INVALID_HANDLE;
1053 if ( !op || !op->in.key || op->in.info_type == 0 || op->in.size == 0
1054 || !op->in.descriptor || !mem_ctx ) {
1055 hnd->status = NT_STATUS_INVALID_PARAMETER;
1059 pipe_hnd = cac_GetPipe( hnd, PI_WINREG );
1061 hnd->status = NT_STATUS_INVALID_HANDLE;
1065 /* FIXME!!! Marshall in the input sec_desc to struct KeySecurityData */
1067 rpccli_winreg_SetKeySecurity( pipe_hnd, mem_ctx, op->in.key,
1068 op->in.info_type, &keysec );
1070 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1077 int cac_Shutdown( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1078 struct Shutdown *op )
1080 SMBCSRV *srv = NULL;
1081 struct rpc_pipe_client *pipe_hnd = NULL;
1082 struct initshutdown_String msg_string;
1083 struct initshutdown_String_sub s;
1090 if ( !hnd->_internal.ctx ) {
1091 hnd->status = NT_STATUS_INVALID_HANDLE;
1095 if ( !op || !mem_ctx ) {
1096 hnd->status = NT_STATUS_INVALID_PARAMETER;
1100 srv = cac_GetServer( hnd );
1102 hnd->status = NT_STATUS_INVALID_HANDLE;
1106 /*initialize for winreg pipe if we have to */
1107 if ( !hnd->_internal.pipes[PI_INITSHUTDOWN] ) {
1110 cli_rpc_pipe_open_noauth( srv->cli, PI_INITSHUTDOWN,
1111 &( hnd->status ) ) ) ) {
1115 hnd->_internal.pipes[PI_INITSHUTDOWN] = True;
1118 pipe_hnd = cac_GetPipe( hnd, PI_INITSHUTDOWN );
1120 hnd->status = NT_STATUS_INVALID_HANDLE;
1124 msg = ( op->in.message !=
1125 NULL ) ? op->in.message : talloc_strdup( mem_ctx, "" );
1126 msg_string.name = &s;
1127 msg_string.name->name = msg;
1129 hnd->status = NT_STATUS_OK;
1131 if ( hnd->_internal.srv_level > SRV_WIN_NT4 ) {
1133 rpccli_initshutdown_InitEx( pipe_hnd, mem_ctx, NULL,
1141 if ( hnd->_internal.srv_level < SRV_WIN_2K
1142 || !NT_STATUS_IS_OK( hnd->status ) ) {
1144 rpccli_initshutdown_Init( pipe_hnd, mem_ctx, NULL,
1145 &msg_string, op->in.timeout,
1149 hnd->_internal.srv_level = SRV_WIN_NT4;
1152 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1159 int cac_AbortShutdown( CacServerHandle * hnd, TALLOC_CTX * mem_ctx )
1161 struct rpc_pipe_client *pipe_hnd = NULL;
1166 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_INITSHUTDOWN] ) {
1167 hnd->status = NT_STATUS_INVALID_HANDLE;
1171 pipe_hnd = cac_GetPipe( hnd, PI_INITSHUTDOWN );
1173 hnd->status = NT_STATUS_INVALID_HANDLE;
1177 hnd->status = rpccli_initshutdown_Abort( pipe_hnd, mem_ctx, NULL );
1179 if ( !NT_STATUS_IS_OK( hnd->status ) )