Add smbta-util to manage the encryption key.
[Samba/nascimento.git] / source3 / rpc_server / srv_winreg_nt.c
blob2a2ff68f40fc6a40a5e6f3562d7029bb637b58ce
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->in.value_name->name == NULL) {
234 return WERR_INVALID_PARAM;
237 if ((r->out.data_length == NULL) || (r->out.type == NULL) || (r->out.data_size == NULL)) {
238 return WERR_INVALID_PARAM;
241 DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey->key->name));
242 DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey->key->type));
244 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
245 if(regkey->key->type == REG_KEY_HKPD)
247 if (strequal(r->in.value_name->name, "Global")) {
248 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
249 return WERR_NOMEM;
250 status = reg_perfcount_get_hkpd(
251 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
252 outbuf = (uint8_t *)prs_hkpd.data_p;
253 free_prs = True;
255 else if (strequal(r->in.value_name->name, "Counter 009")) {
256 outbuf_size = reg_perfcount_get_counter_names(
257 reg_perfcount_get_base_index(),
258 (char **)(void *)&outbuf);
259 free_buf = True;
261 else if (strequal(r->in.value_name->name, "Explain 009")) {
262 outbuf_size = reg_perfcount_get_counter_help(
263 reg_perfcount_get_base_index(),
264 (char **)(void *)&outbuf);
265 free_buf = True;
267 else if (isdigit(r->in.value_name->name[0])) {
268 /* we probably have a request for a specific object
269 * here */
270 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
271 return WERR_NOMEM;
272 status = reg_perfcount_get_hkpd(
273 &prs_hkpd, *r->in.data_size, &outbuf_size,
274 r->in.value_name->name);
275 outbuf = (uint8_t *)prs_hkpd.data_p;
276 free_prs = True;
278 else {
279 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
280 r->in.value_name->name));
281 return WERR_BADFILE;
284 *r->out.type = REG_BINARY;
286 else {
287 struct registry_value *val;
289 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name->name,
290 &val);
291 if (!W_ERROR_IS_OK(status)) {
293 DEBUG(10,("_winreg_QueryValue: reg_queryvalue failed with: %s\n",
294 win_errstr(status)));
296 if (r->out.data_size) {
297 *r->out.data_size = 0;
299 if (r->out.data_length) {
300 *r->out.data_length = 0;
302 return status;
305 status = registry_push_value(p->mem_ctx, val, &val_blob);
306 if (!W_ERROR_IS_OK(status)) {
307 return status;
310 outbuf = val_blob.data;
311 outbuf_size = val_blob.length;
312 *r->out.type = val->type;
315 status = WERR_BADFILE;
317 if (*r->in.data_size < outbuf_size) {
318 *r->out.data_size = outbuf_size;
319 status = r->in.data ? WERR_MORE_DATA : WERR_OK;
320 } else {
321 *r->out.data_length = outbuf_size;
322 *r->out.data_size = outbuf_size;
323 memcpy(r->out.data, outbuf, outbuf_size);
324 status = WERR_OK;
327 if (free_prs) prs_mem_free(&prs_hkpd);
328 if (free_buf) SAFE_FREE(outbuf);
330 return status;
333 /*****************************************************************************
334 _winreg_QueryInfoKey
335 ****************************************************************************/
337 WERROR _winreg_QueryInfoKey(pipes_struct *p, struct winreg_QueryInfoKey *r)
339 WERROR status = WERR_OK;
340 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
342 if ( !regkey )
343 return WERR_BADFID;
345 r->out.classname->name = NULL;
347 status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
348 r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
349 r->out.max_valbufsize, r->out.secdescsize,
350 r->out.last_changed_time);
351 if (!W_ERROR_IS_OK(status)) {
352 return status;
356 * These calculations account for the registry buffers being
357 * UTF-16. They are inexact at best, but so far they worked.
360 *r->out.max_subkeylen *= 2;
362 *r->out.max_valnamelen += 1;
363 *r->out.max_valnamelen *= 2;
365 return WERR_OK;
369 /*****************************************************************************
370 _winreg_GetVersion
371 ****************************************************************************/
373 WERROR _winreg_GetVersion(pipes_struct *p, struct winreg_GetVersion *r)
375 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
377 if ( !regkey )
378 return WERR_BADFID;
380 return reg_getversion(r->out.version);
384 /*****************************************************************************
385 _winreg_EnumKey
386 ****************************************************************************/
388 WERROR _winreg_EnumKey(pipes_struct *p, struct winreg_EnumKey *r)
390 WERROR err;
391 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
393 if ( !key )
394 return WERR_BADFID;
396 if ( !r->in.name || !r->in.keyclass )
397 return WERR_INVALID_PARAM;
399 DEBUG(8,("_winreg_EnumKey: enumerating key [%s]\n", key->key->name));
401 err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, (char **)&r->out.name->name,
402 r->out.last_changed_time);
403 if (!W_ERROR_IS_OK(err)) {
404 return err;
406 r->out.keyclass->name = "";
407 return WERR_OK;
410 /*****************************************************************************
411 _winreg_EnumValue
412 ****************************************************************************/
414 WERROR _winreg_EnumValue(pipes_struct *p, struct winreg_EnumValue *r)
416 WERROR err;
417 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
418 char *valname;
419 struct registry_value *val;
420 DATA_BLOB value_blob;
422 if ( !key )
423 return WERR_BADFID;
425 if ( !r->in.name )
426 return WERR_INVALID_PARAM;
428 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
429 key->key->name));
431 err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
432 if (!W_ERROR_IS_OK(err)) {
433 return err;
436 err = registry_push_value(p->mem_ctx, val, &value_blob);
437 if (!W_ERROR_IS_OK(err)) {
438 return err;
441 if (r->out.name != NULL) {
442 r->out.name->name = valname;
445 if (r->out.type != NULL) {
446 *r->out.type = val->type;
449 if (r->out.value != NULL) {
450 if ((r->out.size == NULL) || (r->out.length == NULL)) {
451 return WERR_INVALID_PARAM;
454 if (value_blob.length > *r->out.size) {
455 return WERR_MORE_DATA;
458 memcpy( r->out.value, value_blob.data, value_blob.length );
461 if (r->out.length != NULL) {
462 *r->out.length = value_blob.length;
464 if (r->out.size != NULL) {
465 *r->out.size = value_blob.length;
468 return WERR_OK;
471 /*******************************************************************
472 _winreg_InitiateSystemShutdown
473 ********************************************************************/
475 WERROR _winreg_InitiateSystemShutdown(pipes_struct *p, struct winreg_InitiateSystemShutdown *r)
477 struct winreg_InitiateSystemShutdownEx s;
479 s.in.hostname = r->in.hostname;
480 s.in.message = r->in.message;
481 s.in.timeout = r->in.timeout;
482 s.in.force_apps = r->in.force_apps;
483 s.in.do_reboot = r->in.do_reboot;
484 s.in.reason = 0;
486 /* thunk down to _winreg_InitiateSystemShutdownEx()
487 (just returns a status) */
489 return _winreg_InitiateSystemShutdownEx( p, &s );
492 /*******************************************************************
493 _winreg_InitiateSystemShutdownEx
494 ********************************************************************/
496 #define SHUTDOWN_R_STRING "-r"
497 #define SHUTDOWN_F_STRING "-f"
500 WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateSystemShutdownEx *r)
502 char *shutdown_script = NULL;
503 char *msg = NULL;
504 char *chkmsg = NULL;
505 fstring str_timeout;
506 fstring str_reason;
507 fstring do_reboot;
508 fstring f;
509 int ret;
510 bool can_shutdown;
512 shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
513 if (!shutdown_script) {
514 return WERR_NOMEM;
516 if (!*shutdown_script) {
517 return WERR_ACCESS_DENIED;
520 /* pull the message string and perform necessary sanity checks on it */
522 if ( r->in.message && r->in.message->string ) {
523 if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->string )) == NULL ) {
524 return WERR_NOMEM;
526 chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
527 if (!chkmsg) {
528 return WERR_NOMEM;
530 alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
533 fstr_sprintf(str_timeout, "%d", r->in.timeout);
534 fstr_sprintf(do_reboot, r->in.do_reboot ? SHUTDOWN_R_STRING : "");
535 fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
536 fstr_sprintf(str_reason, "%d", r->in.reason );
538 shutdown_script = talloc_all_string_sub(p->mem_ctx,
539 shutdown_script, "%z", chkmsg ? chkmsg : "");
540 if (!shutdown_script) {
541 return WERR_NOMEM;
543 shutdown_script = talloc_all_string_sub(p->mem_ctx,
544 shutdown_script, "%t", str_timeout);
545 if (!shutdown_script) {
546 return WERR_NOMEM;
548 shutdown_script = talloc_all_string_sub(p->mem_ctx,
549 shutdown_script, "%r", do_reboot);
550 if (!shutdown_script) {
551 return WERR_NOMEM;
553 shutdown_script = talloc_all_string_sub(p->mem_ctx,
554 shutdown_script, "%f", f);
555 if (!shutdown_script) {
556 return WERR_NOMEM;
558 shutdown_script = talloc_all_string_sub(p->mem_ctx,
559 shutdown_script, "%x", str_reason);
560 if (!shutdown_script) {
561 return WERR_NOMEM;
564 can_shutdown = user_has_privileges( p->server_info->ptok,
565 &se_remote_shutdown );
567 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
568 Take the error return from the script and provide it as the Windows return code. */
570 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
572 if ( can_shutdown )
573 become_root();
575 ret = smbrun( shutdown_script, NULL );
577 if ( can_shutdown )
578 unbecome_root();
580 /********** END SeRemoteShutdownPrivilege BLOCK **********/
582 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
583 shutdown_script, ret));
585 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
588 /*******************************************************************
589 _winreg_AbortSystemShutdown
590 ********************************************************************/
592 WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShutdown *r)
594 const char *abort_shutdown_script;
595 int ret;
596 bool can_shutdown;
598 abort_shutdown_script = lp_abort_shutdown_script();
600 if (!*abort_shutdown_script)
601 return WERR_ACCESS_DENIED;
603 can_shutdown = user_has_privileges( p->server_info->ptok,
604 &se_remote_shutdown );
606 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
608 if ( can_shutdown )
609 become_root();
611 ret = smbrun( abort_shutdown_script, NULL );
613 if ( can_shutdown )
614 unbecome_root();
616 /********** END SeRemoteShutdownPrivilege BLOCK **********/
618 DEBUG(3,("_winreg_AbortSystemShutdown: Running the command `%s' gave %d\n",
619 abort_shutdown_script, ret));
621 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
624 /*******************************************************************
625 ********************************************************************/
627 static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
629 char *p = NULL;
630 int num_services = lp_numservices();
631 int snum = -1;
632 const char *share_path;
633 char *fname = *pp_fname;
635 /* convert to a unix path, stripping the C:\ along the way */
637 if (!(p = valid_share_pathname(ctx, fname))) {
638 return -1;
641 /* has to exist within a valid file share */
643 for (snum=0; snum<num_services; snum++) {
644 if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
645 continue;
648 share_path = lp_pathname(snum);
650 /* make sure we have a path (e.g. [homes] ) */
651 if (strlen(share_path) == 0) {
652 continue;
655 if (strncmp(share_path, p, strlen(share_path)) == 0) {
656 break;
660 *pp_fname = p;
661 return (snum < num_services) ? snum : -1;
664 /*******************************************************************
665 _winreg_RestoreKey
666 ********************************************************************/
668 WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r)
670 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
671 char *fname = NULL;
672 int snum;
674 if ( !regkey )
675 return WERR_BADFID;
677 if ( !r->in.filename || !r->in.filename->name )
678 return WERR_INVALID_PARAM;
680 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
681 if (!fname) {
682 return WERR_NOMEM;
685 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
686 "\"%s\"\n", regkey->key->name, fname));
688 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
689 return WERR_OBJECT_PATH_INVALID;
691 /* user must posses SeRestorePrivilege for this this proceed */
693 if ( !user_has_privileges( p->server_info->ptok, &se_restore ) )
694 return WERR_ACCESS_DENIED;
696 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
697 regkey->key->name, fname, lp_servicename(snum) ));
699 return reg_restorekey(regkey, fname);
702 /*******************************************************************
703 _winreg_SaveKey
704 ********************************************************************/
706 WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r)
708 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
709 char *fname = NULL;
710 int snum = -1;
712 if ( !regkey )
713 return WERR_BADFID;
715 if ( !r->in.filename || !r->in.filename->name )
716 return WERR_INVALID_PARAM;
718 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
719 if (!fname) {
720 return WERR_NOMEM;
723 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
724 regkey->key->name, fname));
726 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
727 return WERR_OBJECT_PATH_INVALID;
729 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
730 regkey->key->name, fname, lp_servicename(snum) ));
732 return reg_savekey(regkey, fname);
735 /*******************************************************************
736 _winreg_SaveKeyEx
737 ********************************************************************/
739 WERROR _winreg_SaveKeyEx(pipes_struct *p, struct winreg_SaveKeyEx *r)
741 /* fill in your code here if you think this call should
742 do anything */
744 p->rng_fault_state = True;
745 return WERR_NOT_SUPPORTED;
748 /*******************************************************************
749 _winreg_CreateKey
750 ********************************************************************/
752 WERROR _winreg_CreateKey( pipes_struct *p, struct winreg_CreateKey *r)
754 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
755 struct registry_key *new_key;
756 WERROR result;
758 if ( !parent )
759 return WERR_BADFID;
761 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
762 "subkey name '%s'\n", parent->key->name, r->in.name.name));
764 result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
765 &new_key, r->out.action_taken);
766 if (!W_ERROR_IS_OK(result)) {
767 return result;
770 if (!create_policy_hnd(p, r->out.new_handle, new_key)) {
771 TALLOC_FREE(new_key);
772 return WERR_BADFILE;
775 return WERR_OK;
778 /*******************************************************************
779 _winreg_SetValue
780 ********************************************************************/
782 WERROR _winreg_SetValue(pipes_struct *p, struct winreg_SetValue *r)
784 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
785 struct registry_value *val;
786 WERROR status;
788 if ( !key )
789 return WERR_BADFID;
791 DEBUG(8,("_winreg_SetValue: Setting value for [%s:%s]\n",
792 key->key->name, r->in.name.name));
794 status = registry_pull_value(p->mem_ctx, &val, r->in.type, r->in.data,
795 r->in.size, r->in.size);
796 if (!W_ERROR_IS_OK(status)) {
797 return status;
800 return reg_setvalue(key, r->in.name.name, val);
803 /*******************************************************************
804 _winreg_DeleteKey
805 ********************************************************************/
807 WERROR _winreg_DeleteKey(pipes_struct *p, struct winreg_DeleteKey *r)
809 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
811 if ( !parent )
812 return WERR_BADFID;
814 return reg_deletekey(parent, r->in.key.name);
818 /*******************************************************************
819 _winreg_DeleteValue
820 ********************************************************************/
822 WERROR _winreg_DeleteValue(pipes_struct *p, struct winreg_DeleteValue *r)
824 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
826 if ( !key )
827 return WERR_BADFID;
829 return reg_deletevalue(key, r->in.value.name);
832 /*******************************************************************
833 _winreg_GetKeySecurity
834 ********************************************************************/
836 WERROR _winreg_GetKeySecurity(pipes_struct *p, struct winreg_GetKeySecurity *r)
838 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
839 WERROR err;
840 struct security_descriptor *secdesc;
841 uint8 *data;
842 size_t len;
844 if ( !key )
845 return WERR_BADFID;
847 /* access checks first */
849 if ( !(key->key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) )
850 return WERR_ACCESS_DENIED;
852 err = reg_getkeysecurity(p->mem_ctx, key, &secdesc);
853 if (!W_ERROR_IS_OK(err)) {
854 return err;
857 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
858 &data, &len));
859 if (!W_ERROR_IS_OK(err)) {
860 return err;
863 if (len > r->out.sd->size) {
864 r->out.sd->size = len;
865 return WERR_INSUFFICIENT_BUFFER;
868 r->out.sd->size = len;
869 r->out.sd->len = len;
870 r->out.sd->data = data;
872 return WERR_OK;
875 /*******************************************************************
876 _winreg_SetKeySecurity
877 ********************************************************************/
879 WERROR _winreg_SetKeySecurity(pipes_struct *p, struct winreg_SetKeySecurity *r)
881 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
882 struct security_descriptor *secdesc;
883 WERROR err;
885 if ( !key )
886 return WERR_BADFID;
888 /* access checks first */
890 if ( !(key->key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) )
891 return WERR_ACCESS_DENIED;
893 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
894 r->in.sd->len, &secdesc));
895 if (!W_ERROR_IS_OK(err)) {
896 return err;
899 return reg_setkeysecurity(key, secdesc);
902 /*******************************************************************
903 _winreg_FlushKey
904 ********************************************************************/
906 WERROR _winreg_FlushKey(pipes_struct *p, struct winreg_FlushKey *r)
908 /* I'm just replying OK because there's not a lot
909 here I see to do i --jerry */
911 return WERR_OK;
914 /*******************************************************************
915 _winreg_UnLoadKey
916 ********************************************************************/
918 WERROR _winreg_UnLoadKey(pipes_struct *p, struct winreg_UnLoadKey *r)
920 /* fill in your code here if you think this call should
921 do anything */
923 p->rng_fault_state = True;
924 return WERR_NOT_SUPPORTED;
927 /*******************************************************************
928 _winreg_ReplaceKey
929 ********************************************************************/
931 WERROR _winreg_ReplaceKey(pipes_struct *p, struct winreg_ReplaceKey *r)
933 /* fill in your code here if you think this call should
934 do anything */
936 p->rng_fault_state = True;
937 return WERR_NOT_SUPPORTED;
940 /*******************************************************************
941 _winreg_LoadKey
942 ********************************************************************/
944 WERROR _winreg_LoadKey(pipes_struct *p, struct winreg_LoadKey *r)
946 /* fill in your code here if you think this call should
947 do anything */
949 p->rng_fault_state = True;
950 return WERR_NOT_SUPPORTED;
953 /*******************************************************************
954 _winreg_NotifyChangeKeyValue
955 ********************************************************************/
957 WERROR _winreg_NotifyChangeKeyValue(pipes_struct *p, struct winreg_NotifyChangeKeyValue *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;
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;