s3-passdb: Fix typo in comment.
[Samba.git] / source3 / rpc_server / srv_winreg_nt.c
blob28d5ac923765af185b77b4c41d8c636b392a59c5
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"
25 #include "registry.h"
26 #include "registry/reg_perfcount.h"
27 #include "registry/reg_util_marshalling.h"
29 #undef DBGC_CLASS
30 #define DBGC_CLASS DBGC_RPC_SRV
32 /******************************************************************
33 Find a registry key handle and return a struct registry_key *
34 *****************************************************************/
36 static struct registry_key *find_regkey_by_hnd(pipes_struct *p,
37 struct policy_handle *hnd)
39 struct registry_key *regkey = NULL;
41 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&regkey)) {
42 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
43 return NULL;
46 return regkey;
49 /*******************************************************************
50 Function for open a new registry handle and creating a handle
51 Note that P should be valid & hnd should already have space
53 When we open a key, we store the full path to the key as
54 HK[LM|U]\<key>\<key>\...
55 *******************************************************************/
57 static WERROR open_registry_key( pipes_struct *p, struct policy_handle *hnd,
58 struct registry_key *parent,
59 const char *subkeyname,
60 uint32 access_desired )
62 WERROR result = WERR_OK;
63 struct registry_key *key;
65 if (parent == NULL) {
66 result = reg_openhive(p->mem_ctx, subkeyname, access_desired,
67 p->server_info->ptok, &key);
69 else {
70 result = reg_openkey(p->mem_ctx, parent, subkeyname,
71 access_desired, &key);
74 if ( !W_ERROR_IS_OK(result) ) {
75 return result;
78 if ( !create_policy_hnd( p, hnd, key ) ) {
79 return WERR_BADFILE;
82 return WERR_OK;
85 /*******************************************************************
86 Function for open a new registry handle and creating a handle
87 Note that P should be valid & hnd should already have space
88 *******************************************************************/
90 static bool close_registry_key(pipes_struct *p, struct policy_handle *hnd)
92 struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
94 if ( !regkey ) {
95 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
96 OUR_HANDLE(hnd)));
97 return False;
100 close_policy_hnd(p, hnd);
102 return True;
105 /********************************************************************
106 _winreg_CloseKey
107 ********************************************************************/
109 WERROR _winreg_CloseKey(pipes_struct *p, struct winreg_CloseKey *r)
111 /* close the policy handle */
113 if (!close_registry_key(p, r->in.handle))
114 return WERR_BADFID;
116 ZERO_STRUCTP(r->out.handle);
118 return WERR_OK;
121 /*******************************************************************
122 _winreg_OpenHKLM
123 ********************************************************************/
125 WERROR _winreg_OpenHKLM(pipes_struct *p, struct winreg_OpenHKLM *r)
127 return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
130 /*******************************************************************
131 _winreg_OpenHKPD
132 ********************************************************************/
134 WERROR _winreg_OpenHKPD(pipes_struct *p, struct winreg_OpenHKPD *r)
136 return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
139 /*******************************************************************
140 _winreg_OpenHKPT
141 ********************************************************************/
143 WERROR _winreg_OpenHKPT(pipes_struct *p, struct winreg_OpenHKPT *r)
145 return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
148 /*******************************************************************
149 _winreg_OpenHKCR
150 ********************************************************************/
152 WERROR _winreg_OpenHKCR(pipes_struct *p, struct winreg_OpenHKCR *r)
154 return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
157 /*******************************************************************
158 _winreg_OpenHKU
159 ********************************************************************/
161 WERROR _winreg_OpenHKU(pipes_struct *p, struct winreg_OpenHKU *r)
163 return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
166 /*******************************************************************
167 _winreg_OpenHKCU
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 _winreg_OpenHKCC
177 ********************************************************************/
179 WERROR _winreg_OpenHKCC(pipes_struct *p, struct winreg_OpenHKCC *r)
181 return open_registry_key(p, r->out.handle, NULL, KEY_HKCC, r->in.access_mask);
184 /*******************************************************************
185 _winreg_OpenHKDD
186 ********************************************************************/
188 WERROR _winreg_OpenHKDD(pipes_struct *p, struct winreg_OpenHKDD *r)
190 return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
193 /*******************************************************************
194 _winreg_OpenHKPN
195 ********************************************************************/
197 WERROR _winreg_OpenHKPN(pipes_struct *p, struct winreg_OpenHKPN *r)
199 return open_registry_key(p, r->out.handle, NULL, KEY_HKPN, r->in.access_mask);
202 /*******************************************************************
203 _winreg_OpenKey
204 ********************************************************************/
206 WERROR _winreg_OpenKey(pipes_struct *p, struct winreg_OpenKey *r)
208 struct registry_key *parent = find_regkey_by_hnd(p, r->in.parent_handle );
210 if ( !parent )
211 return WERR_BADFID;
213 return open_registry_key(p, r->out.handle, parent, r->in.keyname.name, r->in.access_mask);
216 /*******************************************************************
217 _winreg_QueryValue
218 ********************************************************************/
220 WERROR _winreg_QueryValue(pipes_struct *p, struct winreg_QueryValue *r)
222 WERROR status = WERR_BADFILE;
223 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
224 prs_struct prs_hkpd;
226 uint8_t *outbuf;
227 uint32_t outbuf_size;
229 DATA_BLOB val_blob;
230 bool free_buf = False;
231 bool free_prs = False;
233 if ( !regkey )
234 return WERR_BADFID;
236 if (r->in.value_name->name == NULL) {
237 return WERR_INVALID_PARAM;
240 if ((r->out.data_length == NULL) || (r->out.type == NULL) || (r->out.data_size == NULL)) {
241 return WERR_INVALID_PARAM;
244 DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey->key->name));
245 DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey->key->type));
247 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
248 if(regkey->key->type == REG_KEY_HKPD)
250 if (strequal(r->in.value_name->name, "Global")) {
251 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
252 return WERR_NOMEM;
253 status = reg_perfcount_get_hkpd(
254 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
255 outbuf = (uint8_t *)prs_hkpd.data_p;
256 free_prs = True;
258 else if (strequal(r->in.value_name->name, "Counter 009")) {
259 outbuf_size = reg_perfcount_get_counter_names(
260 reg_perfcount_get_base_index(),
261 (char **)(void *)&outbuf);
262 free_buf = True;
264 else if (strequal(r->in.value_name->name, "Explain 009")) {
265 outbuf_size = reg_perfcount_get_counter_help(
266 reg_perfcount_get_base_index(),
267 (char **)(void *)&outbuf);
268 free_buf = True;
270 else if (isdigit(r->in.value_name->name[0])) {
271 /* we probably have a request for a specific object
272 * here */
273 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
274 return WERR_NOMEM;
275 status = reg_perfcount_get_hkpd(
276 &prs_hkpd, *r->in.data_size, &outbuf_size,
277 r->in.value_name->name);
278 outbuf = (uint8_t *)prs_hkpd.data_p;
279 free_prs = True;
281 else {
282 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
283 r->in.value_name->name));
284 return WERR_BADFILE;
287 *r->out.type = REG_BINARY;
289 else {
290 struct registry_value *val;
292 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name->name,
293 &val);
294 if (!W_ERROR_IS_OK(status)) {
296 DEBUG(10,("_winreg_QueryValue: reg_queryvalue failed with: %s\n",
297 win_errstr(status)));
299 if (r->out.data_size) {
300 *r->out.data_size = 0;
302 if (r->out.data_length) {
303 *r->out.data_length = 0;
305 return status;
308 status = registry_push_value(p->mem_ctx, val, &val_blob);
309 if (!W_ERROR_IS_OK(status)) {
310 return status;
313 outbuf = val_blob.data;
314 outbuf_size = val_blob.length;
315 *r->out.type = val->type;
318 status = WERR_BADFILE;
320 if (*r->in.data_size < outbuf_size) {
321 *r->out.data_size = outbuf_size;
322 status = r->in.data ? WERR_MORE_DATA : WERR_OK;
323 } else {
324 *r->out.data_length = outbuf_size;
325 *r->out.data_size = outbuf_size;
326 if (r->out.data) {
327 memcpy(r->out.data, outbuf, outbuf_size);
329 status = WERR_OK;
332 if (free_prs) prs_mem_free(&prs_hkpd);
333 if (free_buf) SAFE_FREE(outbuf);
335 return status;
338 /*****************************************************************************
339 _winreg_QueryInfoKey
340 ****************************************************************************/
342 WERROR _winreg_QueryInfoKey(pipes_struct *p, struct winreg_QueryInfoKey *r)
344 WERROR status = WERR_OK;
345 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
347 if ( !regkey )
348 return WERR_BADFID;
350 r->out.classname->name = NULL;
352 status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
353 r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
354 r->out.max_valbufsize, r->out.secdescsize,
355 r->out.last_changed_time);
356 if (!W_ERROR_IS_OK(status)) {
357 return status;
361 * These calculations account for the registry buffers being
362 * UTF-16. They are inexact at best, but so far they worked.
365 *r->out.max_subkeylen *= 2;
367 *r->out.max_valnamelen += 1;
368 *r->out.max_valnamelen *= 2;
370 return WERR_OK;
374 /*****************************************************************************
375 _winreg_GetVersion
376 ****************************************************************************/
378 WERROR _winreg_GetVersion(pipes_struct *p, struct winreg_GetVersion *r)
380 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
382 if ( !regkey )
383 return WERR_BADFID;
385 return reg_getversion(r->out.version);
389 /*****************************************************************************
390 _winreg_EnumKey
391 ****************************************************************************/
393 WERROR _winreg_EnumKey(pipes_struct *p, struct winreg_EnumKey *r)
395 WERROR err;
396 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
398 if ( !key )
399 return WERR_BADFID;
401 if ( !r->in.name || !r->in.keyclass )
402 return WERR_INVALID_PARAM;
404 DEBUG(8,("_winreg_EnumKey: enumerating key [%s]\n", key->key->name));
406 err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, (char **)&r->out.name->name,
407 r->out.last_changed_time);
408 if (!W_ERROR_IS_OK(err)) {
409 return err;
411 r->out.keyclass->name = "";
412 return WERR_OK;
415 /*****************************************************************************
416 _winreg_EnumValue
417 ****************************************************************************/
419 WERROR _winreg_EnumValue(pipes_struct *p, struct winreg_EnumValue *r)
421 WERROR err;
422 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
423 char *valname;
424 struct registry_value *val;
425 DATA_BLOB value_blob;
427 if ( !key )
428 return WERR_BADFID;
430 if ( !r->in.name )
431 return WERR_INVALID_PARAM;
433 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
434 key->key->name));
436 err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
437 if (!W_ERROR_IS_OK(err)) {
438 return err;
441 err = registry_push_value(p->mem_ctx, val, &value_blob);
442 if (!W_ERROR_IS_OK(err)) {
443 return err;
446 if (r->out.name != NULL) {
447 r->out.name->name = valname;
450 if (r->out.type != NULL) {
451 *r->out.type = val->type;
454 if (r->out.value != NULL) {
455 if ((r->out.size == NULL) || (r->out.length == NULL)) {
456 return WERR_INVALID_PARAM;
459 if (value_blob.length > *r->out.size) {
460 return WERR_MORE_DATA;
463 memcpy( r->out.value, value_blob.data, value_blob.length );
466 if (r->out.length != NULL) {
467 *r->out.length = value_blob.length;
469 if (r->out.size != NULL) {
470 *r->out.size = value_blob.length;
473 return WERR_OK;
476 /*******************************************************************
477 _winreg_InitiateSystemShutdown
478 ********************************************************************/
480 WERROR _winreg_InitiateSystemShutdown(pipes_struct *p, struct winreg_InitiateSystemShutdown *r)
482 struct winreg_InitiateSystemShutdownEx s;
484 s.in.hostname = r->in.hostname;
485 s.in.message = r->in.message;
486 s.in.timeout = r->in.timeout;
487 s.in.force_apps = r->in.force_apps;
488 s.in.do_reboot = r->in.do_reboot;
489 s.in.reason = 0;
491 /* thunk down to _winreg_InitiateSystemShutdownEx()
492 (just returns a status) */
494 return _winreg_InitiateSystemShutdownEx( p, &s );
497 /*******************************************************************
498 _winreg_InitiateSystemShutdownEx
499 ********************************************************************/
501 #define SHUTDOWN_R_STRING "-r"
502 #define SHUTDOWN_F_STRING "-f"
505 WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateSystemShutdownEx *r)
507 char *shutdown_script = NULL;
508 char *msg = NULL;
509 char *chkmsg = NULL;
510 fstring str_timeout;
511 fstring str_reason;
512 fstring do_reboot;
513 fstring f;
514 int ret;
515 bool can_shutdown;
517 shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
518 if (!shutdown_script) {
519 return WERR_NOMEM;
521 if (!*shutdown_script) {
522 return WERR_ACCESS_DENIED;
525 /* pull the message string and perform necessary sanity checks on it */
527 if ( r->in.message && r->in.message->string ) {
528 if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->string )) == NULL ) {
529 return WERR_NOMEM;
531 chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
532 if (!chkmsg) {
533 return WERR_NOMEM;
535 alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
538 fstr_sprintf(str_timeout, "%d", r->in.timeout);
539 fstr_sprintf(do_reboot, r->in.do_reboot ? SHUTDOWN_R_STRING : "");
540 fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
541 fstr_sprintf(str_reason, "%d", r->in.reason );
543 shutdown_script = talloc_all_string_sub(p->mem_ctx,
544 shutdown_script, "%z", chkmsg ? chkmsg : "");
545 if (!shutdown_script) {
546 return WERR_NOMEM;
548 shutdown_script = talloc_all_string_sub(p->mem_ctx,
549 shutdown_script, "%t", str_timeout);
550 if (!shutdown_script) {
551 return WERR_NOMEM;
553 shutdown_script = talloc_all_string_sub(p->mem_ctx,
554 shutdown_script, "%r", do_reboot);
555 if (!shutdown_script) {
556 return WERR_NOMEM;
558 shutdown_script = talloc_all_string_sub(p->mem_ctx,
559 shutdown_script, "%f", f);
560 if (!shutdown_script) {
561 return WERR_NOMEM;
563 shutdown_script = talloc_all_string_sub(p->mem_ctx,
564 shutdown_script, "%x", str_reason);
565 if (!shutdown_script) {
566 return WERR_NOMEM;
569 can_shutdown = user_has_privileges( p->server_info->ptok,
570 &se_remote_shutdown );
572 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
573 Take the error return from the script and provide it as the Windows return code. */
575 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
577 if ( can_shutdown )
578 become_root();
580 ret = smbrun( shutdown_script, NULL );
582 if ( can_shutdown )
583 unbecome_root();
585 /********** END SeRemoteShutdownPrivilege BLOCK **********/
587 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
588 shutdown_script, ret));
590 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
593 /*******************************************************************
594 _winreg_AbortSystemShutdown
595 ********************************************************************/
597 WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShutdown *r)
599 const char *abort_shutdown_script;
600 int ret;
601 bool can_shutdown;
603 abort_shutdown_script = lp_abort_shutdown_script();
605 if (!*abort_shutdown_script)
606 return WERR_ACCESS_DENIED;
608 can_shutdown = user_has_privileges( p->server_info->ptok,
609 &se_remote_shutdown );
611 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
613 if ( can_shutdown )
614 become_root();
616 ret = smbrun( abort_shutdown_script, NULL );
618 if ( can_shutdown )
619 unbecome_root();
621 /********** END SeRemoteShutdownPrivilege BLOCK **********/
623 DEBUG(3,("_winreg_AbortSystemShutdown: Running the command `%s' gave %d\n",
624 abort_shutdown_script, ret));
626 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
629 /*******************************************************************
630 ********************************************************************/
632 static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
634 char *p = NULL;
635 int num_services = lp_numservices();
636 int snum = -1;
637 const char *share_path;
638 char *fname = *pp_fname;
640 /* convert to a unix path, stripping the C:\ along the way */
642 if (!(p = valid_share_pathname(ctx, fname))) {
643 return -1;
646 /* has to exist within a valid file share */
648 for (snum=0; snum<num_services; snum++) {
649 if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
650 continue;
653 share_path = lp_pathname(snum);
655 /* make sure we have a path (e.g. [homes] ) */
656 if (strlen(share_path) == 0) {
657 continue;
660 if (strncmp(share_path, p, strlen(share_path)) == 0) {
661 break;
665 *pp_fname = p;
666 return (snum < num_services) ? snum : -1;
669 /*******************************************************************
670 _winreg_RestoreKey
671 ********************************************************************/
673 WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r)
675 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
676 char *fname = NULL;
677 int snum;
679 if ( !regkey )
680 return WERR_BADFID;
682 if ( !r->in.filename || !r->in.filename->name )
683 return WERR_INVALID_PARAM;
685 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
686 if (!fname) {
687 return WERR_NOMEM;
690 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
691 "\"%s\"\n", regkey->key->name, fname));
693 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
694 return WERR_OBJECT_PATH_INVALID;
696 /* user must posses SeRestorePrivilege for this this proceed */
698 if ( !user_has_privileges( p->server_info->ptok, &se_restore ) )
699 return WERR_ACCESS_DENIED;
701 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
702 regkey->key->name, fname, lp_servicename(snum) ));
704 return reg_restorekey(regkey, fname);
707 /*******************************************************************
708 _winreg_SaveKey
709 ********************************************************************/
711 WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r)
713 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
714 char *fname = NULL;
715 int snum = -1;
717 if ( !regkey )
718 return WERR_BADFID;
720 if ( !r->in.filename || !r->in.filename->name )
721 return WERR_INVALID_PARAM;
723 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
724 if (!fname) {
725 return WERR_NOMEM;
728 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
729 regkey->key->name, fname));
731 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
732 return WERR_OBJECT_PATH_INVALID;
734 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
735 regkey->key->name, fname, lp_servicename(snum) ));
737 return reg_savekey(regkey, fname);
740 /*******************************************************************
741 _winreg_SaveKeyEx
742 ********************************************************************/
744 WERROR _winreg_SaveKeyEx(pipes_struct *p, struct winreg_SaveKeyEx *r)
746 /* fill in your code here if you think this call should
747 do anything */
749 p->rng_fault_state = True;
750 return WERR_NOT_SUPPORTED;
753 /*******************************************************************
754 _winreg_CreateKey
755 ********************************************************************/
757 WERROR _winreg_CreateKey( pipes_struct *p, struct winreg_CreateKey *r)
759 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
760 struct registry_key *new_key;
761 WERROR result;
763 if ( !parent )
764 return WERR_BADFID;
766 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
767 "subkey name '%s'\n", parent->key->name, r->in.name.name));
769 result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
770 &new_key, r->out.action_taken);
771 if (!W_ERROR_IS_OK(result)) {
772 return result;
775 if (!create_policy_hnd(p, r->out.new_handle, new_key)) {
776 TALLOC_FREE(new_key);
777 return WERR_BADFILE;
780 return WERR_OK;
783 /*******************************************************************
784 _winreg_SetValue
785 ********************************************************************/
787 WERROR _winreg_SetValue(pipes_struct *p, struct winreg_SetValue *r)
789 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
790 struct registry_value *val;
791 WERROR status;
793 if ( !key )
794 return WERR_BADFID;
796 DEBUG(8,("_winreg_SetValue: Setting value for [%s:%s]\n",
797 key->key->name, r->in.name.name));
799 status = registry_pull_value(p->mem_ctx, &val, r->in.type, r->in.data,
800 r->in.size, r->in.size);
801 if (!W_ERROR_IS_OK(status)) {
802 return status;
805 return reg_setvalue(key, r->in.name.name, val);
808 /*******************************************************************
809 _winreg_DeleteKey
810 ********************************************************************/
812 WERROR _winreg_DeleteKey(pipes_struct *p, struct winreg_DeleteKey *r)
814 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
816 if ( !parent )
817 return WERR_BADFID;
819 return reg_deletekey(parent, r->in.key.name);
823 /*******************************************************************
824 _winreg_DeleteValue
825 ********************************************************************/
827 WERROR _winreg_DeleteValue(pipes_struct *p, struct winreg_DeleteValue *r)
829 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
831 if ( !key )
832 return WERR_BADFID;
834 return reg_deletevalue(key, r->in.value.name);
837 /*******************************************************************
838 _winreg_GetKeySecurity
839 ********************************************************************/
841 WERROR _winreg_GetKeySecurity(pipes_struct *p, struct winreg_GetKeySecurity *r)
843 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
844 WERROR err;
845 struct security_descriptor *secdesc;
846 uint8 *data;
847 size_t len;
849 if ( !key )
850 return WERR_BADFID;
852 /* access checks first */
854 if ( !(key->key->access_granted & SEC_STD_READ_CONTROL) )
855 return WERR_ACCESS_DENIED;
857 err = reg_getkeysecurity(p->mem_ctx, key, &secdesc);
858 if (!W_ERROR_IS_OK(err)) {
859 return err;
862 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
863 &data, &len));
864 if (!W_ERROR_IS_OK(err)) {
865 return err;
868 if (len > r->out.sd->size) {
869 r->out.sd->size = len;
870 return WERR_INSUFFICIENT_BUFFER;
873 r->out.sd->size = len;
874 r->out.sd->len = len;
875 r->out.sd->data = data;
877 return WERR_OK;
880 /*******************************************************************
881 _winreg_SetKeySecurity
882 ********************************************************************/
884 WERROR _winreg_SetKeySecurity(pipes_struct *p, struct winreg_SetKeySecurity *r)
886 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
887 struct security_descriptor *secdesc;
888 WERROR err;
890 if ( !key )
891 return WERR_BADFID;
893 /* access checks first */
895 if ( !(key->key->access_granted & SEC_STD_WRITE_DAC) )
896 return WERR_ACCESS_DENIED;
898 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
899 r->in.sd->len, &secdesc));
900 if (!W_ERROR_IS_OK(err)) {
901 return err;
904 return reg_setkeysecurity(key, secdesc);
907 /*******************************************************************
908 _winreg_FlushKey
909 ********************************************************************/
911 WERROR _winreg_FlushKey(pipes_struct *p, struct winreg_FlushKey *r)
913 /* I'm just replying OK because there's not a lot
914 here I see to do i --jerry */
916 return WERR_OK;
919 /*******************************************************************
920 _winreg_UnLoadKey
921 ********************************************************************/
923 WERROR _winreg_UnLoadKey(pipes_struct *p, struct winreg_UnLoadKey *r)
925 /* fill in your code here if you think this call should
926 do anything */
928 p->rng_fault_state = True;
929 return WERR_NOT_SUPPORTED;
932 /*******************************************************************
933 _winreg_ReplaceKey
934 ********************************************************************/
936 WERROR _winreg_ReplaceKey(pipes_struct *p, struct winreg_ReplaceKey *r)
938 /* fill in your code here if you think this call should
939 do anything */
941 p->rng_fault_state = True;
942 return WERR_NOT_SUPPORTED;
945 /*******************************************************************
946 _winreg_LoadKey
947 ********************************************************************/
949 WERROR _winreg_LoadKey(pipes_struct *p, struct winreg_LoadKey *r)
951 /* fill in your code here if you think this call should
952 do anything */
954 p->rng_fault_state = True;
955 return WERR_NOT_SUPPORTED;
958 /*******************************************************************
959 _winreg_NotifyChangeKeyValue
960 ********************************************************************/
962 WERROR _winreg_NotifyChangeKeyValue(pipes_struct *p, struct winreg_NotifyChangeKeyValue *r)
964 return WERR_NOT_SUPPORTED;
967 /*******************************************************************
968 _winreg_QueryMultipleValues
969 ********************************************************************/
971 WERROR _winreg_QueryMultipleValues(pipes_struct *p, struct winreg_QueryMultipleValues *r)
973 /* fill in your code here if you think this call should
974 do anything */
976 p->rng_fault_state = True;
977 return WERR_NOT_SUPPORTED;
980 /*******************************************************************
981 _winreg_QueryMultipleValues2
982 ********************************************************************/
984 WERROR _winreg_QueryMultipleValues2(pipes_struct *p, struct winreg_QueryMultipleValues2 *r)
986 /* fill in your code here if you think this call should
987 do anything */
989 p->rng_fault_state = True;
990 return WERR_NOT_SUPPORTED;
993 /*******************************************************************
994 _winreg_DeleteKeyEx
995 ********************************************************************/
997 WERROR _winreg_DeleteKeyEx(pipes_struct *p, struct winreg_DeleteKeyEx *r)
999 /* fill in your code here if you think this call should
1000 do anything */
1002 p->rng_fault_state = True;
1003 return WERR_NOT_SUPPORTED;