2 * Unix SMB/CIFS implementation.
3 * MS-RPC client library implementation (LSA pipe)
4 * Copyright (C) Chris Nicholls 2005.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "libsmb_internal.h"
24 int cac_LsaOpenPolicy(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaOpenPolicy
*op
) {
26 POLICY_HND
*policy
= NULL
;
27 struct rpc_pipe_client
*pipe_hnd
= NULL
;
32 if(!hnd
->_internal
.ctx
) {
33 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
38 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
44 srv
= cac_GetServer(hnd
);
46 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
50 /*see if there is already an active session on this pipe, if not then open one*/
51 if(!hnd
->_internal
.pipes
[PI_LSARPC
]) {
52 pipe_hnd
= cli_rpc_pipe_open_noauth(&(srv
->cli
), PI_LSARPC
, &(hnd
->status
));
55 hnd
->status
= NT_STATUS_UNSUCCESSFUL
;
59 hnd
->_internal
.pipes
[PI_LSARPC
] = True
;
62 policy
= SMB_MALLOC_P(POLICY_HND
);
65 hnd
->status
= NT_STATUS_NO_MEMORY
;
69 /*need to make sure that our nt status is good otherwise check might fail below*/
70 hnd
->status
= NT_STATUS_OK
;
72 if(hnd
->_internal
.srv_level
>= SRV_WIN_2K
) {
74 /*try using open_policy2, if this fails try again in next block using open_policy, if that works then adjust hnd->_internal.srv_level*/
76 /*we shouldn't need to modify the access mask to make it work here*/
77 hnd
->status
= rpccli_lsa_open_policy2(pipe_hnd
, mem_ctx
, op
->in
.security_qos
, op
->in
.access
, policy
);
81 if(hnd
->_internal
.srv_level
< SRV_WIN_2K
|| !NT_STATUS_IS_OK(hnd
->status
)) {
82 hnd
->status
= rpccli_lsa_open_policy(pipe_hnd
, mem_ctx
, op
->in
.security_qos
, op
->in
.access
, policy
);
84 if(hnd
->_internal
.srv_level
> SRV_WIN_NT4
&& NT_STATUS_IS_OK(hnd
->status
)) {
85 /*change the server level to 1*/
86 hnd
->_internal
.srv_level
= SRV_WIN_NT4
;
91 if(!NT_STATUS_IS_OK(hnd
->status
)) {
101 int cac_LsaClosePolicy(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*pol
) {
103 struct rpc_pipe_client
*pipe_hnd
= NULL
;
109 return CAC_SUCCESS
; /*if the policy handle doesnt exist then it's already closed*/
111 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
112 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
116 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
118 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
123 hnd
->status
= rpccli_lsa_close(pipe_hnd
, mem_ctx
, pol
);
125 if(!NT_STATUS_IS_OK(hnd
->status
))
133 int cac_LsaGetNamesFromSids(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaGetNamesFromSids
*op
) {
134 struct rpc_pipe_client
*pipe_hnd
= NULL
;
140 /*buffers for outputs*/
141 char **domains
= NULL
;
143 uint32
*types
= NULL
;
145 CacSidInfo
*sids_out
= NULL
;
146 DOM_SID
*unknown_out
= NULL
;
157 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
158 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
162 if(!mem_ctx
|| !op
|| !op
->in
.pol
|| !op
->in
.sids
) {
163 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
167 num_sids
= op
->in
.num_sids
;
169 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
171 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
177 /*now actually lookup the names*/
178 hnd
->status
= rpccli_lsa_lookup_sids(pipe_hnd
, mem_ctx
, op
->in
.pol
, op
->in
.num_sids
,
179 op
->in
.sids
, &domains
, &names
, &types
);
181 if(NT_STATUS_IS_OK(hnd
->status
)) {
182 /*this is the easy part, just make the out.sids array*/
183 sids_out
= TALLOC_ARRAY(mem_ctx
, CacSidInfo
, num_sids
);
186 hnd
->status
= NT_STATUS_NO_MEMORY
;
190 for(i
= 0; i
< num_sids
; i
++) {
191 sids_out
[i
].sid
= op
->in
.sids
[i
];
192 sids_out
[i
].name
= names
[i
];
193 sids_out
[i
].domain
= domains
[i
];
196 result
= CAC_SUCCESS
;
198 else if(NT_STATUS_V(hnd
->status
) == NT_STATUS_V(STATUS_SOME_UNMAPPED
)) {
199 /*first find out how many couldn't be looked up*/
201 for(i
= 0; i
< num_sids
; i
++) {
202 if(names
[i
] == NULL
) {
207 if( num_unknown
>= num_sids
) {
208 hnd
->status
= NT_STATUS_UNSUCCESSFUL
;
212 sids_out
= TALLOC_ARRAY(mem_ctx
, CacSidInfo
, (num_sids
- num_unknown
));
215 hnd
->status
= NT_STATUS_NO_MEMORY
;
219 unknown_out
= TALLOC_ARRAY(mem_ctx
, DOM_SID
, num_unknown
);
222 hnd
->status
= NT_STATUS_NO_MEMORY
;
226 found_idx
= unknown_idx
= 0;
228 /*now we can actually do the real work*/
229 for(i
= 0; i
< num_sids
; i
++) {
230 if(names
[i
] != NULL
) {
231 sids_out
[found_idx
].sid
= op
->in
.sids
[i
];
232 sids_out
[found_idx
].name
= names
[i
];
233 sids_out
[found_idx
].domain
= domains
[i
];
237 else { /*then this one didnt work out*/
238 unknown_out
[unknown_idx
] = op
->in
.sids
[i
];
244 result
= CAC_PARTIAL_SUCCESS
;
246 else { /*then it failed for some reason*/
250 op
->out
.num_found
= num_sids
- num_unknown
;
251 op
->out
.sids
= sids_out
;
252 op
->out
.unknown
= unknown_out
;
258 int cac_LsaGetSidsFromNames(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaGetSidsFromNames
*op
) {
259 struct rpc_pipe_client
*pipe_hnd
= NULL
;
264 /*buffers for outputs*/
265 DOM_SID
*sids
= NULL
;
266 uint32
*types
= NULL
;
268 CacSidInfo
*sids_out
= NULL
;
269 char **unknown_out
= NULL
;
280 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
281 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
285 if(!mem_ctx
|| !op
|| !op
->in
.pol
|| !op
->in
.names
) {
286 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
290 num_names
= op
->in
.num_names
;
292 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
294 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
299 /*now actually lookup the names*/
300 hnd
->status
= rpccli_lsa_lookup_names( pipe_hnd
, mem_ctx
, op
->in
.pol
, num_names
,
301 (const char **)op
->in
.names
, &sids
, &types
);
303 if(NT_STATUS_IS_OK(hnd
->status
)) {
304 /*this is the easy part, just make the out.sids array*/
305 sids_out
= TALLOC_ARRAY(mem_ctx
, CacSidInfo
, num_names
);
308 hnd
->status
= NT_STATUS_NO_MEMORY
;
312 for(i
= 0; i
< num_names
; i
++) {
313 sids_out
[i
].sid
= sids
[i
];
314 sids_out
[i
].name
= talloc_strdup(mem_ctx
, op
->in
.names
[i
]);
315 sids_out
[i
].domain
= NULL
;
318 result
= CAC_SUCCESS
;
320 else if(NT_STATUS_V(hnd
->status
) == NT_STATUS_V(STATUS_SOME_UNMAPPED
)) {
321 /*first find out how many couldn't be looked up*/
323 for(i
= 0; i
< num_names
; i
++) {
324 if(types
[i
] == SID_NAME_UNKNOWN
) {
329 if( num_unknown
>= num_names
) {
330 hnd
->status
= NT_STATUS_UNSUCCESSFUL
;
334 sids_out
= TALLOC_ARRAY(mem_ctx
, CacSidInfo
, (num_names
- num_unknown
));
337 hnd
->status
= NT_STATUS_NO_MEMORY
;
341 unknown_out
= TALLOC_ARRAY(mem_ctx
, char *, num_unknown
);
344 hnd
->status
= NT_STATUS_NO_MEMORY
;
348 unknown_idx
= found_idx
= 0;
350 /*now we can actually do the real work*/
351 for(i
= 0; i
< num_names
; i
++) {
352 if(types
[i
] != SID_NAME_UNKNOWN
) {
353 sids_out
[found_idx
].sid
= sids
[i
];
354 sids_out
[found_idx
].name
= talloc_strdup(mem_ctx
, op
->in
.names
[i
]);
355 sids_out
[found_idx
].domain
= NULL
;
359 else { /*then this one didnt work out*/
360 unknown_out
[unknown_idx
] = talloc_strdup(mem_ctx
, op
->in
.names
[i
]);
366 result
= CAC_PARTIAL_SUCCESS
;
368 else { /*then it failed for some reason*/
372 op
->out
.num_found
= num_names
- num_unknown
;
373 op
->out
.sids
= sids_out
;
374 op
->out
.unknown
= unknown_out
;
380 int cac_LsaFetchSid(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaFetchSid
*op
) {
381 struct rpc_pipe_client
*pipe_hnd
= NULL
;
387 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
] ) {
388 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
392 if(!mem_ctx
|| !op
|| !op
->in
.pol
) {
393 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
397 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
399 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
403 op
->out
.local_sid
= NULL
;
404 op
->out
.domain_sid
= NULL
;
406 if( (op
->in
.info_class
& CAC_LOCAL_INFO
) == CAC_LOCAL_INFO
) {
407 DOM_SID
*local_sid
= NULL
;
408 char *dom_name
= NULL
;
410 hnd
->status
= rpccli_lsa_query_info_policy( pipe_hnd
, mem_ctx
, op
->in
.pol
, CAC_LOCAL_INFO
, &dom_name
, &local_sid
);
412 if(!NT_STATUS_IS_OK(hnd
->status
)) {
413 result
= CAC_FAILURE
;
417 op
->out
.local_sid
= talloc(mem_ctx
, CacSidInfo
);
418 if(!op
->out
.local_sid
) {
419 hnd
->status
= NT_STATUS_NO_MEMORY
;
420 result
= CAC_FAILURE
;
424 op
->out
.local_sid
->domain
= dom_name
;
426 sid_copy(&op
->out
.local_sid
->sid
, local_sid
);
427 talloc_free(local_sid
);
432 if( (op
->in
.info_class
& CAC_DOMAIN_INFO
) == CAC_DOMAIN_INFO
) {
436 hnd
->status
= rpccli_lsa_query_info_policy( pipe_hnd
, mem_ctx
, op
->in
.pol
, CAC_DOMAIN_INFO
, &dom_name
, &domain_sid
);
437 if(!NT_STATUS_IS_OK(hnd
->status
)) {
438 /*if we succeeded above, report partial success*/
439 result
= (result
== CAC_SUCCESS
) ? CAC_PARTIAL_SUCCESS
: CAC_FAILURE
;
442 else if(result
== CAC_FAILURE
) {
443 /*if we failed above but succeded here then report partial success*/
444 result
= CAC_PARTIAL_SUCCESS
;
447 op
->out
.domain_sid
= talloc(mem_ctx
, CacSidInfo
);
448 if(!op
->out
.domain_sid
) {
449 hnd
->status
= NT_STATUS_NO_MEMORY
;
450 result
= CAC_FAILURE
;
454 op
->out
.domain_sid
->domain
= dom_name
;
455 sid_copy(&op
->out
.domain_sid
->sid
, domain_sid
);
456 talloc_free(domain_sid
);
463 int cac_LsaQueryInfoPolicy(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaQueryInfoPolicy
*op
) {
464 struct rpc_pipe_client
*pipe_hnd
= NULL
;
466 char *domain_name
= NULL
;
467 char *dns_name
= NULL
;
468 char *forest_name
= NULL
;
469 struct uuid
*domain_guid
= NULL
;
470 DOM_SID
*domain_sid
= NULL
;
475 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
476 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
481 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
485 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
487 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
491 /*only works if info_class parm is 12*/
492 hnd
->status
= rpccli_lsa_query_info_policy2(pipe_hnd
, mem_ctx
, op
->in
.pol
, 12,
493 &domain_name
, &dns_name
, &forest_name
, &domain_guid
, &domain_sid
);
495 if(!NT_STATUS_IS_OK(hnd
->status
)) {
499 op
->out
.domain_name
= domain_name
;
500 op
->out
.dns_name
= dns_name
;
501 op
->out
.forest_name
= forest_name
;
502 op
->out
.domain_guid
= domain_guid
;
503 op
->out
.domain_sid
= domain_sid
;
508 int cac_LsaEnumSids(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaEnumSids
*op
) {
509 struct rpc_pipe_client
*pipe_hnd
= NULL
;
517 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
518 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
522 if(!op
|| !op
->in
.pol
) {
523 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
526 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
528 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
532 hnd
->status
= rpccli_lsa_enum_sids(pipe_hnd
, mem_ctx
, op
->in
.pol
, &(op
->out
.resume_idx
), op
->in
.pref_max_sids
, &num_sids
, &sids
);
534 if(!NT_STATUS_IS_OK(hnd
->status
)) {
538 op
->out
.num_sids
= num_sids
;
545 int cac_LsaEnumAccountRights(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaEnumAccountRights
*op
) {
546 struct rpc_pipe_client
*pipe_hnd
= NULL
;
554 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
555 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
560 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
564 if(!op
->in
.name
&& !op
->in
.sid
) {
565 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
569 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
571 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
575 if(op
->in
.name
&& !op
->in
.sid
) {
576 DOM_SID
*user_sid
= NULL
;
580 hnd
->status
= rpccli_lsa_lookup_names( pipe_hnd
, mem_ctx
, op
->in
.pol
, 1, (const char **)&(op
->in
.name
), &user_sid
, &type
);
582 if(!NT_STATUS_IS_OK(hnd
->status
))
585 op
->in
.sid
= user_sid
;
588 hnd
->status
= rpccli_lsa_enum_account_rights( pipe_hnd
, mem_ctx
, op
->in
.pol
, op
->in
.sid
,
591 if(!NT_STATUS_IS_OK(hnd
->status
)) {
595 op
->out
.num_privs
= count
;
596 op
->out
.priv_names
= privs
;
601 int cac_LsaEnumTrustedDomains(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaEnumTrustedDomains
*op
) {
602 struct rpc_pipe_client
*pipe_hnd
;
606 DOM_SID
*domain_sids
;
611 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
612 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
617 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
621 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
623 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
627 hnd
->status
= rpccli_lsa_enum_trust_dom( pipe_hnd
, mem_ctx
, op
->in
.pol
, &(op
->out
.resume_idx
), &num_domains
, &domain_names
, &domain_sids
);
629 if(!NT_STATUS_IS_OK(hnd
->status
)) {
633 op
->out
.num_domains
= num_domains
;
634 op
->out
.domain_names
= domain_names
;
635 op
->out
.domain_sids
= domain_sids
;
640 int cac_LsaOpenTrustedDomain(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaOpenTrustedDomain
*op
) {
641 struct rpc_pipe_client
*pipe_hnd
= NULL
;
643 POLICY_HND
*dom_pol
= NULL
;
648 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
649 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
653 if(!op
->in
.pol
|| !op
->in
.access
|| !op
->in
.domain_sid
) {
654 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
658 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
660 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
664 dom_pol
= talloc(mem_ctx
, POLICY_HND
);
666 hnd
->status
= NT_STATUS_NO_MEMORY
;
671 hnd
->status
= rpccli_lsa_open_trusted_domain( pipe_hnd
, mem_ctx
, op
->in
.pol
, op
->in
.domain_sid
, op
->in
.access
, dom_pol
);
673 if(!NT_STATUS_IS_OK(hnd
->status
)) {
677 op
->out
.domain_pol
= dom_pol
;
682 int cac_LsaQueryTrustedDomainInfo(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaQueryTrustedDomainInfo
*op
) {
683 struct rpc_pipe_client
*pipe_hnd
= NULL
;
685 LSA_TRUSTED_DOMAIN_INFO
*dom_info
;
690 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
691 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
695 if(!op
->in
.pol
|| !op
->in
.info_class
) {
696 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
700 if(!op
->in
.domain_sid
&& !op
->in
.domain_name
) {
701 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
705 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
707 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
711 if(op
->in
.domain_sid
) {
712 hnd
->status
= rpccli_lsa_query_trusted_domain_info_by_sid( pipe_hnd
, mem_ctx
, op
->in
.pol
, op
->in
.info_class
, op
->in
.domain_sid
, &dom_info
);
714 else if(op
->in
.domain_name
) {
715 hnd
->status
= rpccli_lsa_query_trusted_domain_info_by_name( pipe_hnd
, mem_ctx
, op
->in
.pol
, op
->in
.info_class
, op
->in
.domain_name
, &dom_info
);
718 if(!NT_STATUS_IS_OK(hnd
->status
)) {
722 op
->out
.info
= dom_info
;
728 int cac_LsaEnumPrivileges(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaEnumPrivileges
*op
) {
729 struct rpc_pipe_client
*pipe_hnd
= NULL
;
740 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
741 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
745 if(!op
|| !op
->in
.pol
) {
746 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
750 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
752 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
756 hnd
->status
= rpccli_lsa_enum_privilege(pipe_hnd
, mem_ctx
, op
->in
.pol
, &(op
->out
.resume_idx
), op
->in
.pref_max_privs
,
757 &num_privs
, &priv_names
, &high_bits
, &low_bits
);
759 if(!NT_STATUS_IS_OK(hnd
->status
)) {
763 op
->out
.num_privs
= num_privs
;
764 op
->out
.priv_names
= priv_names
;
765 op
->out
.high_bits
= high_bits
;
766 op
->out
.low_bits
= low_bits
;
771 int cac_LsaOpenAccount(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaOpenAccount
*op
) {
772 struct rpc_pipe_client
*pipe_hnd
= NULL
;
774 POLICY_HND
*user_pol
= NULL
;
780 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
781 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
785 if(!op
|| !op
->in
.pol
) {
786 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
790 if(!op
->in
.sid
&& !op
->in
.name
) {
791 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
796 /*look up the user's SID if we have to*/
797 if(op
->in
.name
&& !op
->in
.sid
) {
798 DOM_SID
*user_sid
= NULL
;
802 hnd
->status
= rpccli_lsa_lookup_names( pipe_hnd
, mem_ctx
, op
->in
.pol
, 1, (const char **)&(op
->in
.name
), &user_sid
, &type
);
804 if(!NT_STATUS_IS_OK(hnd
->status
))
807 op
->in
.sid
= user_sid
;
810 user_pol
= talloc(mem_ctx
, POLICY_HND
);
812 hnd
->status
= NT_STATUS_NO_MEMORY
;
816 hnd
->status
= rpccli_lsa_open_account(pipe_hnd
, mem_ctx
, op
->in
.pol
, op
->in
.sid
, op
->in
.access
, user_pol
);
818 if(!NT_STATUS_IS_OK(hnd
->status
)) {
819 talloc_free(user_pol
);
823 op
->out
.user
= user_pol
;
829 int cac_LsaAddPrivileges(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaAddPrivileges
*op
) {
830 struct rpc_pipe_client
*pipe_hnd
= NULL
;
832 DOM_SID
*user_sid
= NULL
;
839 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
840 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
844 if(!op
|| !op
->in
.pol
|| !op
->in
.priv_names
) {
845 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
849 if(!op
->in
.sid
&& !op
->in
.name
) {
850 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
854 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
856 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
860 if(op
->in
.name
&& !op
->in
.sid
) {
862 hnd
->status
= rpccli_lsa_lookup_names( pipe_hnd
, mem_ctx
, op
->in
.pol
, 1, (const char **)&(op
->in
.name
), &user_sid
, &type
);
864 if(!NT_STATUS_IS_OK(hnd
->status
))
867 op
->in
.sid
= user_sid
;
870 hnd
->status
= rpccli_lsa_add_account_rights( pipe_hnd
, mem_ctx
, op
->in
.pol
, *(op
->in
.sid
), op
->in
.num_privs
, (const char **)op
->in
.priv_names
);
872 if(!NT_STATUS_IS_OK(hnd
->status
)) {
879 int cac_LsaRemovePrivileges(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaRemovePrivileges
*op
) {
880 struct rpc_pipe_client
*pipe_hnd
= NULL
;
882 DOM_SID
*user_sid
= NULL
;
889 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
890 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
894 if(!op
|| !op
->in
.pol
|| !op
->in
.priv_names
) {
895 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
899 if(!op
->in
.sid
&& !op
->in
.name
) {
900 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
904 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
906 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
910 if(op
->in
.name
&& !op
->in
.sid
) {
912 hnd
->status
= rpccli_lsa_lookup_names( pipe_hnd
, mem_ctx
, op
->in
.pol
, 1, (const char **)&(op
->in
.name
), &user_sid
, &type
);
914 if(!NT_STATUS_IS_OK(hnd
->status
))
917 op
->in
.sid
= user_sid
;
920 hnd
->status
= rpccli_lsa_remove_account_rights( pipe_hnd
, mem_ctx
, op
->in
.pol
, *(op
->in
.sid
), False
, op
->in
.num_privs
, (const char **)op
->in
.priv_names
);
922 if(!NT_STATUS_IS_OK(hnd
->status
)) {
929 int cac_LsaClearPrivileges(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaClearPrivileges
*op
) {
930 struct rpc_pipe_client
*pipe_hnd
= NULL
;
932 DOM_SID
*user_sid
= NULL
;
939 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
940 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
944 if(!op
|| !op
->in
.pol
) {
945 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
949 if(!op
->in
.sid
&& !op
->in
.name
) {
950 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
954 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
956 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
960 if(op
->in
.name
&& !op
->in
.sid
) {
962 hnd
->status
= rpccli_lsa_lookup_names( pipe_hnd
, mem_ctx
, op
->in
.pol
, 1, (const char **)&(op
->in
.name
), &user_sid
, &type
);
964 if(!NT_STATUS_IS_OK(hnd
->status
))
967 op
->in
.sid
= user_sid
;
970 hnd
->status
= rpccli_lsa_remove_account_rights( pipe_hnd
, mem_ctx
, op
->in
.pol
, *(op
->in
.sid
), True
, 0, NULL
);
972 if(!NT_STATUS_IS_OK(hnd
->status
)) {
979 int cac_LsaSetPrivileges(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaAddPrivileges
*op
) {
980 struct rpc_pipe_client
*pipe_hnd
= NULL
;
982 DOM_SID
*user_sid
= NULL
;
989 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
990 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
994 if(!op
|| !op
->in
.pol
|| !op
->in
.priv_names
) {
995 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
999 if(!op
->in
.sid
&& !op
->in
.name
) {
1000 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1004 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
1009 if(op
->in
.name
&& !op
->in
.sid
) {
1011 hnd
->status
= rpccli_lsa_lookup_names( pipe_hnd
, mem_ctx
, op
->in
.pol
, 1, (const char **)&(op
->in
.name
), &user_sid
, &type
);
1013 if(!NT_STATUS_IS_OK(hnd
->status
))
1016 op
->in
.sid
= user_sid
;
1019 /*first remove all privileges*/
1020 hnd
->status
= rpccli_lsa_remove_account_rights( pipe_hnd
, mem_ctx
, op
->in
.pol
, *(op
->in
.sid
), True
, 0, NULL
);
1022 if(!NT_STATUS_IS_OK(hnd
->status
)) {
1026 hnd
->status
= rpccli_lsa_add_account_rights( pipe_hnd
, mem_ctx
, op
->in
.pol
, *(op
->in
.sid
), op
->in
.num_privs
, (const char **)op
->in
.priv_names
);
1028 if(!NT_STATUS_IS_OK(hnd
->status
)) {
1035 int cac_LsaGetSecurityObject(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaGetSecurityObject
*op
) {
1036 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1038 /*this is taken from rpcclient/cmd_lsarpc.c*/
1039 uint16 info_level
= 4;
1041 SEC_DESC_BUF
*sec_out
= NULL
;
1047 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
1048 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1052 if(!op
|| !op
->in
.pol
) {
1053 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1057 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
1059 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1063 hnd
->status
= rpccli_lsa_query_secobj( pipe_hnd
, mem_ctx
, op
->in
.pol
, info_level
, &sec_out
);
1065 if(!NT_STATUS_IS_OK(hnd
->status
))
1068 op
->out
.sec
= sec_out
;