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))
132 /*******************************************************************
133 ********************************************************************/
135 WERROR _winreg_OpenHKLM(pipes_struct *p, uint16_t *system_name, uint32_t access_mask, struct policy_handle *handle)
137 return open_registry_key(p, handle, NULL, KEY_HKLM, access_mask);
140 /*******************************************************************
141 ********************************************************************/
143 WERROR _winreg_OpenHKPD(pipes_struct *p, uint16_t *system_name,
144 uint32_t access_mask, struct policy_handle *handle)
146 return open_registry_key(p, handle, NULL, KEY_HKPD, access_mask);
149 /*******************************************************************
150 ********************************************************************/
152 WERROR _winreg_OpenHKPT(pipes_struct *p, uint16_t *system_name,
153 uint32_t access_mask, struct policy_handle *handle)
155 return open_registry_key(p, handle, NULL, KEY_HKPT, access_mask);
158 /*******************************************************************
159 ********************************************************************/
161 WERROR _winreg_OpenHKCR(pipes_struct *p, uint16_t *system_name,
162 uint32_t access_mask, struct policy_handle *handle)
164 return open_registry_key(p, handle, NULL, KEY_HKCR, access_mask);
167 /*******************************************************************
168 ********************************************************************/
170 WERROR _winreg_OpenHKU(pipes_struct *p, uint16_t *system_name,
171 uint32_t access_mask, struct policy_handle *handle)
173 return open_registry_key(p, handle, NULL, KEY_HKU, access_mask);
176 /*******************************************************************
177 ********************************************************************/
179 WERROR _winreg_OpenHKCU(pipes_struct *p, uint16_t *system_name,
180 uint32_t access_mask, struct policy_handle *handle)
182 return open_registry_key(p, handle, NULL, KEY_HKCU, access_mask);
185 /*******************************************************************
186 ********************************************************************/
188 WERROR _winreg_OpenHKCC(pipes_struct *p, uint16_t *system_name,
189 uint32_t access_mask, struct policy_handle *handle)
191 return open_registry_key(p, handle, NULL, KEY_HKCC, access_mask);
194 /*******************************************************************
195 ********************************************************************/
197 WERROR _winreg_OpenHKDD(pipes_struct *p, uint16_t *system_name,
198 uint32_t access_mask, struct policy_handle *handle)
200 return open_registry_key(p, handle, NULL, KEY_HKDD, access_mask);
203 /*******************************************************************
204 ********************************************************************/
206 WERROR _winreg_OpenHKPN(pipes_struct *p, uint16_t *system_name,
207 uint32_t access_mask, struct policy_handle *handle)
209 return open_registry_key(p, handle, NULL, KEY_HKPN, access_mask);
212 /*******************************************************************
214 ********************************************************************/
216 WERROR _winreg_OpenKey(pipes_struct *p, struct policy_handle *parent_handle,
217 struct winreg_String keyname, uint32_t unknown,
218 uint32_t access_mask, struct policy_handle *handle)
220 struct registry_key *parent = find_regkey_by_hnd(p, parent_handle );
225 return open_registry_key(p, handle, parent, keyname.name, access_mask);
228 /*******************************************************************
230 ********************************************************************/
232 WERROR _winreg_QueryValue(pipes_struct *p, struct policy_handle *handle,
233 struct winreg_String value_name,
234 enum winreg_Type *type, uint8_t *data,
235 uint32_t *data_size, uint32_t *value_length)
237 WERROR status = WERR_BADFILE;
238 struct registry_key *regkey = find_regkey_by_hnd( p, handle );
242 uint32_t outbuf_size;
245 BOOL free_buf = False;
246 BOOL free_prs = False;
251 *value_length = *type = 0;
253 DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->key->name));
254 DEBUG(7,("_reg_info: policy key type = [%08x]\n", regkey->key->type));
256 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
257 if(regkey->key->type == REG_KEY_HKPD)
259 if(strequal(value_name.name, "Global")) {
260 prs_init(&prs_hkpd, *data_size, p->mem_ctx, MARSHALL);
261 status = reg_perfcount_get_hkpd(
262 &prs_hkpd, *data_size, &outbuf_size, NULL);
263 outbuf = (uint8_t *)prs_hkpd.data_p;
266 else if(strequal(value_name.name, "Counter 009")) {
267 outbuf_size = reg_perfcount_get_counter_names(
268 reg_perfcount_get_base_index(),
269 (char **)(void *)&outbuf);
272 else if(strequal(value_name.name, "Explain 009")) {
273 outbuf_size = reg_perfcount_get_counter_help(
274 reg_perfcount_get_base_index(),
275 (char **)(void *)&outbuf);
278 else if(isdigit(value_name.name[0])) {
279 /* we probably have a request for a specific object
281 prs_init(&prs_hkpd, *data_size, p->mem_ctx, MARSHALL);
282 status = reg_perfcount_get_hkpd(
283 &prs_hkpd, *data_size, &outbuf_size,
285 outbuf = (uint8_t *)prs_hkpd.data_p;
289 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
297 struct registry_value *val;
299 status = reg_queryvalue(p->mem_ctx, regkey, value_name.name,
301 if (!W_ERROR_IS_OK(status)) {
311 status = registry_push_value(p->mem_ctx, val, &val_blob);
312 if (!W_ERROR_IS_OK(status)) {
316 outbuf = val_blob.data;
317 outbuf_size = val_blob.length;
321 *value_length = outbuf_size;
323 if ( *data_size == 0 || !data ) {
325 } else if ( *value_length > *data_size ) {
326 status = WERR_MORE_DATA;
328 memcpy( data, outbuf, *value_length );
332 *data_size = *value_length;
334 if (free_prs) prs_mem_free(&prs_hkpd);
335 if (free_buf) SAFE_FREE(outbuf);
340 /*****************************************************************************
341 Implementation of REG_QUERY_KEY
342 ****************************************************************************/
344 WERROR _winreg_QueryInfoKey(pipes_struct *p, struct policy_handle *handle,
345 struct winreg_String *classname,
346 uint32_t *num_subkeys, uint32_t *max_subkeylen,
347 uint32_t *max_subkeysize,
348 uint32_t *num_values, uint32_t *max_valnamelen,
349 uint32_t *max_valbufsize,
350 uint32_t *secdescsize, NTTIME *last_changed_time)
352 WERROR status = WERR_OK;
353 struct registry_key *regkey = find_regkey_by_hnd( p, handle );
358 classname->name = NULL;
360 status = reg_queryinfokey(regkey, num_subkeys, max_subkeylen,
361 max_subkeysize, num_values, max_valnamelen,
362 max_valbufsize, secdescsize,
364 if (!W_ERROR_IS_OK(status)) {
369 * These calculations account for the registry buffers being
370 * UTF-16. They are inexact at best, but so far they worked.
375 *max_valnamelen += 1;
376 *max_valnamelen *= 2;
382 /*****************************************************************************
383 Implementation of REG_GETVERSION
384 ****************************************************************************/
386 WERROR _winreg_GetVersion(pipes_struct *p, struct policy_handle *handle, uint32_t *version)
388 struct registry_key *regkey = find_regkey_by_hnd( p, handle );
393 *version = 0x00000005; /* Windows 2000 registry API version */
399 /*****************************************************************************
400 Implementation of REG_ENUM_KEY
401 ****************************************************************************/
403 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)
406 struct registry_key *key = find_regkey_by_hnd( p, handle );
411 if ( !name || !keyclass )
412 return WERR_INVALID_PARAM;
414 DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", key->key->name));
416 err = reg_enumkey(p->mem_ctx, key, enum_index, (char **)&name->name,
418 if (!W_ERROR_IS_OK(err)) {
425 /*****************************************************************************
426 Implementation of REG_ENUM_VALUE
427 ****************************************************************************/
429 WERROR _winreg_EnumValue(pipes_struct *p, struct policy_handle *handle,
430 uint32_t enum_index, struct winreg_ValNameBuf *name,
431 enum winreg_Type *type, uint8_t *data,
432 uint32_t *data_size, uint32_t *value_length)
435 struct registry_key *key = find_regkey_by_hnd( p, handle );
437 struct registry_value *val;
438 DATA_BLOB value_blob;
444 return WERR_INVALID_PARAM;
446 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
449 err = reg_enumvalue(p->mem_ctx, key, enum_index, &valname, &val);
450 if (!W_ERROR_IS_OK(err)) {
454 err = registry_push_value(p->mem_ctx, val, &value_blob);
455 if (!W_ERROR_IS_OK(err)) {
460 name->name = valname;
468 if ((data_size == NULL) || (value_length == NULL)) {
469 return WERR_INVALID_PARAM;
472 if (value_blob.length > *data_size) {
473 return WERR_MORE_DATA;
476 memcpy( data, value_blob.data, value_blob.length );
479 if (value_length != NULL) {
480 *value_length = value_blob.length;
482 if (data_size != NULL) {
483 *data_size = value_blob.length;
489 /*******************************************************************
491 ********************************************************************/
493 WERROR _winreg_InitiateSystemShutdown(pipes_struct *p, uint16_t *hostname, struct initshutdown_String *message, uint32_t timeout, uint8_t force_apps, uint8_t reboot)
497 /* thunk down to _winreg_InitiateSystemShutdownEx()
498 (just returns a status) */
500 return _winreg_InitiateSystemShutdownEx( p, hostname, message, timeout,
501 force_apps, reboot, reason );
504 /*******************************************************************
506 ********************************************************************/
508 #define SHUTDOWN_R_STRING "-r"
509 #define SHUTDOWN_F_STRING "-f"
512 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)
514 pstring shutdown_script;
525 pstrcpy(shutdown_script, lp_shutdown_script());
527 if ( !*shutdown_script )
528 return WERR_ACCESS_DENIED;
530 /* pull the message string and perform necessary sanity checks on it */
534 if ( message && message->name && message->name->name ) {
535 if ( (msg = talloc_strdup(p->mem_ctx, message->name->name )) == NULL ) {
538 alpha_strcpy (chkmsg, msg, NULL, sizeof(chkmsg));
541 fstr_sprintf(str_timeout, "%d", timeout);
542 fstr_sprintf(r, reboot ? SHUTDOWN_R_STRING : "");
543 fstr_sprintf(f, force_apps ? SHUTDOWN_F_STRING : "");
544 fstr_sprintf(str_reason, "%d", reason );
546 all_string_sub( shutdown_script, "%z", chkmsg, sizeof(shutdown_script) );
547 all_string_sub( shutdown_script, "%t", str_timeout, sizeof(shutdown_script) );
548 all_string_sub( shutdown_script, "%r", r, sizeof(shutdown_script) );
549 all_string_sub( shutdown_script, "%f", f, sizeof(shutdown_script) );
550 all_string_sub( shutdown_script, "%x", str_reason, sizeof(shutdown_script) );
552 can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
554 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
555 Take the error return from the script and provide it as the Windows return code. */
557 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
562 ret = smbrun( shutdown_script, NULL );
567 /********** END SeRemoteShutdownPrivilege BLOCK **********/
569 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
570 shutdown_script, ret));
573 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
579 /*******************************************************************
581 ********************************************************************/
583 WERROR _winreg_AbortSystemShutdown(pipes_struct *p, uint16_t *server)
585 pstring abort_shutdown_script;
589 pstrcpy(abort_shutdown_script, lp_abort_shutdown_script());
591 if ( !*abort_shutdown_script )
592 return WERR_ACCESS_DENIED;
594 can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
596 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
601 ret = smbrun( abort_shutdown_script, NULL );
606 /********** END SeRemoteShutdownPrivilege BLOCK **********/
608 DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",
609 abort_shutdown_script, ret));
612 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
615 /*******************************************************************
616 ********************************************************************/
618 static int validate_reg_filename( pstring fname )
621 int num_services = lp_numservices();
626 /* convert to a unix path, stripping the C:\ along the way */
628 if ( !(p = valid_share_pathname( fname ) ))
631 /* has to exist within a valid file share */
633 for ( snum=0; snum<num_services; snum++ ) {
635 if ( !lp_snum_ok(snum) || lp_print_ok(snum) )
638 pstrcpy( share_path, lp_pathname(snum) );
640 /* make sure we have a path (e.g. [homes] ) */
642 if ( strlen( share_path ) == 0 )
645 if ( strncmp( share_path, p, strlen( share_path )) == 0 )
649 /* p and fname are overlapping memory so copy out and back in again */
651 pstrcpy( unix_fname, p );
652 pstrcpy( fname, unix_fname );
654 return (snum < num_services) ? snum : -1;
657 /*******************************************************************
658 Note: topkeypat is the *full* path that this *key will be
659 loaded into (including the name of the key)
660 ********************************************************************/
662 static WERROR reg_load_tree( REGF_FILE *regfile, const char *topkeypath,
666 REGISTRY_KEY registry_key;
668 REGSUBKEY_CTR *subkeys;
671 WERROR result = WERR_OK;
673 /* initialize the REGISTRY_KEY structure */
675 if ( !(registry_key.hook = reghook_cache_find(topkeypath)) ) {
676 DEBUG(0,("reg_load_tree: Failed to assigned a REGISTRY_HOOK to [%s]\n",
680 pstrcpy( registry_key.name, topkeypath );
682 /* now start parsing the values and subkeys */
684 if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) )
687 if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) )
690 /* copy values into the REGVAL_CTR */
692 for ( i=0; i<key->num_values; i++ ) {
693 regval_ctr_addvalue( values, key->values[i].valuename, key->values[i].type,
694 (char*)key->values[i].data, (key->values[i].data_size & ~VK_DATA_IN_OFFSET) );
697 /* copy subkeys into the REGSUBKEY_CTR */
699 key->subkey_index = 0;
700 while ( (subkey = regfio_fetch_subkey( regfile, key )) ) {
701 regsubkey_ctr_addkey( subkeys, subkey->keyname );
704 /* write this key and values out */
706 if ( !store_reg_values( ®istry_key, values )
707 || !store_reg_keys( ®istry_key, subkeys ) )
709 DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath));
710 result = WERR_REG_IO_FAILURE;
713 TALLOC_FREE( subkeys );
715 if ( !W_ERROR_IS_OK(result) )
718 /* now continue to load each subkey registry tree */
720 key->subkey_index = 0;
721 while ( (subkey = regfio_fetch_subkey( regfile, key )) ) {
722 pstr_sprintf( path, "%s%s%s", topkeypath, "\\", subkey->keyname );
723 result = reg_load_tree( regfile, path, subkey );
724 if ( !W_ERROR_IS_OK(result) )
731 /*******************************************************************
732 ********************************************************************/
734 static WERROR restore_registry_key ( REGISTRY_KEY *krecord, const char *fname )
737 REGF_NK_REC *rootkey;
740 /* open the registry file....fail if the file already exists */
742 if ( !(regfile = regfio_open( fname, (O_RDONLY), 0 )) ) {
743 DEBUG(0,("restore_registry_key: failed to open \"%s\" (%s)\n",
744 fname, strerror(errno) ));
745 return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) );
748 /* get the rootkey from the regf file and then load the tree
749 via recursive calls */
751 if ( !(rootkey = regfio_rootkey( regfile )) ) {
752 regfio_close( regfile );
753 return WERR_REG_FILE_INVALID;
756 result = reg_load_tree( regfile, krecord->name, rootkey );
760 regfio_close( regfile );
765 /*******************************************************************
766 ********************************************************************/
768 WERROR _winreg_RestoreKey(pipes_struct *p, struct policy_handle *handle, struct winreg_String *filename, uint32_t flags)
770 struct registry_key *regkey = find_regkey_by_hnd( p, handle );
777 if ( !filename || !filename->name )
778 return WERR_INVALID_PARAM;
780 pstrcpy( fname, filename->name );
782 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
783 "\"%s\"\n", regkey->key->name, fname));
785 if ( (snum = validate_reg_filename( fname )) == -1 )
786 return WERR_OBJECT_PATH_INVALID;
788 /* user must posses SeRestorePrivilege for this this proceed */
790 if ( !user_has_privileges( p->pipe_user.nt_user_token, &se_restore ) )
791 return WERR_ACCESS_DENIED;
793 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
794 regkey->key->name, fname, lp_servicename(snum) ));
796 return restore_registry_key( regkey->key, fname );
799 /********************************************************************
800 ********************************************************************/
802 static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath,
803 REGF_NK_REC *parent, SEC_DESC *sec_desc )
807 REGSUBKEY_CTR *subkeys;
810 char *keyname, *parentpath;
813 REGISTRY_KEY registry_key;
814 WERROR result = WERR_OK;
817 return WERR_GENERAL_FAILURE;
820 return WERR_OBJECT_PATH_INVALID;
822 /* split up the registry key path */
824 pstrcpy( key_tmp, keypath );
825 if ( !reg_split_key( key_tmp, &parentpath, &keyname ) )
826 return WERR_OBJECT_PATH_INVALID;
829 keyname = parentpath;
831 /* we need a REGISTRY_KEY object here to enumerate subkeys and values */
833 ZERO_STRUCT( registry_key );
835 if ( (registry_key.name = talloc_strdup(regfile->mem_ctx, keypath)) == NULL )
838 if ( (registry_key.hook = reghook_cache_find( registry_key.name )) == NULL )
841 /* lookup the values and subkeys */
843 if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) )
846 if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) )
849 fetch_reg_keys( ®istry_key, subkeys );
850 fetch_reg_values( ®istry_key, values );
852 /* write out this key */
854 if ( !(key = regfio_write_key( regfile, keyname, values, subkeys, sec_desc, parent )) ) {
855 result = WERR_CAN_NOT_COMPLETE;
859 /* write each one of the subkeys out */
861 num_subkeys = regsubkey_ctr_numkeys( subkeys );
862 for ( i=0; i<num_subkeys; i++ ) {
863 subkeyname = regsubkey_ctr_specific_key( subkeys, i );
864 pstr_sprintf( subkeypath, "%s\\%s", keypath, subkeyname );
865 result = reg_write_tree( regfile, subkeypath, key, sec_desc );
866 if ( !W_ERROR_IS_OK(result) )
870 DEBUG(6,("reg_write_tree: wrote key [%s]\n", keypath ));
873 TALLOC_FREE( subkeys );
874 TALLOC_FREE( registry_key.name );
879 /*******************************************************************
880 ********************************************************************/
882 static WERROR make_default_reg_sd( TALLOC_CTX *ctx, SEC_DESC **psd )
884 DOM_SID adm_sid, owner_sid;
885 SEC_ACE ace[2]; /* at most 2 entries */
890 /* set the owner to BUILTIN\Administrator */
892 sid_copy(&owner_sid, &global_sid_Builtin);
893 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN );
896 /* basic access for Everyone */
898 init_sec_access(&mask, reg_generic_map.generic_execute | reg_generic_map.generic_read );
899 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
901 /* add Full Access 'BUILTIN\Administrators' */
903 init_sec_access(&mask, reg_generic_map.generic_all);
904 sid_copy(&adm_sid, &global_sid_Builtin);
905 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
906 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
908 /* create the security descriptor */
910 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 2, ace)) == NULL)
913 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &owner_sid, NULL, NULL, psa, &sd_size)) == NULL)
919 /*******************************************************************
920 ********************************************************************/
922 static WERROR backup_registry_key ( REGISTRY_KEY *krecord, const char *fname )
928 /* open the registry file....fail if the file already exists */
930 if ( !(regfile = regfio_open( fname, (O_RDWR|O_CREAT|O_EXCL), (S_IREAD|S_IWRITE) )) ) {
931 DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n",
932 fname, strerror(errno) ));
933 return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) );
936 if ( !W_ERROR_IS_OK(result = make_default_reg_sd( regfile->mem_ctx, &sd )) ) {
937 regfio_close( regfile );
941 /* write the registry tree to the file */
943 result = reg_write_tree( regfile, krecord->name, NULL, sd );
947 regfio_close( regfile );
952 /*******************************************************************
953 ********************************************************************/
955 WERROR _winreg_SaveKey(pipes_struct *p, struct policy_handle *handle, struct winreg_String *filename, struct KeySecurityAttribute *sec_attrib)
957 struct registry_key *regkey = find_regkey_by_hnd( p, handle );
964 if ( !filename || !filename->name )
965 return WERR_INVALID_PARAM;
967 pstrcpy( fname, filename->name );
969 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
970 regkey->key->name, fname));
972 if ( (snum = validate_reg_filename( fname )) == -1 )
973 return WERR_OBJECT_PATH_INVALID;
975 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
976 regkey->key->name, fname, lp_servicename(snum) ));
978 return backup_registry_key( regkey->key, fname );
981 /*******************************************************************
982 ********************************************************************/
984 WERROR _winreg_SaveKeyEx(pipes_struct *p)
986 /* fill in your code here if you think this call should
989 p->rng_fault_state = True;
990 return WERR_NOT_SUPPORTED;
993 /*******************************************************************
994 ********************************************************************/
996 WERROR _winreg_CreateKey( pipes_struct *p, struct policy_handle *handle,
997 struct winreg_String keyname,
998 struct winreg_String keyclass,
999 uint32_t options, uint32_t access_mask,
1000 struct winreg_SecBuf *secdesc,
1001 struct policy_handle *new_handle,
1002 enum winreg_CreateAction *action_taken )
1004 struct registry_key *parent = find_regkey_by_hnd(p, handle);
1005 struct registry_key *new_key;
1011 result = reg_createkey(NULL, parent, keyname.name, access_mask,
1012 &new_key, action_taken);
1013 if (!W_ERROR_IS_OK(result)) {
1017 if (!create_policy_hnd(p, new_handle, free_regkey, new_key)) {
1018 TALLOC_FREE(new_key);
1019 return WERR_BADFILE;
1025 /*******************************************************************
1026 ********************************************************************/
1028 WERROR _winreg_SetValue(pipes_struct *p, struct policy_handle *handle,
1029 struct winreg_String name, enum winreg_Type type,
1030 uint8_t *data, uint32_t size)
1032 struct registry_key *key = find_regkey_by_hnd(p, handle);
1033 struct registry_value *val;
1039 DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n", key->key->name,
1042 status = registry_pull_value(p->mem_ctx, &val, type, data, size, size);
1043 if (!W_ERROR_IS_OK(status)) {
1047 return reg_setvalue(key, name.name, val);
1050 /*******************************************************************
1051 ********************************************************************/
1053 WERROR _winreg_DeleteKey(pipes_struct *p, struct policy_handle *handle,
1054 struct winreg_String key)
1056 struct registry_key *parent = find_regkey_by_hnd(p, handle);
1061 return reg_deletekey(parent, key.name);
1065 /*******************************************************************
1066 ********************************************************************/
1068 WERROR _winreg_DeleteValue(pipes_struct *p, struct policy_handle *handle,
1069 struct winreg_String value)
1071 struct registry_key *key = find_regkey_by_hnd(p, handle);
1076 return reg_deletevalue(key, value.name);
1079 /*******************************************************************
1080 ********************************************************************/
1082 WERROR _winreg_GetKeySecurity(pipes_struct *p, struct policy_handle *handle,
1083 uint32_t sec_info, struct KeySecurityData *sd)
1085 struct registry_key *key = find_regkey_by_hnd(p, handle);
1087 struct security_descriptor *secdesc;
1094 /* access checks first */
1096 if ( !(key->key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) )
1097 return WERR_ACCESS_DENIED;
1099 err = regkey_get_secdesc(p->mem_ctx, key->key, &secdesc);
1100 if (!W_ERROR_IS_OK(err)) {
1104 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
1106 if (!W_ERROR_IS_OK(err)) {
1110 if (len > sd->size) {
1112 return WERR_INSUFFICIENT_BUFFER;
1122 /*******************************************************************
1123 ********************************************************************/
1125 WERROR _winreg_SetKeySecurity(pipes_struct *p, struct policy_handle *handle, uint32_t access_mask, struct KeySecurityData *sd)
1127 struct registry_key *key = find_regkey_by_hnd(p, handle);
1128 struct security_descriptor *secdesc;
1134 /* access checks first */
1136 if ( !(key->key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) )
1137 return WERR_ACCESS_DENIED;
1139 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, sd->data,
1140 sd->len, &secdesc));
1141 if (!W_ERROR_IS_OK(err)) {
1145 return regkey_set_secdesc(key->key, secdesc);
1148 /*******************************************************************
1149 ********************************************************************/
1151 WERROR _winreg_FlushKey(pipes_struct *p, struct policy_handle *handle)
1153 /* I'm just replying OK because there's not a lot
1154 here I see to do i --jerry */
1159 /*******************************************************************
1160 ********************************************************************/
1162 WERROR _winreg_UnLoadKey(pipes_struct *p)
1164 /* fill in your code here if you think this call should
1167 p->rng_fault_state = True;
1168 return WERR_NOT_SUPPORTED;
1171 /*******************************************************************
1172 ********************************************************************/
1174 WERROR _winreg_ReplaceKey(pipes_struct *p)
1176 /* fill in your code here if you think this call should
1179 p->rng_fault_state = True;
1180 return WERR_NOT_SUPPORTED;
1183 /*******************************************************************
1184 ********************************************************************/
1186 WERROR _winreg_LoadKey(pipes_struct *p, struct policy_handle *handle, struct winreg_String *keyname, struct winreg_String *filename)
1188 /* fill in your code here if you think this call should
1191 p->rng_fault_state = True;
1192 return WERR_NOT_SUPPORTED;
1195 /*******************************************************************
1196 ********************************************************************/
1198 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)
1200 /* fill in your code here if you think this call should
1203 p->rng_fault_state = True;
1204 return WERR_NOT_SUPPORTED;
1207 /*******************************************************************
1208 ********************************************************************/
1210 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)
1212 /* fill in your code here if you think this call should
1215 p->rng_fault_state = True;
1216 return WERR_NOT_SUPPORTED;
1219 /*******************************************************************
1220 ********************************************************************/
1222 WERROR _winreg_QueryMultipleValues2(pipes_struct *p)
1224 /* fill in your code here if you think this call should
1227 p->rng_fault_state = True;
1228 return WERR_NOT_SUPPORTED;