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. */
25
#include "../librpc/gen_ndr/srv_winreg.h"
27
#include "registry/reg_api.h"
28
#include "registry/reg_api_regf.h"
29
#include "registry/reg_perfcount.h"
32
#include "lib/privileges.h"
35
#define DBGC_CLASS DBGC_RPC_SRV
37
/******************************************************************
38
Find a registry key handle and return a struct registry_key *
39
*****************************************************************/
41
static struct registry_key *find_regkey_by_hnd(struct pipes_struct *p,
42
struct policy_handle *hnd)
44
struct registry_key *regkey = NULL;
46
if(!find_policy_by_hnd(p,hnd,(void **)(void *)®key)) {
47
DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
54
/*******************************************************************
55
Function for open a new registry handle and creating a handle
56
Note that P should be valid & hnd should already have space
58
When we open a key, we store the full path to the key as
59
HK[LM|U]\<key>\<key>\...
60
*******************************************************************/
62
static WERROR open_registry_key(struct pipes_struct *p,
63
struct policy_handle *hnd,
64
struct registry_key *parent,
65
const char *subkeyname,
66
uint32_t access_desired)
68
WERROR result = WERR_OK;
69
struct registry_key *key;
72
result = reg_openhive(p->mem_ctx, subkeyname, access_desired,
73
p->session_info->security_token, &key);
76
result = reg_openkey(p->mem_ctx, parent, subkeyname,
77
access_desired, &key);
80
if ( !W_ERROR_IS_OK(result) ) {
84
if ( !create_policy_hnd( p, hnd, key ) ) {
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
*******************************************************************/
96
static bool close_registry_key(struct pipes_struct *p,
97
struct policy_handle *hnd)
99
struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
102
DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
107
close_policy_hnd(p, hnd);
112
/********************************************************************
114
********************************************************************/
116
WERROR _winreg_CloseKey(struct pipes_struct *p,
117
struct winreg_CloseKey *r)
119
/* close the policy handle */
121
if (!close_registry_key(p, r->in.handle))
124
ZERO_STRUCTP(r->out.handle);
129
/*******************************************************************
131
********************************************************************/
133
WERROR _winreg_OpenHKLM(struct pipes_struct *p,
134
struct winreg_OpenHKLM *r)
136
return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
139
/*******************************************************************
141
********************************************************************/
143
WERROR _winreg_OpenHKPD(struct pipes_struct *p,
144
struct winreg_OpenHKPD *r)
146
return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
149
/*******************************************************************
151
********************************************************************/
153
WERROR _winreg_OpenHKPT(struct pipes_struct *p,
154
struct winreg_OpenHKPT *r)
156
return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
159
/*******************************************************************
161
********************************************************************/
163
WERROR _winreg_OpenHKCR(struct pipes_struct *p,
164
struct winreg_OpenHKCR *r)
166
return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
169
/*******************************************************************
171
********************************************************************/
173
WERROR _winreg_OpenHKU(struct pipes_struct *p,
174
struct winreg_OpenHKU *r)
176
return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
179
/*******************************************************************
181
********************************************************************/
183
WERROR _winreg_OpenHKCU(struct pipes_struct *p,
184
struct winreg_OpenHKCU *r)
186
return open_registry_key(p, r->out.handle, NULL, KEY_HKCU, r->in.access_mask);
189
/*******************************************************************
191
********************************************************************/
193
WERROR _winreg_OpenHKCC(struct pipes_struct *p,
194
struct winreg_OpenHKCC *r)
196
return open_registry_key(p, r->out.handle, NULL, KEY_HKCC, r->in.access_mask);
199
/*******************************************************************
201
********************************************************************/
203
WERROR _winreg_OpenHKDD(struct pipes_struct *p,
204
struct winreg_OpenHKDD *r)
206
return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
209
/*******************************************************************
211
********************************************************************/
213
WERROR _winreg_OpenHKPN(struct pipes_struct *p,
214
struct winreg_OpenHKPN *r)
216
return open_registry_key(p, r->out.handle, NULL, KEY_HKPN, r->in.access_mask);
219
/*******************************************************************
221
********************************************************************/
223
WERROR _winreg_OpenKey(struct pipes_struct *p,
224
struct winreg_OpenKey *r)
226
struct registry_key *parent = find_regkey_by_hnd(p, r->in.parent_handle );
231
return open_registry_key(p, r->out.handle, parent, r->in.keyname.name, r->in.access_mask);
234
/*******************************************************************
236
********************************************************************/
238
WERROR _winreg_QueryValue(struct pipes_struct *p,
239
struct winreg_QueryValue *r)
241
WERROR status = WERR_BADFILE;
242
struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
245
uint8_t *outbuf = NULL;
246
uint32_t outbuf_size = 0;
248
bool free_buf = False;
249
bool free_prs = False;
254
if (r->in.value_name->name == NULL) {
255
return WERR_INVALID_PARAM;
258
if ((r->out.data_length == NULL) || (r->out.type == NULL) || (r->out.data_size == NULL)) {
259
return WERR_INVALID_PARAM;
262
DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey->key->name));
263
DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey->key->type));
265
/* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
266
if(regkey->key->type == REG_KEY_HKPD)
268
if (strequal(r->in.value_name->name, "Global")) {
269
if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
271
status = reg_perfcount_get_hkpd(
272
&prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
273
outbuf = (uint8_t *)prs_hkpd.data_p;
276
else if (strequal(r->in.value_name->name, "Counter 009")) {
277
outbuf_size = reg_perfcount_get_counter_names(
278
reg_perfcount_get_base_index(),
279
(char **)(void *)&outbuf);
282
else if (strequal(r->in.value_name->name, "Explain 009")) {
283
outbuf_size = reg_perfcount_get_counter_help(
284
reg_perfcount_get_base_index(),
285
(char **)(void *)&outbuf);
288
else if (isdigit(r->in.value_name->name[0])) {
289
/* we probably have a request for a specific object
291
if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
293
status = reg_perfcount_get_hkpd(
294
&prs_hkpd, *r->in.data_size, &outbuf_size,
295
r->in.value_name->name);
296
outbuf = (uint8_t *)prs_hkpd.data_p;
300
DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
301
r->in.value_name->name));
305
*r->out.type = REG_BINARY;
308
struct registry_value *val;
310
status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name->name,
312
if (!W_ERROR_IS_OK(status)) {
314
DEBUG(10,("_winreg_QueryValue: reg_queryvalue failed with: %s\n",
315
win_errstr(status)));
317
if (r->out.data_size) {
318
*r->out.data_size = 0;
320
if (r->out.data_length) {
321
*r->out.data_length = 0;
326
outbuf = val->data.data;
327
outbuf_size = val->data.length;
328
*r->out.type = val->type;
331
status = WERR_BADFILE;
333
if (*r->in.data_size < outbuf_size) {
334
*r->out.data_size = outbuf_size;
335
status = r->in.data ? WERR_MORE_DATA : WERR_OK;
337
*r->out.data_length = outbuf_size;
338
*r->out.data_size = outbuf_size;
340
memcpy(r->out.data, outbuf, outbuf_size);
345
if (free_prs) prs_mem_free(&prs_hkpd);
346
if (free_buf) SAFE_FREE(outbuf);
351
/*****************************************************************************
353
****************************************************************************/
355
WERROR _winreg_QueryInfoKey(struct pipes_struct *p,
356
struct winreg_QueryInfoKey *r)
358
WERROR status = WERR_OK;
359
struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
364
r->out.classname->name = NULL;
366
status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
367
r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
368
r->out.max_valbufsize, r->out.secdescsize,
369
r->out.last_changed_time);
370
if (!W_ERROR_IS_OK(status)) {
375
* These calculations account for the registry buffers being
376
* UTF-16. They are inexact at best, but so far they worked.
379
*r->out.max_subkeylen *= 2;
381
*r->out.max_valnamelen += 1;
382
*r->out.max_valnamelen *= 2;
388
/*****************************************************************************
390
****************************************************************************/
392
WERROR _winreg_GetVersion(struct pipes_struct *p,
393
struct winreg_GetVersion *r)
395
struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
400
return reg_getversion(r->out.version);
404
/*****************************************************************************
406
****************************************************************************/
408
WERROR _winreg_EnumKey(struct pipes_struct *p,
409
struct winreg_EnumKey *r)
411
WERROR err = WERR_OK;
412
struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
417
if ( !r->in.name || !r->in.keyclass )
418
return WERR_INVALID_PARAM;
420
DEBUG(8,("_winreg_EnumKey: enumerating key [%s]\n", key->key->name));
422
err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, (char **)&r->out.name->name,
423
r->out.last_changed_time);
424
if (!W_ERROR_IS_OK(err)) {
427
r->out.keyclass->name = "";
431
/*****************************************************************************
433
****************************************************************************/
435
WERROR _winreg_EnumValue(struct pipes_struct *p,
436
struct winreg_EnumValue *r)
438
WERROR err = WERR_OK;
439
struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
440
char *valname = NULL;
441
struct registry_value *val = NULL;
447
return WERR_INVALID_PARAM;
449
DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
452
err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
453
if (!W_ERROR_IS_OK(err)) {
457
if (r->out.name != NULL) {
458
r->out.name->name = valname;
461
if (r->out.type != NULL) {
462
*r->out.type = val->type;
465
if (r->out.value != NULL) {
466
if ((r->out.size == NULL) || (r->out.length == NULL)) {
467
return WERR_INVALID_PARAM;
470
if (val->data.length > *r->out.size) {
471
return WERR_MORE_DATA;
474
memcpy( r->out.value, val->data.data, val->data.length );
477
if (r->out.length != NULL) {
478
*r->out.length = val->data.length;
480
if (r->out.size != NULL) {
481
*r->out.size = val->data.length;
487
/*******************************************************************
488
_winreg_InitiateSystemShutdown
489
********************************************************************/
491
WERROR _winreg_InitiateSystemShutdown(struct pipes_struct *p,
492
struct winreg_InitiateSystemShutdown *r)
494
struct winreg_InitiateSystemShutdownEx s;
496
s.in.hostname = r->in.hostname;
497
s.in.message = r->in.message;
498
s.in.timeout = r->in.timeout;
499
s.in.force_apps = r->in.force_apps;
500
s.in.do_reboot = r->in.do_reboot;
503
/* thunk down to _winreg_InitiateSystemShutdownEx()
504
(just returns a status) */
506
return _winreg_InitiateSystemShutdownEx( p, &s );
509
/*******************************************************************
510
_winreg_InitiateSystemShutdownEx
511
********************************************************************/
513
#define SHUTDOWN_R_STRING "-r"
514
#define SHUTDOWN_F_STRING "-f"
517
WERROR _winreg_InitiateSystemShutdownEx(struct pipes_struct *p,
518
struct winreg_InitiateSystemShutdownEx *r)
520
char *shutdown_script = NULL;
528
bool can_shutdown = false;
530
shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
531
if (!shutdown_script) {
534
if (!*shutdown_script) {
535
return WERR_ACCESS_DENIED;
538
/* pull the message string and perform necessary sanity checks on it */
540
if ( r->in.message && r->in.message->string ) {
541
if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->string )) == NULL ) {
544
chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
548
alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
551
fstr_sprintf(str_timeout, "%d", r->in.timeout);
552
fstr_sprintf(do_reboot, r->in.do_reboot ? SHUTDOWN_R_STRING : "");
553
fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
554
fstr_sprintf(str_reason, "%d", r->in.reason );
556
shutdown_script = talloc_all_string_sub(p->mem_ctx,
557
shutdown_script, "%z", chkmsg ? chkmsg : "");
558
if (!shutdown_script) {
561
shutdown_script = talloc_all_string_sub(p->mem_ctx,
562
shutdown_script, "%t", str_timeout);
563
if (!shutdown_script) {
566
shutdown_script = talloc_all_string_sub(p->mem_ctx,
567
shutdown_script, "%r", do_reboot);
568
if (!shutdown_script) {
571
shutdown_script = talloc_all_string_sub(p->mem_ctx,
572
shutdown_script, "%f", f);
573
if (!shutdown_script) {
576
shutdown_script = talloc_all_string_sub(p->mem_ctx,
577
shutdown_script, "%x", str_reason);
578
if (!shutdown_script) {
582
can_shutdown = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_REMOTE_SHUTDOWN);
584
/* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
585
Take the error return from the script and provide it as the Windows return code. */
587
/********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
592
ret = smbrun( shutdown_script, NULL );
597
/********** END SeRemoteShutdownPrivilege BLOCK **********/
599
DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
600
shutdown_script, ret));
602
return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
605
/*******************************************************************
606
_winreg_AbortSystemShutdown
607
********************************************************************/
609
WERROR _winreg_AbortSystemShutdown(struct pipes_struct *p,
610
struct winreg_AbortSystemShutdown *r)
612
const char *abort_shutdown_script = lp_abort_shutdown_script();
614
bool can_shutdown = false;
616
if (!*abort_shutdown_script)
617
return WERR_ACCESS_DENIED;
619
can_shutdown = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_REMOTE_SHUTDOWN);
621
/********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
626
ret = smbrun( abort_shutdown_script, NULL );
631
/********** END SeRemoteShutdownPrivilege BLOCK **********/
633
DEBUG(3,("_winreg_AbortSystemShutdown: Running the command `%s' gave %d\n",
634
abort_shutdown_script, ret));
636
return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
639
/*******************************************************************
640
********************************************************************/
642
static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
645
int num_services = lp_numservices();
647
const char *share_path = NULL;
648
char *fname = *pp_fname;
650
/* convert to a unix path, stripping the C:\ along the way */
652
if (!(p = valid_share_pathname(ctx, fname))) {
656
/* has to exist within a valid file share */
658
for (snum=0; snum<num_services; snum++) {
659
if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
663
share_path = lp_pathname(snum);
665
/* make sure we have a path (e.g. [homes] ) */
666
if (strlen(share_path) == 0) {
670
if (strncmp(share_path, p, strlen(share_path)) == 0) {
676
return (snum < num_services) ? snum : -1;
679
/*******************************************************************
681
********************************************************************/
683
WERROR _winreg_RestoreKey(struct pipes_struct *p,
684
struct winreg_RestoreKey *r)
686
struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
693
if ( !r->in.filename || !r->in.filename->name )
694
return WERR_INVALID_PARAM;
696
fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
701
DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
702
"\"%s\"\n", regkey->key->name, fname));
704
if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
705
return WERR_OBJECT_PATH_INVALID;
707
/* user must posses SeRestorePrivilege for this this proceed */
709
if ( !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_RESTORE)) {
710
return WERR_ACCESS_DENIED;
713
DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
714
regkey->key->name, fname, lp_servicename(snum) ));
716
return reg_restorekey(regkey, fname);
719
/*******************************************************************
721
********************************************************************/
723
WERROR _winreg_SaveKey(struct pipes_struct *p,
724
struct winreg_SaveKey *r)
726
struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
733
if ( !r->in.filename || !r->in.filename->name )
734
return WERR_INVALID_PARAM;
736
fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
741
DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
742
regkey->key->name, fname));
744
if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
745
return WERR_OBJECT_PATH_INVALID;
747
DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
748
regkey->key->name, fname, lp_servicename(snum) ));
750
return reg_savekey(regkey, fname);
753
/*******************************************************************
755
********************************************************************/
757
WERROR _winreg_SaveKeyEx(struct pipes_struct *p,
758
struct winreg_SaveKeyEx *r)
760
/* fill in your code here if you think this call should
763
p->rng_fault_state = True;
764
return WERR_NOT_SUPPORTED;
767
/*******************************************************************
769
********************************************************************/
771
WERROR _winreg_CreateKey(struct pipes_struct *p,
772
struct winreg_CreateKey *r)
774
struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
775
struct registry_key *new_key = NULL;
776
WERROR result = WERR_OK;
781
DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
782
"subkey name '%s'\n", parent->key->name, r->in.name.name));
784
result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
785
&new_key, r->out.action_taken);
786
if (!W_ERROR_IS_OK(result)) {
790
if (!create_policy_hnd(p, r->out.new_handle, new_key)) {
791
TALLOC_FREE(new_key);
798
/*******************************************************************
800
********************************************************************/
802
WERROR _winreg_SetValue(struct pipes_struct *p,
803
struct winreg_SetValue *r)
805
struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
806
struct registry_value *val = NULL;
811
DEBUG(8,("_winreg_SetValue: Setting value for [%s:%s]\n",
812
key->key->name, r->in.name.name));
814
val = talloc_zero(p->mem_ctx, struct registry_value);
819
val->type = r->in.type;
820
val->data = data_blob_talloc(p->mem_ctx, r->in.data, r->in.size);
822
return reg_setvalue(key, r->in.name.name, val);
825
/*******************************************************************
827
********************************************************************/
829
WERROR _winreg_DeleteKey(struct pipes_struct *p,
830
struct winreg_DeleteKey *r)
832
struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
837
return reg_deletekey(parent, r->in.key.name);
841
/*******************************************************************
843
********************************************************************/
845
WERROR _winreg_DeleteValue(struct pipes_struct *p,
846
struct winreg_DeleteValue *r)
848
struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
853
return reg_deletevalue(key, r->in.value.name);
856
/*******************************************************************
857
_winreg_GetKeySecurity
858
********************************************************************/
860
WERROR _winreg_GetKeySecurity(struct pipes_struct *p,
861
struct winreg_GetKeySecurity *r)
863
struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
864
WERROR err = WERR_OK;
865
struct security_descriptor *secdesc = NULL;
872
/* access checks first */
874
if ( !(key->key->access_granted & SEC_STD_READ_CONTROL) )
875
return WERR_ACCESS_DENIED;
877
err = reg_getkeysecurity(p->mem_ctx, key, &secdesc);
878
if (!W_ERROR_IS_OK(err)) {
882
err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
884
if (!W_ERROR_IS_OK(err)) {
888
if (len > r->out.sd->size) {
889
r->out.sd->size = len;
890
return WERR_INSUFFICIENT_BUFFER;
893
r->out.sd->size = len;
894
r->out.sd->len = len;
895
r->out.sd->data = data;
900
/*******************************************************************
901
_winreg_SetKeySecurity
902
********************************************************************/
904
WERROR _winreg_SetKeySecurity(struct pipes_struct *p,
905
struct winreg_SetKeySecurity *r)
907
struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
908
struct security_descriptor *secdesc = NULL;
909
WERROR err = WERR_OK;
914
/* access checks first */
916
if ( !(key->key->access_granted & SEC_STD_WRITE_DAC) )
917
return WERR_ACCESS_DENIED;
919
err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
920
r->in.sd->len, &secdesc));
921
if (!W_ERROR_IS_OK(err)) {
925
return reg_setkeysecurity(key, secdesc);
928
/*******************************************************************
930
********************************************************************/
932
WERROR _winreg_FlushKey(struct pipes_struct *p,
933
struct winreg_FlushKey *r)
935
/* I'm just replying OK because there's not a lot
936
here I see to do i --jerry */
941
/*******************************************************************
943
********************************************************************/
945
WERROR _winreg_UnLoadKey(struct pipes_struct *p,
946
struct winreg_UnLoadKey *r)
948
/* fill in your code here if you think this call should
951
p->rng_fault_state = True;
952
return WERR_NOT_SUPPORTED;
955
/*******************************************************************
957
********************************************************************/
959
WERROR _winreg_ReplaceKey(struct pipes_struct *p,
960
struct winreg_ReplaceKey *r)
962
/* fill in your code here if you think this call should
965
p->rng_fault_state = True;
966
return WERR_NOT_SUPPORTED;
969
/*******************************************************************
971
********************************************************************/
973
WERROR _winreg_LoadKey(struct pipes_struct *p,
974
struct winreg_LoadKey *r)
976
/* fill in your code here if you think this call should
979
p->rng_fault_state = True;
980
return WERR_NOT_SUPPORTED;
983
/*******************************************************************
984
_winreg_NotifyChangeKeyValue
985
********************************************************************/
987
WERROR _winreg_NotifyChangeKeyValue(struct pipes_struct *p,
988
struct winreg_NotifyChangeKeyValue *r)
990
return WERR_NOT_SUPPORTED;
993
/*******************************************************************
994
_winreg_QueryMultipleValues
995
********************************************************************/
997
WERROR _winreg_QueryMultipleValues(struct pipes_struct *p,
998
struct winreg_QueryMultipleValues *r)
1000
struct winreg_QueryMultipleValues2 r2;
1001
uint32_t needed = 0;
1003
r2.in.key_handle = r->in.key_handle;
1004
r2.in.values_in = r->in.values_in;
1005
r2.in.num_values = r->in.num_values;
1006
r2.in.offered = r->in.buffer_size;
1007
r2.in.buffer = r->in.buffer;
1008
r2.out.values_out = r->out.values_out;
1009
r2.out.needed = &needed;
1010
r2.out.buffer = r->out.buffer;
1012
return _winreg_QueryMultipleValues2(p, &r2);
1015
/*******************************************************************
1016
********************************************************************/
1018
static WERROR construct_multiple_entry(TALLOC_CTX *mem_ctx,
1019
const char *valuename,
1020
uint32_t value_length,
1022
enum winreg_Type type,
1023
struct QueryMultipleValue *r)
1025
r->ve_valuename = talloc_zero(mem_ctx, struct winreg_ValNameBuf);
1026
if (r->ve_valuename == NULL) {
1030
r->ve_valuename->name = talloc_strdup(r->ve_valuename, valuename ? valuename : "");
1031
if (r->ve_valuename->name == NULL) {
1035
r->ve_valuename->size = strlen_m_term(r->ve_valuename->name)*2;
1036
r->ve_valuelen = value_length;
1037
r->ve_valueptr = offset;
1043
/*******************************************************************
1044
_winreg_QueryMultipleValues2
1045
********************************************************************/
1047
WERROR _winreg_QueryMultipleValues2(struct pipes_struct *p,
1048
struct winreg_QueryMultipleValues2 *r)
1050
struct registry_key *regkey = find_regkey_by_hnd(p, r->in.key_handle);
1051
struct registry_value *vals = NULL;
1052
const char **names = NULL;
1053
uint32_t offset = 0, num_vals = 0;
1054
DATA_BLOB result = data_blob_null;
1056
WERROR err = WERR_OK;
1062
names = talloc_zero_array(p->mem_ctx, const char *, r->in.num_values);
1063
if (names == NULL) {
1067
for (i=0; i < r->in.num_values; i++) {
1068
if (r->in.values_in[i].ve_valuename &&
1069
r->in.values_in[i].ve_valuename->name) {
1070
names[i] = talloc_strdup(names,
1071
r->in.values_in[i].ve_valuename->name);
1072
if (names[i] == NULL) {
1078
err = reg_querymultiplevalues(p->mem_ctx, regkey,
1079
r->in.num_values, names,
1081
if (!W_ERROR_IS_OK(err)) {
1085
result = data_blob_talloc(p->mem_ctx, NULL, 0);
1087
for (i=0; i < r->in.num_values; i++) {
1088
const char *valuename = NULL;
1090
if (vals[i].data.length > 0) {
1091
if (!data_blob_append(p->mem_ctx, &result,
1093
vals[i].data.length)) {
1098
if (r->in.values_in[i].ve_valuename &&
1099
r->in.values_in[i].ve_valuename->name) {
1100
valuename = r->in.values_in[i].ve_valuename->name;
1103
err = construct_multiple_entry(r->out.values_out,
1105
vals[i].data.length,
1108
&r->out.values_out[i]);
1109
if (!W_ERROR_IS_OK(err)) {
1113
offset += vals[i].data.length;
1116
*r->out.needed = result.length;
1118
if (r->in.num_values != num_vals) {
1119
return WERR_BADFILE;
1122
if (*r->in.offered >= *r->out.needed) {
1123
if (r->out.buffer) {
1124
memcpy(r->out.buffer, result.data, MIN(result.length, *r->in.offered));
1128
return WERR_MORE_DATA;
1132
/*******************************************************************
1134
********************************************************************/
1136
WERROR _winreg_DeleteKeyEx(struct pipes_struct *p,
1137
struct winreg_DeleteKeyEx *r)
1139
/* fill in your code here if you think this call should
1142
p->rng_fault_state = True;
1143
return WERR_NOT_SUPPORTED;