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 3 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, see <http://www.gnu.org/licenses/>.
21 /* Implementation of registry functions. */
27 #define DBGC_CLASS DBGC_RPC_SRV
29 static const struct generic_mapping reg_generic_map =
30 { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL };
32 /******************************************************************
33 free() function for struct registry_key
34 *****************************************************************/
36 static void free_regkey(void *ptr)
38 struct registry_key *key = (struct registry_key *)ptr;
42 /******************************************************************
43 Find a registry key handle and return a REGISTRY_KEY
44 *****************************************************************/
46 static struct registry_key *find_regkey_by_hnd(pipes_struct *p,
49 struct registry_key *regkey = NULL;
51 if(!find_policy_by_hnd(p,hnd,(void **)(void *)®key)) {
52 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
59 /*******************************************************************
60 Function for open a new registry handle and creating a handle
61 Note that P should be valid & hnd should already have space
63 When we open a key, we store the full path to the key as
64 HK[LM|U]\<key>\<key>\...
65 *******************************************************************/
67 static WERROR open_registry_key( pipes_struct *p, POLICY_HND *hnd,
68 struct registry_key *parent,
69 const char *subkeyname,
70 uint32 access_desired )
72 WERROR result = WERR_OK;
73 struct registry_key *key;
76 result = reg_openhive(NULL, subkeyname, access_desired,
77 p->pipe_user.nt_user_token, &key);
80 result = reg_openkey(NULL, parent, subkeyname, access_desired,
84 if ( !W_ERROR_IS_OK(result) ) {
88 if ( !create_policy_hnd( p, hnd, free_regkey, key ) ) {
95 /*******************************************************************
96 Function for open a new registry handle and creating a handle
97 Note that P should be valid & hnd should already have space
98 *******************************************************************/
100 static bool close_registry_key(pipes_struct *p, POLICY_HND *hnd)
102 struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
105 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
110 close_policy_hnd(p, hnd);
115 /********************************************************************
117 ********************************************************************/
119 WERROR _winreg_CloseKey(pipes_struct *p, struct winreg_CloseKey *r)
121 /* close the policy handle */
123 if (!close_registry_key(p, r->in.handle))
126 ZERO_STRUCTP(r->out.handle);
131 /*******************************************************************
132 ********************************************************************/
134 WERROR _winreg_OpenHKLM(pipes_struct *p, struct winreg_OpenHKLM *r)
136 return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
139 /*******************************************************************
140 ********************************************************************/
142 WERROR _winreg_OpenHKPD(pipes_struct *p, struct winreg_OpenHKPD *r)
144 return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
147 /*******************************************************************
148 ********************************************************************/
150 WERROR _winreg_OpenHKPT(pipes_struct *p, struct winreg_OpenHKPT *r)
152 return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
155 /*******************************************************************
156 ********************************************************************/
158 WERROR _winreg_OpenHKCR(pipes_struct *p, struct winreg_OpenHKCR *r)
160 return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
163 /*******************************************************************
164 ********************************************************************/
166 WERROR _winreg_OpenHKU(pipes_struct *p, struct winreg_OpenHKU *r)
168 return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
171 /*******************************************************************
172 ********************************************************************/
174 WERROR _winreg_OpenHKCU(pipes_struct *p, struct winreg_OpenHKCU *r)
176 return open_registry_key(p, r->out.handle, NULL, KEY_HKCU, r->in.access_mask);
179 /*******************************************************************
180 ********************************************************************/
182 WERROR _winreg_OpenHKCC(pipes_struct *p, struct winreg_OpenHKCC *r)
184 return open_registry_key(p, r->out.handle, NULL, KEY_HKCC, r->in.access_mask);
187 /*******************************************************************
188 ********************************************************************/
190 WERROR _winreg_OpenHKDD(pipes_struct *p, struct winreg_OpenHKDD *r)
192 return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
195 /*******************************************************************
196 ********************************************************************/
198 WERROR _winreg_OpenHKPN(pipes_struct *p, struct winreg_OpenHKPN *r)
200 return open_registry_key(p, r->out.handle, NULL, KEY_HKPN, r->in.access_mask);
203 /*******************************************************************
205 ********************************************************************/
207 WERROR _winreg_OpenKey(pipes_struct *p, struct winreg_OpenKey *r)
209 struct registry_key *parent = find_regkey_by_hnd(p, r->in.parent_handle );
214 return open_registry_key(p, r->out.handle, parent, r->in.keyname.name, r->in.access_mask);
217 /*******************************************************************
219 ********************************************************************/
221 WERROR _winreg_QueryValue(pipes_struct *p, struct winreg_QueryValue *r)
223 WERROR status = WERR_BADFILE;
224 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
228 uint32_t outbuf_size;
231 bool free_buf = False;
232 bool free_prs = False;
237 *r->out.value_length = *r->out.type = REG_NONE;
239 DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->key->name));
240 DEBUG(7,("_reg_info: policy key type = [%08x]\n", regkey->key->type));
242 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
243 if(regkey->key->type == REG_KEY_HKPD)
245 if(strequal(r->in.value_name.name, "Global")) {
246 prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL);
247 status = reg_perfcount_get_hkpd(
248 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
249 outbuf = (uint8_t *)prs_hkpd.data_p;
252 else if(strequal(r->in.value_name.name, "Counter 009")) {
253 outbuf_size = reg_perfcount_get_counter_names(
254 reg_perfcount_get_base_index(),
255 (char **)(void *)&outbuf);
258 else if(strequal(r->in.value_name.name, "Explain 009")) {
259 outbuf_size = reg_perfcount_get_counter_help(
260 reg_perfcount_get_base_index(),
261 (char **)(void *)&outbuf);
264 else if(isdigit(r->in.value_name.name[0])) {
265 /* we probably have a request for a specific object
267 prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL);
268 status = reg_perfcount_get_hkpd(
269 &prs_hkpd, *r->in.data_size, &outbuf_size,
270 r->in.value_name.name);
271 outbuf = (uint8_t *)prs_hkpd.data_p;
275 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
276 r->in.value_name.name));
280 *r->out.type = REG_BINARY;
283 struct registry_value *val;
285 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name.name,
287 if (!W_ERROR_IS_OK(status)) {
288 if (r->out.data_size) {
289 *r->out.data_size = 0;
291 if (r->out.value_length) {
292 *r->out.value_length = 0;
297 status = registry_push_value(p->mem_ctx, val, &val_blob);
298 if (!W_ERROR_IS_OK(status)) {
302 outbuf = val_blob.data;
303 outbuf_size = val_blob.length;
304 *r->out.type = val->type;
307 *r->out.value_length = outbuf_size;
309 if ( *r->in.data_size == 0 || !r->out.data ) {
311 } else if ( *r->out.value_length > *r->in.data_size ) {
312 status = WERR_MORE_DATA;
314 memcpy( r->out.data, outbuf, *r->out.value_length );
318 *r->out.data_size = *r->out.value_length;
320 if (free_prs) prs_mem_free(&prs_hkpd);
321 if (free_buf) SAFE_FREE(outbuf);
326 /*****************************************************************************
327 Implementation of REG_QUERY_KEY
328 ****************************************************************************/
330 WERROR _winreg_QueryInfoKey(pipes_struct *p, struct winreg_QueryInfoKey *r)
332 WERROR status = WERR_OK;
333 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
338 r->out.classname->name = NULL;
340 status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
341 r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
342 r->out.max_valbufsize, r->out.secdescsize,
343 r->out.last_changed_time);
344 if (!W_ERROR_IS_OK(status)) {
349 * These calculations account for the registry buffers being
350 * UTF-16. They are inexact at best, but so far they worked.
353 *r->out.max_subkeylen *= 2;
355 *r->out.max_valnamelen += 1;
356 *r->out.max_valnamelen *= 2;
362 /*****************************************************************************
363 Implementation of REG_GETVERSION
364 ****************************************************************************/
366 WERROR _winreg_GetVersion(pipes_struct *p, struct winreg_GetVersion *r)
368 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
373 *r->out.version = 0x00000005; /* Windows 2000 registry API version */
379 /*****************************************************************************
380 Implementation of REG_ENUM_KEY
381 ****************************************************************************/
383 WERROR _winreg_EnumKey(pipes_struct *p, struct winreg_EnumKey *r)
386 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
391 if ( !r->in.name || !r->in.keyclass )
392 return WERR_INVALID_PARAM;
394 DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", key->key->name));
396 err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, (char **)&r->out.name->name,
397 r->out.last_changed_time);
398 if (!W_ERROR_IS_OK(err)) {
401 r->out.keyclass->name = "";
405 /*****************************************************************************
406 Implementation of REG_ENUM_VALUE
407 ****************************************************************************/
409 WERROR _winreg_EnumValue(pipes_struct *p, struct winreg_EnumValue *r)
412 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
414 struct registry_value *val;
415 DATA_BLOB value_blob;
421 return WERR_INVALID_PARAM;
423 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
426 err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
427 if (!W_ERROR_IS_OK(err)) {
431 err = registry_push_value(p->mem_ctx, val, &value_blob);
432 if (!W_ERROR_IS_OK(err)) {
436 if (r->out.name != NULL) {
437 r->out.name->name = valname;
440 if (r->out.type != NULL) {
441 *r->out.type = val->type;
444 if (r->out.value != NULL) {
445 if ((r->out.size == NULL) || (r->out.length == NULL)) {
446 return WERR_INVALID_PARAM;
449 if (value_blob.length > *r->out.size) {
450 return WERR_MORE_DATA;
453 memcpy( r->out.value, value_blob.data, value_blob.length );
456 if (r->out.length != NULL) {
457 *r->out.length = value_blob.length;
459 if (r->out.size != NULL) {
460 *r->out.size = value_blob.length;
466 /*******************************************************************
468 ********************************************************************/
470 WERROR _winreg_InitiateSystemShutdown(pipes_struct *p, struct winreg_InitiateSystemShutdown *r)
472 struct winreg_InitiateSystemShutdownEx s;
474 s.in.hostname = r->in.hostname;
475 s.in.message = r->in.message;
476 s.in.timeout = r->in.timeout;
477 s.in.force_apps = r->in.force_apps;
478 s.in.reboot = r->in.reboot;
481 /* thunk down to _winreg_InitiateSystemShutdownEx()
482 (just returns a status) */
484 return _winreg_InitiateSystemShutdownEx( p, &s );
487 /*******************************************************************
489 ********************************************************************/
491 #define SHUTDOWN_R_STRING "-r"
492 #define SHUTDOWN_F_STRING "-f"
495 WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateSystemShutdownEx *r)
497 char *shutdown_script = NULL;
507 shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
508 if (!shutdown_script) {
511 if (!*shutdown_script) {
512 return WERR_ACCESS_DENIED;
515 /* pull the message string and perform necessary sanity checks on it */
519 if ( r->in.message && r->in.message->name && r->in.message->name->name ) {
520 if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->name->name )) == NULL ) {
523 chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
527 alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
530 fstr_sprintf(str_timeout, "%d", r->in.timeout);
531 fstr_sprintf(reboot, r->in.reboot ? SHUTDOWN_R_STRING : "");
532 fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
533 fstr_sprintf(str_reason, "%d", r->in.reason );
535 shutdown_script = talloc_all_string_sub(p->mem_ctx,
536 shutdown_script, "%z", chkmsg ? chkmsg : "");
537 if (!shutdown_script) {
540 shutdown_script = talloc_all_string_sub(p->mem_ctx,
541 shutdown_script, "%t", str_timeout);
542 if (!shutdown_script) {
545 shutdown_script = talloc_all_string_sub(p->mem_ctx,
546 shutdown_script, "%r", reboot);
547 if (!shutdown_script) {
550 shutdown_script = talloc_all_string_sub(p->mem_ctx,
551 shutdown_script, "%f", f);
552 if (!shutdown_script) {
555 shutdown_script = talloc_all_string_sub(p->mem_ctx,
556 shutdown_script, "%x", str_reason);
557 if (!shutdown_script) {
561 can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
563 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
564 Take the error return from the script and provide it as the Windows return code. */
566 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
571 ret = smbrun( shutdown_script, NULL );
576 /********** END SeRemoteShutdownPrivilege BLOCK **********/
578 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
579 shutdown_script, ret));
581 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
584 /*******************************************************************
586 ********************************************************************/
588 WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShutdown *r)
590 const char *abort_shutdown_script;
594 abort_shutdown_script = lp_abort_shutdown_script();
596 if (!*abort_shutdown_script)
597 return WERR_ACCESS_DENIED;
599 can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
601 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
606 ret = smbrun( abort_shutdown_script, NULL );
611 /********** END SeRemoteShutdownPrivilege BLOCK **********/
613 DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",
614 abort_shutdown_script, ret));
616 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
619 /*******************************************************************
620 ********************************************************************/
622 static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
625 int num_services = lp_numservices();
627 const char *share_path;
628 char *fname = *pp_fname;
630 /* convert to a unix path, stripping the C:\ along the way */
632 if (!(p = valid_share_pathname(ctx, fname))) {
636 /* has to exist within a valid file share */
638 for (snum=0; snum<num_services; snum++) {
639 if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
643 share_path = lp_pathname(snum);
645 /* make sure we have a path (e.g. [homes] ) */
646 if (strlen(share_path) == 0) {
650 if (strncmp(share_path, p, strlen(share_path)) == 0) {
656 return (snum < num_services) ? snum : -1;
659 /*******************************************************************
660 Note: topkeypat is the *full* path that this *key will be
661 loaded into (including the name of the key)
662 ********************************************************************/
664 static WERROR reg_load_tree( REGF_FILE *regfile, const char *topkeypath,
668 REGISTRY_KEY registry_key;
670 REGSUBKEY_CTR *subkeys;
673 WERROR result = WERR_OK;
675 /* initialize the REGISTRY_KEY structure */
677 if ( !(registry_key.hook = reghook_cache_find(topkeypath)) ) {
678 DEBUG(0,("reg_load_tree: Failed to assigned a REGISTRY_HOOK to [%s]\n",
683 registry_key.name = talloc_strdup( regfile->mem_ctx, topkeypath );
684 if ( !registry_key.name ) {
685 DEBUG(0,("reg_load_tree: Talloc failed for reg_key.name!\n"));
689 /* now start parsing the values and subkeys */
691 if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) )
694 if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) )
697 /* copy values into the REGVAL_CTR */
699 for ( i=0; i<key->num_values; i++ ) {
700 regval_ctr_addvalue( values, key->values[i].valuename, key->values[i].type,
701 (char*)key->values[i].data, (key->values[i].data_size & ~VK_DATA_IN_OFFSET) );
704 /* copy subkeys into the REGSUBKEY_CTR */
706 key->subkey_index = 0;
707 while ( (subkey = regfio_fetch_subkey( regfile, key )) ) {
708 regsubkey_ctr_addkey( subkeys, subkey->keyname );
711 /* write this key and values out */
713 if ( !store_reg_values( ®istry_key, values )
714 || !store_reg_keys( ®istry_key, subkeys ) )
716 DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath));
717 result = WERR_REG_IO_FAILURE;
720 TALLOC_FREE( subkeys );
722 if ( !W_ERROR_IS_OK(result) )
725 /* now continue to load each subkey registry tree */
727 key->subkey_index = 0;
728 while ( (subkey = regfio_fetch_subkey( regfile, key )) ) {
729 path = talloc_asprintf(regfile->mem_ctx,
736 result = reg_load_tree( regfile, path, subkey );
737 if ( !W_ERROR_IS_OK(result) )
744 /*******************************************************************
745 ********************************************************************/
747 static WERROR restore_registry_key ( REGISTRY_KEY *krecord, const char *fname )
750 REGF_NK_REC *rootkey;
753 /* open the registry file....fail if the file already exists */
755 if ( !(regfile = regfio_open( fname, (O_RDONLY), 0 )) ) {
756 DEBUG(0,("restore_registry_key: failed to open \"%s\" (%s)\n",
757 fname, strerror(errno) ));
758 return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) );
761 /* get the rootkey from the regf file and then load the tree
762 via recursive calls */
764 if ( !(rootkey = regfio_rootkey( regfile )) ) {
765 regfio_close( regfile );
766 return WERR_REG_FILE_INVALID;
769 result = reg_load_tree( regfile, krecord->name, rootkey );
773 regfio_close( regfile );
778 /*******************************************************************
779 ********************************************************************/
781 WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r)
783 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
790 if ( !r->in.filename || !r->in.filename->name )
791 return WERR_INVALID_PARAM;
793 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
798 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
799 "\"%s\"\n", regkey->key->name, fname));
801 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
802 return WERR_OBJECT_PATH_INVALID;
804 /* user must posses SeRestorePrivilege for this this proceed */
806 if ( !user_has_privileges( p->pipe_user.nt_user_token, &se_restore ) )
807 return WERR_ACCESS_DENIED;
809 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
810 regkey->key->name, fname, lp_servicename(snum) ));
812 return restore_registry_key( regkey->key, fname );
815 /********************************************************************
816 ********************************************************************/
818 static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath,
819 REGF_NK_REC *parent, SEC_DESC *sec_desc )
823 REGSUBKEY_CTR *subkeys;
825 char *key_tmp = NULL;
826 char *keyname, *parentpath;
827 char *subkeypath = NULL;
829 REGISTRY_KEY registry_key;
830 WERROR result = WERR_OK;
833 return WERR_GENERAL_FAILURE;
836 return WERR_OBJECT_PATH_INVALID;
838 /* split up the registry key path */
840 key_tmp = talloc_strdup(regfile->mem_ctx, keypath);
844 if (!reg_split_key( key_tmp, &parentpath, &keyname ) )
845 return WERR_OBJECT_PATH_INVALID;
848 keyname = parentpath;
850 /* we need a REGISTRY_KEY object here to enumerate subkeys and values */
852 ZERO_STRUCT( registry_key );
854 if ( (registry_key.name = talloc_strdup(regfile->mem_ctx, keypath)) == NULL )
857 if ( (registry_key.hook = reghook_cache_find( registry_key.name )) == NULL )
860 /* lookup the values and subkeys */
862 if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) )
865 if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) )
868 fetch_reg_keys( ®istry_key, subkeys );
869 fetch_reg_values( ®istry_key, values );
871 /* write out this key */
873 if ( !(key = regfio_write_key( regfile, keyname, values, subkeys, sec_desc, parent )) ) {
874 result = WERR_CAN_NOT_COMPLETE;
878 /* write each one of the subkeys out */
880 num_subkeys = regsubkey_ctr_numkeys( subkeys );
881 for ( i=0; i<num_subkeys; i++ ) {
882 subkeyname = regsubkey_ctr_specific_key( subkeys, i );
883 subkeypath = talloc_asprintf(regfile->mem_ctx,
884 "%s\\%s", keypath, subkeyname);
889 result = reg_write_tree( regfile, subkeypath, key, sec_desc );
890 if ( !W_ERROR_IS_OK(result) )
894 DEBUG(6,("reg_write_tree: wrote key [%s]\n", keypath ));
897 TALLOC_FREE( subkeys );
898 TALLOC_FREE( registry_key.name );
903 /*******************************************************************
904 ********************************************************************/
906 static WERROR make_default_reg_sd( TALLOC_CTX *ctx, SEC_DESC **psd )
908 DOM_SID adm_sid, owner_sid;
909 SEC_ACE ace[2]; /* at most 2 entries */
914 /* set the owner to BUILTIN\Administrator */
916 sid_copy(&owner_sid, &global_sid_Builtin);
917 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN );
920 /* basic access for Everyone */
922 init_sec_access(&mask, reg_generic_map.generic_execute | reg_generic_map.generic_read );
923 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
925 /* add Full Access 'BUILTIN\Administrators' */
927 init_sec_access(&mask, reg_generic_map.generic_all);
928 sid_copy(&adm_sid, &global_sid_Builtin);
929 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
930 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
932 /* create the security descriptor */
934 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 2, ace)) == NULL)
937 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &owner_sid, NULL, NULL, psa, &sd_size)) == NULL)
943 /*******************************************************************
944 ********************************************************************/
946 static WERROR backup_registry_key ( REGISTRY_KEY *krecord, const char *fname )
952 /* open the registry file....fail if the file already exists */
954 if ( !(regfile = regfio_open( fname, (O_RDWR|O_CREAT|O_EXCL), (S_IREAD|S_IWRITE) )) ) {
955 DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n",
956 fname, strerror(errno) ));
957 return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) );
960 if ( !W_ERROR_IS_OK(result = make_default_reg_sd( regfile->mem_ctx, &sd )) ) {
961 regfio_close( regfile );
965 /* write the registry tree to the file */
967 result = reg_write_tree( regfile, krecord->name, NULL, sd );
971 regfio_close( regfile );
976 /*******************************************************************
977 ********************************************************************/
979 WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r)
981 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
988 if ( !r->in.filename || !r->in.filename->name )
989 return WERR_INVALID_PARAM;
991 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
996 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
997 regkey->key->name, fname));
999 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
1000 return WERR_OBJECT_PATH_INVALID;
1002 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
1003 regkey->key->name, fname, lp_servicename(snum) ));
1005 return backup_registry_key( regkey->key, fname );
1008 /*******************************************************************
1009 ********************************************************************/
1011 WERROR _winreg_SaveKeyEx(pipes_struct *p, struct winreg_SaveKeyEx *r)
1013 /* fill in your code here if you think this call should
1016 p->rng_fault_state = True;
1017 return WERR_NOT_SUPPORTED;
1020 /*******************************************************************
1021 ********************************************************************/
1023 WERROR _winreg_CreateKey( pipes_struct *p, struct winreg_CreateKey *r)
1025 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
1026 struct registry_key *new_key;
1032 result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
1033 &new_key, r->out.action_taken);
1034 if (!W_ERROR_IS_OK(result)) {
1038 if (!create_policy_hnd(p, r->out.new_handle, free_regkey, new_key)) {
1039 TALLOC_FREE(new_key);
1040 return WERR_BADFILE;
1046 /*******************************************************************
1047 ********************************************************************/
1049 WERROR _winreg_SetValue(pipes_struct *p, struct winreg_SetValue *r)
1051 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
1052 struct registry_value *val;
1058 DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n",
1059 key->key->name, r->in.name.name));
1061 status = registry_pull_value(p->mem_ctx, &val, r->in.type, r->in.data,
1062 r->in.size, r->in.size);
1063 if (!W_ERROR_IS_OK(status)) {
1067 return reg_setvalue(key, r->in.name.name, val);
1070 /*******************************************************************
1071 ********************************************************************/
1073 WERROR _winreg_DeleteKey(pipes_struct *p, struct winreg_DeleteKey *r)
1075 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
1080 return reg_deletekey(parent, r->in.key.name);
1084 /*******************************************************************
1085 ********************************************************************/
1087 WERROR _winreg_DeleteValue(pipes_struct *p, struct winreg_DeleteValue *r)
1089 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
1094 return reg_deletevalue(key, r->in.value.name);
1097 /*******************************************************************
1098 ********************************************************************/
1100 WERROR _winreg_GetKeySecurity(pipes_struct *p, struct winreg_GetKeySecurity *r)
1102 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
1104 struct security_descriptor *secdesc;
1111 /* access checks first */
1113 if ( !(key->key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) )
1114 return WERR_ACCESS_DENIED;
1116 err = regkey_get_secdesc(p->mem_ctx, key->key, &secdesc);
1117 if (!W_ERROR_IS_OK(err)) {
1121 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
1123 if (!W_ERROR_IS_OK(err)) {
1127 if (len > r->out.sd->size) {
1128 r->out.sd->size = len;
1129 return WERR_INSUFFICIENT_BUFFER;
1132 r->out.sd->size = len;
1133 r->out.sd->len = len;
1134 r->out.sd->data = data;
1139 /*******************************************************************
1140 ********************************************************************/
1142 WERROR _winreg_SetKeySecurity(pipes_struct *p, struct winreg_SetKeySecurity *r)
1144 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
1145 struct security_descriptor *secdesc;
1151 /* access checks first */
1153 if ( !(key->key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) )
1154 return WERR_ACCESS_DENIED;
1156 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
1157 r->in.sd->len, &secdesc));
1158 if (!W_ERROR_IS_OK(err)) {
1162 return regkey_set_secdesc(key->key, secdesc);
1165 /*******************************************************************
1166 ********************************************************************/
1168 WERROR _winreg_FlushKey(pipes_struct *p, struct winreg_FlushKey *r)
1170 /* I'm just replying OK because there's not a lot
1171 here I see to do i --jerry */
1176 /*******************************************************************
1177 ********************************************************************/
1179 WERROR _winreg_UnLoadKey(pipes_struct *p, struct winreg_UnLoadKey *r)
1181 /* fill in your code here if you think this call should
1184 p->rng_fault_state = True;
1185 return WERR_NOT_SUPPORTED;
1188 /*******************************************************************
1189 ********************************************************************/
1191 WERROR _winreg_ReplaceKey(pipes_struct *p, struct winreg_ReplaceKey *r)
1193 /* fill in your code here if you think this call should
1196 p->rng_fault_state = True;
1197 return WERR_NOT_SUPPORTED;
1200 /*******************************************************************
1201 ********************************************************************/
1203 WERROR _winreg_LoadKey(pipes_struct *p, struct winreg_LoadKey *r)
1205 /* fill in your code here if you think this call should
1208 p->rng_fault_state = True;
1209 return WERR_NOT_SUPPORTED;
1212 /*******************************************************************
1213 ********************************************************************/
1215 WERROR _winreg_NotifyChangeKeyValue(pipes_struct *p, struct winreg_NotifyChangeKeyValue *r)
1217 /* fill in your code here if you think this call should
1220 p->rng_fault_state = True;
1221 return WERR_NOT_SUPPORTED;
1224 /*******************************************************************
1225 ********************************************************************/
1227 WERROR _winreg_QueryMultipleValues(pipes_struct *p, struct winreg_QueryMultipleValues *r)
1229 /* fill in your code here if you think this call should
1232 p->rng_fault_state = True;
1233 return WERR_NOT_SUPPORTED;
1236 /*******************************************************************
1237 ********************************************************************/
1239 WERROR _winreg_QueryMultipleValues2(pipes_struct *p, struct winreg_QueryMultipleValues2 *r)
1241 /* fill in your code here if you think this call should
1244 p->rng_fault_state = True;
1245 return WERR_NOT_SUPPORTED;