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 winreg_CloseKey *r)
124 /* close the policy handle */
126 if (!close_registry_key(p, r->in.handle))
129 ZERO_STRUCTP(r->out.handle);
134 /*******************************************************************
135 ********************************************************************/
137 WERROR _winreg_OpenHKLM(pipes_struct *p, struct winreg_OpenHKLM *r)
139 return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
142 /*******************************************************************
143 ********************************************************************/
145 WERROR _winreg_OpenHKPD(pipes_struct *p, struct winreg_OpenHKPD *r)
147 return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
150 /*******************************************************************
151 ********************************************************************/
153 WERROR _winreg_OpenHKPT(pipes_struct *p, struct winreg_OpenHKPT *r)
155 return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
158 /*******************************************************************
159 ********************************************************************/
161 WERROR _winreg_OpenHKCR(pipes_struct *p, struct winreg_OpenHKCR *r)
163 return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
166 /*******************************************************************
167 ********************************************************************/
169 WERROR _winreg_OpenHKU(pipes_struct *p, struct winreg_OpenHKU *r)
171 return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
174 /*******************************************************************
175 ********************************************************************/
177 WERROR _winreg_OpenHKCU(pipes_struct *p, struct winreg_OpenHKCU *r)
179 return open_registry_key(p, r->out.handle, NULL, KEY_HKCU, r->in.access_mask);
182 /*******************************************************************
183 ********************************************************************/
185 WERROR _winreg_OpenHKCC(pipes_struct *p, struct winreg_OpenHKCC *r)
187 return open_registry_key(p, r->out.handle, NULL, KEY_HKCC, r->in.access_mask);
190 /*******************************************************************
191 ********************************************************************/
193 WERROR _winreg_OpenHKDD(pipes_struct *p, struct winreg_OpenHKDD *r)
195 return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
198 /*******************************************************************
199 ********************************************************************/
201 WERROR _winreg_OpenHKPN(pipes_struct *p, struct winreg_OpenHKPN *r)
203 return open_registry_key(p, r->out.handle, NULL, KEY_HKPN, r->in.access_mask);
206 /*******************************************************************
208 ********************************************************************/
210 WERROR _winreg_OpenKey(pipes_struct *p, struct winreg_OpenKey *r)
212 struct registry_key *parent = find_regkey_by_hnd(p, r->in.parent_handle );
217 return open_registry_key(p, r->out.handle, parent, r->in.keyname.name, r->in.access_mask);
220 /*******************************************************************
222 ********************************************************************/
224 WERROR _winreg_QueryValue(pipes_struct *p, struct winreg_QueryValue *r)
226 WERROR status = WERR_BADFILE;
227 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
231 uint32_t outbuf_size;
234 BOOL free_buf = False;
235 BOOL free_prs = False;
240 *r->out.value_length = *r->out.type = 0;
242 DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->key->name));
243 DEBUG(7,("_reg_info: policy key type = [%08x]\n", regkey->key->type));
245 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
246 if(regkey->key->type == REG_KEY_HKPD)
248 if(strequal(r->in.value_name.name, "Global")) {
249 prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL);
250 status = reg_perfcount_get_hkpd(
251 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
252 outbuf = (uint8_t *)prs_hkpd.data_p;
255 else if(strequal(r->in.value_name.name, "Counter 009")) {
256 outbuf_size = reg_perfcount_get_counter_names(
257 reg_perfcount_get_base_index(),
258 (char **)(void *)&outbuf);
261 else if(strequal(r->in.value_name.name, "Explain 009")) {
262 outbuf_size = reg_perfcount_get_counter_help(
263 reg_perfcount_get_base_index(),
264 (char **)(void *)&outbuf);
267 else if(isdigit(r->in.value_name.name[0])) {
268 /* we probably have a request for a specific object
270 prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL);
271 status = reg_perfcount_get_hkpd(
272 &prs_hkpd, *r->in.data_size, &outbuf_size,
273 r->in.value_name.name);
274 outbuf = (uint8_t *)prs_hkpd.data_p;
278 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
279 r->in.value_name.name));
283 *r->out.type = REG_BINARY;
286 struct registry_value *val;
288 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name.name,
290 if (!W_ERROR_IS_OK(status)) {
291 if (r->out.data_size) {
292 *r->out.data_size = 0;
294 if (r->out.value_length) {
295 *r->out.value_length = 0;
300 status = registry_push_value(p->mem_ctx, val, &val_blob);
301 if (!W_ERROR_IS_OK(status)) {
305 outbuf = val_blob.data;
306 outbuf_size = val_blob.length;
307 *r->out.type = val->type;
310 *r->out.value_length = outbuf_size;
312 if ( *r->in.data_size == 0 || !r->out.data ) {
314 } else if ( *r->out.value_length > *r->in.data_size ) {
315 status = WERR_MORE_DATA;
317 memcpy( r->out.data, outbuf, *r->out.value_length );
321 *r->out.data_size = *r->out.value_length;
323 if (free_prs) prs_mem_free(&prs_hkpd);
324 if (free_buf) SAFE_FREE(outbuf);
329 /*****************************************************************************
330 Implementation of REG_QUERY_KEY
331 ****************************************************************************/
333 WERROR _winreg_QueryInfoKey(pipes_struct *p, struct winreg_QueryInfoKey *r)
335 WERROR status = WERR_OK;
336 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
341 r->out.classname->name = NULL;
343 status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
344 r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
345 r->out.max_valbufsize, r->out.secdescsize,
346 r->out.last_changed_time);
347 if (!W_ERROR_IS_OK(status)) {
352 * These calculations account for the registry buffers being
353 * UTF-16. They are inexact at best, but so far they worked.
356 *r->out.max_subkeylen *= 2;
358 *r->out.max_valnamelen += 1;
359 *r->out.max_valnamelen *= 2;
365 /*****************************************************************************
366 Implementation of REG_GETVERSION
367 ****************************************************************************/
369 WERROR _winreg_GetVersion(pipes_struct *p, struct winreg_GetVersion *r)
371 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
376 *r->out.version = 0x00000005; /* Windows 2000 registry API version */
382 /*****************************************************************************
383 Implementation of REG_ENUM_KEY
384 ****************************************************************************/
386 WERROR _winreg_EnumKey(pipes_struct *p, struct winreg_EnumKey *r)
389 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
394 if ( !r->in.name || !r->in.keyclass )
395 return WERR_INVALID_PARAM;
397 DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", key->key->name));
399 err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, (char **)&r->out.name->name,
400 r->out.last_changed_time);
401 if (!W_ERROR_IS_OK(err)) {
404 r->out.keyclass->name = "";
408 /*****************************************************************************
409 Implementation of REG_ENUM_VALUE
410 ****************************************************************************/
412 WERROR _winreg_EnumValue(pipes_struct *p, struct winreg_EnumValue *r)
415 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
417 struct registry_value *val;
418 DATA_BLOB value_blob;
424 return WERR_INVALID_PARAM;
426 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
429 err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
430 if (!W_ERROR_IS_OK(err)) {
434 err = registry_push_value(p->mem_ctx, val, &value_blob);
435 if (!W_ERROR_IS_OK(err)) {
439 if (r->out.name != NULL) {
440 r->out.name->name = valname;
443 if (r->out.type != NULL) {
444 *r->out.type = val->type;
447 if (r->out.value != NULL) {
448 if ((r->out.size == NULL) || (r->out.length == NULL)) {
449 return WERR_INVALID_PARAM;
452 if (value_blob.length > *r->out.size) {
453 return WERR_MORE_DATA;
456 memcpy( r->out.value, value_blob.data, value_blob.length );
459 if (r->out.length != NULL) {
460 *r->out.length = value_blob.length;
462 if (r->out.size != NULL) {
463 *r->out.size = value_blob.length;
469 /*******************************************************************
471 ********************************************************************/
473 WERROR _winreg_InitiateSystemShutdown(pipes_struct *p, struct winreg_InitiateSystemShutdown *r)
475 struct winreg_InitiateSystemShutdownEx s;
477 s.in.hostname = r->in.hostname;
478 s.in.message = r->in.message;
479 s.in.timeout = r->in.timeout;
480 s.in.force_apps = r->in.force_apps;
481 s.in.reboot = r->in.reboot;
484 /* thunk down to _winreg_InitiateSystemShutdownEx()
485 (just returns a status) */
487 return _winreg_InitiateSystemShutdownEx( p, &s );
490 /*******************************************************************
492 ********************************************************************/
494 #define SHUTDOWN_R_STRING "-r"
495 #define SHUTDOWN_F_STRING "-f"
498 WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateSystemShutdownEx *r)
500 pstring shutdown_script;
511 pstrcpy(shutdown_script, lp_shutdown_script());
513 if ( !*shutdown_script )
514 return WERR_ACCESS_DENIED;
516 /* pull the message string and perform necessary sanity checks on it */
520 if ( r->in.message && r->in.message->name && r->in.message->name->name ) {
521 if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->name->name )) == NULL ) {
524 alpha_strcpy (chkmsg, msg, NULL, sizeof(chkmsg));
527 fstr_sprintf(str_timeout, "%d", r->in.timeout);
528 fstr_sprintf(reboot, r->in.reboot ? SHUTDOWN_R_STRING : "");
529 fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
530 fstr_sprintf(str_reason, "%d", r->in.reason );
532 all_string_sub( shutdown_script, "%z", chkmsg, sizeof(shutdown_script) );
533 all_string_sub( shutdown_script, "%t", str_timeout, sizeof(shutdown_script) );
534 all_string_sub( shutdown_script, "%r", reboot, sizeof(shutdown_script) );
535 all_string_sub( shutdown_script, "%f", f, sizeof(shutdown_script) );
536 all_string_sub( shutdown_script, "%x", str_reason, sizeof(shutdown_script) );
538 can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
540 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
541 Take the error return from the script and provide it as the Windows return code. */
543 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
548 ret = smbrun( shutdown_script, NULL );
553 /********** END SeRemoteShutdownPrivilege BLOCK **********/
555 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
556 shutdown_script, ret));
559 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
565 /*******************************************************************
567 ********************************************************************/
569 WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShutdown *r)
571 pstring abort_shutdown_script;
575 pstrcpy(abort_shutdown_script, lp_abort_shutdown_script());
577 if ( !*abort_shutdown_script )
578 return WERR_ACCESS_DENIED;
580 can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
582 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
587 ret = smbrun( abort_shutdown_script, NULL );
592 /********** END SeRemoteShutdownPrivilege BLOCK **********/
594 DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",
595 abort_shutdown_script, ret));
598 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
601 /*******************************************************************
602 ********************************************************************/
604 static int validate_reg_filename( pstring fname )
607 int num_services = lp_numservices();
612 /* convert to a unix path, stripping the C:\ along the way */
614 if ( !(p = valid_share_pathname( fname ) ))
617 /* has to exist within a valid file share */
619 for ( snum=0; snum<num_services; snum++ ) {
621 if ( !lp_snum_ok(snum) || lp_print_ok(snum) )
624 pstrcpy( share_path, lp_pathname(snum) );
626 /* make sure we have a path (e.g. [homes] ) */
628 if ( strlen( share_path ) == 0 )
631 if ( strncmp( share_path, p, strlen( share_path )) == 0 )
635 /* p and fname are overlapping memory so copy out and back in again */
637 pstrcpy( unix_fname, p );
638 pstrcpy( fname, unix_fname );
640 return (snum < num_services) ? snum : -1;
643 /*******************************************************************
644 Note: topkeypat is the *full* path that this *key will be
645 loaded into (including the name of the key)
646 ********************************************************************/
648 static WERROR reg_load_tree( REGF_FILE *regfile, const char *topkeypath,
652 REGISTRY_KEY registry_key;
654 REGSUBKEY_CTR *subkeys;
657 WERROR result = WERR_OK;
659 /* initialize the REGISTRY_KEY structure */
661 if ( !(registry_key.hook = reghook_cache_find(topkeypath)) ) {
662 DEBUG(0,("reg_load_tree: Failed to assigned a REGISTRY_HOOK to [%s]\n",
666 pstrcpy( registry_key.name, topkeypath );
668 /* now start parsing the values and subkeys */
670 if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) )
673 if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) )
676 /* copy values into the REGVAL_CTR */
678 for ( i=0; i<key->num_values; i++ ) {
679 regval_ctr_addvalue( values, key->values[i].valuename, key->values[i].type,
680 (char*)key->values[i].data, (key->values[i].data_size & ~VK_DATA_IN_OFFSET) );
683 /* copy subkeys into the REGSUBKEY_CTR */
685 key->subkey_index = 0;
686 while ( (subkey = regfio_fetch_subkey( regfile, key )) ) {
687 regsubkey_ctr_addkey( subkeys, subkey->keyname );
690 /* write this key and values out */
692 if ( !store_reg_values( ®istry_key, values )
693 || !store_reg_keys( ®istry_key, subkeys ) )
695 DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath));
696 result = WERR_REG_IO_FAILURE;
699 TALLOC_FREE( subkeys );
701 if ( !W_ERROR_IS_OK(result) )
704 /* now continue to load each subkey registry tree */
706 key->subkey_index = 0;
707 while ( (subkey = regfio_fetch_subkey( regfile, key )) ) {
708 pstr_sprintf( path, "%s%s%s", topkeypath, "\\", subkey->keyname );
709 result = reg_load_tree( regfile, path, subkey );
710 if ( !W_ERROR_IS_OK(result) )
717 /*******************************************************************
718 ********************************************************************/
720 static WERROR restore_registry_key ( REGISTRY_KEY *krecord, const char *fname )
723 REGF_NK_REC *rootkey;
726 /* open the registry file....fail if the file already exists */
728 if ( !(regfile = regfio_open( fname, (O_RDONLY), 0 )) ) {
729 DEBUG(0,("restore_registry_key: failed to open \"%s\" (%s)\n",
730 fname, strerror(errno) ));
731 return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) );
734 /* get the rootkey from the regf file and then load the tree
735 via recursive calls */
737 if ( !(rootkey = regfio_rootkey( regfile )) ) {
738 regfio_close( regfile );
739 return WERR_REG_FILE_INVALID;
742 result = reg_load_tree( regfile, krecord->name, rootkey );
746 regfio_close( regfile );
751 /*******************************************************************
752 ********************************************************************/
754 WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r)
756 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
763 if ( !r->in.filename || !r->in.filename->name )
764 return WERR_INVALID_PARAM;
766 pstrcpy( fname, r->in.filename->name );
768 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
769 "\"%s\"\n", regkey->key->name, fname));
771 if ( (snum = validate_reg_filename( fname )) == -1 )
772 return WERR_OBJECT_PATH_INVALID;
774 /* user must posses SeRestorePrivilege for this this proceed */
776 if ( !user_has_privileges( p->pipe_user.nt_user_token, &se_restore ) )
777 return WERR_ACCESS_DENIED;
779 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
780 regkey->key->name, fname, lp_servicename(snum) ));
782 return restore_registry_key( regkey->key, fname );
785 /********************************************************************
786 ********************************************************************/
788 static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath,
789 REGF_NK_REC *parent, SEC_DESC *sec_desc )
793 REGSUBKEY_CTR *subkeys;
796 char *keyname, *parentpath;
799 REGISTRY_KEY registry_key;
800 WERROR result = WERR_OK;
803 return WERR_GENERAL_FAILURE;
806 return WERR_OBJECT_PATH_INVALID;
808 /* split up the registry key path */
810 pstrcpy( key_tmp, keypath );
811 if ( !reg_split_key( key_tmp, &parentpath, &keyname ) )
812 return WERR_OBJECT_PATH_INVALID;
815 keyname = parentpath;
817 /* we need a REGISTRY_KEY object here to enumerate subkeys and values */
819 ZERO_STRUCT( registry_key );
821 if ( (registry_key.name = talloc_strdup(regfile->mem_ctx, keypath)) == NULL )
824 if ( (registry_key.hook = reghook_cache_find( registry_key.name )) == NULL )
827 /* lookup the values and subkeys */
829 if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) )
832 if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) )
835 fetch_reg_keys( ®istry_key, subkeys );
836 fetch_reg_values( ®istry_key, values );
838 /* write out this key */
840 if ( !(key = regfio_write_key( regfile, keyname, values, subkeys, sec_desc, parent )) ) {
841 result = WERR_CAN_NOT_COMPLETE;
845 /* write each one of the subkeys out */
847 num_subkeys = regsubkey_ctr_numkeys( subkeys );
848 for ( i=0; i<num_subkeys; i++ ) {
849 subkeyname = regsubkey_ctr_specific_key( subkeys, i );
850 pstr_sprintf( subkeypath, "%s\\%s", keypath, subkeyname );
851 result = reg_write_tree( regfile, subkeypath, key, sec_desc );
852 if ( !W_ERROR_IS_OK(result) )
856 DEBUG(6,("reg_write_tree: wrote key [%s]\n", keypath ));
859 TALLOC_FREE( subkeys );
860 TALLOC_FREE( registry_key.name );
865 /*******************************************************************
866 ********************************************************************/
868 static WERROR make_default_reg_sd( TALLOC_CTX *ctx, SEC_DESC **psd )
870 DOM_SID adm_sid, owner_sid;
871 SEC_ACE ace[2]; /* at most 2 entries */
876 /* set the owner to BUILTIN\Administrator */
878 sid_copy(&owner_sid, &global_sid_Builtin);
879 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN );
882 /* basic access for Everyone */
884 init_sec_access(&mask, reg_generic_map.generic_execute | reg_generic_map.generic_read );
885 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
887 /* add Full Access 'BUILTIN\Administrators' */
889 init_sec_access(&mask, reg_generic_map.generic_all);
890 sid_copy(&adm_sid, &global_sid_Builtin);
891 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
892 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
894 /* create the security descriptor */
896 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 2, ace)) == NULL)
899 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &owner_sid, NULL, NULL, psa, &sd_size)) == NULL)
905 /*******************************************************************
906 ********************************************************************/
908 static WERROR backup_registry_key ( REGISTRY_KEY *krecord, const char *fname )
914 /* open the registry file....fail if the file already exists */
916 if ( !(regfile = regfio_open( fname, (O_RDWR|O_CREAT|O_EXCL), (S_IREAD|S_IWRITE) )) ) {
917 DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n",
918 fname, strerror(errno) ));
919 return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) );
922 if ( !W_ERROR_IS_OK(result = make_default_reg_sd( regfile->mem_ctx, &sd )) ) {
923 regfio_close( regfile );
927 /* write the registry tree to the file */
929 result = reg_write_tree( regfile, krecord->name, NULL, sd );
933 regfio_close( regfile );
938 /*******************************************************************
939 ********************************************************************/
941 WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r)
943 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
950 if ( !r->in.filename || !r->in.filename->name )
951 return WERR_INVALID_PARAM;
953 pstrcpy( fname, r->in.filename->name );
955 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
956 regkey->key->name, fname));
958 if ( (snum = validate_reg_filename( fname )) == -1 )
959 return WERR_OBJECT_PATH_INVALID;
961 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
962 regkey->key->name, fname, lp_servicename(snum) ));
964 return backup_registry_key( regkey->key, fname );
967 /*******************************************************************
968 ********************************************************************/
970 WERROR _winreg_SaveKeyEx(pipes_struct *p, struct winreg_SaveKeyEx *r)
972 /* fill in your code here if you think this call should
975 p->rng_fault_state = True;
976 return WERR_NOT_SUPPORTED;
979 /*******************************************************************
980 ********************************************************************/
982 WERROR _winreg_CreateKey( pipes_struct *p, struct winreg_CreateKey *r)
984 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
985 struct registry_key *new_key;
991 result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
992 &new_key, r->out.action_taken);
993 if (!W_ERROR_IS_OK(result)) {
997 if (!create_policy_hnd(p, r->out.new_handle, free_regkey, new_key)) {
998 TALLOC_FREE(new_key);
1005 /*******************************************************************
1006 ********************************************************************/
1008 WERROR _winreg_SetValue(pipes_struct *p, struct winreg_SetValue *r)
1010 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
1011 struct registry_value *val;
1017 DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n",
1018 key->key->name, r->in.name.name));
1020 status = registry_pull_value(p->mem_ctx, &val, r->in.type, r->in.data,
1021 r->in.size, r->in.size);
1022 if (!W_ERROR_IS_OK(status)) {
1026 return reg_setvalue(key, r->in.name.name, val);
1029 /*******************************************************************
1030 ********************************************************************/
1032 WERROR _winreg_DeleteKey(pipes_struct *p, struct winreg_DeleteKey *r)
1034 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
1039 return reg_deletekey(parent, r->in.key.name);
1043 /*******************************************************************
1044 ********************************************************************/
1046 WERROR _winreg_DeleteValue(pipes_struct *p, struct winreg_DeleteValue *r)
1048 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
1053 return reg_deletevalue(key, r->in.value.name);
1056 /*******************************************************************
1057 ********************************************************************/
1059 WERROR _winreg_GetKeySecurity(pipes_struct *p, struct winreg_GetKeySecurity *r)
1061 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
1063 struct security_descriptor *secdesc;
1070 /* access checks first */
1072 if ( !(key->key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) )
1073 return WERR_ACCESS_DENIED;
1075 err = regkey_get_secdesc(p->mem_ctx, key->key, &secdesc);
1076 if (!W_ERROR_IS_OK(err)) {
1080 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
1082 if (!W_ERROR_IS_OK(err)) {
1086 if (len > r->out.sd->size) {
1087 r->out.sd->size = len;
1088 return WERR_INSUFFICIENT_BUFFER;
1091 r->out.sd->size = len;
1092 r->out.sd->len = len;
1093 r->out.sd->data = data;
1098 /*******************************************************************
1099 ********************************************************************/
1101 WERROR _winreg_SetKeySecurity(pipes_struct *p, struct winreg_SetKeySecurity *r)
1103 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
1104 struct security_descriptor *secdesc;
1110 /* access checks first */
1112 if ( !(key->key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) )
1113 return WERR_ACCESS_DENIED;
1115 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
1116 r->in.sd->len, &secdesc));
1117 if (!W_ERROR_IS_OK(err)) {
1121 return regkey_set_secdesc(key->key, secdesc);
1124 /*******************************************************************
1125 ********************************************************************/
1127 WERROR _winreg_FlushKey(pipes_struct *p, struct winreg_FlushKey *r)
1129 /* I'm just replying OK because there's not a lot
1130 here I see to do i --jerry */
1135 /*******************************************************************
1136 ********************************************************************/
1138 WERROR _winreg_UnLoadKey(pipes_struct *p, struct winreg_UnLoadKey *r)
1140 /* fill in your code here if you think this call should
1143 p->rng_fault_state = True;
1144 return WERR_NOT_SUPPORTED;
1147 /*******************************************************************
1148 ********************************************************************/
1150 WERROR _winreg_ReplaceKey(pipes_struct *p, struct winreg_ReplaceKey *r)
1152 /* fill in your code here if you think this call should
1155 p->rng_fault_state = True;
1156 return WERR_NOT_SUPPORTED;
1159 /*******************************************************************
1160 ********************************************************************/
1162 WERROR _winreg_LoadKey(pipes_struct *p, struct winreg_LoadKey *r)
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_NotifyChangeKeyValue(pipes_struct *p, struct winreg_NotifyChangeKeyValue *r)
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_QueryMultipleValues(pipes_struct *p, struct winreg_QueryMultipleValues *r)
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_QueryMultipleValues2(pipes_struct *p, struct winreg_QueryMultipleValues2 *r)
1200 /* fill in your code here if you think this call should
1203 p->rng_fault_state = True;
1204 return WERR_NOT_SUPPORTED;