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