3 * Unix SMB/Netbios implementation.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-1997,
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
8 * Copyright (C) Paul Ashton 1997.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 extern int DEBUGLEVEL;
35 /****************************************************************************
37 ****************************************************************************/
38 BOOL do_reg_connect(struct cli_state *cli, char *full_keyname,
49 if (full_keyname == NULL)
55 if (strnequal(full_keyname, srch, strlen(srch)))
57 full_keyname += strlen(srch);
58 if (*full_keyname == '\\')
61 fstrcpy(key_name, full_keyname);
63 else if (*full_keyname != 0)
69 /* open registry receive a policy handle */
73 res = do_reg_open_hklm(cli,
80 res = do_reg_open_hku(cli,
86 res1 = res ? do_reg_open_entry(cli, reg_hnd,
87 key_name, 0x02000000, key_hnd) : False;
92 /****************************************************************************
94 ****************************************************************************/
95 BOOL do_reg_open_hklm(struct cli_state *cli, uint16 unknown_0, uint32 level,
101 BOOL valid_pol = False;
103 if (hnd == NULL) return False;
105 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
106 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
108 /* create and send a MSRPC command with api REG_OPEN_HKLM */
110 DEBUG(4,("REG Open HKLM\n"));
112 make_reg_q_open_hklm(&q_o, unknown_0, level);
114 /* turn parameters into data stream */
115 reg_io_q_open_hklm("", &q_o, &buf, 0);
117 /* send the data on \PIPE\ */
118 if (rpc_api_pipe_req(cli, REG_OPEN_HKLM, &buf, &rbuf))
125 reg_io_r_open_hklm("", &r_o, &rbuf, 0);
126 p = rbuf.offset != 0;
128 if (p && r_o.status != 0)
130 /* report error code */
131 DEBUG(0,("REG_OPEN_HKLM: %s\n", get_nt_error_msg(r_o.status)));
137 /* ok, at last: we're happy. return the policy handle */
138 memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
149 /****************************************************************************
151 ****************************************************************************/
152 BOOL do_reg_open_hku(struct cli_state *cli, uint16 unknown_0, uint32 level,
158 BOOL valid_pol = False;
160 if (hnd == NULL) return False;
162 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
163 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
165 /* create and send a MSRPC command with api REG_OPEN_HKU */
167 DEBUG(4,("REG Open HKU\n"));
169 make_reg_q_open_hku(&q_o, unknown_0, level);
171 /* turn parameters into data stream */
172 reg_io_q_open_hku("", &q_o, &buf, 0);
174 /* send the data on \PIPE\ */
175 if (rpc_api_pipe_req(cli, REG_OPEN_HKU, &buf, &rbuf))
182 reg_io_r_open_hku("", &r_o, &rbuf, 0);
183 p = rbuf.offset != 0;
185 if (p && r_o.status != 0)
187 /* report error code */
188 DEBUG(0,("REG_OPEN_HKU: %s\n", get_nt_error_msg(r_o.status)));
194 /* ok, at last: we're happy. return the policy handle */
195 memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
206 /****************************************************************************
207 do a REG Unknown 0xB command. sent after a create key or create value.
208 this might be some sort of "sync" or "refresh" command, sent after
209 modification of the registry...
210 ****************************************************************************/
211 BOOL do_reg_flush_key(struct cli_state *cli, POLICY_HND *hnd)
216 BOOL valid_query = False;
218 if (hnd == NULL) return False;
220 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
221 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
223 /* create and send a MSRPC command with api REG_FLUSH_KEY */
225 DEBUG(4,("REG Unknown 0xB\n"));
227 make_reg_q_flush_key(&q_o, hnd);
229 /* turn parameters into data stream */
230 reg_io_q_flush_key("", &q_o, &buf, 0);
232 /* send the data on \PIPE\ */
233 if (rpc_api_pipe_req(cli, REG_FLUSH_KEY, &buf, &rbuf))
240 reg_io_r_flush_key("", &r_o, &rbuf, 0);
241 p = rbuf.offset != 0;
243 if (p && r_o.status != 0)
245 /* report error code */
246 DEBUG(0,("REG_FLUSH_KEY: %s\n", get_nt_error_msg(r_o.status)));
262 /****************************************************************************
264 ****************************************************************************/
265 BOOL do_reg_query_key(struct cli_state *cli, POLICY_HND *hnd,
266 char *class, uint32 *class_len,
267 uint32 *num_subkeys, uint32 *max_subkeylen,
268 uint32 *max_subkeysize, uint32 *num_values,
269 uint32 *max_valnamelen, uint32 *max_valbufsize,
270 uint32 *sec_desc, NTTIME *mod_time)
275 BOOL valid_query = False;
277 if (hnd == NULL) return False;
279 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
280 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
282 /* create and send a MSRPC command with api REG_QUERY_KEY */
284 DEBUG(4,("REG Query Key\n"));
286 make_reg_q_query_key(&q_o, hnd, *class_len);
288 /* turn parameters into data stream */
289 reg_io_q_query_key("", &q_o, &buf, 0);
291 /* send the data on \PIPE\ */
292 if (rpc_api_pipe_req(cli, REG_QUERY_KEY, &buf, &rbuf))
299 reg_io_r_query_key("", &r_o, &rbuf, 0);
300 p = rbuf.offset != 0;
302 if (p && r_o.status != 0)
304 /* report error code */
305 DEBUG(0,("REG_QUERY_KEY: %s\n", get_nt_error_msg(r_o.status)));
313 *class_len = r_o.hdr_class.uni_max_len;
314 fstrcpy(class, unistr2_to_str(&r_o.uni_class));
315 *num_subkeys = r_o.num_subkeys ;
316 *max_subkeylen = r_o.max_subkeylen ;
317 *max_subkeysize = r_o.max_subkeysize;
318 *num_values = r_o.num_values ;
319 *max_valnamelen = r_o.max_valnamelen;
320 *max_valbufsize = r_o.max_valbufsize;
321 *sec_desc = r_o.sec_desc ;
322 *mod_time = r_o.mod_time ;
332 /****************************************************************************
334 ****************************************************************************/
335 BOOL do_reg_unknown_1a(struct cli_state *cli, POLICY_HND *hnd, uint32 *unk)
340 BOOL valid_query = False;
342 if (hnd == NULL) return False;
344 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
345 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
347 /* create and send a MSRPC command with api REG_UNKNOWN_1A */
349 DEBUG(4,("REG Unknown 1a\n"));
351 make_reg_q_unk_1a(&q_o, hnd);
353 /* turn parameters into data stream */
354 reg_io_q_unk_1a("", &q_o, &buf, 0);
356 /* send the data on \PIPE\ */
357 if (rpc_api_pipe_req(cli, REG_UNK_1A, &buf, &rbuf))
364 reg_io_r_unk_1a("", &r_o, &rbuf, 0);
365 p = rbuf.offset != 0;
367 if (p && r_o.status != 0)
369 /* report error code */
370 DEBUG(0,("REG_UNK_1A: %s\n", get_nt_error_msg(r_o.status)));
377 (*unk) = r_o.unknown;
387 /****************************************************************************
389 ****************************************************************************/
390 BOOL do_reg_query_info(struct cli_state *cli, POLICY_HND *hnd,
391 char *type, uint32 *unk_0, uint32 *unk_1)
396 BOOL valid_query = False;
398 if (hnd == NULL) return False;
400 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
401 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
403 /* create and send a MSRPC command with api REG_INFO */
405 DEBUG(4,("REG Query Info\n"));
407 make_reg_q_info(&q_o, hnd, "ProductType", time(NULL), 4, 1);
409 /* turn parameters into data stream */
410 reg_io_q_info("", &q_o, &buf, 0);
412 /* send the data on \PIPE\ */
413 if (rpc_api_pipe_req(cli, REG_INFO, &buf, &rbuf))
420 reg_io_r_info("", &r_o, &rbuf, 0);
421 p = rbuf.offset != 0;
423 if (p && r_o.status != 0)
425 /* report error code */
426 DEBUG(0,("REG_INFO: %s\n", get_nt_error_msg(r_o.status)));
433 fstrcpy(type, buffer2_to_str(&r_o.uni_type));
434 (*unk_0) = r_o.unknown_0;
435 (*unk_1) = r_o.unknown_1;
445 /****************************************************************************
446 do a REG Query Key Security
447 ****************************************************************************/
448 BOOL do_reg_get_key_sec(struct cli_state *cli, POLICY_HND *hnd,
449 uint32 *sec_buf_size, SEC_DESC_BUF *sec_buf)
453 REG_Q_GET_KEY_SEC q_o;
454 BOOL valid_query = False;
456 if (hnd == NULL) return False;
458 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
459 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
461 /* create and send a MSRPC command with api REG_GET_KEY_SEC */
463 DEBUG(4,("REG query key security. buf_size: %d\n", *sec_buf_size));
465 make_reg_q_get_key_sec(&q_o, hnd, *sec_buf_size, sec_buf);
467 /* turn parameters into data stream */
468 reg_io_q_get_key_sec("", &q_o, &buf, 0);
470 /* send the data on \PIPE\ */
471 if (rpc_api_pipe_req(cli, REG_GET_KEY_SEC, &buf, &rbuf))
473 REG_R_GET_KEY_SEC r_o;
479 reg_io_r_get_key_sec("", &r_o, &rbuf, 0);
480 p = rbuf.offset != 0;
482 if (p && r_o.status == 0x0000007a)
485 * get the maximum buffer size: it was too small
487 (*sec_buf_size) = r_o.hdr_sec.buf_max_len;
488 DEBUG(5,("sec_buf_size too small. use %d\n", *sec_buf_size));
491 else if (p && r_o.status != 0)
493 /* report error code */
494 DEBUG(0,("REG_GET_KEY_SEC: %s\n", get_nt_error_msg(r_o.status)));
500 (*sec_buf_size) = r_o.data->len;
510 /****************************************************************************
511 do a REG Delete Value
512 ****************************************************************************/
513 BOOL do_reg_delete_val(struct cli_state *cli, POLICY_HND *hnd, char *val_name)
517 REG_Q_DELETE_VALUE q_o;
518 BOOL valid_delete = False;
520 if (hnd == NULL) return False;
522 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
523 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
525 /* create and send a MSRPC command with api REG_DELETE_VALUE */
527 DEBUG(4,("REG Delete Value: %s\n", val_name));
529 make_reg_q_delete_val(&q_o, hnd, val_name);
531 /* turn parameters into data stream */
532 reg_io_q_delete_val("", &q_o, &buf, 0);
534 /* send the data on \PIPE\ */
535 if (rpc_api_pipe_req(cli, REG_DELETE_VALUE, &buf, &rbuf))
537 REG_R_DELETE_VALUE r_o;
542 reg_io_r_delete_val("", &r_o, &rbuf, 0);
543 p = rbuf.offset != 0;
545 if (p && r_o.status != 0)
547 /* report error code */
548 DEBUG(0,("REG_DELETE_VALUE: %s\n", get_nt_error_msg(r_o.status)));
564 /****************************************************************************
566 ****************************************************************************/
567 BOOL do_reg_delete_key(struct cli_state *cli, POLICY_HND *hnd, char *key_name)
571 REG_Q_DELETE_KEY q_o;
572 BOOL valid_delete = False;
574 if (hnd == NULL) return False;
576 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
577 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
579 /* create and send a MSRPC command with api REG_DELETE_KEY */
581 DEBUG(4,("REG Delete Key: %s\n", key_name));
583 make_reg_q_delete_key(&q_o, hnd, key_name);
585 /* turn parameters into data stream */
586 reg_io_q_delete_key("", &q_o, &buf, 0);
588 /* send the data on \PIPE\ */
589 if (rpc_api_pipe_req(cli, REG_DELETE_KEY, &buf, &rbuf))
591 REG_R_DELETE_KEY r_o;
596 reg_io_r_delete_key("", &r_o, &rbuf, 0);
597 p = rbuf.offset != 0;
599 if (p && r_o.status != 0)
601 /* report error code */
602 DEBUG(0,("REG_DELETE_KEY: %s\n", get_nt_error_msg(r_o.status)));
618 /****************************************************************************
620 ****************************************************************************/
621 BOOL do_reg_create_key(struct cli_state *cli, POLICY_HND *hnd,
622 char *key_name, char *key_class,
623 SEC_INFO *sam_access,
628 REG_Q_CREATE_KEY q_o;
629 BOOL valid_create = False;
631 if (hnd == NULL) return False;
633 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
634 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
636 /* create and send a MSRPC command with api REG_CREATE_KEY */
638 DEBUG(4,("REG Create Key: %s %s 0x%08x\n", key_name, key_class,
639 sam_access != NULL ? sam_access->perms : 0));
641 make_reg_q_create_key(&q_o, hnd, key_name, key_class, sam_access);
643 /* turn parameters into data stream */
644 reg_io_q_create_key("", &q_o, &buf, 0);
646 /* send the data on \PIPE\ */
647 if (rpc_api_pipe_req(cli, REG_CREATE_KEY, &buf, &rbuf))
649 REG_R_CREATE_KEY r_o;
654 reg_io_r_create_key("", &r_o, &rbuf, 0);
655 p = rbuf.offset != 0;
657 if (p && r_o.status != 0)
659 /* report error code */
660 DEBUG(0,("REG_CREATE_KEY: %s\n", get_nt_error_msg(r_o.status)));
667 memcpy(key, r_o.key_pol.data, sizeof(key->data));
677 /****************************************************************************
679 ****************************************************************************/
680 BOOL do_reg_enum_key(struct cli_state *cli, POLICY_HND *hnd,
681 int key_index, char *key_name,
682 uint32 *unk_1, uint32 *unk_2,
688 BOOL valid_query = False;
690 if (hnd == NULL) return False;
692 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
693 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
695 /* create and send a MSRPC command with api REG_ENUM_KEY */
697 DEBUG(4,("REG Enum Key\n"));
699 make_reg_q_enum_key(&q_o, hnd, key_index);
701 /* turn parameters into data stream */
702 reg_io_q_enum_key("", &q_o, &buf, 0);
704 /* send the data on \PIPE\ */
705 if (rpc_api_pipe_req(cli, REG_ENUM_KEY, &buf, &rbuf))
712 reg_io_r_enum_key("", &r_o, &rbuf, 0);
713 p = rbuf.offset != 0;
715 if (p && r_o.status != 0)
717 /* report error code */
718 DEBUG(0,("REG_ENUM_KEY: %s\n", get_nt_error_msg(r_o.status)));
725 (*unk_1) = r_o.unknown_1;
726 (*unk_2) = r_o.unknown_2;
727 fstrcpy(key_name, unistr2(r_o.key_name.str.buffer));
728 (*mod_time) = nt_time_to_unix(&r_o.time);
738 /****************************************************************************
739 do a REG Create Value
740 ****************************************************************************/
741 BOOL do_reg_create_val(struct cli_state *cli, POLICY_HND *hnd,
742 char *val_name, uint32 type, BUFFER3 *data)
746 REG_Q_CREATE_VALUE q_o;
747 BOOL valid_create = False;
749 if (hnd == NULL) return False;
751 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
752 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
754 /* create and send a MSRPC command with api REG_CREATE_VALUE */
756 DEBUG(4,("REG Create Value: %s\n", val_name));
758 make_reg_q_create_val(&q_o, hnd, val_name, type, data);
760 /* turn parameters into data stream */
761 reg_io_q_create_val("", &q_o, &buf, 0);
763 /* send the data on \PIPE\ */
764 if (rpc_api_pipe_req(cli, REG_CREATE_VALUE, &buf, &rbuf))
766 REG_R_CREATE_VALUE r_o;
771 reg_io_r_create_val("", &r_o, &rbuf, 0);
772 p = rbuf.offset != 0;
774 if (p && r_o.status != 0)
776 /* report error code */
777 DEBUG(0,("REG_CREATE_VALUE: %s\n", get_nt_error_msg(r_o.status)));
793 /****************************************************************************
795 ****************************************************************************/
796 BOOL do_reg_enum_val(struct cli_state *cli, POLICY_HND *hnd,
797 int val_index, int max_valnamelen, int max_valbufsize,
799 uint32 *val_type, BUFFER2 *value)
803 REG_Q_ENUM_VALUE q_o;
804 BOOL valid_query = False;
806 if (hnd == NULL) return False;
808 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
809 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
811 /* create and send a MSRPC command with api REG_ENUM_VALUE */
813 DEBUG(4,("REG Enum Value\n"));
815 make_reg_q_enum_val(&q_o, hnd, val_index, max_valnamelen, max_valbufsize);
817 /* turn parameters into data stream */
818 reg_io_q_enum_val("", &q_o, &buf, 0);
820 /* send the data on \PIPE\ */
821 if (rpc_api_pipe_req(cli, REG_ENUM_VALUE, &buf, &rbuf))
823 REG_R_ENUM_VALUE r_o;
827 r_o.buf_value = value;
829 reg_io_r_enum_val("", &r_o, &rbuf, 0);
830 p = rbuf.offset != 0;
832 if (p && r_o.status != 0)
834 /* report error code */
835 DEBUG(0,("REG_ENUM_VALUE: %s\n", get_nt_error_msg(r_o.status)));
842 (*val_type) = r_o.type;
843 fstrcpy(val_name, unistr2_to_str(&r_o.uni_name));
853 /****************************************************************************
855 ****************************************************************************/
856 BOOL do_reg_open_entry(struct cli_state *cli, POLICY_HND *hnd,
857 char *key_name, uint32 unk_0,
862 REG_Q_OPEN_ENTRY q_o;
863 BOOL valid_pol = False;
865 if (hnd == NULL) return False;
867 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
868 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
870 /* create and send a MSRPC command with api REG_OPEN_ENTRY */
872 DEBUG(4,("REG Open Entry\n"));
874 make_reg_q_open_entry(&q_o, hnd, key_name, unk_0);
876 /* turn parameters into data stream */
877 reg_io_q_open_entry("", &q_o, &buf, 0);
879 /* send the data on \PIPE\ */
880 if (rpc_api_pipe_req(cli, REG_OPEN_ENTRY, &buf, &rbuf))
882 REG_R_OPEN_ENTRY r_o;
887 reg_io_r_open_entry("", &r_o, &rbuf, 0);
888 p = rbuf.offset != 0;
890 if (p && r_o.status != 0)
892 /* report error code */
893 DEBUG(0,("REG_OPEN_ENTRY: %s\n", get_nt_error_msg(r_o.status)));
900 memcpy(key_hnd, r_o.pol.data, sizeof(key_hnd->data));
910 /****************************************************************************
912 ****************************************************************************/
913 BOOL do_reg_close(struct cli_state *cli, POLICY_HND *hnd)
918 BOOL valid_close = False;
920 if (hnd == NULL) return False;
922 /* create and send a MSRPC command with api REG_CLOSE */
924 prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
925 prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
927 DEBUG(4,("REG Close\n"));
929 /* store the parameters */
930 make_reg_q_close(&q_c, hnd);
932 /* turn parameters into data stream */
933 reg_io_q_close("", &q_c, &buf, 0);
935 /* send the data on \PIPE\ */
936 if (rpc_api_pipe_req(cli, REG_CLOSE, &buf, &rbuf))
943 reg_io_r_close("", &r_c, &rbuf, 0);
944 p = rbuf.offset != 0;
946 if (p && r_c.status != 0)
948 /* report error code */
949 DEBUG(0,("REG_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
955 /* check that the returned policy handle is all zeros */
959 for (i = 0; i < sizeof(r_c.pol.data); i++)
961 if (r_c.pol.data[i] != 0)
969 DEBUG(0,("REG_CLOSE: non-zero handle returned\n"));