Bug 6488: acl_group_override() call in posix acls references an uninitialized variable.
[Samba.git] / source / rpc_server / srv_winreg_nt.c
blob84bcf0bf8921952682859123fb876828f25c2206
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 *
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. */
23 #include "includes.h"
25 #undef DBGC_CLASS
26 #define DBGC_CLASS DBGC_RPC_SRV
28 /******************************************************************
29 free() function for struct registry_key
30 *****************************************************************/
32 static void free_regkey(void *ptr)
34 struct registry_key *key = (struct registry_key *)ptr;
35 TALLOC_FREE(key);
38 /******************************************************************
39 Find a registry key handle and return a struct registry_key *
40 *****************************************************************/
42 static struct registry_key *find_regkey_by_hnd(pipes_struct *p,
43 POLICY_HND *hnd)
45 struct registry_key *regkey = NULL;
47 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&regkey)) {
48 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
49 return NULL;
52 return regkey;
55 /*******************************************************************
56 Function for open a new registry handle and creating a handle
57 Note that P should be valid & hnd should already have space
59 When we open a key, we store the full path to the key as
60 HK[LM|U]\<key>\<key>\...
61 *******************************************************************/
63 static WERROR open_registry_key( pipes_struct *p, POLICY_HND *hnd,
64 struct registry_key *parent,
65 const char *subkeyname,
66 uint32 access_desired )
68 WERROR result = WERR_OK;
69 struct registry_key *key;
71 if (parent == NULL) {
72 result = reg_openhive(NULL, subkeyname, access_desired,
73 p->pipe_user.nt_user_token, &key);
75 else {
76 result = reg_openkey(NULL, parent, subkeyname, access_desired,
77 &key);
80 if ( !W_ERROR_IS_OK(result) ) {
81 return result;
84 if ( !create_policy_hnd( p, hnd, free_regkey, key ) ) {
85 return WERR_BADFILE;
88 return WERR_OK;
91 /*******************************************************************
92 Function for open a new registry handle and creating a handle
93 Note that P should be valid & hnd should already have space
94 *******************************************************************/
96 static bool close_registry_key(pipes_struct *p, POLICY_HND *hnd)
98 struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
100 if ( !regkey ) {
101 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
102 OUR_HANDLE(hnd)));
103 return False;
106 close_policy_hnd(p, hnd);
108 return True;
111 /********************************************************************
112 reg_close
113 ********************************************************************/
115 WERROR _winreg_CloseKey(pipes_struct *p, struct winreg_CloseKey *r)
117 /* close the policy handle */
119 if (!close_registry_key(p, r->in.handle))
120 return WERR_BADFID;
122 ZERO_STRUCTP(r->out.handle);
124 return WERR_OK;
127 /*******************************************************************
128 ********************************************************************/
130 WERROR _winreg_OpenHKLM(pipes_struct *p, struct winreg_OpenHKLM *r)
132 return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
135 /*******************************************************************
136 ********************************************************************/
138 WERROR _winreg_OpenHKPD(pipes_struct *p, struct winreg_OpenHKPD *r)
140 return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
143 /*******************************************************************
144 ********************************************************************/
146 WERROR _winreg_OpenHKPT(pipes_struct *p, struct winreg_OpenHKPT *r)
148 return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
151 /*******************************************************************
152 ********************************************************************/
154 WERROR _winreg_OpenHKCR(pipes_struct *p, struct winreg_OpenHKCR *r)
156 return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
159 /*******************************************************************
160 ********************************************************************/
162 WERROR _winreg_OpenHKU(pipes_struct *p, struct winreg_OpenHKU *r)
164 return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
167 /*******************************************************************
168 ********************************************************************/
170 WERROR _winreg_OpenHKCU(pipes_struct *p, struct winreg_OpenHKCU *r)
172 return open_registry_key(p, r->out.handle, NULL, KEY_HKCU, r->in.access_mask);
175 /*******************************************************************
176 ********************************************************************/
178 WERROR _winreg_OpenHKCC(pipes_struct *p, struct winreg_OpenHKCC *r)
180 return open_registry_key(p, r->out.handle, NULL, KEY_HKCC, r->in.access_mask);
183 /*******************************************************************
184 ********************************************************************/
186 WERROR _winreg_OpenHKDD(pipes_struct *p, struct winreg_OpenHKDD *r)
188 return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
191 /*******************************************************************
192 ********************************************************************/
194 WERROR _winreg_OpenHKPN(pipes_struct *p, struct winreg_OpenHKPN *r)
196 return open_registry_key(p, r->out.handle, NULL, KEY_HKPN, r->in.access_mask);
199 /*******************************************************************
200 reg_reply_open_entry
201 ********************************************************************/
203 WERROR _winreg_OpenKey(pipes_struct *p, struct winreg_OpenKey *r)
205 struct registry_key *parent = find_regkey_by_hnd(p, r->in.parent_handle );
207 if ( !parent )
208 return WERR_BADFID;
210 return open_registry_key(p, r->out.handle, parent, r->in.keyname.name, r->in.access_mask);
213 /*******************************************************************
214 reg_reply_info
215 ********************************************************************/
217 WERROR _winreg_QueryValue(pipes_struct *p, struct winreg_QueryValue *r)
219 WERROR status = WERR_BADFILE;
220 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
221 prs_struct prs_hkpd;
223 uint8_t *outbuf;
224 uint32_t outbuf_size;
226 DATA_BLOB val_blob;
227 bool free_buf = False;
228 bool free_prs = False;
230 if ( !regkey )
231 return WERR_BADFID;
233 if ((r->out.value_length == NULL) || (r->out.type == NULL)) {
234 return WERR_INVALID_PARAM;
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 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
247 return WERR_NOMEM;
248 status = reg_perfcount_get_hkpd(
249 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
250 outbuf = (uint8_t *)prs_hkpd.data_p;
251 free_prs = True;
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);
257 free_buf = True;
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);
263 free_buf = True;
265 else if (isdigit(r->in.value_name->name[0])) {
266 /* we probably have a request for a specific object
267 * here */
268 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
269 return WERR_NOMEM;
270 status = reg_perfcount_get_hkpd(
271 &prs_hkpd, *r->in.data_size, &outbuf_size,
272 r->in.value_name->name);
273 outbuf = (uint8_t *)prs_hkpd.data_p;
274 free_prs = True;
276 else {
277 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
278 r->in.value_name->name));
279 return WERR_BADFILE;
282 *r->out.type = REG_BINARY;
284 else {
285 struct registry_value *val;
287 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name->name,
288 &val);
289 if (!W_ERROR_IS_OK(status)) {
290 if (r->out.data_size) {
291 *r->out.data_size = 0;
293 if (r->out.value_length) {
294 *r->out.value_length = 0;
296 return status;
299 status = registry_push_value(p->mem_ctx, val, &val_blob);
300 if (!W_ERROR_IS_OK(status)) {
301 return status;
304 outbuf = val_blob.data;
305 outbuf_size = val_blob.length;
306 *r->out.type = val->type;
309 *r->out.value_length = outbuf_size;
311 if ( *r->in.data_size == 0 || !r->out.data ) {
312 status = WERR_OK;
313 } else if ( *r->out.value_length > *r->in.data_size ) {
314 status = WERR_MORE_DATA;
315 } else {
316 memcpy( r->out.data, outbuf, *r->out.value_length );
317 status = WERR_OK;
320 *r->out.data_size = *r->out.value_length;
322 if (free_prs) prs_mem_free(&prs_hkpd);
323 if (free_buf) SAFE_FREE(outbuf);
325 return status;
328 /*****************************************************************************
329 Implementation of REG_QUERY_KEY
330 ****************************************************************************/
332 WERROR _winreg_QueryInfoKey(pipes_struct *p, struct winreg_QueryInfoKey *r)
334 WERROR status = WERR_OK;
335 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
337 if ( !regkey )
338 return WERR_BADFID;
340 r->out.classname->name = NULL;
342 status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
343 r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
344 r->out.max_valbufsize, r->out.secdescsize,
345 r->out.last_changed_time);
346 if (!W_ERROR_IS_OK(status)) {
347 return status;
351 * These calculations account for the registry buffers being
352 * UTF-16. They are inexact at best, but so far they worked.
355 *r->out.max_subkeylen *= 2;
357 *r->out.max_valnamelen += 1;
358 *r->out.max_valnamelen *= 2;
360 return WERR_OK;
364 /*****************************************************************************
365 Implementation of REG_GETVERSION
366 ****************************************************************************/
368 WERROR _winreg_GetVersion(pipes_struct *p, struct winreg_GetVersion *r)
370 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
372 if ( !regkey )
373 return WERR_BADFID;
375 return reg_getversion(r->out.version);
379 /*****************************************************************************
380 Implementation of REG_ENUM_KEY
381 ****************************************************************************/
383 WERROR _winreg_EnumKey(pipes_struct *p, struct winreg_EnumKey *r)
385 WERROR err;
386 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
388 if ( !key )
389 return WERR_BADFID;
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)) {
399 return err;
401 r->out.keyclass->name = "";
402 return WERR_OK;
405 /*****************************************************************************
406 Implementation of REG_ENUM_VALUE
407 ****************************************************************************/
409 WERROR _winreg_EnumValue(pipes_struct *p, struct winreg_EnumValue *r)
411 WERROR err;
412 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
413 char *valname;
414 struct registry_value *val;
415 DATA_BLOB value_blob;
417 if ( !key )
418 return WERR_BADFID;
420 if ( !r->in.name )
421 return WERR_INVALID_PARAM;
423 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
424 key->key->name));
426 err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
427 if (!W_ERROR_IS_OK(err)) {
428 return err;
431 err = registry_push_value(p->mem_ctx, val, &value_blob);
432 if (!W_ERROR_IS_OK(err)) {
433 return 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;
463 return WERR_OK;
466 /*******************************************************************
467 reg_shutdwon
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;
479 s.in.reason = 0;
481 /* thunk down to _winreg_InitiateSystemShutdownEx()
482 (just returns a status) */
484 return _winreg_InitiateSystemShutdownEx( p, &s );
487 /*******************************************************************
488 reg_shutdown_ex
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;
498 char *msg = NULL;
499 char *chkmsg = NULL;
500 fstring str_timeout;
501 fstring str_reason;
502 fstring reboot;
503 fstring f;
504 int ret;
505 bool can_shutdown;
507 shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
508 if (!shutdown_script) {
509 return WERR_NOMEM;
511 if (!*shutdown_script) {
512 return WERR_ACCESS_DENIED;
515 /* pull the message string and perform necessary sanity checks on it */
517 if ( r->in.message && r->in.message->name && r->in.message->name->name ) {
518 if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->name->name )) == NULL ) {
519 return WERR_NOMEM;
521 chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
522 if (!chkmsg) {
523 return WERR_NOMEM;
525 alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
528 fstr_sprintf(str_timeout, "%d", r->in.timeout);
529 fstr_sprintf(reboot, r->in.reboot ? SHUTDOWN_R_STRING : "");
530 fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
531 fstr_sprintf(str_reason, "%d", r->in.reason );
533 shutdown_script = talloc_all_string_sub(p->mem_ctx,
534 shutdown_script, "%z", chkmsg ? chkmsg : "");
535 if (!shutdown_script) {
536 return WERR_NOMEM;
538 shutdown_script = talloc_all_string_sub(p->mem_ctx,
539 shutdown_script, "%t", str_timeout);
540 if (!shutdown_script) {
541 return WERR_NOMEM;
543 shutdown_script = talloc_all_string_sub(p->mem_ctx,
544 shutdown_script, "%r", reboot);
545 if (!shutdown_script) {
546 return WERR_NOMEM;
548 shutdown_script = talloc_all_string_sub(p->mem_ctx,
549 shutdown_script, "%f", f);
550 if (!shutdown_script) {
551 return WERR_NOMEM;
553 shutdown_script = talloc_all_string_sub(p->mem_ctx,
554 shutdown_script, "%x", str_reason);
555 if (!shutdown_script) {
556 return WERR_NOMEM;
559 can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
561 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
562 Take the error return from the script and provide it as the Windows return code. */
564 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
566 if ( can_shutdown )
567 become_root();
569 ret = smbrun( shutdown_script, NULL );
571 if ( can_shutdown )
572 unbecome_root();
574 /********** END SeRemoteShutdownPrivilege BLOCK **********/
576 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
577 shutdown_script, ret));
579 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
582 /*******************************************************************
583 reg_abort_shutdwon
584 ********************************************************************/
586 WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShutdown *r)
588 const char *abort_shutdown_script;
589 int ret;
590 bool can_shutdown;
592 abort_shutdown_script = lp_abort_shutdown_script();
594 if (!*abort_shutdown_script)
595 return WERR_ACCESS_DENIED;
597 can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
599 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
601 if ( can_shutdown )
602 become_root();
604 ret = smbrun( abort_shutdown_script, NULL );
606 if ( can_shutdown )
607 unbecome_root();
609 /********** END SeRemoteShutdownPrivilege BLOCK **********/
611 DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",
612 abort_shutdown_script, ret));
614 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
617 /*******************************************************************
618 ********************************************************************/
620 static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
622 char *p = NULL;
623 int num_services = lp_numservices();
624 int snum = -1;
625 const char *share_path;
626 char *fname = *pp_fname;
628 /* convert to a unix path, stripping the C:\ along the way */
630 if (!(p = valid_share_pathname(ctx, fname))) {
631 return -1;
634 /* has to exist within a valid file share */
636 for (snum=0; snum<num_services; snum++) {
637 if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
638 continue;
641 share_path = lp_pathname(snum);
643 /* make sure we have a path (e.g. [homes] ) */
644 if (strlen(share_path) == 0) {
645 continue;
648 if (strncmp(share_path, p, strlen(share_path)) == 0) {
649 break;
653 *pp_fname = p;
654 return (snum < num_services) ? snum : -1;
657 /*******************************************************************
658 ********************************************************************/
660 WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r)
662 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
663 char *fname = NULL;
664 int snum;
666 if ( !regkey )
667 return WERR_BADFID;
669 if ( !r->in.filename || !r->in.filename->name )
670 return WERR_INVALID_PARAM;
672 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
673 if (!fname) {
674 return WERR_NOMEM;
677 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
678 "\"%s\"\n", regkey->key->name, fname));
680 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
681 return WERR_OBJECT_PATH_INVALID;
683 /* user must posses SeRestorePrivilege for this this proceed */
685 if ( !user_has_privileges( p->pipe_user.nt_user_token, &se_restore ) )
686 return WERR_ACCESS_DENIED;
688 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
689 regkey->key->name, fname, lp_servicename(snum) ));
691 return reg_restorekey(regkey, fname);
694 WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r)
696 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
697 char *fname = NULL;
698 int snum = -1;
700 if ( !regkey )
701 return WERR_BADFID;
703 if ( !r->in.filename || !r->in.filename->name )
704 return WERR_INVALID_PARAM;
706 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
707 if (!fname) {
708 return WERR_NOMEM;
711 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
712 regkey->key->name, fname));
714 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
715 return WERR_OBJECT_PATH_INVALID;
717 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
718 regkey->key->name, fname, lp_servicename(snum) ));
720 return reg_savekey(regkey, fname);
723 /*******************************************************************
724 ********************************************************************/
726 WERROR _winreg_SaveKeyEx(pipes_struct *p, struct winreg_SaveKeyEx *r)
728 /* fill in your code here if you think this call should
729 do anything */
731 p->rng_fault_state = True;
732 return WERR_NOT_SUPPORTED;
735 /*******************************************************************
736 ********************************************************************/
738 WERROR _winreg_CreateKey( pipes_struct *p, struct winreg_CreateKey *r)
740 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
741 struct registry_key *new_key;
742 WERROR result;
744 if ( !parent )
745 return WERR_BADFID;
747 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
748 "subkey name '%s'\n", parent->key->name, r->in.name.name));
750 result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
751 &new_key, r->out.action_taken);
752 if (!W_ERROR_IS_OK(result)) {
753 return result;
756 if (!create_policy_hnd(p, r->out.new_handle, free_regkey, new_key)) {
757 TALLOC_FREE(new_key);
758 return WERR_BADFILE;
761 return WERR_OK;
764 /*******************************************************************
765 ********************************************************************/
767 WERROR _winreg_SetValue(pipes_struct *p, struct winreg_SetValue *r)
769 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
770 struct registry_value *val;
771 WERROR status;
773 if ( !key )
774 return WERR_BADFID;
776 DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n",
777 key->key->name, r->in.name.name));
779 status = registry_pull_value(p->mem_ctx, &val, r->in.type, r->in.data,
780 r->in.size, r->in.size);
781 if (!W_ERROR_IS_OK(status)) {
782 return status;
785 return reg_setvalue(key, r->in.name.name, val);
788 /*******************************************************************
789 ********************************************************************/
791 WERROR _winreg_DeleteKey(pipes_struct *p, struct winreg_DeleteKey *r)
793 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
795 if ( !parent )
796 return WERR_BADFID;
798 return reg_deletekey(parent, r->in.key.name);
802 /*******************************************************************
803 ********************************************************************/
805 WERROR _winreg_DeleteValue(pipes_struct *p, struct winreg_DeleteValue *r)
807 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
809 if ( !key )
810 return WERR_BADFID;
812 return reg_deletevalue(key, r->in.value.name);
815 /*******************************************************************
816 ********************************************************************/
818 WERROR _winreg_GetKeySecurity(pipes_struct *p, struct winreg_GetKeySecurity *r)
820 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
821 WERROR err;
822 struct security_descriptor *secdesc;
823 uint8 *data;
824 size_t len;
826 if ( !key )
827 return WERR_BADFID;
829 /* access checks first */
831 if ( !(key->key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) )
832 return WERR_ACCESS_DENIED;
834 err = reg_getkeysecurity(p->mem_ctx, key, &secdesc);
835 if (!W_ERROR_IS_OK(err)) {
836 return err;
839 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
840 &data, &len));
841 if (!W_ERROR_IS_OK(err)) {
842 return err;
845 if (len > r->out.sd->size) {
846 r->out.sd->size = len;
847 return WERR_INSUFFICIENT_BUFFER;
850 r->out.sd->size = len;
851 r->out.sd->len = len;
852 r->out.sd->data = data;
854 return WERR_OK;
857 /*******************************************************************
858 ********************************************************************/
860 WERROR _winreg_SetKeySecurity(pipes_struct *p, struct winreg_SetKeySecurity *r)
862 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
863 struct security_descriptor *secdesc;
864 WERROR err;
866 if ( !key )
867 return WERR_BADFID;
869 /* access checks first */
871 if ( !(key->key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) )
872 return WERR_ACCESS_DENIED;
874 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
875 r->in.sd->len, &secdesc));
876 if (!W_ERROR_IS_OK(err)) {
877 return err;
880 return reg_setkeysecurity(key, secdesc);
883 /*******************************************************************
884 ********************************************************************/
886 WERROR _winreg_FlushKey(pipes_struct *p, struct winreg_FlushKey *r)
888 /* I'm just replying OK because there's not a lot
889 here I see to do i --jerry */
891 return WERR_OK;
894 /*******************************************************************
895 ********************************************************************/
897 WERROR _winreg_UnLoadKey(pipes_struct *p, struct winreg_UnLoadKey *r)
899 /* fill in your code here if you think this call should
900 do anything */
902 p->rng_fault_state = True;
903 return WERR_NOT_SUPPORTED;
906 /*******************************************************************
907 ********************************************************************/
909 WERROR _winreg_ReplaceKey(pipes_struct *p, struct winreg_ReplaceKey *r)
911 /* fill in your code here if you think this call should
912 do anything */
914 p->rng_fault_state = True;
915 return WERR_NOT_SUPPORTED;
918 /*******************************************************************
919 ********************************************************************/
921 WERROR _winreg_LoadKey(pipes_struct *p, struct winreg_LoadKey *r)
923 /* fill in your code here if you think this call should
924 do anything */
926 p->rng_fault_state = True;
927 return WERR_NOT_SUPPORTED;
930 /*******************************************************************
931 ********************************************************************/
933 WERROR _winreg_NotifyChangeKeyValue(pipes_struct *p, struct winreg_NotifyChangeKeyValue *r)
935 /* fill in your code here if you think this call should
936 do anything */
938 p->rng_fault_state = True;
939 return WERR_NOT_SUPPORTED;
942 /*******************************************************************
943 ********************************************************************/
945 WERROR _winreg_QueryMultipleValues(pipes_struct *p, struct winreg_QueryMultipleValues *r)
947 /* fill in your code here if you think this call should
948 do anything */
950 p->rng_fault_state = True;
951 return WERR_NOT_SUPPORTED;
954 /*******************************************************************
955 ********************************************************************/
957 WERROR _winreg_QueryMultipleValues2(pipes_struct *p, struct winreg_QueryMultipleValues2 *r)
959 /* fill in your code here if you think this call should
960 do anything */
962 p->rng_fault_state = True;
963 return WERR_NOT_SUPPORTED;