2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
5 * Copyright (C) Gerald Carter 2002-2006.
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.
22 /* Implementation of registry functions. */
28 #define DBGC_CLASS DBGC_RPC_SRV
30 static struct generic_mapping reg_generic_map =
31 { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL };
33 /******************************************************************
34 free() function for struct regkey_info
35 *****************************************************************/
37 static void free_regkey(void *ptr)
39 struct registry_key *key = (struct registry_key *)ptr;
43 /******************************************************************
44 Find a registry key handle and return a REGISTRY_KEY
45 *****************************************************************/
47 static struct registry_key *find_regkey_by_hnd(pipes_struct *p,
50 struct registry_key *regkey = NULL;
52 if(!find_policy_by_hnd(p,hnd,(void **)(void *)®key)) {
53 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
60 /*******************************************************************
61 Function for open a new registry handle and creating a handle
62 Note that P should be valid & hnd should already have space
64 When we open a key, we store the full path to the key as
65 HK[LM|U]\<key>\<key>\...
66 *******************************************************************/
68 static WERROR open_registry_key( pipes_struct *p, POLICY_HND *hnd,
69 struct registry_key *parent,
70 const char *subkeyname,
71 uint32 access_desired )
73 WERROR result = WERR_OK;
74 struct registry_key *key;
76 /* now do the internal open */
79 result = reg_openhive(NULL, subkeyname, access_desired,
80 p->pipe_user.nt_user_token, &key);
83 result = reg_openkey(NULL, parent, subkeyname, access_desired,
87 if ( !W_ERROR_IS_OK(result) ) {
91 if ( !create_policy_hnd( p, hnd, free_regkey, key ) ) {
98 /*******************************************************************
99 Function for open a new registry handle and creating a handle
100 Note that P should be valid & hnd should already have space
101 *******************************************************************/
103 static BOOL close_registry_key(pipes_struct *p, POLICY_HND *hnd)
105 struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
108 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
113 close_policy_hnd(p, hnd);
118 /********************************************************************
120 ********************************************************************/
122 WERROR _winreg_CloseKey(pipes_struct *p, struct policy_handle *handle)
124 /* close the policy handle */
126 if (!close_registry_key(p, handle))
129 ZERO_STRUCTP(handle);
134 /*******************************************************************
135 ********************************************************************/
137 WERROR _winreg_OpenHKLM(pipes_struct *p, uint16_t *system_name, uint32_t access_mask, struct policy_handle *handle)
139 return open_registry_key(p, handle, NULL, KEY_HKLM, access_mask);
142 /*******************************************************************
143 ********************************************************************/
145 WERROR _winreg_OpenHKPD(pipes_struct *p, uint16_t *system_name,
146 uint32_t access_mask, struct policy_handle *handle)
148 return open_registry_key(p, handle, NULL, KEY_HKPD, access_mask);
151 /*******************************************************************
152 ********************************************************************/
154 WERROR _winreg_OpenHKPT(pipes_struct *p, uint16_t *system_name,
155 uint32_t access_mask, struct policy_handle *handle)
157 return open_registry_key(p, handle, NULL, KEY_HKPT, access_mask);
160 /*******************************************************************
161 ********************************************************************/
163 WERROR _winreg_OpenHKCR(pipes_struct *p, uint16_t *system_name,
164 uint32_t access_mask, struct policy_handle *handle)
166 return open_registry_key(p, handle, NULL, KEY_HKCR, access_mask);
169 /*******************************************************************
170 ********************************************************************/
172 WERROR _winreg_OpenHKU(pipes_struct *p, uint16_t *system_name,
173 uint32_t access_mask, struct policy_handle *handle)
175 return open_registry_key(p, handle, NULL, KEY_HKU, access_mask);
178 /*******************************************************************
179 ********************************************************************/
181 WERROR _winreg_OpenHKCU(pipes_struct *p, uint16_t *system_name,
182 uint32_t access_mask, struct policy_handle *handle)
184 return open_registry_key(p, handle, NULL, KEY_HKCU, access_mask);
187 /*******************************************************************
188 ********************************************************************/
190 WERROR _winreg_OpenHKCC(pipes_struct *p, uint16_t *system_name,
191 uint32_t access_mask, struct policy_handle *handle)
193 return open_registry_key(p, handle, NULL, KEY_HKCC, access_mask);
196 /*******************************************************************
197 ********************************************************************/
199 WERROR _winreg_OpenHKDD(pipes_struct *p, uint16_t *system_name,
200 uint32_t access_mask, struct policy_handle *handle)
202 return open_registry_key(p, handle, NULL, KEY_HKDD, access_mask);
205 /*******************************************************************
206 ********************************************************************/
208 WERROR _winreg_OpenHKPN(pipes_struct *p, uint16_t *system_name,
209 uint32_t access_mask, struct policy_handle *handle)
211 return open_registry_key(p, handle, NULL, KEY_HKPN, access_mask);
214 /*******************************************************************
216 ********************************************************************/
218 WERROR _winreg_OpenKey(pipes_struct *p, struct policy_handle *parent_handle,
219 struct winreg_String keyname, uint32_t unknown,
220 uint32_t access_mask, struct policy_handle *handle)
222 struct registry_key *parent = find_regkey_by_hnd(p, parent_handle );
227 return open_registry_key(p, handle, parent, keyname.name, access_mask);
230 /*******************************************************************
232 ********************************************************************/
234 WERROR _winreg_QueryValue(pipes_struct *p, struct policy_handle *handle,
235 struct winreg_String value_name,
236 enum winreg_Type *type, uint8_t *data,
237 uint32_t *data_size, uint32_t *value_length)
239 WERROR status = WERR_BADFILE;
240 struct registry_key *regkey = find_regkey_by_hnd( p, handle );
244 uint32_t outbuf_size;
247 BOOL free_buf = False;
248 BOOL free_prs = False;
253 *value_length = *type = 0;
255 DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->key->name));
256 DEBUG(7,("_reg_info: policy key type = [%08x]\n", regkey->key->type));
258 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
259 if(regkey->key->type == REG_KEY_HKPD)
261 if(strequal(value_name.name, "Global")) {
262 prs_init(&prs_hkpd, *data_size, p->mem_ctx, MARSHALL);
263 status = reg_perfcount_get_hkpd(
264 &prs_hkpd, *data_size, &outbuf_size, NULL);
265 outbuf = (uint8_t *)prs_hkpd.data_p;
268 else if(strequal(value_name.name, "Counter 009")) {
269 outbuf_size = reg_perfcount_get_counter_names(
270 reg_perfcount_get_base_index(),
271 (char **)(void *)&outbuf);
274 else if(strequal(value_name.name, "Explain 009")) {
275 outbuf_size = reg_perfcount_get_counter_help(
276 reg_perfcount_get_base_index(),
277 (char **)(void *)&outbuf);
280 else if(isdigit(value_name.name[0])) {
281 /* we probably have a request for a specific object
283 prs_init(&prs_hkpd, *data_size, p->mem_ctx, MARSHALL);
284 status = reg_perfcount_get_hkpd(
285 &prs_hkpd, *data_size, &outbuf_size,
287 outbuf = (uint8_t *)prs_hkpd.data_p;
291 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
299 struct registry_value *val;
301 status = reg_queryvalue(p->mem_ctx, regkey, value_name.name,
303 if (!W_ERROR_IS_OK(status)) {
313 status = registry_push_value(p->mem_ctx, val, &val_blob);
314 if (!W_ERROR_IS_OK(status)) {
318 outbuf = val_blob.data;
319 outbuf_size = val_blob.length;
323 *value_length = outbuf_size;
325 if ( *data_size == 0 || !data ) {
327 } else if ( *value_length > *data_size ) {
328 status = WERR_MORE_DATA;
330 memcpy( data, outbuf, *value_length );
334 *data_size = *value_length;
336 if (free_prs) prs_mem_free(&prs_hkpd);
337 if (free_buf) SAFE_FREE(outbuf);
342 /*****************************************************************************
343 Implementation of REG_QUERY_KEY
344 ****************************************************************************/
346 WERROR _winreg_QueryInfoKey(pipes_struct *p, struct policy_handle *handle,
347 struct winreg_String *classname,
348 uint32_t *num_subkeys, uint32_t *max_subkeylen,
349 uint32_t *max_subkeysize,
350 uint32_t *num_values, uint32_t *max_valnamelen,
351 uint32_t *max_valbufsize,
352 uint32_t *secdescsize, NTTIME *last_changed_time)
354 WERROR status = WERR_OK;
355 struct registry_key *regkey = find_regkey_by_hnd( p, handle );
360 classname->name = NULL;
362 status = reg_queryinfokey(regkey, num_subkeys, max_subkeylen,
363 max_subkeysize, num_values, max_valnamelen,
364 max_valbufsize, secdescsize,
366 if (!W_ERROR_IS_OK(status)) {
371 * These calculations account for the registry buffers being
372 * UTF-16. They are inexact at best, but so far they worked.
377 *max_valnamelen += 1;
378 *max_valnamelen *= 2;
384 /*****************************************************************************
385 Implementation of REG_GETVERSION
386 ****************************************************************************/
388 WERROR _winreg_GetVersion(pipes_struct *p, struct policy_handle *handle, uint32_t *version)
390 struct registry_key *regkey = find_regkey_by_hnd( p, handle );
395 *version = 0x00000005; /* Windows 2000 registry API version */
401 /*****************************************************************************
402 Implementation of REG_ENUM_KEY
403 ****************************************************************************/
405 WERROR _winreg_EnumKey(pipes_struct *p, struct policy_handle *handle, uint32_t enum_index, struct winreg_StringBuf *name, struct winreg_StringBuf *keyclass, NTTIME *last_changed_time)
408 struct registry_key *key = find_regkey_by_hnd( p, handle );
413 if ( !name || !keyclass )
414 return WERR_INVALID_PARAM;
416 DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", key->key->name));
418 err = reg_enumkey(p->mem_ctx, key, enum_index, (char **)&name->name,
420 if (!W_ERROR_IS_OK(err)) {
427 /*****************************************************************************
428 Implementation of REG_ENUM_VALUE
429 ****************************************************************************/
431 WERROR _winreg_EnumValue(pipes_struct *p, struct policy_handle *handle,
432 uint32_t enum_index, struct winreg_ValNameBuf *name,
433 enum winreg_Type *type, uint8_t **data,
434 uint32_t *data_size, uint32_t *value_length)
437 struct registry_key *key = find_regkey_by_hnd( p, handle );
439 struct registry_value *val;
440 DATA_BLOB value_blob;
446 return WERR_INVALID_PARAM;
448 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
451 err = reg_enumvalue(p->mem_ctx, key, enum_index, &valname, &val);
452 if (!W_ERROR_IS_OK(err)) {
456 err = registry_push_value(p->mem_ctx, val, &value_blob);
457 if (!W_ERROR_IS_OK(err)) {
462 name->name = valname;
470 if ((data_size == NULL) || (value_length == NULL)) {
471 return WERR_INVALID_PARAM;
474 if (value_blob.length > *data_size) {
475 return WERR_MORE_DATA;
478 memcpy( data, value_blob.data, value_blob.length );
481 if (value_length != NULL) {
482 *value_length = value_blob.length;
484 if (data_size != NULL) {
485 *data_size = value_blob.length;
491 /*******************************************************************
493 ********************************************************************/
495 WERROR _winreg_InitiateSystemShutdown(pipes_struct *p, uint16_t *hostname, struct initshutdown_String *message, uint32_t timeout, uint8_t force_apps, uint8_t reboot)
499 /* thunk down to _winreg_InitiateSystemShutdownEx()
500 (just returns a status) */
502 return _winreg_InitiateSystemShutdownEx( p, hostname, message, timeout,
503 force_apps, reboot, reason );
506 /*******************************************************************
508 ********************************************************************/
510 #define SHUTDOWN_R_STRING "-r"
511 #define SHUTDOWN_F_STRING "-f"
514 WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, uint16_t *hostname, struct initshutdown_String *message, uint32_t timeout, uint8_t force_apps, uint8_t reboot, uint32_t reason)
516 pstring shutdown_script;
527 pstrcpy(shutdown_script, lp_shutdown_script());
529 if ( !*shutdown_script )
530 return WERR_ACCESS_DENIED;
532 /* pull the message string and perform necessary sanity checks on it */
536 if ( message && message->name && message->name->name ) {
537 if ( (msg = talloc_strdup(p->mem_ctx, message->name->name )) == NULL ) {
540 alpha_strcpy (chkmsg, msg, NULL, sizeof(chkmsg));
543 fstr_sprintf(str_timeout, "%d", timeout);
544 fstr_sprintf(r, reboot ? SHUTDOWN_R_STRING : "");
545 fstr_sprintf(f, force_apps ? SHUTDOWN_F_STRING : "");
546 fstr_sprintf(str_reason, "%d", reason );
548 all_string_sub( shutdown_script, "%z", chkmsg, sizeof(shutdown_script) );
549 all_string_sub( shutdown_script, "%t", str_timeout, sizeof(shutdown_script) );
550 all_string_sub( shutdown_script, "%r", r, sizeof(shutdown_script) );
551 all_string_sub( shutdown_script, "%f", f, sizeof(shutdown_script) );
552 all_string_sub( shutdown_script, "%x", str_reason, sizeof(shutdown_script) );
554 can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
556 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
557 Take the error return from the script and provide it as the Windows return code. */
559 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
564 ret = smbrun( shutdown_script, NULL );
569 /********** END SeRemoteShutdownPrivilege BLOCK **********/
571 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
572 shutdown_script, ret));
575 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
581 /*******************************************************************
583 ********************************************************************/
585 WERROR _winreg_AbortSystemShutdown(pipes_struct *p, uint16_t *server)
587 pstring abort_shutdown_script;
591 pstrcpy(abort_shutdown_script, lp_abort_shutdown_script());
593 if ( !*abort_shutdown_script )
594 return WERR_ACCESS_DENIED;
596 can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
598 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
603 ret = smbrun( abort_shutdown_script, NULL );
608 /********** END SeRemoteShutdownPrivilege BLOCK **********/
610 DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",
611 abort_shutdown_script, ret));
614 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
617 /*******************************************************************
618 ********************************************************************/
620 static int validate_reg_filename( pstring fname )
623 int num_services = lp_numservices();
628 /* convert to a unix path, stripping the C:\ along the way */
630 if ( !(p = valid_share_pathname( fname ) ))
633 /* has to exist within a valid file share */
635 for ( snum=0; snum<num_services; snum++ ) {
637 if ( !lp_snum_ok(snum) || lp_print_ok(snum) )
640 pstrcpy( share_path, lp_pathname(snum) );
642 /* make sure we have a path (e.g. [homes] ) */
644 if ( strlen( share_path ) == 0 )
647 if ( strncmp( share_path, p, strlen( share_path )) == 0 )
651 /* p and fname are overlapping memory so copy out and back in again */
653 pstrcpy( unix_fname, p );
654 pstrcpy( fname, unix_fname );
656 return (snum < num_services) ? snum : -1;
659 /*******************************************************************
660 Note: topkeypat is the *full* path that this *key will be
661 loaded into (including the name of the key)
662 ********************************************************************/
664 static WERROR reg_load_tree( REGF_FILE *regfile, const char *topkeypath,
668 REGISTRY_KEY registry_key;
670 REGSUBKEY_CTR *subkeys;
673 WERROR result = WERR_OK;
675 /* initialize the REGISTRY_KEY structure */
677 if ( !(registry_key.hook = reghook_cache_find(topkeypath)) ) {
678 DEBUG(0,("reg_load_tree: Failed to assigned a REGISTRY_HOOK to [%s]\n",
682 pstrcpy( registry_key.name, topkeypath );
684 /* now start parsing the values and subkeys */
686 if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) )
689 if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) )
692 /* copy values into the REGVAL_CTR */
694 for ( i=0; i<key->num_values; i++ ) {
695 regval_ctr_addvalue( values, key->values[i].valuename, key->values[i].type,
696 (char*)key->values[i].data, (key->values[i].data_size & ~VK_DATA_IN_OFFSET) );
699 /* copy subkeys into the REGSUBKEY_CTR */
701 key->subkey_index = 0;
702 while ( (subkey = regfio_fetch_subkey( regfile, key )) ) {
703 regsubkey_ctr_addkey( subkeys, subkey->keyname );
706 /* write this key and values out */
708 if ( !store_reg_values( ®istry_key, values )
709 || !store_reg_keys( ®istry_key, subkeys ) )
711 DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath));
712 result = WERR_REG_IO_FAILURE;
715 TALLOC_FREE( subkeys );
717 if ( !W_ERROR_IS_OK(result) )
720 /* now continue to load each subkey registry tree */
722 key->subkey_index = 0;
723 while ( (subkey = regfio_fetch_subkey( regfile, key )) ) {
724 pstr_sprintf( path, "%s%s%s", topkeypath, "\\", subkey->keyname );
725 result = reg_load_tree( regfile, path, subkey );
726 if ( !W_ERROR_IS_OK(result) )
733 /*******************************************************************
734 ********************************************************************/
736 static WERROR restore_registry_key ( REGISTRY_KEY *krecord, const char *fname )
739 REGF_NK_REC *rootkey;
742 /* open the registry file....fail if the file already exists */
744 if ( !(regfile = regfio_open( fname, (O_RDONLY), 0 )) ) {
745 DEBUG(0,("restore_registry_key: failed to open \"%s\" (%s)\n",
746 fname, strerror(errno) ));
747 return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) );
750 /* get the rootkey from the regf file and then load the tree
751 via recursive calls */
753 if ( !(rootkey = regfio_rootkey( regfile )) ) {
754 regfio_close( regfile );
755 return WERR_REG_FILE_INVALID;
758 result = reg_load_tree( regfile, krecord->name, rootkey );
762 regfio_close( regfile );
767 /*******************************************************************
768 ********************************************************************/
770 WERROR _winreg_RestoreKey(pipes_struct *p, struct policy_handle *handle, struct winreg_String *filename, uint32_t flags)
772 struct registry_key *regkey = find_regkey_by_hnd( p, handle );
779 if ( !filename || !filename->name )
780 return WERR_INVALID_PARAM;
782 pstrcpy( fname, filename->name );
784 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
785 "\"%s\"\n", regkey->key->name, fname));
787 if ( (snum = validate_reg_filename( fname )) == -1 )
788 return WERR_OBJECT_PATH_INVALID;
790 /* user must posses SeRestorePrivilege for this this proceed */
792 if ( !user_has_privileges( p->pipe_user.nt_user_token, &se_restore ) )
793 return WERR_ACCESS_DENIED;
795 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
796 regkey->key->name, fname, lp_servicename(snum) ));
798 return restore_registry_key( regkey->key, fname );
801 /********************************************************************
802 ********************************************************************/
804 static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath,
805 REGF_NK_REC *parent, SEC_DESC *sec_desc )
809 REGSUBKEY_CTR *subkeys;
812 char *keyname, *parentpath;
815 REGISTRY_KEY registry_key;
816 WERROR result = WERR_OK;
819 return WERR_GENERAL_FAILURE;
822 return WERR_OBJECT_PATH_INVALID;
824 /* split up the registry key path */
826 pstrcpy( key_tmp, keypath );
827 if ( !reg_split_key( key_tmp, &parentpath, &keyname ) )
828 return WERR_OBJECT_PATH_INVALID;
831 keyname = parentpath;
833 /* we need a REGISTRY_KEY object here to enumerate subkeys and values */
835 ZERO_STRUCT( registry_key );
837 if ( (registry_key.name = talloc_strdup(regfile->mem_ctx, keypath)) == NULL )
840 if ( (registry_key.hook = reghook_cache_find( registry_key.name )) == NULL )
843 /* lookup the values and subkeys */
845 if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) )
848 if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) )
851 fetch_reg_keys( ®istry_key, subkeys );
852 fetch_reg_values( ®istry_key, values );
854 /* write out this key */
856 if ( !(key = regfio_write_key( regfile, keyname, values, subkeys, sec_desc, parent )) ) {
857 result = WERR_CAN_NOT_COMPLETE;
861 /* write each one of the subkeys out */
863 num_subkeys = regsubkey_ctr_numkeys( subkeys );
864 for ( i=0; i<num_subkeys; i++ ) {
865 subkeyname = regsubkey_ctr_specific_key( subkeys, i );
866 pstr_sprintf( subkeypath, "%s\\%s", keypath, subkeyname );
867 result = reg_write_tree( regfile, subkeypath, key, sec_desc );
868 if ( !W_ERROR_IS_OK(result) )
872 DEBUG(6,("reg_write_tree: wrote key [%s]\n", keypath ));
875 TALLOC_FREE( subkeys );
876 TALLOC_FREE( registry_key.name );
881 /*******************************************************************
882 ********************************************************************/
884 static WERROR make_default_reg_sd( TALLOC_CTX *ctx, SEC_DESC **psd )
886 DOM_SID adm_sid, owner_sid;
887 SEC_ACE ace[2]; /* at most 2 entries */
892 /* set the owner to BUILTIN\Administrator */
894 sid_copy(&owner_sid, &global_sid_Builtin);
895 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN );
898 /* basic access for Everyone */
900 init_sec_access(&mask, reg_generic_map.generic_execute | reg_generic_map.generic_read );
901 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
903 /* add Full Access 'BUILTIN\Administrators' */
905 init_sec_access(&mask, reg_generic_map.generic_all);
906 sid_copy(&adm_sid, &global_sid_Builtin);
907 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
908 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
910 /* create the security descriptor */
912 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 2, ace)) == NULL)
915 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &owner_sid, NULL, NULL, psa, &sd_size)) == NULL)
921 /*******************************************************************
922 ********************************************************************/
924 static WERROR backup_registry_key ( REGISTRY_KEY *krecord, const char *fname )
930 /* open the registry file....fail if the file already exists */
932 if ( !(regfile = regfio_open( fname, (O_RDWR|O_CREAT|O_EXCL), (S_IREAD|S_IWRITE) )) ) {
933 DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n",
934 fname, strerror(errno) ));
935 return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) );
938 if ( !W_ERROR_IS_OK(result = make_default_reg_sd( regfile->mem_ctx, &sd )) ) {
939 regfio_close( regfile );
943 /* write the registry tree to the file */
945 result = reg_write_tree( regfile, krecord->name, NULL, sd );
949 regfio_close( regfile );
954 /*******************************************************************
955 ********************************************************************/
957 WERROR _winreg_SaveKey(pipes_struct *p, struct policy_handle *handle, struct winreg_String *filename, struct KeySecurityAttribute *sec_attrib)
959 struct registry_key *regkey = find_regkey_by_hnd( p, handle );
966 if ( !filename || !filename->name )
967 return WERR_INVALID_PARAM;
969 pstrcpy( fname, filename->name );
971 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
972 regkey->key->name, fname));
974 if ( (snum = validate_reg_filename( fname )) == -1 )
975 return WERR_OBJECT_PATH_INVALID;
977 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
978 regkey->key->name, fname, lp_servicename(snum) ));
980 return backup_registry_key( regkey->key, fname );
983 /*******************************************************************
984 ********************************************************************/
986 WERROR _winreg_SaveKeyEx(pipes_struct *p)
988 /* fill in your code here if you think this call should
991 p->rng_fault_state = True;
992 return WERR_NOT_SUPPORTED;
995 /*******************************************************************
996 ********************************************************************/
998 WERROR _winreg_CreateKey( pipes_struct *p, struct policy_handle *handle,
999 struct winreg_String keyname,
1000 struct winreg_String keyclass,
1001 uint32_t options, uint32_t access_mask,
1002 struct winreg_SecBuf *secdesc,
1003 struct policy_handle *new_handle,
1004 enum winreg_CreateAction *action_taken )
1006 struct registry_key *parent = find_regkey_by_hnd(p, handle);
1007 struct registry_key *new_key;
1013 result = reg_createkey(NULL, parent, keyname.name, access_mask,
1014 &new_key, action_taken);
1015 if (!W_ERROR_IS_OK(result)) {
1019 if (!create_policy_hnd(p, new_handle, free_regkey, new_key)) {
1020 TALLOC_FREE(new_key);
1021 return WERR_BADFILE;
1027 /*******************************************************************
1028 ********************************************************************/
1030 WERROR _winreg_SetValue(pipes_struct *p, struct policy_handle *handle,
1031 struct winreg_String name, enum winreg_Type type,
1032 uint8_t *data, uint32_t size)
1034 struct registry_key *key = find_regkey_by_hnd(p, handle);
1035 struct registry_value *val;
1041 DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n", key->key->name,
1044 status = registry_pull_value(p->mem_ctx, &val, type, data, size, size);
1045 if (!W_ERROR_IS_OK(status)) {
1049 return reg_setvalue(key, name.name, val);
1052 /*******************************************************************
1053 ********************************************************************/
1055 WERROR _winreg_DeleteKey(pipes_struct *p, struct policy_handle *handle,
1056 struct winreg_String key)
1058 struct registry_key *parent = find_regkey_by_hnd(p, handle);
1063 return reg_deletekey(parent, key.name);
1067 /*******************************************************************
1068 ********************************************************************/
1070 WERROR _winreg_DeleteValue(pipes_struct *p, struct policy_handle *handle,
1071 struct winreg_String value)
1073 struct registry_key *key = find_regkey_by_hnd(p, handle);
1078 return reg_deletevalue(key, value.name);
1081 /*******************************************************************
1082 ********************************************************************/
1084 WERROR _winreg_GetKeySecurity(pipes_struct *p, struct policy_handle *handle,
1085 uint32_t sec_info, struct KeySecurityData *sd)
1087 struct registry_key *key = find_regkey_by_hnd(p, handle);
1089 struct security_descriptor *secdesc;
1096 /* access checks first */
1098 if ( !(key->key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) )
1099 return WERR_ACCESS_DENIED;
1101 err = regkey_get_secdesc(p->mem_ctx, key->key, &secdesc);
1102 if (!W_ERROR_IS_OK(err)) {
1106 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
1108 if (!W_ERROR_IS_OK(err)) {
1112 if (len > sd->size) {
1114 return WERR_INSUFFICIENT_BUFFER;
1124 /*******************************************************************
1125 ********************************************************************/
1127 WERROR _winreg_SetKeySecurity(pipes_struct *p, struct policy_handle *handle, uint32_t access_mask, struct KeySecurityData *sd)
1129 struct registry_key *key = find_regkey_by_hnd(p, handle);
1130 struct security_descriptor *secdesc;
1136 /* access checks first */
1138 if ( !(key->key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) )
1139 return WERR_ACCESS_DENIED;
1141 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, sd->data,
1142 sd->len, &secdesc));
1143 if (!W_ERROR_IS_OK(err)) {
1147 return regkey_set_secdesc(key->key, secdesc);
1150 /*******************************************************************
1151 ********************************************************************/
1153 WERROR _winreg_FlushKey(pipes_struct *p, struct policy_handle *handle)
1155 /* I'm just replying OK because there's not a lot
1156 here I see to do i --jerry */
1161 /*******************************************************************
1162 ********************************************************************/
1164 WERROR _winreg_UnLoadKey(pipes_struct *p)
1166 /* fill in your code here if you think this call should
1169 p->rng_fault_state = True;
1170 return WERR_NOT_SUPPORTED;
1173 /*******************************************************************
1174 ********************************************************************/
1176 WERROR _winreg_ReplaceKey(pipes_struct *p)
1178 /* fill in your code here if you think this call should
1181 p->rng_fault_state = True;
1182 return WERR_NOT_SUPPORTED;
1185 /*******************************************************************
1186 ********************************************************************/
1188 WERROR _winreg_LoadKey(pipes_struct *p, struct policy_handle *handle, struct winreg_String *keyname, struct winreg_String *filename)
1190 /* fill in your code here if you think this call should
1193 p->rng_fault_state = True;
1194 return WERR_NOT_SUPPORTED;
1197 /*******************************************************************
1198 ********************************************************************/
1200 WERROR _winreg_NotifyChangeKeyValue(pipes_struct *p, struct policy_handle *handle, uint8_t watch_subtree, uint32_t notify_filter, uint32_t unknown, struct winreg_String string1, struct winreg_String string2, uint32_t unknown2)
1202 /* fill in your code here if you think this call should
1205 p->rng_fault_state = True;
1206 return WERR_NOT_SUPPORTED;
1209 /*******************************************************************
1210 ********************************************************************/
1212 WERROR _winreg_QueryMultipleValues(pipes_struct *p, struct policy_handle *key_handle, struct QueryMultipleValue *values, uint32_t num_values, uint8_t *buffer, uint32_t *buffer_size)
1214 /* fill in your code here if you think this call should
1217 p->rng_fault_state = True;
1218 return WERR_NOT_SUPPORTED;
1221 /*******************************************************************
1222 ********************************************************************/
1224 WERROR _winreg_QueryMultipleValues2(pipes_struct *p)
1226 /* fill in your code here if you think this call should
1229 p->rng_fault_state = True;
1230 return WERR_NOT_SUPPORTED;