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"
34 #define DBGC_CLASS DBGC_RPC_SRV
36 /******************************************************************
37 Find a registry key handle and return a struct registry_key *
38 *****************************************************************/
40 static struct registry_key *find_regkey_by_hnd(struct pipes_struct *p,
41 struct policy_handle *hnd)
43 struct registry_key *regkey = NULL;
45 if(!find_policy_by_hnd(p,hnd,(void **)(void *)®key)) {
46 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
53 /*******************************************************************
54 Function for open a new registry handle and creating a handle
55 Note that P should be valid & hnd should already have space
57 When we open a key, we store the full path to the key as
58 HK[LM|U]\<key>\<key>\...
59 *******************************************************************/
61 static WERROR open_registry_key(struct pipes_struct *p,
62 struct policy_handle *hnd,
63 struct registry_key *parent,
64 const char *subkeyname,
65 uint32_t access_desired)
67 WERROR result = WERR_OK;
68 struct registry_key *key;
71 result = reg_openhive(p->mem_ctx, subkeyname, access_desired,
72 p->session_info->security_token, &key);
75 result = reg_openkey(p->mem_ctx, parent, subkeyname,
76 access_desired, &key);
79 if ( !W_ERROR_IS_OK(result) ) {
83 if ( !create_policy_hnd( p, hnd, key ) ) {
90 /*******************************************************************
91 Function for open a new registry handle and creating a handle
92 Note that P should be valid & hnd should already have space
93 *******************************************************************/
95 static bool close_registry_key(struct pipes_struct *p,
96 struct policy_handle *hnd)
98 struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
101 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
106 close_policy_hnd(p, hnd);
111 /********************************************************************
113 ********************************************************************/
115 WERROR _winreg_CloseKey(struct pipes_struct *p,
116 struct winreg_CloseKey *r)
118 /* close the policy handle */
120 if (!close_registry_key(p, r->in.handle))
123 ZERO_STRUCTP(r->out.handle);
128 /*******************************************************************
130 ********************************************************************/
132 WERROR _winreg_OpenHKLM(struct pipes_struct *p,
133 struct winreg_OpenHKLM *r)
135 return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
138 /*******************************************************************
140 ********************************************************************/
142 WERROR _winreg_OpenHKPD(struct pipes_struct *p,
143 struct winreg_OpenHKPD *r)
145 return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
148 /*******************************************************************
150 ********************************************************************/
152 WERROR _winreg_OpenHKPT(struct pipes_struct *p,
153 struct winreg_OpenHKPT *r)
155 return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
158 /*******************************************************************
160 ********************************************************************/
162 WERROR _winreg_OpenHKCR(struct pipes_struct *p,
163 struct winreg_OpenHKCR *r)
165 return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
168 /*******************************************************************
170 ********************************************************************/
172 WERROR _winreg_OpenHKU(struct pipes_struct *p,
173 struct winreg_OpenHKU *r)
175 return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
178 /*******************************************************************
180 ********************************************************************/
182 WERROR _winreg_OpenHKCU(struct pipes_struct *p,
183 struct winreg_OpenHKCU *r)
185 return open_registry_key(p, r->out.handle, NULL, KEY_HKCU, r->in.access_mask);
188 /*******************************************************************
190 ********************************************************************/
192 WERROR _winreg_OpenHKCC(struct pipes_struct *p,
193 struct winreg_OpenHKCC *r)
195 return open_registry_key(p, r->out.handle, NULL, KEY_HKCC, r->in.access_mask);
198 /*******************************************************************
200 ********************************************************************/
202 WERROR _winreg_OpenHKDD(struct pipes_struct *p,
203 struct winreg_OpenHKDD *r)
205 return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
208 /*******************************************************************
210 ********************************************************************/
212 WERROR _winreg_OpenHKPN(struct pipes_struct *p,
213 struct winreg_OpenHKPN *r)
215 return open_registry_key(p, r->out.handle, NULL, KEY_HKPN, r->in.access_mask);
218 /*******************************************************************
220 ********************************************************************/
222 WERROR _winreg_OpenKey(struct pipes_struct *p,
223 struct winreg_OpenKey *r)
225 struct registry_key *parent = find_regkey_by_hnd(p, r->in.parent_handle );
230 return open_registry_key(p, r->out.handle, parent, r->in.keyname.name, r->in.access_mask);
233 /*******************************************************************
235 ********************************************************************/
237 WERROR _winreg_QueryValue(struct pipes_struct *p,
238 struct winreg_QueryValue *r)
240 WERROR status = WERR_BADFILE;
241 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
244 uint8_t *outbuf = NULL;
245 uint32_t outbuf_size = 0;
247 bool free_buf = False;
248 bool free_prs = False;
253 if (r->in.value_name->name == NULL) {
254 return WERR_INVALID_PARAM;
257 if ((r->out.data_length == NULL) || (r->out.type == NULL) || (r->out.data_size == NULL)) {
258 return WERR_INVALID_PARAM;
261 DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey->key->name));
262 DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey->key->type));
264 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
265 if(regkey->key->type == REG_KEY_HKPD)
267 if (strequal(r->in.value_name->name, "Global")) {
268 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
270 status = reg_perfcount_get_hkpd(
271 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
272 outbuf = (uint8_t *)prs_hkpd.data_p;
275 else if (strequal(r->in.value_name->name, "Counter 009")) {
276 outbuf_size = reg_perfcount_get_counter_names(
277 reg_perfcount_get_base_index(),
278 (char **)(void *)&outbuf);
281 else if (strequal(r->in.value_name->name, "Explain 009")) {
282 outbuf_size = reg_perfcount_get_counter_help(
283 reg_perfcount_get_base_index(),
284 (char **)(void *)&outbuf);
287 else if (isdigit(r->in.value_name->name[0])) {
288 /* we probably have a request for a specific object
290 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
292 status = reg_perfcount_get_hkpd(
293 &prs_hkpd, *r->in.data_size, &outbuf_size,
294 r->in.value_name->name);
295 outbuf = (uint8_t *)prs_hkpd.data_p;
299 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
300 r->in.value_name->name));
304 *r->out.type = REG_BINARY;
307 struct registry_value *val;
309 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name->name,
311 if (!W_ERROR_IS_OK(status)) {
313 DEBUG(10,("_winreg_QueryValue: reg_queryvalue failed with: %s\n",
314 win_errstr(status)));
316 if (r->out.data_size) {
317 *r->out.data_size = 0;
319 if (r->out.data_length) {
320 *r->out.data_length = 0;
325 outbuf = val->data.data;
326 outbuf_size = val->data.length;
327 *r->out.type = val->type;
330 status = WERR_BADFILE;
332 if (*r->in.data_size < outbuf_size) {
333 *r->out.data_size = outbuf_size;
334 status = r->in.data ? WERR_MORE_DATA : WERR_OK;
336 *r->out.data_length = outbuf_size;
337 *r->out.data_size = outbuf_size;
339 memcpy(r->out.data, outbuf, outbuf_size);
344 if (free_prs) prs_mem_free(&prs_hkpd);
345 if (free_buf) SAFE_FREE(outbuf);
350 /*****************************************************************************
352 ****************************************************************************/
354 WERROR _winreg_QueryInfoKey(struct pipes_struct *p,
355 struct winreg_QueryInfoKey *r)
357 WERROR status = WERR_OK;
358 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
363 r->out.classname->name = NULL;
365 status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
366 r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
367 r->out.max_valbufsize, r->out.secdescsize,
368 r->out.last_changed_time);
369 if (!W_ERROR_IS_OK(status)) {
374 * These calculations account for the registry buffers being
375 * UTF-16. They are inexact at best, but so far they worked.
378 *r->out.max_subkeylen *= 2;
380 *r->out.max_valnamelen += 1;
381 *r->out.max_valnamelen *= 2;
387 /*****************************************************************************
389 ****************************************************************************/
391 WERROR _winreg_GetVersion(struct pipes_struct *p,
392 struct winreg_GetVersion *r)
394 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
399 return reg_getversion(r->out.version);
403 /*****************************************************************************
405 ****************************************************************************/
407 WERROR _winreg_EnumKey(struct pipes_struct *p,
408 struct winreg_EnumKey *r)
410 WERROR err = WERR_OK;
411 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
416 if ( !r->in.name || !r->in.keyclass )
417 return WERR_INVALID_PARAM;
419 DEBUG(8,("_winreg_EnumKey: enumerating key [%s]\n", key->key->name));
421 err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, (char **)&r->out.name->name,
422 r->out.last_changed_time);
423 if (!W_ERROR_IS_OK(err)) {
426 r->out.keyclass->name = "";
430 /*****************************************************************************
432 ****************************************************************************/
434 WERROR _winreg_EnumValue(struct pipes_struct *p,
435 struct winreg_EnumValue *r)
437 WERROR err = WERR_OK;
438 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
439 char *valname = NULL;
440 struct registry_value *val = NULL;
446 return WERR_INVALID_PARAM;
448 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
451 err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
452 if (!W_ERROR_IS_OK(err)) {
456 if (r->out.name != NULL) {
457 r->out.name->name = valname;
460 if (r->out.type != NULL) {
461 *r->out.type = val->type;
464 if (r->out.value != NULL) {
465 if ((r->out.size == NULL) || (r->out.length == NULL)) {
466 return WERR_INVALID_PARAM;
469 if (val->data.length > *r->out.size) {
470 return WERR_MORE_DATA;
473 memcpy( r->out.value, val->data.data, val->data.length );
476 if (r->out.length != NULL) {
477 *r->out.length = val->data.length;
479 if (r->out.size != NULL) {
480 *r->out.size = val->data.length;
486 /*******************************************************************
487 _winreg_InitiateSystemShutdown
488 ********************************************************************/
490 WERROR _winreg_InitiateSystemShutdown(struct pipes_struct *p,
491 struct winreg_InitiateSystemShutdown *r)
493 struct winreg_InitiateSystemShutdownEx s;
495 s.in.hostname = r->in.hostname;
496 s.in.message = r->in.message;
497 s.in.timeout = r->in.timeout;
498 s.in.force_apps = r->in.force_apps;
499 s.in.do_reboot = r->in.do_reboot;
502 /* thunk down to _winreg_InitiateSystemShutdownEx()
503 (just returns a status) */
505 return _winreg_InitiateSystemShutdownEx( p, &s );
508 /*******************************************************************
509 _winreg_InitiateSystemShutdownEx
510 ********************************************************************/
512 #define SHUTDOWN_R_STRING "-r"
513 #define SHUTDOWN_F_STRING "-f"
516 WERROR _winreg_InitiateSystemShutdownEx(struct pipes_struct *p,
517 struct winreg_InitiateSystemShutdownEx *r)
519 char *shutdown_script = NULL;
527 bool can_shutdown = false;
529 shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
530 if (!shutdown_script) {
533 if (!*shutdown_script) {
534 return WERR_ACCESS_DENIED;
537 /* pull the message string and perform necessary sanity checks on it */
539 if ( r->in.message && r->in.message->string ) {
540 if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->string )) == NULL ) {
543 chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
547 alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
550 fstr_sprintf(str_timeout, "%d", r->in.timeout);
551 fstr_sprintf(do_reboot, r->in.do_reboot ? SHUTDOWN_R_STRING : "");
552 fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
553 fstr_sprintf(str_reason, "%d", r->in.reason );
555 shutdown_script = talloc_all_string_sub(p->mem_ctx,
556 shutdown_script, "%z", chkmsg ? chkmsg : "");
557 if (!shutdown_script) {
560 shutdown_script = talloc_all_string_sub(p->mem_ctx,
561 shutdown_script, "%t", str_timeout);
562 if (!shutdown_script) {
565 shutdown_script = talloc_all_string_sub(p->mem_ctx,
566 shutdown_script, "%r", do_reboot);
567 if (!shutdown_script) {
570 shutdown_script = talloc_all_string_sub(p->mem_ctx,
571 shutdown_script, "%f", f);
572 if (!shutdown_script) {
575 shutdown_script = talloc_all_string_sub(p->mem_ctx,
576 shutdown_script, "%x", str_reason);
577 if (!shutdown_script) {
581 can_shutdown = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_REMOTE_SHUTDOWN);
583 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
584 Take the error return from the script and provide it as the Windows return code. */
586 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
591 ret = smbrun( shutdown_script, NULL );
596 /********** END SeRemoteShutdownPrivilege BLOCK **********/
598 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
599 shutdown_script, ret));
601 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
604 /*******************************************************************
605 _winreg_AbortSystemShutdown
606 ********************************************************************/
608 WERROR _winreg_AbortSystemShutdown(struct pipes_struct *p,
609 struct winreg_AbortSystemShutdown *r)
611 const char *abort_shutdown_script = lp_abort_shutdown_script();
613 bool can_shutdown = false;
615 if (!*abort_shutdown_script)
616 return WERR_ACCESS_DENIED;
618 can_shutdown = security_token_has_privilege(p->session_info->security_token, SEC_PRIV_REMOTE_SHUTDOWN);
620 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
625 ret = smbrun( abort_shutdown_script, NULL );
630 /********** END SeRemoteShutdownPrivilege BLOCK **********/
632 DEBUG(3,("_winreg_AbortSystemShutdown: Running the command `%s' gave %d\n",
633 abort_shutdown_script, ret));
635 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
638 /*******************************************************************
639 ********************************************************************/
641 static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
644 int num_services = lp_numservices();
646 const char *share_path = NULL;
647 char *fname = *pp_fname;
649 /* convert to a unix path, stripping the C:\ along the way */
651 if (!(p = valid_share_pathname(ctx, fname))) {
655 /* has to exist within a valid file share */
657 for (snum=0; snum<num_services; snum++) {
658 if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
662 share_path = lp_pathname(snum);
664 /* make sure we have a path (e.g. [homes] ) */
665 if (strlen(share_path) == 0) {
669 if (strncmp(share_path, p, strlen(share_path)) == 0) {
675 return (snum < num_services) ? snum : -1;
678 /*******************************************************************
680 ********************************************************************/
682 WERROR _winreg_RestoreKey(struct pipes_struct *p,
683 struct winreg_RestoreKey *r)
685 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
692 if ( !r->in.filename || !r->in.filename->name )
693 return WERR_INVALID_PARAM;
695 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
700 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
701 "\"%s\"\n", regkey->key->name, fname));
703 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
704 return WERR_OBJECT_PATH_INVALID;
706 /* user must posses SeRestorePrivilege for this this proceed */
708 if ( !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_RESTORE)) {
709 return WERR_ACCESS_DENIED;
712 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
713 regkey->key->name, fname, lp_servicename(snum) ));
715 return reg_restorekey(regkey, fname);
718 /*******************************************************************
720 ********************************************************************/
722 WERROR _winreg_SaveKey(struct pipes_struct *p,
723 struct winreg_SaveKey *r)
725 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
732 if ( !r->in.filename || !r->in.filename->name )
733 return WERR_INVALID_PARAM;
735 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
740 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
741 regkey->key->name, fname));
743 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
744 return WERR_OBJECT_PATH_INVALID;
746 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
747 regkey->key->name, fname, lp_servicename(snum) ));
749 return reg_savekey(regkey, fname);
752 /*******************************************************************
754 ********************************************************************/
756 WERROR _winreg_SaveKeyEx(struct pipes_struct *p,
757 struct winreg_SaveKeyEx *r)
759 /* fill in your code here if you think this call should
762 p->rng_fault_state = True;
763 return WERR_NOT_SUPPORTED;
766 /*******************************************************************
768 ********************************************************************/
770 WERROR _winreg_CreateKey(struct pipes_struct *p,
771 struct winreg_CreateKey *r)
773 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
774 struct registry_key *new_key = NULL;
775 WERROR result = WERR_OK;
780 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
781 "subkey name '%s'\n", parent->key->name, r->in.name.name));
783 result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
784 &new_key, r->out.action_taken);
785 if (!W_ERROR_IS_OK(result)) {
789 if (!create_policy_hnd(p, r->out.new_handle, new_key)) {
790 TALLOC_FREE(new_key);
797 /*******************************************************************
799 ********************************************************************/
801 WERROR _winreg_SetValue(struct pipes_struct *p,
802 struct winreg_SetValue *r)
804 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
805 struct registry_value *val = NULL;
810 DEBUG(8,("_winreg_SetValue: Setting value for [%s:%s]\n",
811 key->key->name, r->in.name.name));
813 val = talloc_zero(p->mem_ctx, struct registry_value);
818 val->type = r->in.type;
819 val->data = data_blob_talloc(p->mem_ctx, r->in.data, r->in.size);
821 return reg_setvalue(key, r->in.name.name, val);
824 /*******************************************************************
826 ********************************************************************/
828 WERROR _winreg_DeleteKey(struct pipes_struct *p,
829 struct winreg_DeleteKey *r)
831 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
836 return reg_deletekey(parent, r->in.key.name);
840 /*******************************************************************
842 ********************************************************************/
844 WERROR _winreg_DeleteValue(struct pipes_struct *p,
845 struct winreg_DeleteValue *r)
847 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
852 return reg_deletevalue(key, r->in.value.name);
855 /*******************************************************************
856 _winreg_GetKeySecurity
857 ********************************************************************/
859 WERROR _winreg_GetKeySecurity(struct pipes_struct *p,
860 struct winreg_GetKeySecurity *r)
862 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
863 WERROR err = WERR_OK;
864 struct security_descriptor *secdesc = NULL;
871 /* access checks first */
873 if ( !(key->key->access_granted & SEC_STD_READ_CONTROL) )
874 return WERR_ACCESS_DENIED;
876 err = reg_getkeysecurity(p->mem_ctx, key, &secdesc);
877 if (!W_ERROR_IS_OK(err)) {
881 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
883 if (!W_ERROR_IS_OK(err)) {
887 if (len > r->out.sd->size) {
888 r->out.sd->size = len;
889 return WERR_INSUFFICIENT_BUFFER;
892 r->out.sd->size = len;
893 r->out.sd->len = len;
894 r->out.sd->data = data;
899 /*******************************************************************
900 _winreg_SetKeySecurity
901 ********************************************************************/
903 WERROR _winreg_SetKeySecurity(struct pipes_struct *p,
904 struct winreg_SetKeySecurity *r)
906 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
907 struct security_descriptor *secdesc = NULL;
908 WERROR err = WERR_OK;
913 /* access checks first */
915 if ( !(key->key->access_granted & SEC_STD_WRITE_DAC) )
916 return WERR_ACCESS_DENIED;
918 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
919 r->in.sd->len, &secdesc));
920 if (!W_ERROR_IS_OK(err)) {
924 return reg_setkeysecurity(key, secdesc);
927 /*******************************************************************
929 ********************************************************************/
931 WERROR _winreg_FlushKey(struct pipes_struct *p,
932 struct winreg_FlushKey *r)
934 /* I'm just replying OK because there's not a lot
935 here I see to do i --jerry */
940 /*******************************************************************
942 ********************************************************************/
944 WERROR _winreg_UnLoadKey(struct pipes_struct *p,
945 struct winreg_UnLoadKey *r)
947 /* fill in your code here if you think this call should
950 p->rng_fault_state = True;
951 return WERR_NOT_SUPPORTED;
954 /*******************************************************************
956 ********************************************************************/
958 WERROR _winreg_ReplaceKey(struct pipes_struct *p,
959 struct winreg_ReplaceKey *r)
961 /* fill in your code here if you think this call should
964 p->rng_fault_state = True;
965 return WERR_NOT_SUPPORTED;
968 /*******************************************************************
970 ********************************************************************/
972 WERROR _winreg_LoadKey(struct pipes_struct *p,
973 struct winreg_LoadKey *r)
975 /* fill in your code here if you think this call should
978 p->rng_fault_state = True;
979 return WERR_NOT_SUPPORTED;
982 /*******************************************************************
983 _winreg_NotifyChangeKeyValue
984 ********************************************************************/
986 WERROR _winreg_NotifyChangeKeyValue(struct pipes_struct *p,
987 struct winreg_NotifyChangeKeyValue *r)
989 return WERR_NOT_SUPPORTED;
992 /*******************************************************************
993 _winreg_QueryMultipleValues
994 ********************************************************************/
996 WERROR _winreg_QueryMultipleValues(struct pipes_struct *p,
997 struct winreg_QueryMultipleValues *r)
999 struct winreg_QueryMultipleValues2 r2;
1000 uint32_t needed = 0;
1002 r2.in.key_handle = r->in.key_handle;
1003 r2.in.values_in = r->in.values_in;
1004 r2.in.num_values = r->in.num_values;
1005 r2.in.offered = r->in.buffer_size;
1006 r2.in.buffer = r->in.buffer;
1007 r2.out.values_out = r->out.values_out;
1008 r2.out.needed = &needed;
1009 r2.out.buffer = r->out.buffer;
1011 return _winreg_QueryMultipleValues2(p, &r2);
1014 /*******************************************************************
1015 ********************************************************************/
1017 static WERROR construct_multiple_entry(TALLOC_CTX *mem_ctx,
1018 const char *valuename,
1019 uint32_t value_length,
1021 enum winreg_Type type,
1022 struct QueryMultipleValue *r)
1024 r->ve_valuename = talloc_zero(mem_ctx, struct winreg_ValNameBuf);
1025 if (r->ve_valuename == NULL) {
1029 r->ve_valuename->name = talloc_strdup(r->ve_valuename, valuename ? valuename : "");
1030 if (r->ve_valuename->name == NULL) {
1034 r->ve_valuename->size = strlen_m_term(r->ve_valuename->name)*2;
1035 r->ve_valuelen = value_length;
1036 r->ve_valueptr = offset;
1042 /*******************************************************************
1043 _winreg_QueryMultipleValues2
1044 ********************************************************************/
1046 WERROR _winreg_QueryMultipleValues2(struct pipes_struct *p,
1047 struct winreg_QueryMultipleValues2 *r)
1049 struct registry_key *regkey = find_regkey_by_hnd(p, r->in.key_handle);
1050 struct registry_value *vals = NULL;
1051 const char **names = NULL;
1052 uint32_t offset = 0, num_vals = 0;
1053 DATA_BLOB result = data_blob_null;
1055 WERROR err = WERR_OK;
1061 names = talloc_zero_array(p->mem_ctx, const char *, r->in.num_values);
1062 if (names == NULL) {
1066 for (i=0; i < r->in.num_values; i++) {
1067 if (r->in.values_in[i].ve_valuename &&
1068 r->in.values_in[i].ve_valuename->name) {
1069 names[i] = talloc_strdup(names,
1070 r->in.values_in[i].ve_valuename->name);
1071 if (names[i] == NULL) {
1077 err = reg_querymultiplevalues(p->mem_ctx, regkey,
1078 r->in.num_values, names,
1080 if (!W_ERROR_IS_OK(err)) {
1084 result = data_blob_talloc(p->mem_ctx, NULL, 0);
1086 for (i=0; i < r->in.num_values; i++) {
1087 const char *valuename = NULL;
1089 if (vals[i].data.length > 0) {
1090 if (!data_blob_append(p->mem_ctx, &result,
1092 vals[i].data.length)) {
1097 if (r->in.values_in[i].ve_valuename &&
1098 r->in.values_in[i].ve_valuename->name) {
1099 valuename = r->in.values_in[i].ve_valuename->name;
1102 err = construct_multiple_entry(r->out.values_out,
1104 vals[i].data.length,
1107 &r->out.values_out[i]);
1108 if (!W_ERROR_IS_OK(err)) {
1112 offset += vals[i].data.length;
1115 *r->out.needed = result.length;
1117 if (r->in.num_values != num_vals) {
1118 return WERR_BADFILE;
1121 if (*r->in.offered >= *r->out.needed) {
1122 if (r->out.buffer) {
1123 memcpy(r->out.buffer, result.data, MIN(result.length, *r->in.offered));
1127 return WERR_MORE_DATA;
1131 /*******************************************************************
1133 ********************************************************************/
1135 WERROR _winreg_DeleteKeyEx(struct pipes_struct *p,
1136 struct winreg_DeleteKeyEx *r)
1138 /* fill in your code here if you think this call should
1141 p->rng_fault_state = True;
1142 return WERR_NOT_SUPPORTED;