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;
77 result = reg_openhive(NULL, subkeyname, access_desired,
78 p->pipe_user.nt_user_token, &key);
81 result = reg_openkey(NULL, parent, subkeyname, access_desired,
85 if ( !W_ERROR_IS_OK(result) ) {
89 if ( !create_policy_hnd( p, hnd, free_regkey, key ) ) {
96 /*******************************************************************
97 Function for open a new registry handle and creating a handle
98 Note that P should be valid & hnd should already have space
99 *******************************************************************/
101 static BOOL close_registry_key(pipes_struct *p, POLICY_HND *hnd)
103 struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
106 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
111 close_policy_hnd(p, hnd);
116 /********************************************************************
118 ********************************************************************/
120 WERROR _winreg_CloseKey(pipes_struct *p, struct winreg_CloseKey *r)
122 /* close the policy handle */
124 if (!close_registry_key(p, r->in.handle))
127 ZERO_STRUCTP(r->out.handle);
132 /*******************************************************************
133 ********************************************************************/
135 WERROR _winreg_OpenHKLM(pipes_struct *p, struct winreg_OpenHKLM *r)
137 return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
140 /*******************************************************************
141 ********************************************************************/
143 WERROR _winreg_OpenHKPD(pipes_struct *p, struct winreg_OpenHKPD *r)
145 return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
148 /*******************************************************************
149 ********************************************************************/
151 WERROR _winreg_OpenHKPT(pipes_struct *p, struct winreg_OpenHKPT *r)
153 return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
156 /*******************************************************************
157 ********************************************************************/
159 WERROR _winreg_OpenHKCR(pipes_struct *p, struct winreg_OpenHKCR *r)
161 return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
164 /*******************************************************************
165 ********************************************************************/
167 WERROR _winreg_OpenHKU(pipes_struct *p, struct winreg_OpenHKU *r)
169 return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
172 /*******************************************************************
173 ********************************************************************/
175 WERROR _winreg_OpenHKCU(pipes_struct *p, struct winreg_OpenHKCU *r)
177 return open_registry_key(p, r->out.handle, NULL, KEY_HKCU, r->in.access_mask);
180 /*******************************************************************
181 ********************************************************************/
183 WERROR _winreg_OpenHKCC(pipes_struct *p, struct winreg_OpenHKCC *r)
185 return open_registry_key(p, r->out.handle, NULL, KEY_HKCC, r->in.access_mask);
188 /*******************************************************************
189 ********************************************************************/
191 WERROR _winreg_OpenHKDD(pipes_struct *p, struct winreg_OpenHKDD *r)
193 return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
196 /*******************************************************************
197 ********************************************************************/
199 WERROR _winreg_OpenHKPN(pipes_struct *p, struct winreg_OpenHKPN *r)
201 return open_registry_key(p, r->out.handle, NULL, KEY_HKPN, r->in.access_mask);
204 /*******************************************************************
206 ********************************************************************/
208 WERROR _winreg_OpenKey(pipes_struct *p, struct winreg_OpenKey *r)
210 struct registry_key *parent = find_regkey_by_hnd(p, r->in.parent_handle );
215 return open_registry_key(p, r->out.handle, parent, r->in.keyname.name, r->in.access_mask);
218 /*******************************************************************
220 ********************************************************************/
222 WERROR _winreg_QueryValue(pipes_struct *p, struct winreg_QueryValue *r)
224 WERROR status = WERR_BADFILE;
225 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
229 uint32_t outbuf_size;
232 BOOL free_buf = False;
233 BOOL free_prs = False;
238 *r->out.value_length = *r->out.type = 0;
240 DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->key->name));
241 DEBUG(7,("_reg_info: policy key type = [%08x]\n", regkey->key->type));
243 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
244 if(regkey->key->type == REG_KEY_HKPD)
246 if(strequal(r->in.value_name.name, "Global")) {
247 prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL);
248 status = reg_perfcount_get_hkpd(
249 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
250 outbuf = (uint8_t *)prs_hkpd.data_p;
253 else if(strequal(r->in.value_name.name, "Counter 009")) {
254 outbuf_size = reg_perfcount_get_counter_names(
255 reg_perfcount_get_base_index(),
256 (char **)(void *)&outbuf);
259 else if(strequal(r->in.value_name.name, "Explain 009")) {
260 outbuf_size = reg_perfcount_get_counter_help(
261 reg_perfcount_get_base_index(),
262 (char **)(void *)&outbuf);
265 else if(isdigit(r->in.value_name.name[0])) {
266 /* we probably have a request for a specific object
268 prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL);
269 status = reg_perfcount_get_hkpd(
270 &prs_hkpd, *r->in.data_size, &outbuf_size,
271 r->in.value_name.name);
272 outbuf = (uint8_t *)prs_hkpd.data_p;
276 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
277 r->in.value_name.name));
281 *r->out.type = REG_BINARY;
284 struct registry_value *val;
286 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name.name,
288 if (!W_ERROR_IS_OK(status)) {
289 if (r->out.data_size) {
290 *r->out.data_size = 0;
292 if (r->out.value_length) {
293 *r->out.value_length = 0;
298 status = registry_push_value(p->mem_ctx, val, &val_blob);
299 if (!W_ERROR_IS_OK(status)) {
303 outbuf = val_blob.data;
304 outbuf_size = val_blob.length;
305 *r->out.type = val->type;
308 *r->out.value_length = outbuf_size;
310 if ( *r->in.data_size == 0 || !r->out.data ) {
312 } else if ( *r->out.value_length > *r->in.data_size ) {
313 status = WERR_MORE_DATA;
315 memcpy( r->out.data, outbuf, *r->out.value_length );
319 *r->out.data_size = *r->out.value_length;
321 if (free_prs) prs_mem_free(&prs_hkpd);
322 if (free_buf) SAFE_FREE(outbuf);
327 /*****************************************************************************
328 Implementation of REG_QUERY_KEY
329 ****************************************************************************/
331 WERROR _winreg_QueryInfoKey(pipes_struct *p, struct winreg_QueryInfoKey *r)
333 WERROR status = WERR_OK;
334 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
339 r->out.classname->name = NULL;
341 status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
342 r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
343 r->out.max_valbufsize, r->out.secdescsize,
344 r->out.last_changed_time);
345 if (!W_ERROR_IS_OK(status)) {
350 * These calculations account for the registry buffers being
351 * UTF-16. They are inexact at best, but so far they worked.
354 *r->out.max_subkeylen *= 2;
356 *r->out.max_valnamelen += 1;
357 *r->out.max_valnamelen *= 2;
363 /*****************************************************************************
364 Implementation of REG_GETVERSION
365 ****************************************************************************/
367 WERROR _winreg_GetVersion(pipes_struct *p, struct winreg_GetVersion *r)
369 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
374 *r->out.version = 0x00000005; /* Windows 2000 registry API version */
380 /*****************************************************************************
381 Implementation of REG_ENUM_KEY
382 ****************************************************************************/
384 WERROR _winreg_EnumKey(pipes_struct *p, struct winreg_EnumKey *r)
387 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
392 if ( !r->in.name || !r->in.keyclass )
393 return WERR_INVALID_PARAM;
395 DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", key->key->name));
397 err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, (char **)&r->out.name->name,
398 r->out.last_changed_time);
399 if (!W_ERROR_IS_OK(err)) {
402 r->out.keyclass->name = "";
406 /*****************************************************************************
407 Implementation of REG_ENUM_VALUE
408 ****************************************************************************/
410 WERROR _winreg_EnumValue(pipes_struct *p, struct winreg_EnumValue *r)
413 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
415 struct registry_value *val;
416 DATA_BLOB value_blob;
422 return WERR_INVALID_PARAM;
424 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
427 err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
428 if (!W_ERROR_IS_OK(err)) {
432 err = registry_push_value(p->mem_ctx, val, &value_blob);
433 if (!W_ERROR_IS_OK(err)) {
437 if (r->out.name != NULL) {
438 r->out.name->name = valname;
441 if (r->out.type != NULL) {
442 *r->out.type = val->type;
445 if (r->out.value != NULL) {
446 if ((r->out.size == NULL) || (r->out.length == NULL)) {
447 return WERR_INVALID_PARAM;
450 if (value_blob.length > *r->out.size) {
451 return WERR_MORE_DATA;
454 memcpy( r->out.value, value_blob.data, value_blob.length );
457 if (r->out.length != NULL) {
458 *r->out.length = value_blob.length;
460 if (r->out.size != NULL) {
461 *r->out.size = value_blob.length;
467 /*******************************************************************
469 ********************************************************************/
471 WERROR _winreg_InitiateSystemShutdown(pipes_struct *p, struct winreg_InitiateSystemShutdown *r)
473 struct winreg_InitiateSystemShutdownEx s;
475 s.in.hostname = r->in.hostname;
476 s.in.message = r->in.message;
477 s.in.timeout = r->in.timeout;
478 s.in.force_apps = r->in.force_apps;
479 s.in.reboot = r->in.reboot;
482 /* thunk down to _winreg_InitiateSystemShutdownEx()
483 (just returns a status) */
485 return _winreg_InitiateSystemShutdownEx( p, &s );
488 /*******************************************************************
490 ********************************************************************/
492 #define SHUTDOWN_R_STRING "-r"
493 #define SHUTDOWN_F_STRING "-f"
496 WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateSystemShutdownEx *r)
498 pstring shutdown_script;
509 pstrcpy(shutdown_script, lp_shutdown_script());
511 if ( !*shutdown_script )
512 return WERR_ACCESS_DENIED;
514 /* pull the message string and perform necessary sanity checks on it */
518 if ( r->in.message && r->in.message->name && r->in.message->name->name ) {
519 if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->name->name )) == NULL ) {
522 alpha_strcpy (chkmsg, msg, NULL, sizeof(chkmsg));
525 fstr_sprintf(str_timeout, "%d", r->in.timeout);
526 fstr_sprintf(reboot, r->in.reboot ? SHUTDOWN_R_STRING : "");
527 fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
528 fstr_sprintf(str_reason, "%d", r->in.reason );
530 all_string_sub( shutdown_script, "%z", chkmsg, sizeof(shutdown_script) );
531 all_string_sub( shutdown_script, "%t", str_timeout, sizeof(shutdown_script) );
532 all_string_sub( shutdown_script, "%r", reboot, sizeof(shutdown_script) );
533 all_string_sub( shutdown_script, "%f", f, sizeof(shutdown_script) );
534 all_string_sub( shutdown_script, "%x", str_reason, sizeof(shutdown_script) );
536 can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
538 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
539 Take the error return from the script and provide it as the Windows return code. */
541 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
546 ret = smbrun( shutdown_script, NULL );
551 /********** END SeRemoteShutdownPrivilege BLOCK **********/
553 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
554 shutdown_script, ret));
557 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
563 /*******************************************************************
565 ********************************************************************/
567 WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShutdown *r)
569 pstring abort_shutdown_script;
573 pstrcpy(abort_shutdown_script, lp_abort_shutdown_script());
575 if ( !*abort_shutdown_script )
576 return WERR_ACCESS_DENIED;
578 can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
580 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
585 ret = smbrun( abort_shutdown_script, NULL );
590 /********** END SeRemoteShutdownPrivilege BLOCK **********/
592 DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",
593 abort_shutdown_script, ret));
596 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
599 /*******************************************************************
600 ********************************************************************/
602 static int validate_reg_filename( pstring fname )
605 int num_services = lp_numservices();
610 /* convert to a unix path, stripping the C:\ along the way */
612 if ( !(p = valid_share_pathname( fname ) ))
615 /* has to exist within a valid file share */
617 for ( snum=0; snum<num_services; snum++ ) {
619 if ( !lp_snum_ok(snum) || lp_print_ok(snum) )
622 pstrcpy( share_path, lp_pathname(snum) );
624 /* make sure we have a path (e.g. [homes] ) */
626 if ( strlen( share_path ) == 0 )
629 if ( strncmp( share_path, p, strlen( share_path )) == 0 )
633 /* p and fname are overlapping memory so copy out and back in again */
635 pstrcpy( unix_fname, p );
636 pstrcpy( fname, unix_fname );
638 return (snum < num_services) ? snum : -1;
641 /*******************************************************************
642 Note: topkeypat is the *full* path that this *key will be
643 loaded into (including the name of the key)
644 ********************************************************************/
646 static WERROR reg_load_tree( REGF_FILE *regfile, const char *topkeypath,
650 REGISTRY_KEY registry_key;
652 REGSUBKEY_CTR *subkeys;
655 WERROR result = WERR_OK;
657 /* initialize the REGISTRY_KEY structure */
659 if ( !(registry_key.hook = reghook_cache_find(topkeypath)) ) {
660 DEBUG(0,("reg_load_tree: Failed to assigned a REGISTRY_HOOK to [%s]\n",
664 pstrcpy( registry_key.name, topkeypath );
666 /* now start parsing the values and subkeys */
668 if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) )
671 if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) )
674 /* copy values into the REGVAL_CTR */
676 for ( i=0; i<key->num_values; i++ ) {
677 regval_ctr_addvalue( values, key->values[i].valuename, key->values[i].type,
678 (char*)key->values[i].data, (key->values[i].data_size & ~VK_DATA_IN_OFFSET) );
681 /* copy subkeys into the REGSUBKEY_CTR */
683 key->subkey_index = 0;
684 while ( (subkey = regfio_fetch_subkey( regfile, key )) ) {
685 regsubkey_ctr_addkey( subkeys, subkey->keyname );
688 /* write this key and values out */
690 if ( !store_reg_values( ®istry_key, values )
691 || !store_reg_keys( ®istry_key, subkeys ) )
693 DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath));
694 result = WERR_REG_IO_FAILURE;
697 TALLOC_FREE( subkeys );
699 if ( !W_ERROR_IS_OK(result) )
702 /* now continue to load each subkey registry tree */
704 key->subkey_index = 0;
705 while ( (subkey = regfio_fetch_subkey( regfile, key )) ) {
706 pstr_sprintf( path, "%s%s%s", topkeypath, "\\", subkey->keyname );
707 result = reg_load_tree( regfile, path, subkey );
708 if ( !W_ERROR_IS_OK(result) )
715 /*******************************************************************
716 ********************************************************************/
718 static WERROR restore_registry_key ( REGISTRY_KEY *krecord, const char *fname )
721 REGF_NK_REC *rootkey;
724 /* open the registry file....fail if the file already exists */
726 if ( !(regfile = regfio_open( fname, (O_RDONLY), 0 )) ) {
727 DEBUG(0,("restore_registry_key: failed to open \"%s\" (%s)\n",
728 fname, strerror(errno) ));
729 return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) );
732 /* get the rootkey from the regf file and then load the tree
733 via recursive calls */
735 if ( !(rootkey = regfio_rootkey( regfile )) ) {
736 regfio_close( regfile );
737 return WERR_REG_FILE_INVALID;
740 result = reg_load_tree( regfile, krecord->name, rootkey );
744 regfio_close( regfile );
749 /*******************************************************************
750 ********************************************************************/
752 WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r)
754 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
761 if ( !r->in.filename || !r->in.filename->name )
762 return WERR_INVALID_PARAM;
764 pstrcpy( fname, r->in.filename->name );
766 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
767 "\"%s\"\n", regkey->key->name, fname));
769 if ( (snum = validate_reg_filename( fname )) == -1 )
770 return WERR_OBJECT_PATH_INVALID;
772 /* user must posses SeRestorePrivilege for this this proceed */
774 if ( !user_has_privileges( p->pipe_user.nt_user_token, &se_restore ) )
775 return WERR_ACCESS_DENIED;
777 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
778 regkey->key->name, fname, lp_servicename(snum) ));
780 return restore_registry_key( regkey->key, fname );
783 /********************************************************************
784 ********************************************************************/
786 static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath,
787 REGF_NK_REC *parent, SEC_DESC *sec_desc )
791 REGSUBKEY_CTR *subkeys;
794 char *keyname, *parentpath;
797 REGISTRY_KEY registry_key;
798 WERROR result = WERR_OK;
801 return WERR_GENERAL_FAILURE;
804 return WERR_OBJECT_PATH_INVALID;
806 /* split up the registry key path */
808 pstrcpy( key_tmp, keypath );
809 if ( !reg_split_key( key_tmp, &parentpath, &keyname ) )
810 return WERR_OBJECT_PATH_INVALID;
813 keyname = parentpath;
815 /* we need a REGISTRY_KEY object here to enumerate subkeys and values */
817 ZERO_STRUCT( registry_key );
819 if ( (registry_key.name = talloc_strdup(regfile->mem_ctx, keypath)) == NULL )
822 if ( (registry_key.hook = reghook_cache_find( registry_key.name )) == NULL )
825 /* lookup the values and subkeys */
827 if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) )
830 if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) )
833 fetch_reg_keys( ®istry_key, subkeys );
834 fetch_reg_values( ®istry_key, values );
836 /* write out this key */
838 if ( !(key = regfio_write_key( regfile, keyname, values, subkeys, sec_desc, parent )) ) {
839 result = WERR_CAN_NOT_COMPLETE;
843 /* write each one of the subkeys out */
845 num_subkeys = regsubkey_ctr_numkeys( subkeys );
846 for ( i=0; i<num_subkeys; i++ ) {
847 subkeyname = regsubkey_ctr_specific_key( subkeys, i );
848 pstr_sprintf( subkeypath, "%s\\%s", keypath, subkeyname );
849 result = reg_write_tree( regfile, subkeypath, key, sec_desc );
850 if ( !W_ERROR_IS_OK(result) )
854 DEBUG(6,("reg_write_tree: wrote key [%s]\n", keypath ));
857 TALLOC_FREE( subkeys );
858 TALLOC_FREE( registry_key.name );
863 /*******************************************************************
864 ********************************************************************/
866 static WERROR make_default_reg_sd( TALLOC_CTX *ctx, SEC_DESC **psd )
868 DOM_SID adm_sid, owner_sid;
869 SEC_ACE ace[2]; /* at most 2 entries */
874 /* set the owner to BUILTIN\Administrator */
876 sid_copy(&owner_sid, &global_sid_Builtin);
877 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN );
880 /* basic access for Everyone */
882 init_sec_access(&mask, reg_generic_map.generic_execute | reg_generic_map.generic_read );
883 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
885 /* add Full Access 'BUILTIN\Administrators' */
887 init_sec_access(&mask, reg_generic_map.generic_all);
888 sid_copy(&adm_sid, &global_sid_Builtin);
889 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
890 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
892 /* create the security descriptor */
894 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 2, ace)) == NULL)
897 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &owner_sid, NULL, NULL, psa, &sd_size)) == NULL)
903 /*******************************************************************
904 ********************************************************************/
906 static WERROR backup_registry_key ( REGISTRY_KEY *krecord, const char *fname )
912 /* open the registry file....fail if the file already exists */
914 if ( !(regfile = regfio_open( fname, (O_RDWR|O_CREAT|O_EXCL), (S_IREAD|S_IWRITE) )) ) {
915 DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n",
916 fname, strerror(errno) ));
917 return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) );
920 if ( !W_ERROR_IS_OK(result = make_default_reg_sd( regfile->mem_ctx, &sd )) ) {
921 regfio_close( regfile );
925 /* write the registry tree to the file */
927 result = reg_write_tree( regfile, krecord->name, NULL, sd );
931 regfio_close( regfile );
936 /*******************************************************************
937 ********************************************************************/
939 WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r)
941 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
948 if ( !r->in.filename || !r->in.filename->name )
949 return WERR_INVALID_PARAM;
951 pstrcpy( fname, r->in.filename->name );
953 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
954 regkey->key->name, fname));
956 if ( (snum = validate_reg_filename( fname )) == -1 )
957 return WERR_OBJECT_PATH_INVALID;
959 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
960 regkey->key->name, fname, lp_servicename(snum) ));
962 return backup_registry_key( regkey->key, fname );
965 /*******************************************************************
966 ********************************************************************/
968 WERROR _winreg_SaveKeyEx(pipes_struct *p, struct winreg_SaveKeyEx *r)
970 /* fill in your code here if you think this call should
973 p->rng_fault_state = True;
974 return WERR_NOT_SUPPORTED;
977 /*******************************************************************
978 ********************************************************************/
980 WERROR _winreg_CreateKey( pipes_struct *p, struct winreg_CreateKey *r)
982 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
983 struct registry_key *new_key;
989 result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
990 &new_key, r->out.action_taken);
991 if (!W_ERROR_IS_OK(result)) {
995 if (!create_policy_hnd(p, r->out.new_handle, free_regkey, new_key)) {
996 TALLOC_FREE(new_key);
1003 /*******************************************************************
1004 ********************************************************************/
1006 WERROR _winreg_SetValue(pipes_struct *p, struct winreg_SetValue *r)
1008 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
1009 struct registry_value *val;
1015 DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n",
1016 key->key->name, r->in.name.name));
1018 status = registry_pull_value(p->mem_ctx, &val, r->in.type, r->in.data,
1019 r->in.size, r->in.size);
1020 if (!W_ERROR_IS_OK(status)) {
1024 return reg_setvalue(key, r->in.name.name, val);
1027 /*******************************************************************
1028 ********************************************************************/
1030 WERROR _winreg_DeleteKey(pipes_struct *p, struct winreg_DeleteKey *r)
1032 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
1037 return reg_deletekey(parent, r->in.key.name);
1041 /*******************************************************************
1042 ********************************************************************/
1044 WERROR _winreg_DeleteValue(pipes_struct *p, struct winreg_DeleteValue *r)
1046 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
1051 return reg_deletevalue(key, r->in.value.name);
1054 /*******************************************************************
1055 ********************************************************************/
1057 WERROR _winreg_GetKeySecurity(pipes_struct *p, struct winreg_GetKeySecurity *r)
1059 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
1061 struct security_descriptor *secdesc;
1068 /* access checks first */
1070 if ( !(key->key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) )
1071 return WERR_ACCESS_DENIED;
1073 err = regkey_get_secdesc(p->mem_ctx, key->key, &secdesc);
1074 if (!W_ERROR_IS_OK(err)) {
1078 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
1080 if (!W_ERROR_IS_OK(err)) {
1084 if (len > r->out.sd->size) {
1085 r->out.sd->size = len;
1086 return WERR_INSUFFICIENT_BUFFER;
1089 r->out.sd->size = len;
1090 r->out.sd->len = len;
1091 r->out.sd->data = data;
1096 /*******************************************************************
1097 ********************************************************************/
1099 WERROR _winreg_SetKeySecurity(pipes_struct *p, struct winreg_SetKeySecurity *r)
1101 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
1102 struct security_descriptor *secdesc;
1108 /* access checks first */
1110 if ( !(key->key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) )
1111 return WERR_ACCESS_DENIED;
1113 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
1114 r->in.sd->len, &secdesc));
1115 if (!W_ERROR_IS_OK(err)) {
1119 return regkey_set_secdesc(key->key, secdesc);
1122 /*******************************************************************
1123 ********************************************************************/
1125 WERROR _winreg_FlushKey(pipes_struct *p, struct winreg_FlushKey *r)
1127 /* I'm just replying OK because there's not a lot
1128 here I see to do i --jerry */
1133 /*******************************************************************
1134 ********************************************************************/
1136 WERROR _winreg_UnLoadKey(pipes_struct *p, struct winreg_UnLoadKey *r)
1138 /* fill in your code here if you think this call should
1141 p->rng_fault_state = True;
1142 return WERR_NOT_SUPPORTED;
1145 /*******************************************************************
1146 ********************************************************************/
1148 WERROR _winreg_ReplaceKey(pipes_struct *p, struct winreg_ReplaceKey *r)
1150 /* fill in your code here if you think this call should
1153 p->rng_fault_state = True;
1154 return WERR_NOT_SUPPORTED;
1157 /*******************************************************************
1158 ********************************************************************/
1160 WERROR _winreg_LoadKey(pipes_struct *p, struct winreg_LoadKey *r)
1162 /* fill in your code here if you think this call should
1165 p->rng_fault_state = True;
1166 return WERR_NOT_SUPPORTED;
1169 /*******************************************************************
1170 ********************************************************************/
1172 WERROR _winreg_NotifyChangeKeyValue(pipes_struct *p, struct winreg_NotifyChangeKeyValue *r)
1174 /* fill in your code here if you think this call should
1177 p->rng_fault_state = True;
1178 return WERR_NOT_SUPPORTED;
1181 /*******************************************************************
1182 ********************************************************************/
1184 WERROR _winreg_QueryMultipleValues(pipes_struct *p, struct winreg_QueryMultipleValues *r)
1186 /* fill in your code here if you think this call should
1189 p->rng_fault_state = True;
1190 return WERR_NOT_SUPPORTED;
1193 /*******************************************************************
1194 ********************************************************************/
1196 WERROR _winreg_QueryMultipleValues2(pipes_struct *p, struct winreg_QueryMultipleValues2 *r)
1198 /* fill in your code here if you think this call should
1201 p->rng_fault_state = True;
1202 return WERR_NOT_SUPPORTED;