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. */
24 #include "../librpc/gen_ndr/srv_winreg.h"
26 #include "registry/reg_api.h"
27 #include "registry/reg_api_regf.h"
28 #include "registry/reg_perfcount.h"
32 #define DBGC_CLASS DBGC_RPC_SRV
34 /******************************************************************
35 Find a registry key handle and return a struct registry_key *
36 *****************************************************************/
38 static struct registry_key *find_regkey_by_hnd(struct pipes_struct *p,
39 struct policy_handle *hnd)
41 struct registry_key *regkey = NULL;
43 if(!find_policy_by_hnd(p,hnd,(void **)(void *)®key)) {
44 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
51 /*******************************************************************
52 Function for open a new registry handle and creating a handle
53 Note that P should be valid & hnd should already have space
55 When we open a key, we store the full path to the key as
56 HK[LM|U]\<key>\<key>\...
57 *******************************************************************/
59 static WERROR open_registry_key(struct pipes_struct *p,
60 struct policy_handle *hnd,
61 struct registry_key *parent,
62 const char *subkeyname,
63 uint32_t access_desired)
65 WERROR result = WERR_OK;
66 struct registry_key *key;
69 result = reg_openhive(p->mem_ctx, subkeyname, access_desired,
70 p->session_info->security_token, &key);
73 result = reg_openkey(p->mem_ctx, parent, subkeyname,
74 access_desired, &key);
77 if ( !W_ERROR_IS_OK(result) ) {
81 if ( !create_policy_hnd( p, hnd, key ) ) {
88 /*******************************************************************
89 Function for open a new registry handle and creating a handle
90 Note that P should be valid & hnd should already have space
91 *******************************************************************/
93 static bool close_registry_key(struct pipes_struct *p,
94 struct policy_handle *hnd)
96 struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
99 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
104 close_policy_hnd(p, hnd);
109 /********************************************************************
111 ********************************************************************/
113 WERROR _winreg_CloseKey(struct pipes_struct *p,
114 struct winreg_CloseKey *r)
116 /* close the policy handle */
118 if (!close_registry_key(p, r->in.handle))
121 ZERO_STRUCTP(r->out.handle);
126 /*******************************************************************
128 ********************************************************************/
130 WERROR _winreg_OpenHKLM(struct pipes_struct *p,
131 struct winreg_OpenHKLM *r)
133 return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
136 /*******************************************************************
138 ********************************************************************/
140 WERROR _winreg_OpenHKPD(struct pipes_struct *p,
141 struct winreg_OpenHKPD *r)
143 return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
146 /*******************************************************************
148 ********************************************************************/
150 WERROR _winreg_OpenHKPT(struct pipes_struct *p,
151 struct winreg_OpenHKPT *r)
153 return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
156 /*******************************************************************
158 ********************************************************************/
160 WERROR _winreg_OpenHKCR(struct pipes_struct *p,
161 struct winreg_OpenHKCR *r)
163 return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
166 /*******************************************************************
168 ********************************************************************/
170 WERROR _winreg_OpenHKU(struct pipes_struct *p,
171 struct winreg_OpenHKU *r)
173 return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
176 /*******************************************************************
178 ********************************************************************/
180 WERROR _winreg_OpenHKCU(struct pipes_struct *p,
181 struct winreg_OpenHKCU *r)
183 return open_registry_key(p, r->out.handle, NULL, KEY_HKCU, r->in.access_mask);
186 /*******************************************************************
188 ********************************************************************/
190 WERROR _winreg_OpenHKCC(struct pipes_struct *p,
191 struct winreg_OpenHKCC *r)
193 return open_registry_key(p, r->out.handle, NULL, KEY_HKCC, r->in.access_mask);
196 /*******************************************************************
198 ********************************************************************/
200 WERROR _winreg_OpenHKDD(struct pipes_struct *p,
201 struct winreg_OpenHKDD *r)
203 return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
206 /*******************************************************************
208 ********************************************************************/
210 WERROR _winreg_OpenHKPN(struct pipes_struct *p,
211 struct winreg_OpenHKPN *r)
213 return open_registry_key(p, r->out.handle, NULL, KEY_HKPN, r->in.access_mask);
216 /*******************************************************************
218 ********************************************************************/
220 WERROR _winreg_OpenKey(struct pipes_struct *p,
221 struct winreg_OpenKey *r)
223 struct registry_key *parent = find_regkey_by_hnd(p, r->in.parent_handle );
228 return open_registry_key(p, r->out.handle, parent, r->in.keyname.name, r->in.access_mask);
231 /*******************************************************************
233 ********************************************************************/
235 WERROR _winreg_QueryValue(struct pipes_struct *p,
236 struct winreg_QueryValue *r)
238 WERROR status = WERR_BADFILE;
239 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
242 uint8_t *outbuf = NULL;
243 uint32_t outbuf_size = 0;
245 bool free_buf = False;
246 bool free_prs = False;
251 if (r->in.value_name->name == NULL) {
252 return WERR_INVALID_PARAM;
255 if ((r->out.data_length == NULL) || (r->out.type == NULL) || (r->out.data_size == NULL)) {
256 return WERR_INVALID_PARAM;
259 DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey->key->name));
260 DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey->key->type));
262 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
263 if(regkey->key->type == REG_KEY_HKPD)
265 if (strequal(r->in.value_name->name, "Global")) {
266 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
268 status = reg_perfcount_get_hkpd(
269 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
270 outbuf = (uint8_t *)prs_hkpd.data_p;
273 else if (strequal(r->in.value_name->name, "Counter 009")) {
274 outbuf_size = reg_perfcount_get_counter_names(
275 reg_perfcount_get_base_index(),
276 (char **)(void *)&outbuf);
279 else if (strequal(r->in.value_name->name, "Explain 009")) {
280 outbuf_size = reg_perfcount_get_counter_help(
281 reg_perfcount_get_base_index(),
282 (char **)(void *)&outbuf);
285 else if (isdigit(r->in.value_name->name[0])) {
286 /* we probably have a request for a specific object
288 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
290 status = reg_perfcount_get_hkpd(
291 &prs_hkpd, *r->in.data_size, &outbuf_size,
292 r->in.value_name->name);
293 outbuf = (uint8_t *)prs_hkpd.data_p;
297 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
298 r->in.value_name->name));
302 *r->out.type = REG_BINARY;
305 struct registry_value *val;
307 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name->name,
309 if (!W_ERROR_IS_OK(status)) {
311 DEBUG(10,("_winreg_QueryValue: reg_queryvalue failed with: %s\n",
312 win_errstr(status)));
314 if (r->out.data_size) {
315 *r->out.data_size = 0;
317 if (r->out.data_length) {
318 *r->out.data_length = 0;
323 outbuf = val->data.data;
324 outbuf_size = val->data.length;
325 *r->out.type = val->type;
328 status = WERR_BADFILE;
330 if (*r->in.data_size < outbuf_size) {
331 *r->out.data_size = outbuf_size;
332 status = r->in.data ? WERR_MORE_DATA : WERR_OK;
334 *r->out.data_length = outbuf_size;
335 *r->out.data_size = outbuf_size;
337 memcpy(r->out.data, outbuf, outbuf_size);
342 if (free_prs) prs_mem_free(&prs_hkpd);
343 if (free_buf) SAFE_FREE(outbuf);
348 /*****************************************************************************
350 ****************************************************************************/
352 WERROR _winreg_QueryInfoKey(struct pipes_struct *p,
353 struct winreg_QueryInfoKey *r)
355 WERROR status = WERR_OK;
356 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
361 r->out.classname->name = NULL;
363 status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
364 r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
365 r->out.max_valbufsize, r->out.secdescsize,
366 r->out.last_changed_time);
367 if (!W_ERROR_IS_OK(status)) {
372 * These calculations account for the registry buffers being
373 * UTF-16. They are inexact at best, but so far they worked.
376 *r->out.max_subkeylen *= 2;
378 *r->out.max_valnamelen += 1;
379 *r->out.max_valnamelen *= 2;
385 /*****************************************************************************
387 ****************************************************************************/
389 WERROR _winreg_GetVersion(struct pipes_struct *p,
390 struct winreg_GetVersion *r)
392 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
397 return reg_getversion(r->out.version);
401 /*****************************************************************************
403 ****************************************************************************/
405 WERROR _winreg_EnumKey(struct pipes_struct *p,
406 struct winreg_EnumKey *r)
408 WERROR err = WERR_OK;
409 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
414 if ( !r->in.name || !r->in.keyclass )
415 return WERR_INVALID_PARAM;
417 DEBUG(8,("_winreg_EnumKey: enumerating key [%s]\n", key->key->name));
419 err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, (char **)&r->out.name->name,
420 r->out.last_changed_time);
421 if (!W_ERROR_IS_OK(err)) {
424 r->out.keyclass->name = "";
428 /*****************************************************************************
430 ****************************************************************************/
432 WERROR _winreg_EnumValue(struct pipes_struct *p,
433 struct winreg_EnumValue *r)
435 WERROR err = WERR_OK;
436 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
437 char *valname = NULL;
438 struct registry_value *val = NULL;
444 return WERR_INVALID_PARAM;
446 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
449 err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
450 if (!W_ERROR_IS_OK(err)) {
454 if (r->out.name != NULL) {
455 r->out.name->name = valname;
458 if (r->out.type != NULL) {
459 *r->out.type = val->type;
462 if (r->out.value != NULL) {
463 if ((r->out.size == NULL) || (r->out.length == NULL)) {
464 return WERR_INVALID_PARAM;
467 if (val->data.length > *r->out.size) {
468 return WERR_MORE_DATA;
471 memcpy( r->out.value, val->data.data, val->data.length );
474 if (r->out.length != NULL) {
475 *r->out.length = val->data.length;
477 if (r->out.size != NULL) {
478 *r->out.size = val->data.length;
484 /*******************************************************************
485 _winreg_InitiateSystemShutdown
486 ********************************************************************/
488 WERROR _winreg_InitiateSystemShutdown(struct pipes_struct *p,
489 struct winreg_InitiateSystemShutdown *r)
491 struct winreg_InitiateSystemShutdownEx s;
493 s.in.hostname = r->in.hostname;
494 s.in.message = r->in.message;
495 s.in.timeout = r->in.timeout;
496 s.in.force_apps = r->in.force_apps;
497 s.in.do_reboot = r->in.do_reboot;
500 /* thunk down to _winreg_InitiateSystemShutdownEx()
501 (just returns a status) */
503 return _winreg_InitiateSystemShutdownEx( p, &s );
506 /*******************************************************************
507 _winreg_InitiateSystemShutdownEx
508 ********************************************************************/
510 #define SHUTDOWN_R_STRING "-r"
511 #define SHUTDOWN_F_STRING "-f"
514 WERROR _winreg_InitiateSystemShutdownEx(struct pipes_struct *p,
515 struct winreg_InitiateSystemShutdownEx *r)
517 char *shutdown_script = NULL;
525 bool can_shutdown = false;
527 shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
528 if (!shutdown_script) {
531 if (!*shutdown_script) {
532 return WERR_ACCESS_DENIED;
535 /* pull the message string and perform necessary sanity checks on it */
537 if ( r->in.message && r->in.message->string ) {
538 if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->string )) == NULL ) {
541 chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
545 alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
548 fstr_sprintf(str_timeout, "%d", r->in.timeout);
549 fstr_sprintf(do_reboot, r->in.do_reboot ? SHUTDOWN_R_STRING : "");
550 fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
551 fstr_sprintf(str_reason, "%d", r->in.reason );
553 shutdown_script = talloc_all_string_sub(p->mem_ctx,
554 shutdown_script, "%z", chkmsg ? chkmsg : "");
555 if (!shutdown_script) {
558 shutdown_script = talloc_all_string_sub(p->mem_ctx,
559 shutdown_script, "%t", str_timeout);
560 if (!shutdown_script) {
563 shutdown_script = talloc_all_string_sub(p->mem_ctx,
564 shutdown_script, "%r", do_reboot);
565 if (!shutdown_script) {
568 shutdown_script = talloc_all_string_sub(p->mem_ctx,
569 shutdown_script, "%f", f);
570 if (!shutdown_script) {
573 shutdown_script = talloc_all_string_sub(p->mem_ctx,
574 shutdown_script, "%x", str_reason);
575 if (!shutdown_script) {
579 can_shutdown = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_REMOTE_SHUTDOWN);
581 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
582 Take the error return from the script and provide it as the Windows return code. */
584 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
589 ret = smbrun( shutdown_script, NULL );
594 /********** END SeRemoteShutdownPrivilege BLOCK **********/
596 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
597 shutdown_script, ret));
599 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
602 /*******************************************************************
603 _winreg_AbortSystemShutdown
604 ********************************************************************/
606 WERROR _winreg_AbortSystemShutdown(struct pipes_struct *p,
607 struct winreg_AbortSystemShutdown *r)
609 const char *abort_shutdown_script = lp_abort_shutdown_script();
611 bool can_shutdown = false;
613 if (!*abort_shutdown_script)
614 return WERR_ACCESS_DENIED;
616 can_shutdown = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_REMOTE_SHUTDOWN);
618 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
623 ret = smbrun( abort_shutdown_script, NULL );
628 /********** END SeRemoteShutdownPrivilege BLOCK **********/
630 DEBUG(3,("_winreg_AbortSystemShutdown: Running the command `%s' gave %d\n",
631 abort_shutdown_script, ret));
633 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
636 /*******************************************************************
637 ********************************************************************/
639 static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
642 int num_services = lp_numservices();
644 const char *share_path = NULL;
645 char *fname = *pp_fname;
647 /* convert to a unix path, stripping the C:\ along the way */
649 if (!(p = valid_share_pathname(ctx, fname))) {
653 /* has to exist within a valid file share */
655 for (snum=0; snum<num_services; snum++) {
656 if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
660 share_path = lp_pathname(snum);
662 /* make sure we have a path (e.g. [homes] ) */
663 if (strlen(share_path) == 0) {
667 if (strncmp(share_path, p, strlen(share_path)) == 0) {
673 return (snum < num_services) ? snum : -1;
676 /*******************************************************************
678 ********************************************************************/
680 WERROR _winreg_RestoreKey(struct pipes_struct *p,
681 struct winreg_RestoreKey *r)
683 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
690 if ( !r->in.filename || !r->in.filename->name )
691 return WERR_INVALID_PARAM;
693 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
698 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
699 "\"%s\"\n", regkey->key->name, fname));
701 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
702 return WERR_OBJECT_PATH_INVALID;
704 /* user must posses SeRestorePrivilege for this this proceed */
706 if ( !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_RESTORE)) {
707 return WERR_ACCESS_DENIED;
710 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
711 regkey->key->name, fname, lp_servicename(snum) ));
713 return reg_restorekey(regkey, fname);
716 /*******************************************************************
718 ********************************************************************/
720 WERROR _winreg_SaveKey(struct pipes_struct *p,
721 struct winreg_SaveKey *r)
723 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
730 if ( !r->in.filename || !r->in.filename->name )
731 return WERR_INVALID_PARAM;
733 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
738 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
739 regkey->key->name, fname));
741 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
742 return WERR_OBJECT_PATH_INVALID;
744 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
745 regkey->key->name, fname, lp_servicename(snum) ));
747 return reg_savekey(regkey, fname);
750 /*******************************************************************
752 ********************************************************************/
754 WERROR _winreg_SaveKeyEx(struct pipes_struct *p,
755 struct winreg_SaveKeyEx *r)
757 /* fill in your code here if you think this call should
760 p->rng_fault_state = True;
761 return WERR_NOT_SUPPORTED;
764 /*******************************************************************
766 ********************************************************************/
768 WERROR _winreg_CreateKey(struct pipes_struct *p,
769 struct winreg_CreateKey *r)
771 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
772 struct registry_key *new_key = NULL;
773 WERROR result = WERR_OK;
778 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
779 "subkey name '%s'\n", parent->key->name, r->in.name.name));
781 result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
782 &new_key, r->out.action_taken);
783 if (!W_ERROR_IS_OK(result)) {
787 if (!create_policy_hnd(p, r->out.new_handle, new_key)) {
788 TALLOC_FREE(new_key);
795 /*******************************************************************
797 ********************************************************************/
799 WERROR _winreg_SetValue(struct pipes_struct *p,
800 struct winreg_SetValue *r)
802 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
803 struct registry_value *val = NULL;
808 DEBUG(8,("_winreg_SetValue: Setting value for [%s:%s]\n",
809 key->key->name, r->in.name.name));
811 val = talloc_zero(p->mem_ctx, struct registry_value);
816 val->type = r->in.type;
817 val->data = data_blob_talloc(p->mem_ctx, r->in.data, r->in.size);
819 return reg_setvalue(key, r->in.name.name, val);
822 /*******************************************************************
824 ********************************************************************/
826 WERROR _winreg_DeleteKey(struct pipes_struct *p,
827 struct winreg_DeleteKey *r)
829 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
834 return reg_deletekey(parent, r->in.key.name);
838 /*******************************************************************
840 ********************************************************************/
842 WERROR _winreg_DeleteValue(struct pipes_struct *p,
843 struct winreg_DeleteValue *r)
845 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
850 return reg_deletevalue(key, r->in.value.name);
853 /*******************************************************************
854 _winreg_GetKeySecurity
855 ********************************************************************/
857 WERROR _winreg_GetKeySecurity(struct pipes_struct *p,
858 struct winreg_GetKeySecurity *r)
860 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
861 WERROR err = WERR_OK;
862 struct security_descriptor *secdesc = NULL;
869 /* access checks first */
871 if ( !(key->key->access_granted & SEC_STD_READ_CONTROL) )
872 return WERR_ACCESS_DENIED;
874 err = reg_getkeysecurity(p->mem_ctx, key, &secdesc);
875 if (!W_ERROR_IS_OK(err)) {
879 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
881 if (!W_ERROR_IS_OK(err)) {
885 if (len > r->out.sd->size) {
886 r->out.sd->size = len;
887 return WERR_INSUFFICIENT_BUFFER;
890 r->out.sd->size = len;
891 r->out.sd->len = len;
892 r->out.sd->data = data;
897 /*******************************************************************
898 _winreg_SetKeySecurity
899 ********************************************************************/
901 WERROR _winreg_SetKeySecurity(struct pipes_struct *p,
902 struct winreg_SetKeySecurity *r)
904 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
905 struct security_descriptor *secdesc = NULL;
906 WERROR err = WERR_OK;
911 /* access checks first */
913 if ( !(key->key->access_granted & SEC_STD_WRITE_DAC) )
914 return WERR_ACCESS_DENIED;
916 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
917 r->in.sd->len, &secdesc));
918 if (!W_ERROR_IS_OK(err)) {
922 return reg_setkeysecurity(key, secdesc);
925 /*******************************************************************
927 ********************************************************************/
929 WERROR _winreg_FlushKey(struct pipes_struct *p,
930 struct winreg_FlushKey *r)
932 /* I'm just replying OK because there's not a lot
933 here I see to do i --jerry */
938 /*******************************************************************
940 ********************************************************************/
942 WERROR _winreg_UnLoadKey(struct pipes_struct *p,
943 struct winreg_UnLoadKey *r)
945 /* fill in your code here if you think this call should
948 p->rng_fault_state = True;
949 return WERR_NOT_SUPPORTED;
952 /*******************************************************************
954 ********************************************************************/
956 WERROR _winreg_ReplaceKey(struct pipes_struct *p,
957 struct winreg_ReplaceKey *r)
959 /* fill in your code here if you think this call should
962 p->rng_fault_state = True;
963 return WERR_NOT_SUPPORTED;
966 /*******************************************************************
968 ********************************************************************/
970 WERROR _winreg_LoadKey(struct pipes_struct *p,
971 struct winreg_LoadKey *r)
973 /* fill in your code here if you think this call should
976 p->rng_fault_state = True;
977 return WERR_NOT_SUPPORTED;
980 /*******************************************************************
981 _winreg_NotifyChangeKeyValue
982 ********************************************************************/
984 WERROR _winreg_NotifyChangeKeyValue(struct pipes_struct *p,
985 struct winreg_NotifyChangeKeyValue *r)
987 return WERR_NOT_SUPPORTED;
990 /*******************************************************************
991 _winreg_QueryMultipleValues
992 ********************************************************************/
994 WERROR _winreg_QueryMultipleValues(struct pipes_struct *p,
995 struct winreg_QueryMultipleValues *r)
997 struct winreg_QueryMultipleValues2 r2;
1000 r2.in.key_handle = r->in.key_handle;
1001 r2.in.values_in = r->in.values_in;
1002 r2.in.num_values = r->in.num_values;
1003 r2.in.offered = r->in.buffer_size;
1004 r2.in.buffer = r->in.buffer;
1005 r2.out.values_out = r->out.values_out;
1006 r2.out.needed = &needed;
1007 r2.out.buffer = r->out.buffer;
1009 return _winreg_QueryMultipleValues2(p, &r2);
1012 /*******************************************************************
1013 ********************************************************************/
1015 static WERROR construct_multiple_entry(TALLOC_CTX *mem_ctx,
1016 const char *valuename,
1017 uint32_t value_length,
1019 enum winreg_Type type,
1020 struct QueryMultipleValue *r)
1022 r->ve_valuename = talloc_zero(mem_ctx, struct winreg_ValNameBuf);
1023 if (r->ve_valuename == NULL) {
1027 r->ve_valuename->name = talloc_strdup(r->ve_valuename, valuename ? valuename : "");
1028 if (r->ve_valuename->name == NULL) {
1032 r->ve_valuename->size = strlen_m_term(r->ve_valuename->name)*2;
1033 r->ve_valuelen = value_length;
1034 r->ve_valueptr = offset;
1040 /*******************************************************************
1041 _winreg_QueryMultipleValues2
1042 ********************************************************************/
1044 WERROR _winreg_QueryMultipleValues2(struct pipes_struct *p,
1045 struct winreg_QueryMultipleValues2 *r)
1047 struct registry_key *regkey = find_regkey_by_hnd(p, r->in.key_handle);
1048 struct registry_value *vals = NULL;
1049 const char **names = NULL;
1050 uint32_t offset = 0, num_vals = 0;
1051 DATA_BLOB result = data_blob_null;
1053 WERROR err = WERR_OK;
1059 names = talloc_zero_array(p->mem_ctx, const char *, r->in.num_values);
1060 if (names == NULL) {
1064 for (i=0; i < r->in.num_values; i++) {
1065 if (r->in.values_in[i].ve_valuename &&
1066 r->in.values_in[i].ve_valuename->name) {
1067 names[i] = talloc_strdup(names,
1068 r->in.values_in[i].ve_valuename->name);
1069 if (names[i] == NULL) {
1075 err = reg_querymultiplevalues(p->mem_ctx, regkey,
1076 r->in.num_values, names,
1078 if (!W_ERROR_IS_OK(err)) {
1082 result = data_blob_talloc(p->mem_ctx, NULL, 0);
1084 for (i=0; i < r->in.num_values; i++) {
1085 const char *valuename = NULL;
1087 if (vals[i].data.length > 0) {
1088 if (!data_blob_append(p->mem_ctx, &result,
1090 vals[i].data.length)) {
1095 if (r->in.values_in[i].ve_valuename &&
1096 r->in.values_in[i].ve_valuename->name) {
1097 valuename = r->in.values_in[i].ve_valuename->name;
1100 err = construct_multiple_entry(r->out.values_out,
1102 vals[i].data.length,
1105 &r->out.values_out[i]);
1106 if (!W_ERROR_IS_OK(err)) {
1110 offset += vals[i].data.length;
1113 *r->out.needed = result.length;
1115 if (r->in.num_values != num_vals) {
1116 return WERR_BADFILE;
1119 if (*r->in.offered >= *r->out.needed) {
1120 if (r->out.buffer) {
1121 memcpy(r->out.buffer, result.data, MIN(result.length, *r->in.offered));
1125 return WERR_MORE_DATA;
1129 /*******************************************************************
1131 ********************************************************************/
1133 WERROR _winreg_DeleteKeyEx(struct pipes_struct *p,
1134 struct winreg_DeleteKeyEx *r)
1136 /* fill in your code here if you think this call should
1139 p->rng_fault_state = True;
1140 return WERR_NOT_SUPPORTED;