source: branches/samba-3.3.x/source/rpc_server/srv_winreg_nt.c@ 614

Last change on this file since 614 was 206, checked in by Herwig Bauernfeind, 17 years ago

Import Samba 3.3 branch at 3.0.0 level (psmedley's port)

File size: 26.3 KB
Line 
1/*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 *
5 * Copyright (C) Gerald Carter 2002-2006.
6 *
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.
11 *
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.
16 *
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/>.
19 */
20
21/* Implementation of registry functions. */
22
23#include "includes.h"
24
25#undef DBGC_CLASS
26#define DBGC_CLASS DBGC_RPC_SRV
27
28/******************************************************************
29 free() function for struct registry_key
30 *****************************************************************/
31
32static void free_regkey(void *ptr)
33{
34 struct registry_key *key = (struct registry_key *)ptr;
35 TALLOC_FREE(key);
36}
37
38/******************************************************************
39 Find a registry key handle and return a struct registry_key *
40 *****************************************************************/
41
42static struct registry_key *find_regkey_by_hnd(pipes_struct *p,
43 POLICY_HND *hnd)
44{
45 struct registry_key *regkey = NULL;
46
47 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&regkey)) {
48 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
49 return NULL;
50 }
51
52 return regkey;
53}
54
55/*******************************************************************
56 Function for open a new registry handle and creating a handle
57 Note that P should be valid & hnd should already have space
58
59 When we open a key, we store the full path to the key as
60 HK[LM|U]\<key>\<key>\...
61 *******************************************************************/
62
63static WERROR open_registry_key( pipes_struct *p, POLICY_HND *hnd,
64 struct registry_key *parent,
65 const char *subkeyname,
66 uint32 access_desired )
67{
68 WERROR result = WERR_OK;
69 struct registry_key *key;
70
71 if (parent == NULL) {
72 result = reg_openhive(NULL, subkeyname, access_desired,
73 p->pipe_user.nt_user_token, &key);
74 }
75 else {
76 result = reg_openkey(NULL, parent, subkeyname, access_desired,
77 &key);
78 }
79
80 if ( !W_ERROR_IS_OK(result) ) {
81 return result;
82 }
83
84 if ( !create_policy_hnd( p, hnd, free_regkey, key ) ) {
85 return WERR_BADFILE;
86 }
87
88 return WERR_OK;
89}
90
91/*******************************************************************
92 Function for open a new registry handle and creating a handle
93 Note that P should be valid & hnd should already have space
94 *******************************************************************/
95
96static bool close_registry_key(pipes_struct *p, POLICY_HND *hnd)
97{
98 struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
99
100 if ( !regkey ) {
101 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
102 OUR_HANDLE(hnd)));
103 return False;
104 }
105
106 close_policy_hnd(p, hnd);
107
108 return True;
109}
110
111/********************************************************************
112 reg_close
113 ********************************************************************/
114
115WERROR _winreg_CloseKey(pipes_struct *p, struct winreg_CloseKey *r)
116{
117 /* close the policy handle */
118
119 if (!close_registry_key(p, r->in.handle))
120 return WERR_BADFID;
121
122 ZERO_STRUCTP(r->out.handle);
123
124 return WERR_OK;
125}
126
127/*******************************************************************
128 ********************************************************************/
129
130WERROR _winreg_OpenHKLM(pipes_struct *p, struct winreg_OpenHKLM *r)
131{
132 return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
133}
134
135/*******************************************************************
136 ********************************************************************/
137
138WERROR _winreg_OpenHKPD(pipes_struct *p, struct winreg_OpenHKPD *r)
139{
140 return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
141}
142
143/*******************************************************************
144 ********************************************************************/
145
146WERROR _winreg_OpenHKPT(pipes_struct *p, struct winreg_OpenHKPT *r)
147{
148 return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
149}
150
151/*******************************************************************
152 ********************************************************************/
153
154WERROR _winreg_OpenHKCR(pipes_struct *p, struct winreg_OpenHKCR *r)
155{
156 return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
157}
158
159/*******************************************************************
160 ********************************************************************/
161
162WERROR _winreg_OpenHKU(pipes_struct *p, struct winreg_OpenHKU *r)
163{
164 return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
165}
166
167/*******************************************************************
168 ********************************************************************/
169
170WERROR _winreg_OpenHKCU(pipes_struct *p, struct winreg_OpenHKCU *r)
171{
172 return open_registry_key(p, r->out.handle, NULL, KEY_HKCU, r->in.access_mask);
173}
174
175/*******************************************************************
176 ********************************************************************/
177
178WERROR _winreg_OpenHKCC(pipes_struct *p, struct winreg_OpenHKCC *r)
179{
180 return open_registry_key(p, r->out.handle, NULL, KEY_HKCC, r->in.access_mask);
181}
182
183/*******************************************************************
184 ********************************************************************/
185
186WERROR _winreg_OpenHKDD(pipes_struct *p, struct winreg_OpenHKDD *r)
187{
188 return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
189}
190
191/*******************************************************************
192 ********************************************************************/
193
194WERROR _winreg_OpenHKPN(pipes_struct *p, struct winreg_OpenHKPN *r)
195{
196 return open_registry_key(p, r->out.handle, NULL, KEY_HKPN, r->in.access_mask);
197}
198
199/*******************************************************************
200 reg_reply_open_entry
201 ********************************************************************/
202
203WERROR _winreg_OpenKey(pipes_struct *p, struct winreg_OpenKey *r)
204{
205 struct registry_key *parent = find_regkey_by_hnd(p, r->in.parent_handle );
206
207 if ( !parent )
208 return WERR_BADFID;
209
210 return open_registry_key(p, r->out.handle, parent, r->in.keyname.name, r->in.access_mask);
211}
212
213/*******************************************************************
214 reg_reply_info
215 ********************************************************************/
216
217WERROR _winreg_QueryValue(pipes_struct *p, struct winreg_QueryValue *r)
218{
219 WERROR status = WERR_BADFILE;
220 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
221 prs_struct prs_hkpd;
222
223 uint8_t *outbuf;
224 uint32_t outbuf_size;
225
226 DATA_BLOB val_blob;
227 bool free_buf = False;
228 bool free_prs = False;
229
230 if ( !regkey )
231 return WERR_BADFID;
232
233 if ((r->out.value_length == NULL) || (r->out.type == NULL)) {
234 return WERR_INVALID_PARAM;
235 }
236
237 *r->out.value_length = *r->out.type = REG_NONE;
238
239 DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->key->name));
240 DEBUG(7,("_reg_info: policy key type = [%08x]\n", regkey->key->type));
241
242 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
243 if(regkey->key->type == REG_KEY_HKPD)
244 {
245 if (strequal(r->in.value_name->name, "Global")) {
246 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
247 return WERR_NOMEM;
248 status = reg_perfcount_get_hkpd(
249 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
250 outbuf = (uint8_t *)prs_hkpd.data_p;
251 free_prs = True;
252 }
253 else if (strequal(r->in.value_name->name, "Counter 009")) {
254 outbuf_size = reg_perfcount_get_counter_names(
255 reg_perfcount_get_base_index(),
256 (char **)(void *)&outbuf);
257 free_buf = True;
258 }
259 else if (strequal(r->in.value_name->name, "Explain 009")) {
260 outbuf_size = reg_perfcount_get_counter_help(
261 reg_perfcount_get_base_index(),
262 (char **)(void *)&outbuf);
263 free_buf = True;
264 }
265 else if (isdigit(r->in.value_name->name[0])) {
266 /* we probably have a request for a specific object
267 * here */
268 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
269 return WERR_NOMEM;
270 status = reg_perfcount_get_hkpd(
271 &prs_hkpd, *r->in.data_size, &outbuf_size,
272 r->in.value_name->name);
273 outbuf = (uint8_t *)prs_hkpd.data_p;
274 free_prs = True;
275 }
276 else {
277 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
278 r->in.value_name->name));
279 return WERR_BADFILE;
280 }
281
282 *r->out.type = REG_BINARY;
283 }
284 else {
285 struct registry_value *val;
286
287 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name->name,
288 &val);
289 if (!W_ERROR_IS_OK(status)) {
290 if (r->out.data_size) {
291 *r->out.data_size = 0;
292 }
293 if (r->out.value_length) {
294 *r->out.value_length = 0;
295 }
296 return status;
297 }
298
299 status = registry_push_value(p->mem_ctx, val, &val_blob);
300 if (!W_ERROR_IS_OK(status)) {
301 return status;
302 }
303
304 outbuf = val_blob.data;
305 outbuf_size = val_blob.length;
306 *r->out.type = val->type;
307 }
308
309 *r->out.value_length = outbuf_size;
310
311 if ( *r->in.data_size == 0 || !r->out.data ) {
312 status = WERR_OK;
313 } else if ( *r->out.value_length > *r->in.data_size ) {
314 status = WERR_MORE_DATA;
315 } else {
316 memcpy( r->out.data, outbuf, *r->out.value_length );
317 status = WERR_OK;
318 }
319
320 *r->out.data_size = *r->out.value_length;
321
322 if (free_prs) prs_mem_free(&prs_hkpd);
323 if (free_buf) SAFE_FREE(outbuf);
324
325 return status;
326}
327
328/*****************************************************************************
329 Implementation of REG_QUERY_KEY
330 ****************************************************************************/
331
332WERROR _winreg_QueryInfoKey(pipes_struct *p, struct winreg_QueryInfoKey *r)
333{
334 WERROR status = WERR_OK;
335 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
336
337 if ( !regkey )
338 return WERR_BADFID;
339
340 r->out.classname->name = NULL;
341
342 status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
343 r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
344 r->out.max_valbufsize, r->out.secdescsize,
345 r->out.last_changed_time);
346 if (!W_ERROR_IS_OK(status)) {
347 return status;
348 }
349
350 /*
351 * These calculations account for the registry buffers being
352 * UTF-16. They are inexact at best, but so far they worked.
353 */
354
355 *r->out.max_subkeylen *= 2;
356
357 *r->out.max_valnamelen += 1;
358 *r->out.max_valnamelen *= 2;
359
360 return WERR_OK;
361}
362
363
364/*****************************************************************************
365 Implementation of REG_GETVERSION
366 ****************************************************************************/
367
368WERROR _winreg_GetVersion(pipes_struct *p, struct winreg_GetVersion *r)
369{
370 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
371
372 if ( !regkey )
373 return WERR_BADFID;
374
375 return reg_getversion(r->out.version);
376}
377
378
379/*****************************************************************************
380 Implementation of REG_ENUM_KEY
381 ****************************************************************************/
382
383WERROR _winreg_EnumKey(pipes_struct *p, struct winreg_EnumKey *r)
384{
385 WERROR err;
386 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
387
388 if ( !key )
389 return WERR_BADFID;
390
391 if ( !r->in.name || !r->in.keyclass )
392 return WERR_INVALID_PARAM;
393
394 DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", key->key->name));
395
396 err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, (char **)&r->out.name->name,
397 r->out.last_changed_time);
398 if (!W_ERROR_IS_OK(err)) {
399 return err;
400 }
401 r->out.keyclass->name = "";
402 return WERR_OK;
403}
404
405/*****************************************************************************
406 Implementation of REG_ENUM_VALUE
407 ****************************************************************************/
408
409WERROR _winreg_EnumValue(pipes_struct *p, struct winreg_EnumValue *r)
410{
411 WERROR err;
412 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
413 char *valname;
414 struct registry_value *val;
415 DATA_BLOB value_blob;
416
417 if ( !key )
418 return WERR_BADFID;
419
420 if ( !r->in.name )
421 return WERR_INVALID_PARAM;
422
423 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
424 key->key->name));
425
426 err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
427 if (!W_ERROR_IS_OK(err)) {
428 return err;
429 }
430
431 err = registry_push_value(p->mem_ctx, val, &value_blob);
432 if (!W_ERROR_IS_OK(err)) {
433 return err;
434 }
435
436 if (r->out.name != NULL) {
437 r->out.name->name = valname;
438 }
439
440 if (r->out.type != NULL) {
441 *r->out.type = val->type;
442 }
443
444 if (r->out.value != NULL) {
445 if ((r->out.size == NULL) || (r->out.length == NULL)) {
446 return WERR_INVALID_PARAM;
447 }
448
449 if (value_blob.length > *r->out.size) {
450 return WERR_MORE_DATA;
451 }
452
453 memcpy( r->out.value, value_blob.data, value_blob.length );
454 }
455
456 if (r->out.length != NULL) {
457 *r->out.length = value_blob.length;
458 }
459 if (r->out.size != NULL) {
460 *r->out.size = value_blob.length;
461 }
462
463 return WERR_OK;
464}
465
466/*******************************************************************
467 reg_shutdwon
468 ********************************************************************/
469
470WERROR _winreg_InitiateSystemShutdown(pipes_struct *p, struct winreg_InitiateSystemShutdown *r)
471{
472 struct winreg_InitiateSystemShutdownEx s;
473
474 s.in.hostname = r->in.hostname;
475 s.in.message = r->in.message;
476 s.in.timeout = r->in.timeout;
477 s.in.force_apps = r->in.force_apps;
478 s.in.do_reboot = r->in.do_reboot;
479 s.in.reason = 0;
480
481 /* thunk down to _winreg_InitiateSystemShutdownEx()
482 (just returns a status) */
483
484 return _winreg_InitiateSystemShutdownEx( p, &s );
485}
486
487/*******************************************************************
488 reg_shutdown_ex
489 ********************************************************************/
490
491#define SHUTDOWN_R_STRING "-r"
492#define SHUTDOWN_F_STRING "-f"
493
494
495WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateSystemShutdownEx *r)
496{
497 char *shutdown_script = NULL;
498 char *msg = NULL;
499 char *chkmsg = NULL;
500 fstring str_timeout;
501 fstring str_reason;
502 fstring do_reboot;
503 fstring f;
504 int ret;
505 bool can_shutdown;
506
507 shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
508 if (!shutdown_script) {
509 return WERR_NOMEM;
510 }
511 if (!*shutdown_script) {
512 return WERR_ACCESS_DENIED;
513 }
514
515 /* pull the message string and perform necessary sanity checks on it */
516
517 if ( r->in.message && r->in.message->name && r->in.message->name->name ) {
518 if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->name->name )) == NULL ) {
519 return WERR_NOMEM;
520 }
521 chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
522 if (!chkmsg) {
523 return WERR_NOMEM;
524 }
525 alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
526 }
527
528 fstr_sprintf(str_timeout, "%d", r->in.timeout);
529 fstr_sprintf(do_reboot, r->in.do_reboot ? SHUTDOWN_R_STRING : "");
530 fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
531 fstr_sprintf(str_reason, "%d", r->in.reason );
532
533 shutdown_script = talloc_all_string_sub(p->mem_ctx,
534 shutdown_script, "%z", chkmsg ? chkmsg : "");
535 if (!shutdown_script) {
536 return WERR_NOMEM;
537 }
538 shutdown_script = talloc_all_string_sub(p->mem_ctx,
539 shutdown_script, "%t", str_timeout);
540 if (!shutdown_script) {
541 return WERR_NOMEM;
542 }
543 shutdown_script = talloc_all_string_sub(p->mem_ctx,
544 shutdown_script, "%r", do_reboot);
545 if (!shutdown_script) {
546 return WERR_NOMEM;
547 }
548 shutdown_script = talloc_all_string_sub(p->mem_ctx,
549 shutdown_script, "%f", f);
550 if (!shutdown_script) {
551 return WERR_NOMEM;
552 }
553 shutdown_script = talloc_all_string_sub(p->mem_ctx,
554 shutdown_script, "%x", str_reason);
555 if (!shutdown_script) {
556 return WERR_NOMEM;
557 }
558
559 can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
560
561 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
562 Take the error return from the script and provide it as the Windows return code. */
563
564 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
565
566 if ( can_shutdown )
567 become_root();
568
569 ret = smbrun( shutdown_script, NULL );
570
571 if ( can_shutdown )
572 unbecome_root();
573
574 /********** END SeRemoteShutdownPrivilege BLOCK **********/
575
576 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
577 shutdown_script, ret));
578
579 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
580}
581
582/*******************************************************************
583 reg_abort_shutdwon
584 ********************************************************************/
585
586WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShutdown *r)
587{
588 const char *abort_shutdown_script;
589 int ret;
590 bool can_shutdown;
591
592 abort_shutdown_script = lp_abort_shutdown_script();
593
594 if (!*abort_shutdown_script)
595 return WERR_ACCESS_DENIED;
596
597 can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
598
599 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
600
601 if ( can_shutdown )
602 become_root();
603
604 ret = smbrun( abort_shutdown_script, NULL );
605
606 if ( can_shutdown )
607 unbecome_root();
608
609 /********** END SeRemoteShutdownPrivilege BLOCK **********/
610
611 DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",
612 abort_shutdown_script, ret));
613
614 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
615}
616
617/*******************************************************************
618 ********************************************************************/
619
620static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
621{
622 char *p = NULL;
623 int num_services = lp_numservices();
624 int snum = -1;
625 const char *share_path;
626 char *fname = *pp_fname;
627
628 /* convert to a unix path, stripping the C:\ along the way */
629
630 if (!(p = valid_share_pathname(ctx, fname))) {
631 return -1;
632 }
633
634 /* has to exist within a valid file share */
635
636 for (snum=0; snum<num_services; snum++) {
637 if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
638 continue;
639 }
640
641 share_path = lp_pathname(snum);
642
643 /* make sure we have a path (e.g. [homes] ) */
644 if (strlen(share_path) == 0) {
645 continue;
646 }
647
648 if (strncmp(share_path, p, strlen(share_path)) == 0) {
649 break;
650 }
651 }
652
653 *pp_fname = p;
654 return (snum < num_services) ? snum : -1;
655}
656
657/*******************************************************************
658 ********************************************************************/
659
660WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r)
661{
662 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
663 char *fname = NULL;
664 int snum;
665
666 if ( !regkey )
667 return WERR_BADFID;
668
669 if ( !r->in.filename || !r->in.filename->name )
670 return WERR_INVALID_PARAM;
671
672 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
673 if (!fname) {
674 return WERR_NOMEM;
675 }
676
677 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
678 "\"%s\"\n", regkey->key->name, fname));
679
680 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
681 return WERR_OBJECT_PATH_INVALID;
682
683 /* user must posses SeRestorePrivilege for this this proceed */
684
685 if ( !user_has_privileges( p->pipe_user.nt_user_token, &se_restore ) )
686 return WERR_ACCESS_DENIED;
687
688 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
689 regkey->key->name, fname, lp_servicename(snum) ));
690
691 return reg_restorekey(regkey, fname);
692}
693
694WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r)
695{
696 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
697 char *fname = NULL;
698 int snum = -1;
699
700 if ( !regkey )
701 return WERR_BADFID;
702
703 if ( !r->in.filename || !r->in.filename->name )
704 return WERR_INVALID_PARAM;
705
706 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
707 if (!fname) {
708 return WERR_NOMEM;
709 }
710
711 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
712 regkey->key->name, fname));
713
714 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
715 return WERR_OBJECT_PATH_INVALID;
716
717 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
718 regkey->key->name, fname, lp_servicename(snum) ));
719
720 return reg_savekey(regkey, fname);
721}
722
723/*******************************************************************
724 ********************************************************************/
725
726WERROR _winreg_SaveKeyEx(pipes_struct *p, struct winreg_SaveKeyEx *r)
727{
728 /* fill in your code here if you think this call should
729 do anything */
730
731 p->rng_fault_state = True;
732 return WERR_NOT_SUPPORTED;
733}
734
735/*******************************************************************
736 ********************************************************************/
737
738WERROR _winreg_CreateKey( pipes_struct *p, struct winreg_CreateKey *r)
739{
740 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
741 struct registry_key *new_key;
742 WERROR result;
743
744 if ( !parent )
745 return WERR_BADFID;
746
747 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
748 "subkey name '%s'\n", parent->key->name, r->in.name.name));
749
750 result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
751 &new_key, r->out.action_taken);
752 if (!W_ERROR_IS_OK(result)) {
753 return result;
754 }
755
756 if (!create_policy_hnd(p, r->out.new_handle, free_regkey, new_key)) {
757 TALLOC_FREE(new_key);
758 return WERR_BADFILE;
759 }
760
761 return WERR_OK;
762}
763
764/*******************************************************************
765 ********************************************************************/
766
767WERROR _winreg_SetValue(pipes_struct *p, struct winreg_SetValue *r)
768{
769 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
770 struct registry_value *val;
771 WERROR status;
772
773 if ( !key )
774 return WERR_BADFID;
775
776 DEBUG(8,("_reg_set_value: Setting value for [%s:%s]\n",
777 key->key->name, r->in.name.name));
778
779 status = registry_pull_value(p->mem_ctx, &val, r->in.type, r->in.data,
780 r->in.size, r->in.size);
781 if (!W_ERROR_IS_OK(status)) {
782 return status;
783 }
784
785 return reg_setvalue(key, r->in.name.name, val);
786}
787
788/*******************************************************************
789 ********************************************************************/
790
791WERROR _winreg_DeleteKey(pipes_struct *p, struct winreg_DeleteKey *r)
792{
793 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
794
795 if ( !parent )
796 return WERR_BADFID;
797
798 return reg_deletekey(parent, r->in.key.name);
799}
800
801
802/*******************************************************************
803 ********************************************************************/
804
805WERROR _winreg_DeleteValue(pipes_struct *p, struct winreg_DeleteValue *r)
806{
807 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
808
809 if ( !key )
810 return WERR_BADFID;
811
812 return reg_deletevalue(key, r->in.value.name);
813}
814
815/*******************************************************************
816 ********************************************************************/
817
818WERROR _winreg_GetKeySecurity(pipes_struct *p, struct winreg_GetKeySecurity *r)
819{
820 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
821 WERROR err;
822 struct security_descriptor *secdesc;
823 uint8 *data;
824 size_t len;
825
826 if ( !key )
827 return WERR_BADFID;
828
829 /* access checks first */
830
831 if ( !(key->key->access_granted & STD_RIGHT_READ_CONTROL_ACCESS) )
832 return WERR_ACCESS_DENIED;
833
834 err = reg_getkeysecurity(p->mem_ctx, key, &secdesc);
835 if (!W_ERROR_IS_OK(err)) {
836 return err;
837 }
838
839 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
840 &data, &len));
841 if (!W_ERROR_IS_OK(err)) {
842 return err;
843 }
844
845 if (len > r->out.sd->size) {
846 r->out.sd->size = len;
847 return WERR_INSUFFICIENT_BUFFER;
848 }
849
850 r->out.sd->size = len;
851 r->out.sd->len = len;
852 r->out.sd->data = data;
853
854 return WERR_OK;
855}
856
857/*******************************************************************
858 ********************************************************************/
859
860WERROR _winreg_SetKeySecurity(pipes_struct *p, struct winreg_SetKeySecurity *r)
861{
862 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
863 struct security_descriptor *secdesc;
864 WERROR err;
865
866 if ( !key )
867 return WERR_BADFID;
868
869 /* access checks first */
870
871 if ( !(key->key->access_granted & STD_RIGHT_WRITE_DAC_ACCESS) )
872 return WERR_ACCESS_DENIED;
873
874 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
875 r->in.sd->len, &secdesc));
876 if (!W_ERROR_IS_OK(err)) {
877 return err;
878 }
879
880 return reg_setkeysecurity(key, secdesc);
881}
882
883/*******************************************************************
884 ********************************************************************/
885
886WERROR _winreg_FlushKey(pipes_struct *p, struct winreg_FlushKey *r)
887{
888 /* I'm just replying OK because there's not a lot
889 here I see to do i --jerry */
890
891 return WERR_OK;
892}
893
894/*******************************************************************
895 ********************************************************************/
896
897WERROR _winreg_UnLoadKey(pipes_struct *p, struct winreg_UnLoadKey *r)
898{
899 /* fill in your code here if you think this call should
900 do anything */
901
902 p->rng_fault_state = True;
903 return WERR_NOT_SUPPORTED;
904}
905
906/*******************************************************************
907 ********************************************************************/
908
909WERROR _winreg_ReplaceKey(pipes_struct *p, struct winreg_ReplaceKey *r)
910{
911 /* fill in your code here if you think this call should
912 do anything */
913
914 p->rng_fault_state = True;
915 return WERR_NOT_SUPPORTED;
916}
917
918/*******************************************************************
919 ********************************************************************/
920
921WERROR _winreg_LoadKey(pipes_struct *p, struct winreg_LoadKey *r)
922{
923 /* fill in your code here if you think this call should
924 do anything */
925
926 p->rng_fault_state = True;
927 return WERR_NOT_SUPPORTED;
928}
929
930/*******************************************************************
931 ********************************************************************/
932
933WERROR _winreg_NotifyChangeKeyValue(pipes_struct *p, struct winreg_NotifyChangeKeyValue *r)
934{
935 /* fill in your code here if you think this call should
936 do anything */
937
938 p->rng_fault_state = True;
939 return WERR_NOT_SUPPORTED;
940}
941
942/*******************************************************************
943 ********************************************************************/
944
945WERROR _winreg_QueryMultipleValues(pipes_struct *p, struct winreg_QueryMultipleValues *r)
946{
947 /* fill in your code here if you think this call should
948 do anything */
949
950 p->rng_fault_state = True;
951 return WERR_NOT_SUPPORTED;
952}
953
954/*******************************************************************
955 ********************************************************************/
956
957WERROR _winreg_QueryMultipleValues2(pipes_struct *p, struct winreg_QueryMultipleValues2 *r)
958{
959 /* fill in your code here if you think this call should
960 do anything */
961
962 p->rng_fault_state = True;
963 return WERR_NOT_SUPPORTED;
964}
965
Note: See TracBrowser for help on using the repository browser.