2 Unix SMB/CIFS implementation.
5 Copyright (C) Andrew Tridgell 1992-2000,
6 Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
7 Copyright (C) Paul Ashton 1997-2000.
8 Copyright (C) Jeremy Allison 1999.
9 Copyright (C) Simo Sorce 2001
10 Copyright (C) Jeremy Cooper 2004
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 /* Shutdown a server */
31 /* internal connect to a registry hive root (open a registry policy) */
33 static WERROR
cli_reg_open_hive_int(struct cli_state
*cli
,
34 TALLOC_CTX
*mem_ctx
, uint16 op_code
,
36 uint32 access_mask
, POLICY_HND
*hnd
)
42 WERROR result
= WERR_GENERAL_FAILURE
;
47 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
48 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
50 init_reg_q_open_hive(&q_o
, access_mask
);
52 /* Marshall the query parameters */
53 if (!reg_io_q_open_hive("", &q_o
, &qbuf
, 0))
56 /* Send the request, receive the response */
57 if (!rpc_api_pipe_req(cli
, PI_WINREG
, op_code
, &qbuf
, &rbuf
))
60 /* Unmarshall the response */
61 if (!reg_io_r_open_hive("", &r_o
, &rbuf
, 0))
65 if (NT_STATUS_IS_OK(result
))
76 WERROR
cli_reg_shutdown(struct cli_state
* cli
, TALLOC_CTX
*mem_ctx
,
77 const char *msg
, uint32 timeout
, BOOL do_reboot
,
84 WERROR result
= WERR_GENERAL_FAILURE
;
86 if (msg
== NULL
) return WERR_INVALID_PARAM
;
91 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
92 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
94 /* Marshall data and send request */
96 init_reg_q_shutdown(&q_s
, msg
, timeout
, do_reboot
, force
);
98 if (!reg_io_q_shutdown("", &q_s
, &qbuf
, 0) ||
99 !rpc_api_pipe_req(cli
, PI_WINREG
, REG_SHUTDOWN
, &qbuf
, &rbuf
))
102 /* Unmarshall response */
104 if(reg_io_r_shutdown("", &r_s
, &rbuf
, 0))
115 /* Abort a server shutdown */
117 WERROR
cli_reg_abort_shutdown(struct cli_state
* cli
, TALLOC_CTX
*mem_ctx
)
121 REG_Q_ABORT_SHUTDOWN q_s
;
122 REG_R_ABORT_SHUTDOWN r_s
;
123 WERROR result
= WERR_GENERAL_FAILURE
;
128 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
129 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
131 /* Marshall data and send request */
133 init_reg_q_abort_shutdown(&q_s
);
135 if (!reg_io_q_abort_shutdown("", &q_s
, &qbuf
, 0) ||
136 !rpc_api_pipe_req(cli
, PI_WINREG
, REG_ABORT_SHUTDOWN
, &qbuf
, &rbuf
))
139 /* Unmarshall response */
141 if (reg_io_r_abort_shutdown("", &r_s
, &rbuf
, 0))
146 prs_mem_free(&qbuf
);
151 /* connect to a registry hive root (open a registry policy) */
153 WERROR
cli_reg_connect(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
154 uint32 reg_type
, uint32 access_mask
,
159 ZERO_STRUCTP(reg_hnd
);
163 case HKEY_CLASSES_ROOT
:
164 op_code
= REG_OPEN_HKCR
;
165 op_name
= "REG_OPEN_HKCR";
167 case HKEY_LOCAL_MACHINE
:
168 op_code
= REG_OPEN_HKLM
;
169 op_name
= "REG_OPEN_HKLM";
172 op_code
= REG_OPEN_HKU
;
173 op_name
= "REG_OPEN_HKU";
175 case HKEY_PERFORMANCE_DATA
:
176 op_code
= REG_OPEN_HKPD
;
177 op_name
= "REG_OPEN_HKPD";
180 return WERR_INVALID_PARAM
;
183 return cli_reg_open_hive_int(cli
, mem_ctx
, op_code
, op_name
,
184 access_mask
, reg_hnd
);
187 /****************************************************************************
188 do a REG Unknown 0xB command. sent after a create key or create value.
189 this might be some sort of "sync" or "refresh" command, sent after
190 modification of the registry...
191 ****************************************************************************/
192 WERROR
cli_reg_flush_key(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
199 WERROR result
= WERR_GENERAL_FAILURE
;
201 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
202 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
204 /* Marshall data and send request */
206 init_reg_q_flush_key(&q_o
, hnd
);
208 if (!reg_io_q_flush_key("", &q_o
, &qbuf
, 0) ||
209 !rpc_api_pipe_req(cli
, PI_WINREG
, REG_FLUSH_KEY
, &qbuf
, &rbuf
))
214 /* Unmarshall response */
216 if (reg_io_r_flush_key("", &r_o
, &rbuf
, 0))
226 /****************************************************************************
228 ****************************************************************************/
229 WERROR
cli_reg_query_key(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
231 char *key_class
, uint32
*class_len
,
232 uint32
*num_subkeys
, uint32
*max_subkeylen
,
233 uint32
*max_classlen
, uint32
*num_values
,
234 uint32
*max_valnamelen
, uint32
*max_valbufsize
,
235 uint32
*sec_desc
, NTTIME
*mod_time
)
241 uint32 saved_class_len
= *class_len
;
242 WERROR result
= WERR_GENERAL_FAILURE
;
244 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
245 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
247 /* Marshall data and send request */
249 init_reg_q_query_key( &q_o
, hnd
, key_class
);
251 if (!reg_io_q_query_key("", &q_o
, &qbuf
, 0) ||
252 !rpc_api_pipe_req(cli
, PI_WINREG
, REG_QUERY_KEY
, &qbuf
, &rbuf
))
257 /* Unmarshall response */
259 if (!reg_io_r_query_key("", &r_o
, &rbuf
, 0))
263 if (NT_STATUS_EQUAL(result
, ERROR_INSUFFICIENT_BUFFER
)) {
264 *class_len
= r_o
.class.string
->uni_max_len
;
266 } else if (!NT_STATUS_IS_OK(result
))
269 *class_len
= r_o
.class.string
->uni_max_len
;
270 unistr2_to_ascii(key_class
, r_o
.class.string
, saved_class_len
-1);
271 *num_subkeys
= r_o
.num_subkeys
;
272 *max_subkeylen
= r_o
.max_subkeylen
;
273 *num_values
= r_o
.num_values
;
274 *max_valnamelen
= r_o
.max_valnamelen
;
275 *max_valbufsize
= r_o
.max_valbufsize
;
276 *sec_desc
= r_o
.sec_desc
;
277 *mod_time
= r_o
.mod_time
;
278 /* Maybe: *max_classlen = r_o.reserved; */
287 /****************************************************************************
289 ****************************************************************************/
290 WERROR
cli_reg_getversion(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
291 POLICY_HND
*hnd
, uint32
*unk
)
295 REG_Q_GETVERSION q_o
;
296 REG_R_GETVERSION r_o
;
297 WERROR result
= WERR_GENERAL_FAILURE
;
299 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
300 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
302 /* Marshall data and send request */
304 init_reg_q_getversion(&q_o
, hnd
);
306 if (!reg_io_q_getversion("", &q_o
, &qbuf
, 0) ||
307 !rpc_api_pipe_req(cli
, PI_WINREG
, REG_GETVERSION
, &qbuf
, &rbuf
))
312 /* Unmarshall response */
314 if (!reg_io_r_getversion("", &r_o
, &rbuf
, 0))
318 if (NT_STATUS_IS_OK(result
))
329 /****************************************************************************
331 ****************************************************************************/
332 WERROR
cli_reg_query_info(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
333 POLICY_HND
*hnd
, const char *val_name
,
334 uint32
*type
, REGVAL_BUFFER
*buffer
)
340 WERROR result
= WERR_GENERAL_FAILURE
;
342 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
343 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
345 /* Marshall data and send request */
347 init_reg_q_info(&q_o
, hnd
, val_name
, buffer
);
349 if (!reg_io_q_info("", &q_o
, &qbuf
, 0) ||
350 !rpc_api_pipe_req(cli
, PI_WINREG
, REG_INFO
, &qbuf
, &rbuf
))
355 /* Unmarshall response */
357 if (!reg_io_r_info("", &r_o
, &rbuf
, 0))
361 if (NT_STATUS_IS_OK(result
)) {
363 *buffer
= *r_o
.value
;
373 /****************************************************************************
374 do a REG Set Key Security
375 ****************************************************************************/
376 WERROR
cli_reg_set_key_sec(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
377 POLICY_HND
*hnd
, uint32 sec_info
,
378 size_t secdesc_size
, SEC_DESC
*sec_desc
)
382 REG_Q_SET_KEY_SEC q_o
;
383 REG_R_SET_KEY_SEC r_o
;
384 SEC_DESC_BUF
*sec_desc_buf
;
385 WERROR result
= WERR_GENERAL_FAILURE
;
388 * Flatten the security descriptor.
390 sec_desc_buf
= make_sec_desc_buf(mem_ctx
, secdesc_size
, sec_desc
);
391 if (sec_desc_buf
== NULL
)
394 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
395 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
397 /* Marshall data and send request */
399 init_reg_q_set_key_sec(&q_o
, hnd
, sec_info
, sec_desc_buf
);
401 if (!reg_io_q_set_key_sec("", &q_o
, &qbuf
, 0) ||
402 !rpc_api_pipe_req(cli
, PI_WINREG
, REG_SET_KEY_SEC
, &qbuf
, &rbuf
))
407 /* Unmarshall response */
409 if (reg_io_r_set_key_sec("", &r_o
, &rbuf
, 0))
420 /****************************************************************************
421 do a REG Query Key Security
422 ****************************************************************************/
423 WERROR
cli_reg_get_key_sec(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
424 POLICY_HND
*hnd
, uint32 sec_info
,
425 uint32
*sec_buf_size
, SEC_DESC_BUF
*sec_buf
)
429 REG_Q_GET_KEY_SEC q_o
;
430 REG_R_GET_KEY_SEC r_o
;
431 WERROR result
= WERR_GENERAL_FAILURE
;
433 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
434 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
436 /* Marshall data and send request */
438 init_reg_q_get_key_sec(&q_o
, hnd
, sec_info
, *sec_buf_size
, sec_buf
);
440 if (!reg_io_q_get_key_sec("", &q_o
, &qbuf
, 0) ||
441 !rpc_api_pipe_req(cli
, PI_WINREG
, REG_GET_KEY_SEC
, &qbuf
, &rbuf
))
446 /* Unmarshall response */
450 if (*sec_buf_size
!= 0)
452 sec_buf
->sec
= (SEC_DESC
*)talloc(mem_ctx
, *sec_buf_size
);
455 if (!reg_io_r_get_key_sec("", &r_o
, &rbuf
, 0))
459 if (NT_STATUS_IS_OK(result
))
460 (*sec_buf_size
) = r_o
.data
->len
;
461 else if (NT_STATUS_EQUAL(result
, ERROR_INSUFFICIENT_BUFFER
))
464 * get the maximum buffer size: it was too small
466 (*sec_buf_size
) = r_o
.hdr_sec
.buf_max_len
;
476 /****************************************************************************
477 do a REG Delete Value
478 ****************************************************************************/
479 WERROR
cli_reg_delete_val(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
480 POLICY_HND
*hnd
, char *val_name
)
484 REG_Q_DELETE_VALUE q_o
;
485 REG_R_DELETE_VALUE r_o
;
486 WERROR result
= WERR_GENERAL_FAILURE
;
488 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
489 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
491 /* Marshall data and send request */
493 init_reg_q_delete_val(&q_o
, hnd
, val_name
);
495 if (!reg_io_q_delete_val("", &q_o
, &qbuf
, 0) ||
496 !rpc_api_pipe_req(cli
, PI_WINREG
, REG_DELETE_VALUE
, &qbuf
, &rbuf
))
501 /* Unmarshall response */
503 if (reg_io_r_delete_val("", &r_o
, &rbuf
, 0))
513 /****************************************************************************
515 ****************************************************************************/
516 WERROR
cli_reg_delete_key(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
517 POLICY_HND
*hnd
, char *key_name
)
521 REG_Q_DELETE_KEY q_o
;
522 REG_R_DELETE_KEY r_o
;
523 WERROR result
= WERR_GENERAL_FAILURE
;
525 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
526 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
528 /* Marshall data and send request */
530 init_reg_q_delete_key(&q_o
, hnd
, key_name
);
532 if (!reg_io_q_delete_key("", &q_o
, &qbuf
, 0) ||
533 !rpc_api_pipe_req(cli
, PI_WINREG
, REG_DELETE_KEY
, &qbuf
, &rbuf
))
538 /* Unmarshall response */
540 if (reg_io_r_delete_key("", &r_o
, &rbuf
, 0))
550 /****************************************************************************
552 ****************************************************************************/
553 WERROR
cli_reg_create_key(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
554 POLICY_HND
*hnd
, char *key_name
, char *key_class
,
555 uint32 access_desired
, POLICY_HND
*key
)
559 REG_Q_CREATE_KEY q_o
;
560 REG_R_CREATE_KEY r_o
;
562 SEC_DESC_BUF
*sec_buf
;
564 WERROR result
= WERR_GENERAL_FAILURE
;
568 if ((sec
= make_sec_desc(mem_ctx
, 1, SEC_DESC_SELF_RELATIVE
,
569 NULL
, NULL
, NULL
, NULL
, &sec_len
)) == NULL
)
572 if ((sec_buf
= make_sec_desc_buf(mem_ctx
, sec_len
, sec
)) == NULL
)
575 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
576 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
578 /* Marshall data and send request */
580 init_reg_q_create_key(&q_o
, hnd
, key_name
, key_class
, access_desired
, sec_buf
);
582 if (!reg_io_q_create_key("", &q_o
, &qbuf
, 0) ||
583 !rpc_api_pipe_req(cli
, PI_WINREG
, REG_CREATE_KEY
, &qbuf
, &rbuf
))
588 /* Unmarshall response */
590 if (!reg_io_r_create_key("", &r_o
, &rbuf
, 0))
594 if (NT_STATUS_IS_OK(result
))
604 /****************************************************************************
606 ****************************************************************************/
607 WERROR
cli_reg_enum_key(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
608 POLICY_HND
*hnd
, int key_index
, fstring key_name
,
609 uint32
*unk_1
, uint32
*unk_2
, time_t *mod_time
)
615 WERROR result
= WERR_GENERAL_FAILURE
;
617 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
618 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
620 /* Marshall data and send request */
622 init_reg_q_enum_key(&q_o
, hnd
, key_index
);
624 if (!reg_io_q_enum_key("", &q_o
, &qbuf
, 0) ||
625 !rpc_api_pipe_req(cli
, PI_WINREG
, REG_ENUM_KEY
, &qbuf
, &rbuf
))
630 /* Unmarshall response */
632 if (!reg_io_r_enum_key("", &r_o
, &rbuf
, 0))
636 if (NT_STATUS_IS_OK(result
)) {
637 (*unk_1
) = r_o
.unknown_1
;
638 (*unk_2
) = r_o
.unknown_2
;
639 unistr3_to_ascii(key_name
, &r_o
.key_name
,
641 (*mod_time
) = nt_time_to_unix(&r_o
.time
);
651 /****************************************************************************
652 do a REG Create Value
653 ****************************************************************************/
654 WERROR
cli_reg_create_val(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
655 POLICY_HND
*hnd
, char *val_name
, uint32 type
,
660 REG_Q_CREATE_VALUE q_o
;
661 REG_R_CREATE_VALUE r_o
;
662 WERROR result
= WERR_GENERAL_FAILURE
;
664 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
665 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
667 /* Marshall data and send request */
669 init_reg_q_create_val(&q_o
, hnd
, val_name
, type
, data
);
671 if (!reg_io_q_create_val("", &q_o
, &qbuf
, 0) ||
672 !rpc_api_pipe_req(cli
, PI_WINREG
, REG_CREATE_VALUE
, &qbuf
, &rbuf
))
677 /* Unmarshal response */
679 if (reg_io_r_create_val("", &r_o
, &rbuf
, 0))
689 /****************************************************************************
691 ****************************************************************************/
692 WERROR
cli_reg_enum_val(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
693 POLICY_HND
*hnd
, int val_index
, int max_valnamelen
,
694 int max_valbufsize
, fstring val_name
,
695 uint32
*val_type
, REGVAL_BUFFER
*value
)
699 REG_Q_ENUM_VALUE q_o
;
700 REG_R_ENUM_VALUE r_o
;
701 WERROR result
= WERR_GENERAL_FAILURE
;
703 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
704 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
706 /* Marshall data and send request */
708 init_reg_q_enum_val(&q_o
, hnd
, val_index
, val_name
, max_valbufsize
);
710 if (!reg_io_q_enum_val("", &q_o
, &qbuf
, 0) ||
711 !rpc_api_pipe_req(cli
, PI_WINREG
, REG_ENUM_VALUE
, &qbuf
, &rbuf
))
716 /* Unmarshall response */
718 if (!reg_io_r_enum_val("", &r_o
, &rbuf
, 0))
722 if (NT_STATUS_IS_OK(result
) ||
723 NT_STATUS_EQUAL(result
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
724 (*val_type
) = *r_o
.type
;
725 unistr2_to_ascii(val_name
, r_o
.name
.string
, sizeof(fstring
)-1);
736 /****************************************************************************
738 ****************************************************************************/
739 WERROR
cli_reg_open_entry(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
740 POLICY_HND
*hnd
, char *key_name
,
741 uint32 access_desired
, POLICY_HND
*key_hnd
)
745 REG_Q_OPEN_ENTRY q_o
;
746 REG_R_OPEN_ENTRY r_o
;
747 WERROR result
= WERR_GENERAL_FAILURE
;
749 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
750 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
752 /* Marshall data and send request */
754 init_reg_q_open_entry(&q_o
, hnd
, key_name
, access_desired
);
756 /* turn parameters into data stream */
757 if (!reg_io_q_open_entry("", &q_o
, &qbuf
, 0) ||
758 !rpc_api_pipe_req(cli
, PI_WINREG
, REG_OPEN_ENTRY
, &qbuf
, &rbuf
))
763 /* Unmarsall response */
765 if (!reg_io_r_open_entry("", &r_o
, &rbuf
, 0))
769 if (NT_STATUS_IS_OK(result
))
779 /****************************************************************************
781 ****************************************************************************/
782 WERROR
cli_reg_close(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
789 WERROR result
= WERR_GENERAL_FAILURE
;
791 prs_init(&qbuf
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
);
792 prs_init(&rbuf
, 0, mem_ctx
, UNMARSHALL
);
794 /* Marshall data and send request */
796 init_reg_q_close(&q_c
, hnd
);
798 if (!reg_io_q_close("", &q_c
, &qbuf
, 0) ||
799 !rpc_api_pipe_req(cli
, PI_WINREG
, REG_CLOSE
, &qbuf
, &rbuf
))
804 /* Unmarshall response */
806 if (reg_io_r_close("", &r_c
, &rbuf
, 0))