2 Unix SMB/CIFS implementation.
4 Copyright (C) Tim Potter 2000-2001,
5 Copyright (C) Andrew Tridgell 1992-1997,2000,
6 Copyright (C) Rafal Szczesniak 2002
7 Copyright (C) Jeremy Allison 2005.
8 Copyright (C) Michael Adam 2007.
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 3 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, see <http://www.gnu.org/licenses/>.
26 /** @defgroup lsa LSA - Local Security Architecture
35 * RPC client routines for the LSA RPC pipe. LSA means "local
36 * security authority", which is half of a password database.
39 /** Open a LSA policy handle
41 * @param cli Handle on an initialised SMB connection */
43 NTSTATUS
rpccli_lsa_open_policy(struct rpc_pipe_client
*cli
,
45 bool sec_qos
, uint32 des_access
,
48 prs_struct qbuf
, rbuf
;
57 /* Initialise input parameters */
60 init_lsa_sec_qos(&qos
, 2, 1, 0);
61 init_q_open_pol(&q
, '\\', 0, des_access
, &qos
);
63 init_q_open_pol(&q
, '\\', 0, des_access
, NULL
);
66 /* Marshall data and send request */
68 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_OPENPOLICY
,
73 NT_STATUS_UNSUCCESSFUL
);
75 /* Return output parameters */
79 if (NT_STATUS_IS_OK(result
)) {
86 /** Open a LSA policy handle
88 * @param cli Handle on an initialised SMB connection
91 NTSTATUS
rpccli_lsa_open_policy2(struct rpc_pipe_client
*cli
,
92 TALLOC_CTX
*mem_ctx
, bool sec_qos
,
93 uint32 des_access
, POLICY_HND
*pol
)
95 prs_struct qbuf
, rbuf
;
100 char *srv_name_slash
= talloc_asprintf(mem_ctx
, "\\\\%s", cli
->cli
->desthost
);
106 init_lsa_sec_qos(&qos
, 2, 1, 0);
107 init_q_open_pol2(&q
, srv_name_slash
, 0, des_access
, &qos
);
109 init_q_open_pol2(&q
, srv_name_slash
, 0, des_access
, NULL
);
112 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_OPENPOLICY2
,
117 NT_STATUS_UNSUCCESSFUL
);
119 /* Return output parameters */
123 if (NT_STATUS_IS_OK(result
)) {
130 /* Lookup a list of sids
132 * internal version withOUT memory allocation of the target arrays.
133 * this assumes suffciently sized arrays to store domains, names and types. */
135 static NTSTATUS
rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client
*cli
,
142 enum lsa_SidType
*types
)
144 prs_struct qbuf
, rbuf
;
148 NTSTATUS result
= NT_STATUS_OK
;
149 TALLOC_CTX
*tmp_ctx
= NULL
;
152 tmp_ctx
= talloc_new(mem_ctx
);
154 DEBUG(0, ("rpccli_lsa_lookup_sids_noalloc: out of memory!\n"));
155 result
= NT_STATUS_UNSUCCESSFUL
;
162 init_q_lookup_sids(tmp_ctx
, &q
, pol
, num_sids
, sids
, 1);
168 CLI_DO_RPC( cli
, tmp_ctx
, PI_LSARPC
, LSA_LOOKUPSIDS
,
171 lsa_io_q_lookup_sids
,
172 lsa_io_r_lookup_sids
,
173 NT_STATUS_UNSUCCESSFUL
);
175 DEBUG(10, ("LSA_LOOKUPSIDS returned '%s', mapped count = %d'\n",
176 nt_errstr(r
.status
), r
.mapped_count
));
178 if (!NT_STATUS_IS_OK(r
.status
) &&
179 !NT_STATUS_EQUAL(r
.status
, NT_STATUS_NONE_MAPPED
) &&
180 !NT_STATUS_EQUAL(r
.status
, STATUS_SOME_UNMAPPED
))
182 /* An actual error occured */
187 /* Return output parameters */
189 if (NT_STATUS_EQUAL(r
.status
, NT_STATUS_NONE_MAPPED
) ||
190 (r
.mapped_count
== 0))
192 for (i
= 0; i
< num_sids
; i
++) {
195 (types
)[i
] = SID_NAME_UNKNOWN
;
197 result
= NT_STATUS_NONE_MAPPED
;
201 for (i
= 0; i
< num_sids
; i
++) {
202 fstring name
, dom_name
;
203 uint32 dom_idx
= r
.names
.name
[i
].domain_idx
;
205 /* Translate optimised name through domain index array */
207 if (dom_idx
!= 0xffffffff) {
209 rpcstr_pull_unistr2_fstring(
210 dom_name
, &ref
.ref_dom
[dom_idx
].uni_dom_name
);
211 rpcstr_pull_unistr2_fstring(
212 name
, &r
.names
.uni_name
[i
]);
214 (names
)[i
] = talloc_strdup(mem_ctx
, name
);
215 (domains
)[i
] = talloc_strdup(mem_ctx
, dom_name
);
216 (types
)[i
] = r
.names
.name
[i
].sid_name_use
;
218 if (((names
)[i
] == NULL
) || ((domains
)[i
] == NULL
)) {
219 DEBUG(0, ("cli_lsa_lookup_sids_noalloc(): out of memory\n"));
220 result
= NT_STATUS_UNSUCCESSFUL
;
227 (types
)[i
] = SID_NAME_UNKNOWN
;
232 TALLOC_FREE(tmp_ctx
);
236 /* Lookup a list of sids
238 * do it the right way: there is a limit (of 20480 for w2k3) entries
239 * returned by this call. when the sids list contains more entries,
240 * empty lists are returned. This version of lsa_lookup_sids passes
241 * the list of sids in hunks of LOOKUP_SIDS_HUNK_SIZE to the lsa call. */
243 /* This constant defines the limit of how many sids to look up
244 * in one call (maximum). the limit from the server side is
245 * at 20480 for win2k3, but we keep it at a save 1000 for now. */
246 #define LOOKUP_SIDS_HUNK_SIZE 1000
248 NTSTATUS
rpccli_lsa_lookup_sids(struct rpc_pipe_client
*cli
,
255 enum lsa_SidType
**types
)
257 NTSTATUS result
= NT_STATUS_OK
;
259 int sids_processed
= 0;
260 const DOM_SID
*hunk_sids
= sids
;
261 char **hunk_domains
= NULL
;
262 char **hunk_names
= NULL
;
263 enum lsa_SidType
*hunk_types
= NULL
;
266 if (!((*domains
) = TALLOC_ARRAY(mem_ctx
, char *, num_sids
))) {
267 DEBUG(0, ("rpccli_lsa_lookup_sids(): out of memory\n"));
268 result
= NT_STATUS_NO_MEMORY
;
272 if (!((*names
) = TALLOC_ARRAY(mem_ctx
, char *, num_sids
))) {
273 DEBUG(0, ("rpccli_lsa_lookup_sids(): out of memory\n"));
274 result
= NT_STATUS_NO_MEMORY
;
278 if (!((*types
) = TALLOC_ARRAY(mem_ctx
, enum lsa_SidType
, num_sids
))) {
279 DEBUG(0, ("rpccli_lsa_lookup_sids(): out of memory\n"));
280 result
= NT_STATUS_NO_MEMORY
;
289 sids_left
= num_sids
;
290 hunk_domains
= *domains
;
294 while (sids_left
> 0) {
296 NTSTATUS hunk_result
= NT_STATUS_OK
;
298 hunk_num_sids
= ((sids_left
> LOOKUP_SIDS_HUNK_SIZE
)
299 ? LOOKUP_SIDS_HUNK_SIZE
302 DEBUG(10, ("rpccli_lsa_lookup_sids: processing items "
305 sids_processed
+ hunk_num_sids
- 1,
308 hunk_result
= rpccli_lsa_lookup_sids_noalloc(cli
,
317 if (!NT_STATUS_IS_OK(hunk_result
) &&
318 !NT_STATUS_EQUAL(hunk_result
, STATUS_SOME_UNMAPPED
) &&
319 !NT_STATUS_EQUAL(hunk_result
, NT_STATUS_NONE_MAPPED
))
321 /* An actual error occured */
322 result
= hunk_result
;
326 /* adapt overall result */
327 if (( NT_STATUS_IS_OK(result
) &&
328 !NT_STATUS_IS_OK(hunk_result
))
330 ( NT_STATUS_EQUAL(result
, NT_STATUS_NONE_MAPPED
) &&
331 !NT_STATUS_EQUAL(hunk_result
, NT_STATUS_NONE_MAPPED
)))
333 result
= STATUS_SOME_UNMAPPED
;
336 sids_left
-= hunk_num_sids
;
337 sids_processed
+= hunk_num_sids
; /* only used in DEBUG */
338 hunk_sids
+= hunk_num_sids
;
339 hunk_domains
+= hunk_num_sids
;
340 hunk_names
+= hunk_num_sids
;
341 hunk_types
+= hunk_num_sids
;
347 TALLOC_FREE(*domains
);
353 /** Lookup a list of names */
355 NTSTATUS
rpccli_lsa_lookup_names(struct rpc_pipe_client
*cli
,
357 POLICY_HND
*pol
, int num_names
,
359 const char ***dom_names
,
362 enum lsa_SidType
**types
)
364 prs_struct qbuf
, rbuf
;
365 LSA_Q_LOOKUP_NAMES q
;
366 LSA_R_LOOKUP_NAMES r
;
377 init_q_lookup_names(mem_ctx
, &q
, pol
, num_names
, names
, level
);
379 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_LOOKUPNAMES
,
382 lsa_io_q_lookup_names
,
383 lsa_io_r_lookup_names
,
384 NT_STATUS_UNSUCCESSFUL
);
388 if (!NT_STATUS_IS_OK(result
) && NT_STATUS_V(result
) !=
389 NT_STATUS_V(STATUS_SOME_UNMAPPED
)) {
391 /* An actual error occured */
396 /* Return output parameters */
398 if (r
.mapped_count
== 0) {
399 result
= NT_STATUS_NONE_MAPPED
;
404 if (!((*sids
= TALLOC_ARRAY(mem_ctx
, DOM_SID
, num_names
)))) {
405 DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
406 result
= NT_STATUS_NO_MEMORY
;
410 if (!((*types
= TALLOC_ARRAY(mem_ctx
, enum lsa_SidType
, num_names
)))) {
411 DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
412 result
= NT_STATUS_NO_MEMORY
;
416 if (dom_names
!= NULL
) {
417 *dom_names
= TALLOC_ARRAY(mem_ctx
, const char *, num_names
);
418 if (*dom_names
== NULL
) {
419 DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n"));
420 result
= NT_STATUS_NO_MEMORY
;
427 if (dom_names
!= NULL
) {
432 for (i
= 0; i
< num_names
; i
++) {
433 DOM_RID
*t_rids
= r
.dom_rid
;
434 uint32 dom_idx
= t_rids
[i
].rid_idx
;
435 uint32 dom_rid
= t_rids
[i
].rid
;
436 DOM_SID
*sid
= &(*sids
)[i
];
438 /* Translate optimised sid through domain index array */
440 if (dom_idx
== 0xffffffff) {
441 /* Nothing to do, this is unknown */
443 (*types
)[i
] = SID_NAME_UNKNOWN
;
447 sid_copy(sid
, &ref
.ref_dom
[dom_idx
].ref_dom
.sid
);
449 if (dom_rid
!= 0xffffffff) {
450 sid_append_rid(sid
, dom_rid
);
453 (*types
)[i
] = t_rids
[i
].type
;
455 if (dom_names
== NULL
) {
459 (*dom_names
)[i
] = rpcstr_pull_unistr2_talloc(
460 *dom_names
, &ref
.ref_dom
[dom_idx
].uni_dom_name
);
468 NTSTATUS
rpccli_lsa_query_info_policy_new(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
469 POLICY_HND
*pol
, uint16 info_class
,
472 prs_struct qbuf
, rbuf
;
480 init_q_query(&q
, pol
, info_class
);
482 CLI_DO_RPC(cli
, mem_ctx
, PI_LSARPC
, LSA_QUERYINFOPOLICY
,
487 NT_STATUS_UNSUCCESSFUL
);
491 if (!NT_STATUS_IS_OK(result
)) {
502 NTSTATUS
rpccli_lsa_query_info_policy2_new(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
503 POLICY_HND
*pol
, uint16 info_class
,
506 prs_struct qbuf
, rbuf
;
514 init_q_query2(&q
, pol
, info_class
);
516 CLI_DO_RPC(cli
, mem_ctx
, PI_LSARPC
, LSA_QUERYINFO2
,
519 lsa_io_q_query_info2
,
520 lsa_io_r_query_info2
,
521 NT_STATUS_UNSUCCESSFUL
);
525 if (!NT_STATUS_IS_OK(result
)) {
538 /** Query info policy
540 * @param domain_sid - returned remote server's domain sid */
542 NTSTATUS
rpccli_lsa_query_info_policy(struct rpc_pipe_client
*cli
,
544 POLICY_HND
*pol
, uint16 info_class
,
545 char **domain_name
, DOM_SID
**domain_sid
)
547 prs_struct qbuf
, rbuf
;
555 init_q_query(&q
, pol
, info_class
);
557 CLI_DO_RPC(cli
, mem_ctx
, PI_LSARPC
, LSA_QUERYINFOPOLICY
,
562 NT_STATUS_UNSUCCESSFUL
);
566 if (!NT_STATUS_IS_OK(result
)) {
570 /* Return output parameters */
572 switch (info_class
) {
575 if (domain_name
&& (r
.ctr
.info
.id3
.buffer_dom_name
!= 0)) {
576 *domain_name
= unistr2_to_ascii_talloc(mem_ctx
,
580 return NT_STATUS_NO_MEMORY
;
584 if (domain_sid
&& (r
.ctr
.info
.id3
.buffer_dom_sid
!= 0)) {
585 *domain_sid
= TALLOC_P(mem_ctx
, DOM_SID
);
587 return NT_STATUS_NO_MEMORY
;
589 sid_copy(*domain_sid
, &r
.ctr
.info
.id3
.dom_sid
.sid
);
596 if (domain_name
&& (r
.ctr
.info
.id5
.buffer_dom_name
!= 0)) {
597 *domain_name
= unistr2_to_ascii_talloc(mem_ctx
,
601 return NT_STATUS_NO_MEMORY
;
605 if (domain_sid
&& (r
.ctr
.info
.id5
.buffer_dom_sid
!= 0)) {
606 *domain_sid
= TALLOC_P(mem_ctx
, DOM_SID
);
608 return NT_STATUS_NO_MEMORY
;
610 sid_copy(*domain_sid
, &r
.ctr
.info
.id5
.dom_sid
.sid
);
615 DEBUG(3, ("unknown info class %d\n", info_class
));
624 /** Query info policy2
626 * @param domain_name - returned remote server's domain name
627 * @param dns_name - returned remote server's dns domain name
628 * @param forest_name - returned remote server's forest name
629 * @param domain_guid - returned remote server's domain guid
630 * @param domain_sid - returned remote server's domain sid */
632 NTSTATUS
rpccli_lsa_query_info_policy2(struct rpc_pipe_client
*cli
,
634 POLICY_HND
*pol
, uint16 info_class
,
635 char **domain_name
, char **dns_name
,
637 struct GUID
**domain_guid
,
638 DOM_SID
**domain_sid
)
640 prs_struct qbuf
, rbuf
;
643 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
645 if (info_class
!= 12)
651 init_q_query2(&q
, pol
, info_class
);
653 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_QUERYINFO2
,
656 lsa_io_q_query_info2
,
657 lsa_io_r_query_info2
,
658 NT_STATUS_UNSUCCESSFUL
);
662 if (!NT_STATUS_IS_OK(result
)) {
666 /* Return output parameters */
668 ZERO_STRUCTP(domain_guid
);
670 if (domain_name
&& r
.ctr
.info
.id12
.hdr_nb_dom_name
.buffer
) {
671 *domain_name
= unistr2_to_ascii_talloc(mem_ctx
,
675 return NT_STATUS_NO_MEMORY
;
678 if (dns_name
&& r
.ctr
.info
.id12
.hdr_dns_dom_name
.buffer
) {
679 *dns_name
= unistr2_to_ascii_talloc(mem_ctx
,
683 return NT_STATUS_NO_MEMORY
;
686 if (forest_name
&& r
.ctr
.info
.id12
.hdr_forest_name
.buffer
) {
687 *forest_name
= unistr2_to_ascii_talloc(mem_ctx
,
691 return NT_STATUS_NO_MEMORY
;
696 *domain_guid
= TALLOC_P(mem_ctx
, struct GUID
);
698 return NT_STATUS_NO_MEMORY
;
701 &r
.ctr
.info
.id12
.dom_guid
,
702 sizeof(struct GUID
));
705 if (domain_sid
&& r
.ctr
.info
.id12
.ptr_dom_sid
!= 0) {
706 *domain_sid
= TALLOC_P(mem_ctx
, DOM_SID
);
708 return NT_STATUS_NO_MEMORY
;
710 sid_copy(*domain_sid
,
711 &r
.ctr
.info
.id12
.dom_sid
.sid
);
719 NTSTATUS
rpccli_lsa_set_info_policy(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
720 POLICY_HND
*pol
, uint16 info_class
,
723 prs_struct qbuf
, rbuf
;
731 init_q_set(&q
, pol
, info_class
, ctr
);
733 CLI_DO_RPC(cli
, mem_ctx
, PI_LSARPC
, LSA_SETINFOPOLICY
,
738 NT_STATUS_UNSUCCESSFUL
);
742 if (!NT_STATUS_IS_OK(result
)) {
746 /* Return output parameters */
755 * Enumerate list of trusted domains
757 * @param cli client state (cli_state) structure of the connection
758 * @param mem_ctx memory context
759 * @param pol opened lsa policy handle
760 * @param enum_ctx enumeration context ie. index of first returned domain entry
761 * @param pref_num_domains preferred max number of entries returned in one response
762 * @param num_domains total number of trusted domains returned by response
763 * @param domain_names returned trusted domain names
764 * @param domain_sids returned trusted domain sids
766 * @return nt status code of response
769 NTSTATUS
rpccli_lsa_enum_trust_dom(struct rpc_pipe_client
*cli
,
771 POLICY_HND
*pol
, uint32
*enum_ctx
,
773 char ***domain_names
, DOM_SID
**domain_sids
)
775 prs_struct qbuf
, rbuf
;
776 LSA_Q_ENUM_TRUST_DOM in
;
777 LSA_R_ENUM_TRUST_DOM out
;
784 /* 64k is enough for about 2000 trusted domains */
786 init_q_enum_trust_dom(&in
, pol
, *enum_ctx
, 0x10000);
788 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_ENUMTRUSTDOM
,
791 lsa_io_q_enum_trust_dom
,
792 lsa_io_r_enum_trust_dom
,
793 NT_STATUS_UNSUCCESSFUL
);
796 /* check for an actual error */
798 if ( !NT_STATUS_IS_OK(out
.status
)
799 && !NT_STATUS_EQUAL(out
.status
, NT_STATUS_NO_MORE_ENTRIES
)
800 && !NT_STATUS_EQUAL(out
.status
, STATUS_MORE_ENTRIES
) )
805 /* Return output parameters */
807 *num_domains
= out
.count
;
808 *enum_ctx
= out
.enum_context
;
812 /* Allocate memory for trusted domain names and sids */
814 if ( !(*domain_names
= TALLOC_ARRAY(mem_ctx
, char *, out
.count
)) ) {
815 DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
816 return NT_STATUS_NO_MEMORY
;
819 if ( !(*domain_sids
= TALLOC_ARRAY(mem_ctx
, DOM_SID
, out
.count
)) ) {
820 DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n"));
821 return NT_STATUS_NO_MEMORY
;
824 /* Copy across names and sids */
826 for (i
= 0; i
< out
.count
; i
++) {
828 rpcstr_pull( tmp
, out
.domlist
->domains
[i
].name
.string
->buffer
,
829 sizeof(tmp
), out
.domlist
->domains
[i
].name
.length
, 0);
830 (*domain_names
)[i
] = talloc_strdup(mem_ctx
, tmp
);
832 sid_copy(&(*domain_sids
)[i
], &out
.domlist
->domains
[i
].sid
->sid
);
839 /** Enumerate privileges*/
841 NTSTATUS
rpccli_lsa_enum_privilege(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
842 POLICY_HND
*pol
, uint32
*enum_context
, uint32 pref_max_length
,
843 uint32
*count
, char ***privs_name
, uint32
**privs_high
, uint32
**privs_low
)
845 prs_struct qbuf
, rbuf
;
854 init_q_enum_privs(&q
, pol
, *enum_context
, pref_max_length
);
856 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_ENUM_PRIVS
,
861 NT_STATUS_UNSUCCESSFUL
);
865 if (!NT_STATUS_IS_OK(result
)) {
869 /* Return output parameters */
871 *enum_context
= r
.enum_context
;
875 if (!((*privs_name
= TALLOC_ARRAY(mem_ctx
, char *, r
.count
)))) {
876 DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
877 result
= NT_STATUS_UNSUCCESSFUL
;
881 if (!((*privs_high
= TALLOC_ARRAY(mem_ctx
, uint32
, r
.count
)))) {
882 DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
883 result
= NT_STATUS_UNSUCCESSFUL
;
887 if (!((*privs_low
= TALLOC_ARRAY(mem_ctx
, uint32
, r
.count
)))) {
888 DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n"));
889 result
= NT_STATUS_UNSUCCESSFUL
;
898 for (i
= 0; i
< r
.count
; i
++) {
901 rpcstr_pull_unistr2_fstring( name
, &r
.privs
[i
].name
);
903 (*privs_name
)[i
] = talloc_strdup(mem_ctx
, name
);
905 (*privs_high
)[i
] = r
.privs
[i
].luid_high
;
906 (*privs_low
)[i
] = r
.privs
[i
].luid_low
;
914 /** Get privilege name */
916 NTSTATUS
rpccli_lsa_get_dispname(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
917 POLICY_HND
*pol
, const char *name
,
918 uint16 lang_id
, uint16 lang_id_sys
,
919 fstring description
, uint16
*lang_id_desc
)
921 prs_struct qbuf
, rbuf
;
922 LSA_Q_PRIV_GET_DISPNAME q
;
923 LSA_R_PRIV_GET_DISPNAME r
;
929 init_lsa_priv_get_dispname(&q
, pol
, name
, lang_id
, lang_id_sys
);
931 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_PRIV_GET_DISPNAME
,
934 lsa_io_q_priv_get_dispname
,
935 lsa_io_r_priv_get_dispname
,
936 NT_STATUS_UNSUCCESSFUL
);
940 if (!NT_STATUS_IS_OK(result
)) {
944 /* Return output parameters */
946 rpcstr_pull_unistr2_fstring(description
, &r
.desc
);
947 *lang_id_desc
= r
.lang_id
;
954 /** Enumerate list of SIDs */
956 NTSTATUS
rpccli_lsa_enum_sids(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
957 POLICY_HND
*pol
, uint32
*enum_ctx
, uint32 pref_max_length
,
958 uint32
*num_sids
, DOM_SID
**sids
)
960 prs_struct qbuf
, rbuf
;
961 LSA_Q_ENUM_ACCOUNTS q
;
962 LSA_R_ENUM_ACCOUNTS r
;
969 init_lsa_q_enum_accounts(&q
, pol
, *enum_ctx
, pref_max_length
);
971 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_ENUM_ACCOUNTS
,
974 lsa_io_q_enum_accounts
,
975 lsa_io_r_enum_accounts
,
976 NT_STATUS_UNSUCCESSFUL
);
980 if (!NT_STATUS_IS_OK(result
)) {
984 if (r
.sids
.num_entries
==0)
987 /* Return output parameters */
989 *sids
= TALLOC_ARRAY(mem_ctx
, DOM_SID
, r
.sids
.num_entries
);
991 DEBUG(0, ("(cli_lsa_enum_sids): out of memory\n"));
992 result
= NT_STATUS_UNSUCCESSFUL
;
996 /* Copy across names and sids */
998 for (i
= 0; i
< r
.sids
.num_entries
; i
++) {
999 sid_copy(&(*sids
)[i
], &r
.sids
.sid
[i
].sid
);
1002 *num_sids
= r
.sids
.num_entries
;
1003 *enum_ctx
= r
.enum_context
;
1010 /** Create a LSA user handle
1012 * @param cli Handle on an initialised SMB connection
1014 * FIXME: The code is actually identical to open account
1015 * TODO: Check and code what the function should exactly do
1019 NTSTATUS
rpccli_lsa_create_account(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1020 POLICY_HND
*dom_pol
, DOM_SID
*sid
, uint32 desired_access
,
1021 POLICY_HND
*user_pol
)
1023 prs_struct qbuf
, rbuf
;
1024 LSA_Q_CREATEACCOUNT q
;
1025 LSA_R_CREATEACCOUNT r
;
1031 /* Initialise input parameters */
1033 init_lsa_q_create_account(&q
, dom_pol
, sid
, desired_access
);
1035 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_CREATEACCOUNT
,
1038 lsa_io_q_create_account
,
1039 lsa_io_r_create_account
,
1040 NT_STATUS_UNSUCCESSFUL
);
1042 /* Return output parameters */
1046 if (NT_STATUS_IS_OK(result
)) {
1053 /** Open a LSA user handle
1055 * @param cli Handle on an initialised SMB connection */
1057 NTSTATUS
rpccli_lsa_open_account(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1058 POLICY_HND
*dom_pol
, DOM_SID
*sid
, uint32 des_access
,
1059 POLICY_HND
*user_pol
)
1061 prs_struct qbuf
, rbuf
;
1062 LSA_Q_OPENACCOUNT q
;
1063 LSA_R_OPENACCOUNT r
;
1069 /* Initialise input parameters */
1071 init_lsa_q_open_account(&q
, dom_pol
, sid
, des_access
);
1073 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_OPENACCOUNT
,
1076 lsa_io_q_open_account
,
1077 lsa_io_r_open_account
,
1078 NT_STATUS_UNSUCCESSFUL
);
1080 /* Return output parameters */
1084 if (NT_STATUS_IS_OK(result
)) {
1091 /** Enumerate user privileges
1093 * @param cli Handle on an initialised SMB connection */
1095 NTSTATUS
rpccli_lsa_enum_privsaccount(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1096 POLICY_HND
*pol
, uint32
*count
, LUID_ATTR
**set
)
1098 prs_struct qbuf
, rbuf
;
1099 LSA_Q_ENUMPRIVSACCOUNT q
;
1100 LSA_R_ENUMPRIVSACCOUNT r
;
1107 /* Initialise input parameters */
1109 init_lsa_q_enum_privsaccount(&q
, pol
);
1111 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_ENUMPRIVSACCOUNT
,
1114 lsa_io_q_enum_privsaccount
,
1115 lsa_io_r_enum_privsaccount
,
1116 NT_STATUS_UNSUCCESSFUL
);
1118 /* Return output parameters */
1122 if (!NT_STATUS_IS_OK(result
)) {
1129 if (!((*set
= TALLOC_ARRAY(mem_ctx
, LUID_ATTR
, r
.count
)))) {
1130 DEBUG(0, ("(cli_lsa_enum_privsaccount): out of memory\n"));
1131 result
= NT_STATUS_UNSUCCESSFUL
;
1135 for (i
=0; i
<r
.count
; i
++) {
1136 (*set
)[i
].luid
.low
= r
.set
.set
[i
].luid
.low
;
1137 (*set
)[i
].luid
.high
= r
.set
.set
[i
].luid
.high
;
1138 (*set
)[i
].attr
= r
.set
.set
[i
].attr
;
1147 /** Get a privilege value given its name */
1149 NTSTATUS
rpccli_lsa_lookup_priv_value(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1150 POLICY_HND
*pol
, const char *name
, LUID
*luid
)
1152 prs_struct qbuf
, rbuf
;
1153 LSA_Q_LOOKUP_PRIV_VALUE q
;
1154 LSA_R_LOOKUP_PRIV_VALUE r
;
1160 /* Marshall data and send request */
1162 init_lsa_q_lookup_priv_value(&q
, pol
, name
);
1164 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_LOOKUPPRIVVALUE
,
1167 lsa_io_q_lookup_priv_value
,
1168 lsa_io_r_lookup_priv_value
,
1169 NT_STATUS_UNSUCCESSFUL
);
1173 if (!NT_STATUS_IS_OK(result
)) {
1177 /* Return output parameters */
1179 (*luid
).low
=r
.luid
.low
;
1180 (*luid
).high
=r
.luid
.high
;
1187 /** Query LSA security object */
1189 NTSTATUS
rpccli_lsa_query_secobj(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1190 POLICY_HND
*pol
, uint32 sec_info
,
1191 SEC_DESC_BUF
**psdb
)
1193 prs_struct qbuf
, rbuf
;
1194 LSA_Q_QUERY_SEC_OBJ q
;
1195 LSA_R_QUERY_SEC_OBJ r
;
1201 /* Marshall data and send request */
1203 init_q_query_sec_obj(&q
, pol
, sec_info
);
1205 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_QUERYSECOBJ
,
1208 lsa_io_q_query_sec_obj
,
1209 lsa_io_r_query_sec_obj
,
1210 NT_STATUS_UNSUCCESSFUL
);
1214 if (!NT_STATUS_IS_OK(result
)) {
1218 /* Return output parameters */
1229 /* Enumerate account rights This is similar to enum_privileges but
1230 takes a SID directly, avoiding the open_account call.
1233 NTSTATUS
rpccli_lsa_enum_account_rights(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1234 POLICY_HND
*pol
, DOM_SID
*sid
,
1235 uint32
*count
, char ***priv_names
)
1237 prs_struct qbuf
, rbuf
;
1238 LSA_Q_ENUM_ACCT_RIGHTS q
;
1239 LSA_R_ENUM_ACCT_RIGHTS r
;
1242 fstring
*privileges
;
1248 /* Marshall data and send request */
1249 init_q_enum_acct_rights(&q
, pol
, 2, sid
);
1251 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_ENUMACCTRIGHTS
,
1254 lsa_io_q_enum_acct_rights
,
1255 lsa_io_r_enum_acct_rights
,
1256 NT_STATUS_UNSUCCESSFUL
);
1260 if (!NT_STATUS_IS_OK(result
)) {
1270 privileges
= TALLOC_ARRAY( mem_ctx
, fstring
, *count
);
1271 names
= TALLOC_ARRAY( mem_ctx
, char *, *count
);
1273 if ((privileges
== NULL
) || (names
== NULL
)) {
1274 TALLOC_FREE(privileges
);
1276 return NT_STATUS_NO_MEMORY
;
1279 for ( i
=0; i
<*count
; i
++ ) {
1280 UNISTR4
*uni_string
= &r
.rights
->strings
[i
];
1282 if ( !uni_string
->string
)
1285 rpcstr_pull( privileges
[i
], uni_string
->string
->buffer
, sizeof(privileges
[i
]), -1, STR_TERMINATE
);
1287 /* now copy to the return array */
1288 names
[i
] = talloc_strdup( mem_ctx
, privileges
[i
] );
1291 *priv_names
= names
;
1300 /* add account rights to an account. */
1302 NTSTATUS
rpccli_lsa_add_account_rights(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1303 POLICY_HND
*pol
, DOM_SID sid
,
1304 uint32 count
, const char **privs_name
)
1306 prs_struct qbuf
, rbuf
;
1307 LSA_Q_ADD_ACCT_RIGHTS q
;
1308 LSA_R_ADD_ACCT_RIGHTS r
;
1314 /* Marshall data and send request */
1315 init_q_add_acct_rights(&q
, pol
, &sid
, count
, privs_name
);
1317 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_ADDACCTRIGHTS
,
1320 lsa_io_q_add_acct_rights
,
1321 lsa_io_r_add_acct_rights
,
1322 NT_STATUS_UNSUCCESSFUL
);
1326 if (!NT_STATUS_IS_OK(result
)) {
1335 /* remove account rights for an account. */
1337 NTSTATUS
rpccli_lsa_remove_account_rights(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1338 POLICY_HND
*pol
, DOM_SID sid
, bool removeall
,
1339 uint32 count
, const char **privs_name
)
1341 prs_struct qbuf
, rbuf
;
1342 LSA_Q_REMOVE_ACCT_RIGHTS q
;
1343 LSA_R_REMOVE_ACCT_RIGHTS r
;
1349 /* Marshall data and send request */
1350 init_q_remove_acct_rights(&q
, pol
, &sid
, removeall
?1:0, count
, privs_name
);
1352 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_REMOVEACCTRIGHTS
,
1355 lsa_io_q_remove_acct_rights
,
1356 lsa_io_r_remove_acct_rights
,
1357 NT_STATUS_UNSUCCESSFUL
);
1361 if (!NT_STATUS_IS_OK(result
)) {
1372 /** An example of how to use the routines in this file. Fetch a DOMAIN
1373 sid. Does complete cli setup / teardown anonymously. */
1375 bool fetch_domain_sid( char *domain
, char *remote_machine
, DOM_SID
*psid
)
1377 struct cli_state cli
;
1383 if(cli_initialise(&cli
) == False
) {
1384 DEBUG(0,("fetch_domain_sid: unable to initialize client connection.\n"));
1388 if(!resolve_name( remote_machine
, &cli
.dest_ip
, 0x20)) {
1389 DEBUG(0,("fetch_domain_sid: Can't resolve address for %s\n", remote_machine
));
1393 if (!cli_connect(&cli
, remote_machine
, &cli
.dest_ip
)) {
1394 DEBUG(0,("fetch_domain_sid: unable to connect to SMB server on \
1395 machine %s. Error was : %s.\n", remote_machine
, cli_errstr(&cli
) ));
1399 if (!attempt_netbios_session_request(&cli
, global_myname(), remote_machine
, &cli
.dest_ip
)) {
1400 DEBUG(0,("fetch_domain_sid: machine %s rejected the NetBIOS session request.\n",
1405 cli
.protocol
= PROTOCOL_NT1
;
1407 if (!cli_negprot(&cli
)) {
1408 DEBUG(0,("fetch_domain_sid: machine %s rejected the negotiate protocol. \
1409 Error was : %s.\n", remote_machine
, cli_errstr(&cli
) ));
1413 if (cli
.protocol
!= PROTOCOL_NT1
) {
1414 DEBUG(0,("fetch_domain_sid: machine %s didn't negotiate NT protocol.\n",
1420 * Do an anonymous session setup.
1423 if (!cli_session_setup(&cli
, "", "", 0, "", 0, "")) {
1424 DEBUG(0,("fetch_domain_sid: machine %s rejected the session setup. \
1425 Error was : %s.\n", remote_machine
, cli_errstr(&cli
) ));
1429 if (!(cli
.sec_mode
& NEGOTIATE_SECURITY_USER_LEVEL
)) {
1430 DEBUG(0,("fetch_domain_sid: machine %s isn't in user level security mode\n",
1435 if (!cli_send_tconX(&cli
, "IPC$", "IPC", "", 1)) {
1436 DEBUG(0,("fetch_domain_sid: machine %s rejected the tconX on the IPC$ share. \
1437 Error was : %s.\n", remote_machine
, cli_errstr(&cli
) ));
1441 /* Fetch domain sid */
1443 if (!cli_nt_session_open(&cli
, PI_LSARPC
)) {
1444 DEBUG(0, ("fetch_domain_sid: Error connecting to SAM pipe\n"));
1448 result
= cli_lsa_open_policy(&cli
, cli
.mem_ctx
, True
, SEC_RIGHTS_QUERY_VALUE
, &lsa_pol
);
1449 if (!NT_STATUS_IS_OK(result
)) {
1450 DEBUG(0, ("fetch_domain_sid: Error opening lsa policy handle. %s\n",
1451 nt_errstr(result
) ));
1455 result
= cli_lsa_query_info_policy(&cli
, cli
.mem_ctx
, &lsa_pol
, 5, domain
, psid
);
1456 if (!NT_STATUS_IS_OK(result
)) {
1457 DEBUG(0, ("fetch_domain_sid: Error querying lsa policy handle. %s\n",
1458 nt_errstr(result
) ));
1472 NTSTATUS
rpccli_lsa_open_trusted_domain(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1473 POLICY_HND
*pol
, DOM_SID
*dom_sid
, uint32 access_mask
,
1474 POLICY_HND
*trustdom_pol
)
1476 prs_struct qbuf
, rbuf
;
1477 LSA_Q_OPEN_TRUSTED_DOMAIN q
;
1478 LSA_R_OPEN_TRUSTED_DOMAIN r
;
1484 /* Initialise input parameters */
1486 init_lsa_q_open_trusted_domain(&q
, pol
, dom_sid
, access_mask
);
1488 /* Marshall data and send request */
1490 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_OPENTRUSTDOM
,
1493 lsa_io_q_open_trusted_domain
,
1494 lsa_io_r_open_trusted_domain
,
1495 NT_STATUS_UNSUCCESSFUL
);
1497 /* Return output parameters */
1501 if (NT_STATUS_IS_OK(result
)) {
1502 *trustdom_pol
= r
.handle
;
1508 NTSTATUS
rpccli_lsa_query_trusted_domain_info(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1511 LSA_TRUSTED_DOMAIN_INFO
**info
)
1513 prs_struct qbuf
, rbuf
;
1514 LSA_Q_QUERY_TRUSTED_DOMAIN_INFO q
;
1515 LSA_R_QUERY_TRUSTED_DOMAIN_INFO r
;
1516 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1521 /* Marshall data and send request */
1523 init_q_query_trusted_domain_info(&q
, pol
, info_class
);
1525 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_QUERYTRUSTDOMINFO
,
1528 lsa_io_q_query_trusted_domain_info
,
1529 lsa_io_r_query_trusted_domain_info
,
1530 NT_STATUS_UNSUCCESSFUL
);
1534 if (!NT_STATUS_IS_OK(result
)) {
1544 NTSTATUS
rpccli_lsa_open_trusted_domain_by_name(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1545 POLICY_HND
*pol
, const char *name
, uint32 access_mask
,
1546 POLICY_HND
*trustdom_pol
)
1548 prs_struct qbuf
, rbuf
;
1549 LSA_Q_OPEN_TRUSTED_DOMAIN_BY_NAME q
;
1550 LSA_R_OPEN_TRUSTED_DOMAIN_BY_NAME r
;
1556 /* Initialise input parameters */
1558 init_lsa_q_open_trusted_domain_by_name(&q
, pol
, name
, access_mask
);
1560 /* Marshall data and send request */
1562 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_OPENTRUSTDOMBYNAME
,
1565 lsa_io_q_open_trusted_domain_by_name
,
1566 lsa_io_r_open_trusted_domain_by_name
,
1567 NT_STATUS_UNSUCCESSFUL
);
1569 /* Return output parameters */
1573 if (NT_STATUS_IS_OK(result
)) {
1574 *trustdom_pol
= r
.handle
;
1581 NTSTATUS
rpccli_lsa_query_trusted_domain_info_by_sid(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1583 uint16 info_class
, DOM_SID
*dom_sid
,
1584 LSA_TRUSTED_DOMAIN_INFO
**info
)
1586 prs_struct qbuf
, rbuf
;
1587 LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_SID q
;
1588 LSA_R_QUERY_TRUSTED_DOMAIN_INFO r
;
1589 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1594 /* Marshall data and send request */
1596 init_q_query_trusted_domain_info_by_sid(&q
, pol
, info_class
, dom_sid
);
1598 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_QUERYTRUSTDOMINFOBYSID
,
1601 lsa_io_q_query_trusted_domain_info_by_sid
,
1602 lsa_io_r_query_trusted_domain_info
,
1603 NT_STATUS_UNSUCCESSFUL
);
1607 if (!NT_STATUS_IS_OK(result
)) {
1618 NTSTATUS
rpccli_lsa_query_trusted_domain_info_by_name(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1620 uint16 info_class
, const char *domain_name
,
1621 LSA_TRUSTED_DOMAIN_INFO
**info
)
1623 prs_struct qbuf
, rbuf
;
1624 LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_NAME q
;
1625 LSA_R_QUERY_TRUSTED_DOMAIN_INFO r
;
1626 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1631 /* Marshall data and send request */
1633 init_q_query_trusted_domain_info_by_name(&q
, pol
, info_class
, domain_name
);
1635 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_QUERYTRUSTDOMINFOBYNAME
,
1638 lsa_io_q_query_trusted_domain_info_by_name
,
1639 lsa_io_r_query_trusted_domain_info
,
1640 NT_STATUS_UNSUCCESSFUL
);
1644 if (!NT_STATUS_IS_OK(result
)) {
1655 NTSTATUS
cli_lsa_query_domain_info_policy(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
1657 uint16 info_class
, LSA_DOM_INFO_UNION
**info
)
1659 prs_struct qbuf
, rbuf
;
1660 LSA_Q_QUERY_DOM_INFO_POLICY q
;
1661 LSA_R_QUERY_DOM_INFO_POLICY r
;
1662 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1667 /* Marshall data and send request */
1669 init_q_query_dom_info(&q
, pol
, info_class
);
1671 CLI_DO_RPC( cli
, mem_ctx
, PI_LSARPC
, LSA_QUERYDOMINFOPOL
,
1674 lsa_io_q_query_dom_info
,
1675 lsa_io_r_query_dom_info
,
1676 NT_STATUS_UNSUCCESSFUL
);
1680 if (!NT_STATUS_IS_OK(result
)) {