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;