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"
25 #include "registry/reg_parse_prs.h"
27 #include "registry/reg_perfcount.h"
31 #define DBGC_CLASS DBGC_RPC_SRV
33 /******************************************************************
34 Find a registry key handle and return a struct registry_key *
35 *****************************************************************/
37 static struct registry_key *find_regkey_by_hnd(struct pipes_struct *p,
38 struct policy_handle *hnd)
40 struct registry_key *regkey = NULL;
42 if(!find_policy_by_hnd(p,hnd,(void **)(void *)®key)) {
43 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
50 /*******************************************************************
51 Function for open a new registry handle and creating a handle
52 Note that P should be valid & hnd should already have space
54 When we open a key, we store the full path to the key as
55 HK[LM|U]\<key>\<key>\...
56 *******************************************************************/
58 static WERROR open_registry_key(struct pipes_struct *p,
59 struct policy_handle *hnd,
60 struct registry_key *parent,
61 const char *subkeyname,
62 uint32_t access_desired)
64 WERROR result = WERR_OK;
65 struct registry_key *key;
68 result = reg_openhive(p->mem_ctx, subkeyname, access_desired,
69 p->server_info->ptok, &key);
72 result = reg_openkey(p->mem_ctx, parent, subkeyname,
73 access_desired, &key);
76 if ( !W_ERROR_IS_OK(result) ) {
80 if ( !create_policy_hnd( p, hnd, key ) ) {
87 /*******************************************************************
88 Function for open a new registry handle and creating a handle
89 Note that P should be valid & hnd should already have space
90 *******************************************************************/
92 static bool close_registry_key(struct pipes_struct *p,
93 struct policy_handle *hnd)
95 struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
98 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
103 close_policy_hnd(p, hnd);
108 /********************************************************************
110 ********************************************************************/
112 WERROR _winreg_CloseKey(struct pipes_struct *p,
113 struct winreg_CloseKey *r)
115 /* close the policy handle */
117 if (!close_registry_key(p, r->in.handle))
120 ZERO_STRUCTP(r->out.handle);
125 /*******************************************************************
127 ********************************************************************/
129 WERROR _winreg_OpenHKLM(struct pipes_struct *p,
130 struct winreg_OpenHKLM *r)
132 return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
135 /*******************************************************************
137 ********************************************************************/
139 WERROR _winreg_OpenHKPD(struct pipes_struct *p,
140 struct winreg_OpenHKPD *r)
142 return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
145 /*******************************************************************
147 ********************************************************************/
149 WERROR _winreg_OpenHKPT(struct pipes_struct *p,
150 struct winreg_OpenHKPT *r)
152 return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
155 /*******************************************************************
157 ********************************************************************/
159 WERROR _winreg_OpenHKCR(struct pipes_struct *p,
160 struct winreg_OpenHKCR *r)
162 return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
165 /*******************************************************************
167 ********************************************************************/
169 WERROR _winreg_OpenHKU(struct pipes_struct *p,
170 struct winreg_OpenHKU *r)
172 return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
175 /*******************************************************************
177 ********************************************************************/
179 WERROR _winreg_OpenHKCU(struct pipes_struct *p,
180 struct winreg_OpenHKCU *r)
182 return open_registry_key(p, r->out.handle, NULL, KEY_HKCU, r->in.access_mask);
185 /*******************************************************************
187 ********************************************************************/
189 WERROR _winreg_OpenHKCC(struct pipes_struct *p,
190 struct winreg_OpenHKCC *r)
192 return open_registry_key(p, r->out.handle, NULL, KEY_HKCC, r->in.access_mask);
195 /*******************************************************************
197 ********************************************************************/
199 WERROR _winreg_OpenHKDD(struct pipes_struct *p,
200 struct winreg_OpenHKDD *r)
202 return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
205 /*******************************************************************
207 ********************************************************************/
209 WERROR _winreg_OpenHKPN(struct pipes_struct *p,
210 struct winreg_OpenHKPN *r)
212 return open_registry_key(p, r->out.handle, NULL, KEY_HKPN, r->in.access_mask);
215 /*******************************************************************
217 ********************************************************************/
219 WERROR _winreg_OpenKey(struct pipes_struct *p,
220 struct winreg_OpenKey *r)
222 struct registry_key *parent = find_regkey_by_hnd(p, r->in.parent_handle );
227 return open_registry_key(p, r->out.handle, parent, r->in.keyname.name, r->in.access_mask);
230 /*******************************************************************
232 ********************************************************************/
234 WERROR _winreg_QueryValue(struct pipes_struct *p,
235 struct winreg_QueryValue *r)
237 WERROR status = WERR_BADFILE;
238 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
241 uint8_t *outbuf = NULL;
242 uint32_t outbuf_size = 0;
244 bool free_buf = False;
245 bool free_prs = False;
250 if (r->in.value_name->name == NULL) {
251 return WERR_INVALID_PARAM;
254 if ((r->out.data_length == NULL) || (r->out.type == NULL) || (r->out.data_size == NULL)) {
255 return WERR_INVALID_PARAM;
258 DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey->key->name));
259 DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey->key->type));
261 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
262 if(regkey->key->type == REG_KEY_HKPD)
264 if (strequal(r->in.value_name->name, "Global")) {
265 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
267 status = reg_perfcount_get_hkpd(
268 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
269 outbuf = (uint8_t *)prs_hkpd.data_p;
272 else if (strequal(r->in.value_name->name, "Counter 009")) {
273 outbuf_size = reg_perfcount_get_counter_names(
274 reg_perfcount_get_base_index(),
275 (char **)(void *)&outbuf);
278 else if (strequal(r->in.value_name->name, "Explain 009")) {
279 outbuf_size = reg_perfcount_get_counter_help(
280 reg_perfcount_get_base_index(),
281 (char **)(void *)&outbuf);
284 else if (isdigit(r->in.value_name->name[0])) {
285 /* we probably have a request for a specific object
287 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
289 status = reg_perfcount_get_hkpd(
290 &prs_hkpd, *r->in.data_size, &outbuf_size,
291 r->in.value_name->name);
292 outbuf = (uint8_t *)prs_hkpd.data_p;
296 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
297 r->in.value_name->name));
301 *r->out.type = REG_BINARY;
304 struct registry_value *val;
306 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name->name,
308 if (!W_ERROR_IS_OK(status)) {
310 DEBUG(10,("_winreg_QueryValue: reg_queryvalue failed with: %s\n",
311 win_errstr(status)));
313 if (r->out.data_size) {
314 *r->out.data_size = 0;
316 if (r->out.data_length) {
317 *r->out.data_length = 0;
322 outbuf = val->data.data;
323 outbuf_size = val->data.length;
324 *r->out.type = val->type;
327 status = WERR_BADFILE;
329 if (*r->in.data_size < outbuf_size) {
330 *r->out.data_size = outbuf_size;
331 status = r->in.data ? WERR_MORE_DATA : WERR_OK;
333 *r->out.data_length = outbuf_size;
334 *r->out.data_size = outbuf_size;
336 memcpy(r->out.data, outbuf, outbuf_size);
341 if (free_prs) prs_mem_free(&prs_hkpd);
342 if (free_buf) SAFE_FREE(outbuf);
347 /*****************************************************************************
349 ****************************************************************************/
351 WERROR _winreg_QueryInfoKey(struct pipes_struct *p,
352 struct winreg_QueryInfoKey *r)
354 WERROR status = WERR_OK;
355 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
360 r->out.classname->name = NULL;
362 status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
363 r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
364 r->out.max_valbufsize, r->out.secdescsize,
365 r->out.last_changed_time);
366 if (!W_ERROR_IS_OK(status)) {
371 * These calculations account for the registry buffers being
372 * UTF-16. They are inexact at best, but so far they worked.
375 *r->out.max_subkeylen *= 2;
377 *r->out.max_valnamelen += 1;
378 *r->out.max_valnamelen *= 2;
384 /*****************************************************************************
386 ****************************************************************************/
388 WERROR _winreg_GetVersion(struct pipes_struct *p,
389 struct winreg_GetVersion *r)
391 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
396 return reg_getversion(r->out.version);
400 /*****************************************************************************
402 ****************************************************************************/
404 WERROR _winreg_EnumKey(struct pipes_struct *p,
405 struct winreg_EnumKey *r)
407 WERROR err = WERR_OK;
408 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
413 if ( !r->in.name || !r->in.keyclass )
414 return WERR_INVALID_PARAM;
416 DEBUG(8,("_winreg_EnumKey: enumerating key [%s]\n", key->key->name));
418 err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, (char **)&r->out.name->name,
419 r->out.last_changed_time);
420 if (!W_ERROR_IS_OK(err)) {
423 r->out.keyclass->name = "";
427 /*****************************************************************************
429 ****************************************************************************/
431 WERROR _winreg_EnumValue(struct pipes_struct *p,
432 struct winreg_EnumValue *r)
434 WERROR err = WERR_OK;
435 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
436 char *valname = NULL;
437 struct registry_value *val = NULL;
443 return WERR_INVALID_PARAM;
445 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
448 err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
449 if (!W_ERROR_IS_OK(err)) {
453 if (r->out.name != NULL) {
454 r->out.name->name = valname;
457 if (r->out.type != NULL) {
458 *r->out.type = val->type;
461 if (r->out.value != NULL) {
462 if ((r->out.size == NULL) || (r->out.length == NULL)) {
463 return WERR_INVALID_PARAM;
466 if (val->data.length > *r->out.size) {
467 return WERR_MORE_DATA;
470 memcpy( r->out.value, val->data.data, val->data.length );
473 if (r->out.length != NULL) {
474 *r->out.length = val->data.length;
476 if (r->out.size != NULL) {
477 *r->out.size = val->data.length;
483 /*******************************************************************
484 _winreg_InitiateSystemShutdown
485 ********************************************************************/
487 WERROR _winreg_InitiateSystemShutdown(struct pipes_struct *p,
488 struct winreg_InitiateSystemShutdown *r)
490 struct winreg_InitiateSystemShutdownEx s;
492 s.in.hostname = r->in.hostname;
493 s.in.message = r->in.message;
494 s.in.timeout = r->in.timeout;
495 s.in.force_apps = r->in.force_apps;
496 s.in.do_reboot = r->in.do_reboot;
499 /* thunk down to _winreg_InitiateSystemShutdownEx()
500 (just returns a status) */
502 return _winreg_InitiateSystemShutdownEx( p, &s );
505 /*******************************************************************
506 _winreg_InitiateSystemShutdownEx
507 ********************************************************************/
509 #define SHUTDOWN_R_STRING "-r"
510 #define SHUTDOWN_F_STRING "-f"
513 WERROR _winreg_InitiateSystemShutdownEx(struct pipes_struct *p,
514 struct winreg_InitiateSystemShutdownEx *r)
516 char *shutdown_script = NULL;
524 bool can_shutdown = false;
526 shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
527 if (!shutdown_script) {
530 if (!*shutdown_script) {
531 return WERR_ACCESS_DENIED;
534 /* pull the message string and perform necessary sanity checks on it */
536 if ( r->in.message && r->in.message->string ) {
537 if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->string )) == NULL ) {
540 chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
544 alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
547 fstr_sprintf(str_timeout, "%d", r->in.timeout);
548 fstr_sprintf(do_reboot, r->in.do_reboot ? SHUTDOWN_R_STRING : "");
549 fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
550 fstr_sprintf(str_reason, "%d", r->in.reason );
552 shutdown_script = talloc_all_string_sub(p->mem_ctx,
553 shutdown_script, "%z", chkmsg ? chkmsg : "");
554 if (!shutdown_script) {
557 shutdown_script = talloc_all_string_sub(p->mem_ctx,
558 shutdown_script, "%t", str_timeout);
559 if (!shutdown_script) {
562 shutdown_script = talloc_all_string_sub(p->mem_ctx,
563 shutdown_script, "%r", do_reboot);
564 if (!shutdown_script) {
567 shutdown_script = talloc_all_string_sub(p->mem_ctx,
568 shutdown_script, "%f", f);
569 if (!shutdown_script) {
572 shutdown_script = talloc_all_string_sub(p->mem_ctx,
573 shutdown_script, "%x", str_reason);
574 if (!shutdown_script) {
578 can_shutdown = security_token_has_privilege(p->server_info->ptok, SEC_PRIV_REMOTE_SHUTDOWN);
580 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
581 Take the error return from the script and provide it as the Windows return code. */
583 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
588 ret = smbrun( shutdown_script, NULL );
593 /********** END SeRemoteShutdownPrivilege BLOCK **********/
595 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
596 shutdown_script, ret));
598 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
601 /*******************************************************************
602 _winreg_AbortSystemShutdown
603 ********************************************************************/
605 WERROR _winreg_AbortSystemShutdown(struct pipes_struct *p,
606 struct winreg_AbortSystemShutdown *r)
608 const char *abort_shutdown_script = lp_abort_shutdown_script();
610 bool can_shutdown = false;
612 if (!*abort_shutdown_script)
613 return WERR_ACCESS_DENIED;
615 can_shutdown = security_token_has_privilege(p->server_info->ptok, SEC_PRIV_REMOTE_SHUTDOWN);
617 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
622 ret = smbrun( abort_shutdown_script, NULL );
627 /********** END SeRemoteShutdownPrivilege BLOCK **********/
629 DEBUG(3,("_winreg_AbortSystemShutdown: Running the command `%s' gave %d\n",
630 abort_shutdown_script, ret));
632 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
635 /*******************************************************************
636 ********************************************************************/
638 static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
641 int num_services = lp_numservices();
643 const char *share_path = NULL;
644 char *fname = *pp_fname;
646 /* convert to a unix path, stripping the C:\ along the way */
648 if (!(p = valid_share_pathname(ctx, fname))) {
652 /* has to exist within a valid file share */
654 for (snum=0; snum<num_services; snum++) {
655 if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
659 share_path = lp_pathname(snum);
661 /* make sure we have a path (e.g. [homes] ) */
662 if (strlen(share_path) == 0) {
666 if (strncmp(share_path, p, strlen(share_path)) == 0) {
672 return (snum < num_services) ? snum : -1;
675 /*******************************************************************
677 ********************************************************************/
679 WERROR _winreg_RestoreKey(struct pipes_struct *p,
680 struct winreg_RestoreKey *r)
682 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
689 if ( !r->in.filename || !r->in.filename->name )
690 return WERR_INVALID_PARAM;
692 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
697 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
698 "\"%s\"\n", regkey->key->name, fname));
700 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
701 return WERR_OBJECT_PATH_INVALID;
703 /* user must posses SeRestorePrivilege for this this proceed */
705 if ( !security_token_has_privilege(p->server_info->ptok, SEC_PRIV_RESTORE)) {
706 return WERR_ACCESS_DENIED;
709 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
710 regkey->key->name, fname, lp_servicename(snum) ));
712 return reg_restorekey(regkey, fname);
715 /*******************************************************************
717 ********************************************************************/
719 WERROR _winreg_SaveKey(struct pipes_struct *p,
720 struct winreg_SaveKey *r)
722 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
729 if ( !r->in.filename || !r->in.filename->name )
730 return WERR_INVALID_PARAM;
732 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
737 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
738 regkey->key->name, fname));
740 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
741 return WERR_OBJECT_PATH_INVALID;
743 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
744 regkey->key->name, fname, lp_servicename(snum) ));
746 return reg_savekey(regkey, fname);
749 /*******************************************************************
751 ********************************************************************/
753 WERROR _winreg_SaveKeyEx(struct pipes_struct *p,
754 struct winreg_SaveKeyEx *r)
756 /* fill in your code here if you think this call should
759 p->rng_fault_state = True;
760 return WERR_NOT_SUPPORTED;
763 /*******************************************************************
765 ********************************************************************/
767 WERROR _winreg_CreateKey(struct pipes_struct *p,
768 struct winreg_CreateKey *r)
770 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
771 struct registry_key *new_key = NULL;
772 WERROR result = WERR_OK;
777 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
778 "subkey name '%s'\n", parent->key->name, r->in.name.name));
780 result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
781 &new_key, r->out.action_taken);
782 if (!W_ERROR_IS_OK(result)) {
786 if (!create_policy_hnd(p, r->out.new_handle, new_key)) {
787 TALLOC_FREE(new_key);
794 /*******************************************************************
796 ********************************************************************/
798 WERROR _winreg_SetValue(struct pipes_struct *p,
799 struct winreg_SetValue *r)
801 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
802 struct registry_value *val = NULL;
807 DEBUG(8,("_winreg_SetValue: Setting value for [%s:%s]\n",
808 key->key->name, r->in.name.name));
810 val = talloc_zero(p->mem_ctx, struct registry_value);
815 val->type = r->in.type;
816 val->data = data_blob_talloc(p->mem_ctx, r->in.data, r->in.size);
818 return reg_setvalue(key, r->in.name.name, val);
821 /*******************************************************************
823 ********************************************************************/
825 WERROR _winreg_DeleteKey(struct pipes_struct *p,
826 struct winreg_DeleteKey *r)
828 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
833 return reg_deletekey(parent, r->in.key.name);
837 /*******************************************************************
839 ********************************************************************/
841 WERROR _winreg_DeleteValue(struct pipes_struct *p,
842 struct winreg_DeleteValue *r)
844 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
849 return reg_deletevalue(key, r->in.value.name);
852 /*******************************************************************
853 _winreg_GetKeySecurity
854 ********************************************************************/
856 WERROR _winreg_GetKeySecurity(struct pipes_struct *p,
857 struct winreg_GetKeySecurity *r)
859 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
860 WERROR err = WERR_OK;
861 struct security_descriptor *secdesc = NULL;
868 /* access checks first */
870 if ( !(key->key->access_granted & SEC_STD_READ_CONTROL) )
871 return WERR_ACCESS_DENIED;
873 err = reg_getkeysecurity(p->mem_ctx, key, &secdesc);
874 if (!W_ERROR_IS_OK(err)) {
878 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
880 if (!W_ERROR_IS_OK(err)) {
884 if (len > r->out.sd->size) {
885 r->out.sd->size = len;
886 return WERR_INSUFFICIENT_BUFFER;
889 r->out.sd->size = len;
890 r->out.sd->len = len;
891 r->out.sd->data = data;
896 /*******************************************************************
897 _winreg_SetKeySecurity
898 ********************************************************************/
900 WERROR _winreg_SetKeySecurity(struct pipes_struct *p,
901 struct winreg_SetKeySecurity *r)
903 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
904 struct security_descriptor *secdesc = NULL;
905 WERROR err = WERR_OK;
910 /* access checks first */
912 if ( !(key->key->access_granted & SEC_STD_WRITE_DAC) )
913 return WERR_ACCESS_DENIED;
915 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
916 r->in.sd->len, &secdesc));
917 if (!W_ERROR_IS_OK(err)) {
921 return reg_setkeysecurity(key, secdesc);
924 /*******************************************************************
926 ********************************************************************/
928 WERROR _winreg_FlushKey(struct pipes_struct *p,
929 struct winreg_FlushKey *r)
931 /* I'm just replying OK because there's not a lot
932 here I see to do i --jerry */
937 /*******************************************************************
939 ********************************************************************/
941 WERROR _winreg_UnLoadKey(struct pipes_struct *p,
942 struct winreg_UnLoadKey *r)
944 /* fill in your code here if you think this call should
947 p->rng_fault_state = True;
948 return WERR_NOT_SUPPORTED;
951 /*******************************************************************
953 ********************************************************************/
955 WERROR _winreg_ReplaceKey(struct pipes_struct *p,
956 struct winreg_ReplaceKey *r)
958 /* fill in your code here if you think this call should
961 p->rng_fault_state = True;
962 return WERR_NOT_SUPPORTED;
965 /*******************************************************************
967 ********************************************************************/
969 WERROR _winreg_LoadKey(struct pipes_struct *p,
970 struct winreg_LoadKey *r)
972 /* fill in your code here if you think this call should
975 p->rng_fault_state = True;
976 return WERR_NOT_SUPPORTED;
979 /*******************************************************************
980 _winreg_NotifyChangeKeyValue
981 ********************************************************************/
983 WERROR _winreg_NotifyChangeKeyValue(struct pipes_struct *p,
984 struct winreg_NotifyChangeKeyValue *r)
986 return WERR_NOT_SUPPORTED;
989 /*******************************************************************
990 _winreg_QueryMultipleValues
991 ********************************************************************/
993 WERROR _winreg_QueryMultipleValues(struct pipes_struct *p,
994 struct winreg_QueryMultipleValues *r)
996 struct winreg_QueryMultipleValues2 r2;
999 r2.in.key_handle = r->in.key_handle;
1000 r2.in.values_in = r->in.values_in;
1001 r2.in.num_values = r->in.num_values;
1002 r2.in.offered = r->in.buffer_size;
1003 r2.in.buffer = r->in.buffer;
1004 r2.out.values_out = r->out.values_out;
1005 r2.out.needed = &needed;
1006 r2.out.buffer = r->out.buffer;
1008 return _winreg_QueryMultipleValues2(p, &r2);
1011 /*******************************************************************
1012 ********************************************************************/
1014 static WERROR construct_multiple_entry(TALLOC_CTX *mem_ctx,
1015 const char *valuename,
1016 uint32_t value_length,
1018 enum winreg_Type type,
1019 struct QueryMultipleValue *r)
1021 r->ve_valuename = talloc_zero(mem_ctx, struct winreg_ValNameBuf);
1022 if (r->ve_valuename == NULL) {
1026 r->ve_valuename->name = talloc_strdup(r->ve_valuename, valuename ? valuename : "");
1027 if (r->ve_valuename->name == NULL) {
1031 r->ve_valuename->size = strlen_m_term(r->ve_valuename->name)*2;
1032 r->ve_valuelen = value_length;
1033 r->ve_valueptr = offset;
1039 /*******************************************************************
1040 _winreg_QueryMultipleValues2
1041 ********************************************************************/
1043 WERROR _winreg_QueryMultipleValues2(struct pipes_struct *p,
1044 struct winreg_QueryMultipleValues2 *r)
1046 struct registry_key *regkey = find_regkey_by_hnd(p, r->in.key_handle);
1047 struct registry_value *vals = NULL;
1048 const char **names = NULL;
1049 uint32_t offset = 0, num_vals = 0;
1050 DATA_BLOB result = data_blob_null;
1052 WERROR err = WERR_OK;
1058 names = talloc_zero_array(p->mem_ctx, const char *, r->in.num_values);
1059 if (names == NULL) {
1063 for (i=0; i < r->in.num_values; i++) {
1064 if (r->in.values_in[i].ve_valuename &&
1065 r->in.values_in[i].ve_valuename->name) {
1066 names[i] = talloc_strdup(names,
1067 r->in.values_in[i].ve_valuename->name);
1068 if (names[i] == NULL) {
1074 err = reg_querymultiplevalues(p->mem_ctx, regkey,
1075 r->in.num_values, names,
1077 if (!W_ERROR_IS_OK(err)) {
1081 result = data_blob_talloc(p->mem_ctx, NULL, 0);
1083 for (i=0; i < r->in.num_values; i++) {
1084 const char *valuename = NULL;
1086 if (vals[i].data.length > 0) {
1087 if (!data_blob_append(p->mem_ctx, &result,
1089 vals[i].data.length)) {
1094 if (r->in.values_in[i].ve_valuename &&
1095 r->in.values_in[i].ve_valuename->name) {
1096 valuename = r->in.values_in[i].ve_valuename->name;
1099 err = construct_multiple_entry(r->out.values_out,
1101 vals[i].data.length,
1104 &r->out.values_out[i]);
1105 if (!W_ERROR_IS_OK(err)) {
1109 offset += vals[i].data.length;
1112 *r->out.needed = result.length;
1114 if (r->in.num_values != num_vals) {
1115 return WERR_BADFILE;
1118 if (*r->in.offered >= *r->out.needed) {
1119 if (r->out.buffer) {
1120 memcpy(r->out.buffer, result.data, MIN(result.length, *r->in.offered));
1124 return WERR_MORE_DATA;
1128 /*******************************************************************
1130 ********************************************************************/
1132 WERROR _winreg_DeleteKeyEx(struct pipes_struct *p,
1133 struct winreg_DeleteKeyEx *r)
1135 /* fill in your code here if you think this call should
1138 p->rng_fault_state = True;
1139 return WERR_NOT_SUPPORTED;