s3:registry: extract reg_perfcount prototypes into header of their own.
[Samba/ekacnet.git] / source3 / rpc_server / srv_winreg_nt.c
blobb84740ba041b5a9049121bea0b037bb39c97c47d
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"
28 #undef DBGC_CLASS
29 #define DBGC_CLASS DBGC_RPC_SRV
31 /******************************************************************
32 Find a registry key handle and return a struct registry_key *
33 *****************************************************************/
35 static struct registry_key *find_regkey_by_hnd(pipes_struct *p,
36 struct policy_handle *hnd)
38 struct registry_key *regkey = NULL;
40 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&regkey)) {
41 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
42 return NULL;
45 return regkey;
48 /*******************************************************************
49 Function for open a new registry handle and creating a handle
50 Note that P should be valid & hnd should already have space
52 When we open a key, we store the full path to the key as
53 HK[LM|U]\<key>\<key>\...
54 *******************************************************************/
56 static WERROR open_registry_key( pipes_struct *p, struct policy_handle *hnd,
57 struct registry_key *parent,
58 const char *subkeyname,
59 uint32 access_desired )
61 WERROR result = WERR_OK;
62 struct registry_key *key;
64 if (parent == NULL) {
65 result = reg_openhive(p->mem_ctx, subkeyname, access_desired,
66 p->server_info->ptok, &key);
68 else {
69 result = reg_openkey(p->mem_ctx, parent, subkeyname,
70 access_desired, &key);
73 if ( !W_ERROR_IS_OK(result) ) {
74 return result;
77 if ( !create_policy_hnd( p, hnd, key ) ) {
78 return WERR_BADFILE;
81 return WERR_OK;
84 /*******************************************************************
85 Function for open a new registry handle and creating a handle
86 Note that P should be valid & hnd should already have space
87 *******************************************************************/
89 static bool close_registry_key(pipes_struct *p, struct policy_handle *hnd)
91 struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
93 if ( !regkey ) {
94 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
95 OUR_HANDLE(hnd)));
96 return False;
99 close_policy_hnd(p, hnd);
101 return True;
104 /********************************************************************
105 _winreg_CloseKey
106 ********************************************************************/
108 WERROR _winreg_CloseKey(pipes_struct *p, struct winreg_CloseKey *r)
110 /* close the policy handle */
112 if (!close_registry_key(p, r->in.handle))
113 return WERR_BADFID;
115 ZERO_STRUCTP(r->out.handle);
117 return WERR_OK;
120 /*******************************************************************
121 _winreg_OpenHKLM
122 ********************************************************************/
124 WERROR _winreg_OpenHKLM(pipes_struct *p, struct winreg_OpenHKLM *r)
126 return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
129 /*******************************************************************
130 _winreg_OpenHKPD
131 ********************************************************************/
133 WERROR _winreg_OpenHKPD(pipes_struct *p, struct winreg_OpenHKPD *r)
135 return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
138 /*******************************************************************
139 _winreg_OpenHKPT
140 ********************************************************************/
142 WERROR _winreg_OpenHKPT(pipes_struct *p, struct winreg_OpenHKPT *r)
144 return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
147 /*******************************************************************
148 _winreg_OpenHKCR
149 ********************************************************************/
151 WERROR _winreg_OpenHKCR(pipes_struct *p, struct winreg_OpenHKCR *r)
153 return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
156 /*******************************************************************
157 _winreg_OpenHKU
158 ********************************************************************/
160 WERROR _winreg_OpenHKU(pipes_struct *p, struct winreg_OpenHKU *r)
162 return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
165 /*******************************************************************
166 _winreg_OpenHKCU
167 ********************************************************************/
169 WERROR _winreg_OpenHKCU(pipes_struct *p, struct winreg_OpenHKCU *r)
171 return open_registry_key(p, r->out.handle, NULL, KEY_HKCU, r->in.access_mask);
174 /*******************************************************************
175 _winreg_OpenHKCC
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 _winreg_OpenHKDD
185 ********************************************************************/
187 WERROR _winreg_OpenHKDD(pipes_struct *p, struct winreg_OpenHKDD *r)
189 return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
192 /*******************************************************************
193 _winreg_OpenHKPN
194 ********************************************************************/
196 WERROR _winreg_OpenHKPN(pipes_struct *p, struct winreg_OpenHKPN *r)
198 return open_registry_key(p, r->out.handle, NULL, KEY_HKPN, r->in.access_mask);
201 /*******************************************************************
202 _winreg_OpenKey
203 ********************************************************************/
205 WERROR _winreg_OpenKey(pipes_struct *p, struct winreg_OpenKey *r)
207 struct registry_key *parent = find_regkey_by_hnd(p, r->in.parent_handle );
209 if ( !parent )
210 return WERR_BADFID;
212 return open_registry_key(p, r->out.handle, parent, r->in.keyname.name, r->in.access_mask);
215 /*******************************************************************
216 _winreg_QueryValue
217 ********************************************************************/
219 WERROR _winreg_QueryValue(pipes_struct *p, struct winreg_QueryValue *r)
221 WERROR status = WERR_BADFILE;
222 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
223 prs_struct prs_hkpd;
225 uint8_t *outbuf;
226 uint32_t outbuf_size;
228 DATA_BLOB val_blob;
229 bool free_buf = False;
230 bool free_prs = False;
232 if ( !regkey )
233 return WERR_BADFID;
235 if (r->in.value_name->name == NULL) {
236 return WERR_INVALID_PARAM;
239 if ((r->out.data_length == NULL) || (r->out.type == NULL) || (r->out.data_size == NULL)) {
240 return WERR_INVALID_PARAM;
243 DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey->key->name));
244 DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey->key->type));
246 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
247 if(regkey->key->type == REG_KEY_HKPD)
249 if (strequal(r->in.value_name->name, "Global")) {
250 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
251 return WERR_NOMEM;
252 status = reg_perfcount_get_hkpd(
253 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
254 outbuf = (uint8_t *)prs_hkpd.data_p;
255 free_prs = True;
257 else if (strequal(r->in.value_name->name, "Counter 009")) {
258 outbuf_size = reg_perfcount_get_counter_names(
259 reg_perfcount_get_base_index(),
260 (char **)(void *)&outbuf);
261 free_buf = True;
263 else if (strequal(r->in.value_name->name, "Explain 009")) {
264 outbuf_size = reg_perfcount_get_counter_help(
265 reg_perfcount_get_base_index(),
266 (char **)(void *)&outbuf);
267 free_buf = True;
269 else if (isdigit(r->in.value_name->name[0])) {
270 /* we probably have a request for a specific object
271 * here */
272 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
273 return WERR_NOMEM;
274 status = reg_perfcount_get_hkpd(
275 &prs_hkpd, *r->in.data_size, &outbuf_size,
276 r->in.value_name->name);
277 outbuf = (uint8_t *)prs_hkpd.data_p;
278 free_prs = True;
280 else {
281 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
282 r->in.value_name->name));
283 return WERR_BADFILE;
286 *r->out.type = REG_BINARY;
288 else {
289 struct registry_value *val;
291 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name->name,
292 &val);
293 if (!W_ERROR_IS_OK(status)) {
295 DEBUG(10,("_winreg_QueryValue: reg_queryvalue failed with: %s\n",
296 win_errstr(status)));
298 if (r->out.data_size) {
299 *r->out.data_size = 0;
301 if (r->out.data_length) {
302 *r->out.data_length = 0;
304 return status;
307 status = registry_push_value(p->mem_ctx, val, &val_blob);
308 if (!W_ERROR_IS_OK(status)) {
309 return status;
312 outbuf = val_blob.data;
313 outbuf_size = val_blob.length;
314 *r->out.type = val->type;
317 status = WERR_BADFILE;
319 if (*r->in.data_size < outbuf_size) {
320 *r->out.data_size = outbuf_size;
321 status = r->in.data ? WERR_MORE_DATA : WERR_OK;
322 } else {
323 *r->out.data_length = outbuf_size;
324 *r->out.data_size = outbuf_size;
325 if (r->out.data) {
326 memcpy(r->out.data, outbuf, outbuf_size);
328 status = WERR_OK;
331 if (free_prs) prs_mem_free(&prs_hkpd);
332 if (free_buf) SAFE_FREE(outbuf);
334 return status;
337 /*****************************************************************************
338 _winreg_QueryInfoKey
339 ****************************************************************************/
341 WERROR _winreg_QueryInfoKey(pipes_struct *p, struct winreg_QueryInfoKey *r)
343 WERROR status = WERR_OK;
344 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
346 if ( !regkey )
347 return WERR_BADFID;
349 r->out.classname->name = NULL;
351 status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
352 r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
353 r->out.max_valbufsize, r->out.secdescsize,
354 r->out.last_changed_time);
355 if (!W_ERROR_IS_OK(status)) {
356 return status;
360 * These calculations account for the registry buffers being
361 * UTF-16. They are inexact at best, but so far they worked.
364 *r->out.max_subkeylen *= 2;
366 *r->out.max_valnamelen += 1;
367 *r->out.max_valnamelen *= 2;
369 return WERR_OK;
373 /*****************************************************************************
374 _winreg_GetVersion
375 ****************************************************************************/
377 WERROR _winreg_GetVersion(pipes_struct *p, struct winreg_GetVersion *r)
379 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
381 if ( !regkey )
382 return WERR_BADFID;
384 return reg_getversion(r->out.version);
388 /*****************************************************************************
389 _winreg_EnumKey
390 ****************************************************************************/
392 WERROR _winreg_EnumKey(pipes_struct *p, struct winreg_EnumKey *r)
394 WERROR err;
395 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
397 if ( !key )
398 return WERR_BADFID;
400 if ( !r->in.name || !r->in.keyclass )
401 return WERR_INVALID_PARAM;
403 DEBUG(8,("_winreg_EnumKey: enumerating key [%s]\n", key->key->name));
405 err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, (char **)&r->out.name->name,
406 r->out.last_changed_time);
407 if (!W_ERROR_IS_OK(err)) {
408 return err;
410 r->out.keyclass->name = "";
411 return WERR_OK;
414 /*****************************************************************************
415 _winreg_EnumValue
416 ****************************************************************************/
418 WERROR _winreg_EnumValue(pipes_struct *p, struct winreg_EnumValue *r)
420 WERROR err;
421 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
422 char *valname;
423 struct registry_value *val;
424 DATA_BLOB value_blob;
426 if ( !key )
427 return WERR_BADFID;
429 if ( !r->in.name )
430 return WERR_INVALID_PARAM;
432 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
433 key->key->name));
435 err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
436 if (!W_ERROR_IS_OK(err)) {
437 return err;
440 err = registry_push_value(p->mem_ctx, val, &value_blob);
441 if (!W_ERROR_IS_OK(err)) {
442 return err;
445 if (r->out.name != NULL) {
446 r->out.name->name = valname;
449 if (r->out.type != NULL) {
450 *r->out.type = val->type;
453 if (r->out.value != NULL) {
454 if ((r->out.size == NULL) || (r->out.length == NULL)) {
455 return WERR_INVALID_PARAM;
458 if (value_blob.length > *r->out.size) {
459 return WERR_MORE_DATA;
462 memcpy( r->out.value, value_blob.data, value_blob.length );
465 if (r->out.length != NULL) {
466 *r->out.length = value_blob.length;
468 if (r->out.size != NULL) {
469 *r->out.size = value_blob.length;
472 return WERR_OK;
475 /*******************************************************************
476 _winreg_InitiateSystemShutdown
477 ********************************************************************/
479 WERROR _winreg_InitiateSystemShutdown(pipes_struct *p, struct winreg_InitiateSystemShutdown *r)
481 struct winreg_InitiateSystemShutdownEx s;
483 s.in.hostname = r->in.hostname;
484 s.in.message = r->in.message;
485 s.in.timeout = r->in.timeout;
486 s.in.force_apps = r->in.force_apps;
487 s.in.do_reboot = r->in.do_reboot;
488 s.in.reason = 0;
490 /* thunk down to _winreg_InitiateSystemShutdownEx()
491 (just returns a status) */
493 return _winreg_InitiateSystemShutdownEx( p, &s );
496 /*******************************************************************
497 _winreg_InitiateSystemShutdownEx
498 ********************************************************************/
500 #define SHUTDOWN_R_STRING "-r"
501 #define SHUTDOWN_F_STRING "-f"
504 WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateSystemShutdownEx *r)
506 char *shutdown_script = NULL;
507 char *msg = NULL;
508 char *chkmsg = NULL;
509 fstring str_timeout;
510 fstring str_reason;
511 fstring do_reboot;
512 fstring f;
513 int ret;
514 bool can_shutdown;
516 shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
517 if (!shutdown_script) {
518 return WERR_NOMEM;
520 if (!*shutdown_script) {
521 return WERR_ACCESS_DENIED;
524 /* pull the message string and perform necessary sanity checks on it */
526 if ( r->in.message && r->in.message->string ) {
527 if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->string )) == NULL ) {
528 return WERR_NOMEM;
530 chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
531 if (!chkmsg) {
532 return WERR_NOMEM;
534 alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
537 fstr_sprintf(str_timeout, "%d", r->in.timeout);
538 fstr_sprintf(do_reboot, r->in.do_reboot ? SHUTDOWN_R_STRING : "");
539 fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
540 fstr_sprintf(str_reason, "%d", r->in.reason );
542 shutdown_script = talloc_all_string_sub(p->mem_ctx,
543 shutdown_script, "%z", chkmsg ? chkmsg : "");
544 if (!shutdown_script) {
545 return WERR_NOMEM;
547 shutdown_script = talloc_all_string_sub(p->mem_ctx,
548 shutdown_script, "%t", str_timeout);
549 if (!shutdown_script) {
550 return WERR_NOMEM;
552 shutdown_script = talloc_all_string_sub(p->mem_ctx,
553 shutdown_script, "%r", do_reboot);
554 if (!shutdown_script) {
555 return WERR_NOMEM;
557 shutdown_script = talloc_all_string_sub(p->mem_ctx,
558 shutdown_script, "%f", f);
559 if (!shutdown_script) {
560 return WERR_NOMEM;
562 shutdown_script = talloc_all_string_sub(p->mem_ctx,
563 shutdown_script, "%x", str_reason);
564 if (!shutdown_script) {
565 return WERR_NOMEM;
568 can_shutdown = user_has_privileges( p->server_info->ptok,
569 &se_remote_shutdown );
571 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
572 Take the error return from the script and provide it as the Windows return code. */
574 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
576 if ( can_shutdown )
577 become_root();
579 ret = smbrun( shutdown_script, NULL );
581 if ( can_shutdown )
582 unbecome_root();
584 /********** END SeRemoteShutdownPrivilege BLOCK **********/
586 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
587 shutdown_script, ret));
589 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
592 /*******************************************************************
593 _winreg_AbortSystemShutdown
594 ********************************************************************/
596 WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShutdown *r)
598 const char *abort_shutdown_script;
599 int ret;
600 bool can_shutdown;
602 abort_shutdown_script = lp_abort_shutdown_script();
604 if (!*abort_shutdown_script)
605 return WERR_ACCESS_DENIED;
607 can_shutdown = user_has_privileges( p->server_info->ptok,
608 &se_remote_shutdown );
610 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
612 if ( can_shutdown )
613 become_root();
615 ret = smbrun( abort_shutdown_script, NULL );
617 if ( can_shutdown )
618 unbecome_root();
620 /********** END SeRemoteShutdownPrivilege BLOCK **********/
622 DEBUG(3,("_winreg_AbortSystemShutdown: Running the command `%s' gave %d\n",
623 abort_shutdown_script, ret));
625 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
628 /*******************************************************************
629 ********************************************************************/
631 static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
633 char *p = NULL;
634 int num_services = lp_numservices();
635 int snum = -1;
636 const char *share_path;
637 char *fname = *pp_fname;
639 /* convert to a unix path, stripping the C:\ along the way */
641 if (!(p = valid_share_pathname(ctx, fname))) {
642 return -1;
645 /* has to exist within a valid file share */
647 for (snum=0; snum<num_services; snum++) {
648 if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
649 continue;
652 share_path = lp_pathname(snum);
654 /* make sure we have a path (e.g. [homes] ) */
655 if (strlen(share_path) == 0) {
656 continue;
659 if (strncmp(share_path, p, strlen(share_path)) == 0) {
660 break;
664 *pp_fname = p;
665 return (snum < num_services) ? snum : -1;
668 /*******************************************************************
669 _winreg_RestoreKey
670 ********************************************************************/
672 WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r)
674 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
675 char *fname = NULL;
676 int snum;
678 if ( !regkey )
679 return WERR_BADFID;
681 if ( !r->in.filename || !r->in.filename->name )
682 return WERR_INVALID_PARAM;
684 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
685 if (!fname) {
686 return WERR_NOMEM;
689 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
690 "\"%s\"\n", regkey->key->name, fname));
692 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
693 return WERR_OBJECT_PATH_INVALID;
695 /* user must posses SeRestorePrivilege for this this proceed */
697 if ( !user_has_privileges( p->server_info->ptok, &se_restore ) )
698 return WERR_ACCESS_DENIED;
700 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
701 regkey->key->name, fname, lp_servicename(snum) ));
703 return reg_restorekey(regkey, fname);
706 /*******************************************************************
707 _winreg_SaveKey
708 ********************************************************************/
710 WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r)
712 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
713 char *fname = NULL;
714 int snum = -1;
716 if ( !regkey )
717 return WERR_BADFID;
719 if ( !r->in.filename || !r->in.filename->name )
720 return WERR_INVALID_PARAM;
722 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
723 if (!fname) {
724 return WERR_NOMEM;
727 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
728 regkey->key->name, fname));
730 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
731 return WERR_OBJECT_PATH_INVALID;
733 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
734 regkey->key->name, fname, lp_servicename(snum) ));
736 return reg_savekey(regkey, fname);
739 /*******************************************************************
740 _winreg_SaveKeyEx
741 ********************************************************************/
743 WERROR _winreg_SaveKeyEx(pipes_struct *p, struct winreg_SaveKeyEx *r)
745 /* fill in your code here if you think this call should
746 do anything */
748 p->rng_fault_state = True;
749 return WERR_NOT_SUPPORTED;
752 /*******************************************************************
753 _winreg_CreateKey
754 ********************************************************************/
756 WERROR _winreg_CreateKey( pipes_struct *p, struct winreg_CreateKey *r)
758 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
759 struct registry_key *new_key;
760 WERROR result;
762 if ( !parent )
763 return WERR_BADFID;
765 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
766 "subkey name '%s'\n", parent->key->name, r->in.name.name));
768 result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
769 &new_key, r->out.action_taken);
770 if (!W_ERROR_IS_OK(result)) {
771 return result;
774 if (!create_policy_hnd(p, r->out.new_handle, new_key)) {
775 TALLOC_FREE(new_key);
776 return WERR_BADFILE;
779 return WERR_OK;
782 /*******************************************************************
783 _winreg_SetValue
784 ********************************************************************/
786 WERROR _winreg_SetValue(pipes_struct *p, struct winreg_SetValue *r)
788 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
789 struct registry_value *val;
790 WERROR status;
792 if ( !key )
793 return WERR_BADFID;
795 DEBUG(8,("_winreg_SetValue: Setting value for [%s:%s]\n",
796 key->key->name, r->in.name.name));
798 status = registry_pull_value(p->mem_ctx, &val, r->in.type, r->in.data,
799 r->in.size, r->in.size);
800 if (!W_ERROR_IS_OK(status)) {
801 return status;
804 return reg_setvalue(key, r->in.name.name, val);
807 /*******************************************************************
808 _winreg_DeleteKey
809 ********************************************************************/
811 WERROR _winreg_DeleteKey(pipes_struct *p, struct winreg_DeleteKey *r)
813 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
815 if ( !parent )
816 return WERR_BADFID;
818 return reg_deletekey(parent, r->in.key.name);
822 /*******************************************************************
823 _winreg_DeleteValue
824 ********************************************************************/
826 WERROR _winreg_DeleteValue(pipes_struct *p, struct winreg_DeleteValue *r)
828 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
830 if ( !key )
831 return WERR_BADFID;
833 return reg_deletevalue(key, r->in.value.name);
836 /*******************************************************************
837 _winreg_GetKeySecurity
838 ********************************************************************/
840 WERROR _winreg_GetKeySecurity(pipes_struct *p, struct winreg_GetKeySecurity *r)
842 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
843 WERROR err;
844 struct security_descriptor *secdesc;
845 uint8 *data;
846 size_t len;
848 if ( !key )
849 return WERR_BADFID;
851 /* access checks first */
853 if ( !(key->key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) )
854 return WERR_ACCESS_DENIED;
856 err = reg_getkeysecurity(p->mem_ctx, key, &secdesc);
857 if (!W_ERROR_IS_OK(err)) {
858 return err;
861 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
862 &data, &len));
863 if (!W_ERROR_IS_OK(err)) {
864 return err;
867 if (len > r->out.sd->size) {
868 r->out.sd->size = len;
869 return WERR_INSUFFICIENT_BUFFER;
872 r->out.sd->size = len;
873 r->out.sd->len = len;
874 r->out.sd->data = data;
876 return WERR_OK;
879 /*******************************************************************
880 _winreg_SetKeySecurity
881 ********************************************************************/
883 WERROR _winreg_SetKeySecurity(pipes_struct *p, struct winreg_SetKeySecurity *r)
885 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
886 struct security_descriptor *secdesc;
887 WERROR err;
889 if ( !key )
890 return WERR_BADFID;
892 /* access checks first */
894 if ( !(key->key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) )
895 return WERR_ACCESS_DENIED;
897 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
898 r->in.sd->len, &secdesc));
899 if (!W_ERROR_IS_OK(err)) {
900 return err;
903 return reg_setkeysecurity(key, secdesc);
906 /*******************************************************************
907 _winreg_FlushKey
908 ********************************************************************/
910 WERROR _winreg_FlushKey(pipes_struct *p, struct winreg_FlushKey *r)
912 /* I'm just replying OK because there's not a lot
913 here I see to do i --jerry */
915 return WERR_OK;
918 /*******************************************************************
919 _winreg_UnLoadKey
920 ********************************************************************/
922 WERROR _winreg_UnLoadKey(pipes_struct *p, struct winreg_UnLoadKey *r)
924 /* fill in your code here if you think this call should
925 do anything */
927 p->rng_fault_state = True;
928 return WERR_NOT_SUPPORTED;
931 /*******************************************************************
932 _winreg_ReplaceKey
933 ********************************************************************/
935 WERROR _winreg_ReplaceKey(pipes_struct *p, struct winreg_ReplaceKey *r)
937 /* fill in your code here if you think this call should
938 do anything */
940 p->rng_fault_state = True;
941 return WERR_NOT_SUPPORTED;
944 /*******************************************************************
945 _winreg_LoadKey
946 ********************************************************************/
948 WERROR _winreg_LoadKey(pipes_struct *p, struct winreg_LoadKey *r)
950 /* fill in your code here if you think this call should
951 do anything */
953 p->rng_fault_state = True;
954 return WERR_NOT_SUPPORTED;
957 /*******************************************************************
958 _winreg_NotifyChangeKeyValue
959 ********************************************************************/
961 WERROR _winreg_NotifyChangeKeyValue(pipes_struct *p, struct winreg_NotifyChangeKeyValue *r)
963 return WERR_NOT_SUPPORTED;
966 /*******************************************************************
967 _winreg_QueryMultipleValues
968 ********************************************************************/
970 WERROR _winreg_QueryMultipleValues(pipes_struct *p, struct winreg_QueryMultipleValues *r)
972 /* fill in your code here if you think this call should
973 do anything */
975 p->rng_fault_state = True;
976 return WERR_NOT_SUPPORTED;
979 /*******************************************************************
980 _winreg_QueryMultipleValues2
981 ********************************************************************/
983 WERROR _winreg_QueryMultipleValues2(pipes_struct *p, struct winreg_QueryMultipleValues2 *r)
985 /* fill in your code here if you think this call should
986 do anything */
988 p->rng_fault_state = True;
989 return WERR_NOT_SUPPORTED;
992 /*******************************************************************
993 _winreg_DeleteKeyEx
994 ********************************************************************/
996 WERROR _winreg_DeleteKeyEx(pipes_struct *p, struct winreg_DeleteKeyEx *r)
998 /* fill in your code here if you think this call should
999 do anything */
1001 p->rng_fault_state = True;
1002 return WERR_NOT_SUPPORTED;