s3-winreg: Fix _winreg_QueryValue crash bugs and implement windows behavior.
[Samba/kamenim.git] / source3 / rpc_server / srv_winreg_nt.c
blob5912322d93ff853921a7106f331e57bbef3c46b6
1 /*
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. */
23 #include "includes.h"
24 #include "../librpc/gen_ndr/srv_winreg.h"
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_RPC_SRV
29 /******************************************************************
30 Find a registry key handle and return a struct registry_key *
31 *****************************************************************/
33 static struct registry_key *find_regkey_by_hnd(pipes_struct *p,
34 struct policy_handle *hnd)
36 struct registry_key *regkey = NULL;
38 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&regkey)) {
39 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
40 return NULL;
43 return regkey;
46 /*******************************************************************
47 Function for open a new registry handle and creating a handle
48 Note that P should be valid & hnd should already have space
50 When we open a key, we store the full path to the key as
51 HK[LM|U]\<key>\<key>\...
52 *******************************************************************/
54 static WERROR open_registry_key( pipes_struct *p, struct policy_handle *hnd,
55 struct registry_key *parent,
56 const char *subkeyname,
57 uint32 access_desired )
59 WERROR result = WERR_OK;
60 struct registry_key *key;
62 if (parent == NULL) {
63 result = reg_openhive(p->mem_ctx, subkeyname, access_desired,
64 p->server_info->ptok, &key);
66 else {
67 result = reg_openkey(p->mem_ctx, parent, subkeyname,
68 access_desired, &key);
71 if ( !W_ERROR_IS_OK(result) ) {
72 return result;
75 if ( !create_policy_hnd( p, hnd, key ) ) {
76 return WERR_BADFILE;
79 return WERR_OK;
82 /*******************************************************************
83 Function for open a new registry handle and creating a handle
84 Note that P should be valid & hnd should already have space
85 *******************************************************************/
87 static bool close_registry_key(pipes_struct *p, struct policy_handle *hnd)
89 struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
91 if ( !regkey ) {
92 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
93 OUR_HANDLE(hnd)));
94 return False;
97 close_policy_hnd(p, hnd);
99 return True;
102 /********************************************************************
103 _winreg_CloseKey
104 ********************************************************************/
106 WERROR _winreg_CloseKey(pipes_struct *p, struct winreg_CloseKey *r)
108 /* close the policy handle */
110 if (!close_registry_key(p, r->in.handle))
111 return WERR_BADFID;
113 ZERO_STRUCTP(r->out.handle);
115 return WERR_OK;
118 /*******************************************************************
119 _winreg_OpenHKLM
120 ********************************************************************/
122 WERROR _winreg_OpenHKLM(pipes_struct *p, struct winreg_OpenHKLM *r)
124 return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
127 /*******************************************************************
128 _winreg_OpenHKPD
129 ********************************************************************/
131 WERROR _winreg_OpenHKPD(pipes_struct *p, struct winreg_OpenHKPD *r)
133 return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
136 /*******************************************************************
137 _winreg_OpenHKPT
138 ********************************************************************/
140 WERROR _winreg_OpenHKPT(pipes_struct *p, struct winreg_OpenHKPT *r)
142 return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
145 /*******************************************************************
146 _winreg_OpenHKCR
147 ********************************************************************/
149 WERROR _winreg_OpenHKCR(pipes_struct *p, struct winreg_OpenHKCR *r)
151 return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
154 /*******************************************************************
155 _winreg_OpenHKU
156 ********************************************************************/
158 WERROR _winreg_OpenHKU(pipes_struct *p, struct winreg_OpenHKU *r)
160 return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
163 /*******************************************************************
164 _winreg_OpenHKCU
165 ********************************************************************/
167 WERROR _winreg_OpenHKCU(pipes_struct *p, struct winreg_OpenHKCU *r)
169 return open_registry_key(p, r->out.handle, NULL, KEY_HKCU, r->in.access_mask);
172 /*******************************************************************
173 _winreg_OpenHKCC
174 ********************************************************************/
176 WERROR _winreg_OpenHKCC(pipes_struct *p, struct winreg_OpenHKCC *r)
178 return open_registry_key(p, r->out.handle, NULL, KEY_HKCC, r->in.access_mask);
181 /*******************************************************************
182 _winreg_OpenHKDD
183 ********************************************************************/
185 WERROR _winreg_OpenHKDD(pipes_struct *p, struct winreg_OpenHKDD *r)
187 return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
190 /*******************************************************************
191 _winreg_OpenHKPN
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 _winreg_OpenKey
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 _winreg_QueryValue
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.data_length == NULL) || (r->out.type == NULL) || (r->out.data_size == NULL)) {
234 return WERR_INVALID_PARAM;
237 DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey->key->name));
238 DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey->key->type));
240 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
241 if(regkey->key->type == REG_KEY_HKPD)
243 if (strequal(r->in.value_name->name, "Global")) {
244 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
245 return WERR_NOMEM;
246 status = reg_perfcount_get_hkpd(
247 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
248 outbuf = (uint8_t *)prs_hkpd.data_p;
249 free_prs = True;
251 else if (strequal(r->in.value_name->name, "Counter 009")) {
252 outbuf_size = reg_perfcount_get_counter_names(
253 reg_perfcount_get_base_index(),
254 (char **)(void *)&outbuf);
255 free_buf = True;
257 else if (strequal(r->in.value_name->name, "Explain 009")) {
258 outbuf_size = reg_perfcount_get_counter_help(
259 reg_perfcount_get_base_index(),
260 (char **)(void *)&outbuf);
261 free_buf = True;
263 else if (isdigit(r->in.value_name->name[0])) {
264 /* we probably have a request for a specific object
265 * here */
266 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
267 return WERR_NOMEM;
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;
272 free_prs = True;
274 else {
275 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
276 r->in.value_name->name));
277 return WERR_BADFILE;
280 *r->out.type = REG_BINARY;
282 else {
283 struct registry_value *val;
285 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name->name,
286 &val);
287 if (!W_ERROR_IS_OK(status)) {
289 DEBUG(10,("_winreg_QueryValue: reg_queryvalue failed with: %s\n",
290 win_errstr(status)));
292 if (r->out.data_size) {
293 *r->out.data_size = 0;
295 if (r->out.data_length) {
296 *r->out.data_length = 0;
298 return status;
301 status = registry_push_value(p->mem_ctx, val, &val_blob);
302 if (!W_ERROR_IS_OK(status)) {
303 return status;
306 outbuf = val_blob.data;
307 outbuf_size = val_blob.length;
308 *r->out.type = val->type;
311 status = WERR_BADFILE;
313 if (*r->in.data_size < outbuf_size) {
314 *r->out.data_size = outbuf_size;
315 status = r->in.data ? WERR_MORE_DATA : WERR_OK;
316 } else {
317 *r->out.data_length = outbuf_size;
318 *r->out.data_size = outbuf_size;
319 memcpy(r->out.data, outbuf, outbuf_size);
320 status = WERR_OK;
323 if (free_prs) prs_mem_free(&prs_hkpd);
324 if (free_buf) SAFE_FREE(outbuf);
326 return status;
329 /*****************************************************************************
330 _winreg_QueryInfoKey
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 );
338 if ( !regkey )
339 return WERR_BADFID;
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)) {
348 return 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;
361 return WERR_OK;
365 /*****************************************************************************
366 _winreg_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 );
373 if ( !regkey )
374 return WERR_BADFID;
376 return reg_getversion(r->out.version);
380 /*****************************************************************************
381 _winreg_EnumKey
382 ****************************************************************************/
384 WERROR _winreg_EnumKey(pipes_struct *p, struct winreg_EnumKey *r)
386 WERROR err;
387 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
389 if ( !key )
390 return WERR_BADFID;
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)) {
400 return err;
402 r->out.keyclass->name = "";
403 return WERR_OK;
406 /*****************************************************************************
407 _winreg_EnumValue
408 ****************************************************************************/
410 WERROR _winreg_EnumValue(pipes_struct *p, struct winreg_EnumValue *r)
412 WERROR err;
413 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
414 char *valname;
415 struct registry_value *val;
416 DATA_BLOB value_blob;
418 if ( !key )
419 return WERR_BADFID;
421 if ( !r->in.name )
422 return WERR_INVALID_PARAM;
424 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
425 key->key->name));
427 err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
428 if (!W_ERROR_IS_OK(err)) {
429 return err;
432 err = registry_push_value(p->mem_ctx, val, &value_blob);
433 if (!W_ERROR_IS_OK(err)) {
434 return 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;
464 return WERR_OK;
467 /*******************************************************************
468 _winreg_InitiateSystemShutdown
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.do_reboot = r->in.do_reboot;
480 s.in.reason = 0;
482 /* thunk down to _winreg_InitiateSystemShutdownEx()
483 (just returns a status) */
485 return _winreg_InitiateSystemShutdownEx( p, &s );
488 /*******************************************************************
489 _winreg_InitiateSystemShutdownEx
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 char *shutdown_script = NULL;
499 char *msg = NULL;
500 char *chkmsg = NULL;
501 fstring str_timeout;
502 fstring str_reason;
503 fstring do_reboot;
504 fstring f;
505 int ret;
506 bool can_shutdown;
508 shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
509 if (!shutdown_script) {
510 return WERR_NOMEM;
512 if (!*shutdown_script) {
513 return WERR_ACCESS_DENIED;
516 /* pull the message string and perform necessary sanity checks on it */
518 if ( r->in.message && r->in.message->string ) {
519 if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->string )) == NULL ) {
520 return WERR_NOMEM;
522 chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
523 if (!chkmsg) {
524 return WERR_NOMEM;
526 alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
529 fstr_sprintf(str_timeout, "%d", r->in.timeout);
530 fstr_sprintf(do_reboot, r->in.do_reboot ? SHUTDOWN_R_STRING : "");
531 fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
532 fstr_sprintf(str_reason, "%d", r->in.reason );
534 shutdown_script = talloc_all_string_sub(p->mem_ctx,
535 shutdown_script, "%z", chkmsg ? chkmsg : "");
536 if (!shutdown_script) {
537 return WERR_NOMEM;
539 shutdown_script = talloc_all_string_sub(p->mem_ctx,
540 shutdown_script, "%t", str_timeout);
541 if (!shutdown_script) {
542 return WERR_NOMEM;
544 shutdown_script = talloc_all_string_sub(p->mem_ctx,
545 shutdown_script, "%r", do_reboot);
546 if (!shutdown_script) {
547 return WERR_NOMEM;
549 shutdown_script = talloc_all_string_sub(p->mem_ctx,
550 shutdown_script, "%f", f);
551 if (!shutdown_script) {
552 return WERR_NOMEM;
554 shutdown_script = talloc_all_string_sub(p->mem_ctx,
555 shutdown_script, "%x", str_reason);
556 if (!shutdown_script) {
557 return WERR_NOMEM;
560 can_shutdown = user_has_privileges( p->server_info->ptok,
561 &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 **********/
568 if ( can_shutdown )
569 become_root();
571 ret = smbrun( shutdown_script, NULL );
573 if ( can_shutdown )
574 unbecome_root();
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 /*******************************************************************
585 _winreg_AbortSystemShutdown
586 ********************************************************************/
588 WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShutdown *r)
590 const char *abort_shutdown_script;
591 int ret;
592 bool can_shutdown;
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->server_info->ptok,
600 &se_remote_shutdown );
602 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
604 if ( can_shutdown )
605 become_root();
607 ret = smbrun( abort_shutdown_script, NULL );
609 if ( can_shutdown )
610 unbecome_root();
612 /********** END SeRemoteShutdownPrivilege BLOCK **********/
614 DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",
615 abort_shutdown_script, ret));
617 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
620 /*******************************************************************
621 ********************************************************************/
623 static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
625 char *p = NULL;
626 int num_services = lp_numservices();
627 int snum = -1;
628 const char *share_path;
629 char *fname = *pp_fname;
631 /* convert to a unix path, stripping the C:\ along the way */
633 if (!(p = valid_share_pathname(ctx, fname))) {
634 return -1;
637 /* has to exist within a valid file share */
639 for (snum=0; snum<num_services; snum++) {
640 if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
641 continue;
644 share_path = lp_pathname(snum);
646 /* make sure we have a path (e.g. [homes] ) */
647 if (strlen(share_path) == 0) {
648 continue;
651 if (strncmp(share_path, p, strlen(share_path)) == 0) {
652 break;
656 *pp_fname = p;
657 return (snum < num_services) ? snum : -1;
660 /*******************************************************************
661 _winreg_RestoreKey
662 ********************************************************************/
664 WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r)
666 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
667 char *fname = NULL;
668 int snum;
670 if ( !regkey )
671 return WERR_BADFID;
673 if ( !r->in.filename || !r->in.filename->name )
674 return WERR_INVALID_PARAM;
676 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
677 if (!fname) {
678 return WERR_NOMEM;
681 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
682 "\"%s\"\n", regkey->key->name, fname));
684 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
685 return WERR_OBJECT_PATH_INVALID;
687 /* user must posses SeRestorePrivilege for this this proceed */
689 if ( !user_has_privileges( p->server_info->ptok, &se_restore ) )
690 return WERR_ACCESS_DENIED;
692 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
693 regkey->key->name, fname, lp_servicename(snum) ));
695 return reg_restorekey(regkey, fname);
698 /*******************************************************************
699 _winreg_SaveKey
700 ********************************************************************/
702 WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r)
704 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
705 char *fname = NULL;
706 int snum = -1;
708 if ( !regkey )
709 return WERR_BADFID;
711 if ( !r->in.filename || !r->in.filename->name )
712 return WERR_INVALID_PARAM;
714 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
715 if (!fname) {
716 return WERR_NOMEM;
719 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
720 regkey->key->name, fname));
722 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
723 return WERR_OBJECT_PATH_INVALID;
725 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
726 regkey->key->name, fname, lp_servicename(snum) ));
728 return reg_savekey(regkey, fname);
731 /*******************************************************************
732 _winreg_SaveKeyEx
733 ********************************************************************/
735 WERROR _winreg_SaveKeyEx(pipes_struct *p, struct winreg_SaveKeyEx *r)
737 /* fill in your code here if you think this call should
738 do anything */
740 p->rng_fault_state = True;
741 return WERR_NOT_SUPPORTED;
744 /*******************************************************************
745 _winreg_CreateKey
746 ********************************************************************/
748 WERROR _winreg_CreateKey( pipes_struct *p, struct winreg_CreateKey *r)
750 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
751 struct registry_key *new_key;
752 WERROR result;
754 if ( !parent )
755 return WERR_BADFID;
757 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
758 "subkey name '%s'\n", parent->key->name, r->in.name.name));
760 result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
761 &new_key, r->out.action_taken);
762 if (!W_ERROR_IS_OK(result)) {
763 return result;
766 if (!create_policy_hnd(p, r->out.new_handle, new_key)) {
767 TALLOC_FREE(new_key);
768 return WERR_BADFILE;
771 return WERR_OK;
774 /*******************************************************************
775 _winreg_SetValue
776 ********************************************************************/
778 WERROR _winreg_SetValue(pipes_struct *p, struct winreg_SetValue *r)
780 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
781 struct registry_value *val;
782 WERROR status;
784 if ( !key )
785 return WERR_BADFID;
787 DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n",
788 key->key->name, r->in.name.name));
790 status = registry_pull_value(p->mem_ctx, &val, r->in.type, r->in.data,
791 r->in.size, r->in.size);
792 if (!W_ERROR_IS_OK(status)) {
793 return status;
796 return reg_setvalue(key, r->in.name.name, val);
799 /*******************************************************************
800 _winreg_DeleteKey
801 ********************************************************************/
803 WERROR _winreg_DeleteKey(pipes_struct *p, struct winreg_DeleteKey *r)
805 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
807 if ( !parent )
808 return WERR_BADFID;
810 return reg_deletekey(parent, r->in.key.name);
814 /*******************************************************************
815 _winreg_DeleteValue
816 ********************************************************************/
818 WERROR _winreg_DeleteValue(pipes_struct *p, struct winreg_DeleteValue *r)
820 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
822 if ( !key )
823 return WERR_BADFID;
825 return reg_deletevalue(key, r->in.value.name);
828 /*******************************************************************
829 _winreg_GetKeySecurity
830 ********************************************************************/
832 WERROR _winreg_GetKeySecurity(pipes_struct *p, struct winreg_GetKeySecurity *r)
834 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
835 WERROR err;
836 struct security_descriptor *secdesc;
837 uint8 *data;
838 size_t len;
840 if ( !key )
841 return WERR_BADFID;
843 /* access checks first */
845 if ( !(key->key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) )
846 return WERR_ACCESS_DENIED;
848 err = reg_getkeysecurity(p->mem_ctx, key, &secdesc);
849 if (!W_ERROR_IS_OK(err)) {
850 return err;
853 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
854 &data, &len));
855 if (!W_ERROR_IS_OK(err)) {
856 return err;
859 if (len > r->out.sd->size) {
860 r->out.sd->size = len;
861 return WERR_INSUFFICIENT_BUFFER;
864 r->out.sd->size = len;
865 r->out.sd->len = len;
866 r->out.sd->data = data;
868 return WERR_OK;
871 /*******************************************************************
872 _winreg_SetKeySecurity
873 ********************************************************************/
875 WERROR _winreg_SetKeySecurity(pipes_struct *p, struct winreg_SetKeySecurity *r)
877 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
878 struct security_descriptor *secdesc;
879 WERROR err;
881 if ( !key )
882 return WERR_BADFID;
884 /* access checks first */
886 if ( !(key->key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) )
887 return WERR_ACCESS_DENIED;
889 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
890 r->in.sd->len, &secdesc));
891 if (!W_ERROR_IS_OK(err)) {
892 return err;
895 return reg_setkeysecurity(key, secdesc);
898 /*******************************************************************
899 _winreg_FlushKey
900 ********************************************************************/
902 WERROR _winreg_FlushKey(pipes_struct *p, struct winreg_FlushKey *r)
904 /* I'm just replying OK because there's not a lot
905 here I see to do i --jerry */
907 return WERR_OK;
910 /*******************************************************************
911 _winreg_UnLoadKey
912 ********************************************************************/
914 WERROR _winreg_UnLoadKey(pipes_struct *p, struct winreg_UnLoadKey *r)
916 /* fill in your code here if you think this call should
917 do anything */
919 p->rng_fault_state = True;
920 return WERR_NOT_SUPPORTED;
923 /*******************************************************************
924 _winreg_ReplaceKey
925 ********************************************************************/
927 WERROR _winreg_ReplaceKey(pipes_struct *p, struct winreg_ReplaceKey *r)
929 /* fill in your code here if you think this call should
930 do anything */
932 p->rng_fault_state = True;
933 return WERR_NOT_SUPPORTED;
936 /*******************************************************************
937 _winreg_LoadKey
938 ********************************************************************/
940 WERROR _winreg_LoadKey(pipes_struct *p, struct winreg_LoadKey *r)
942 /* fill in your code here if you think this call should
943 do anything */
945 p->rng_fault_state = True;
946 return WERR_NOT_SUPPORTED;
949 /*******************************************************************
950 _winreg_NotifyChangeKeyValue
951 ********************************************************************/
953 WERROR _winreg_NotifyChangeKeyValue(pipes_struct *p, struct winreg_NotifyChangeKeyValue *r)
955 /* fill in your code here if you think this call should
956 do anything */
958 p->rng_fault_state = True;
959 return WERR_NOT_SUPPORTED;
962 /*******************************************************************
963 _winreg_QueryMultipleValues
964 ********************************************************************/
966 WERROR _winreg_QueryMultipleValues(pipes_struct *p, struct winreg_QueryMultipleValues *r)
968 /* fill in your code here if you think this call should
969 do anything */
971 p->rng_fault_state = True;
972 return WERR_NOT_SUPPORTED;
975 /*******************************************************************
976 _winreg_QueryMultipleValues2
977 ********************************************************************/
979 WERROR _winreg_QueryMultipleValues2(pipes_struct *p, struct winreg_QueryMultipleValues2 *r)
981 /* fill in your code here if you think this call should
982 do anything */
984 p->rng_fault_state = True;
985 return WERR_NOT_SUPPORTED;