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 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
64 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
68 policy
= TALLOC_P(mem_ctx
, POLICY_HND
);
71 hnd
->status
= NT_STATUS_NO_MEMORY
;
75 /*need to make sure that our nt status is good otherwise check might fail below*/
76 hnd
->status
= NT_STATUS_OK
;
78 if(hnd
->_internal
.srv_level
>= SRV_WIN_2K
) {
80 /*try using open_policy2, if this fails try again in next block using open_policy, if that works then adjust hnd->_internal.srv_level*/
82 /*we shouldn't need to modify the access mask to make it work here*/
83 hnd
->status
= rpccli_lsa_open_policy2(pipe_hnd
, mem_ctx
, op
->in
.security_qos
, op
->in
.access
, policy
);
87 if(hnd
->_internal
.srv_level
< SRV_WIN_2K
|| !NT_STATUS_IS_OK(hnd
->status
)) {
88 hnd
->status
= rpccli_lsa_open_policy(pipe_hnd
, mem_ctx
, op
->in
.security_qos
, op
->in
.access
, policy
);
90 if(hnd
->_internal
.srv_level
> SRV_WIN_NT4
&& NT_STATUS_IS_OK(hnd
->status
)) {
91 /*change the server level to 1*/
92 hnd
->_internal
.srv_level
= SRV_WIN_NT4
;
97 if(!NT_STATUS_IS_OK(hnd
->status
)) {
101 op
->out
.pol
= policy
;
106 int cac_LsaClosePolicy(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*pol
) {
108 struct rpc_pipe_client
*pipe_hnd
= NULL
;
114 return CAC_SUCCESS
; /*if the policy handle doesnt exist then it's already closed*/
116 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
117 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
121 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
123 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
127 hnd
->status
= rpccli_lsa_close(pipe_hnd
, mem_ctx
, pol
);
131 if(!NT_STATUS_IS_OK(hnd
->status
))
137 int cac_LsaGetNamesFromSids(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaGetNamesFromSids
*op
) {
138 struct rpc_pipe_client
*pipe_hnd
= NULL
;
144 /*buffers for outputs*/
145 char **domains
= NULL
;
147 uint32
*types
= NULL
;
149 CacSidInfo
*sids_out
= NULL
;
150 DOM_SID
*unknown_out
= NULL
;
161 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
162 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
166 if(!mem_ctx
|| !op
|| !op
->in
.pol
|| !op
->in
.sids
) {
167 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
171 num_sids
= op
->in
.num_sids
;
173 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
175 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
181 /*now actually lookup the names*/
182 hnd
->status
= rpccli_lsa_lookup_sids(pipe_hnd
, mem_ctx
, op
->in
.pol
, op
->in
.num_sids
,
183 op
->in
.sids
, &domains
, &names
, &types
);
185 if(NT_STATUS_IS_OK(hnd
->status
)) {
186 /*this is the easy part, just make the out.sids array*/
187 sids_out
= TALLOC_ARRAY(mem_ctx
, CacSidInfo
, num_sids
);
190 hnd
->status
= NT_STATUS_NO_MEMORY
;
194 for(i
= 0; i
< num_sids
; i
++) {
195 sids_out
[i
].sid
= op
->in
.sids
[i
];
196 sids_out
[i
].name
= names
[i
];
197 sids_out
[i
].domain
= domains
[i
];
200 result
= CAC_SUCCESS
;
202 else if(NT_STATUS_V(hnd
->status
) == NT_STATUS_V(STATUS_SOME_UNMAPPED
)) {
203 /*first find out how many couldn't be looked up*/
205 for(i
= 0; i
< num_sids
; i
++) {
206 if(names
[i
] == NULL
) {
211 if( num_unknown
>= num_sids
) {
212 hnd
->status
= NT_STATUS_UNSUCCESSFUL
;
216 sids_out
= TALLOC_ARRAY(mem_ctx
, CacSidInfo
, (num_sids
- num_unknown
));
219 hnd
->status
= NT_STATUS_NO_MEMORY
;
223 unknown_out
= TALLOC_ARRAY(mem_ctx
, DOM_SID
, num_unknown
);
226 hnd
->status
= NT_STATUS_NO_MEMORY
;
230 found_idx
= unknown_idx
= 0;
232 /*now we can actually do the real work*/
233 for(i
= 0; i
< num_sids
; i
++) {
234 if(names
[i
] != NULL
) {
235 sids_out
[found_idx
].sid
= op
->in
.sids
[i
];
236 sids_out
[found_idx
].name
= names
[i
];
237 sids_out
[found_idx
].domain
= domains
[i
];
241 else { /*then this one didnt work out*/
242 unknown_out
[unknown_idx
] = op
->in
.sids
[i
];
248 result
= CAC_PARTIAL_SUCCESS
;
250 else { /*then it failed for some reason*/
254 op
->out
.num_found
= num_sids
- num_unknown
;
255 op
->out
.sids
= sids_out
;
256 op
->out
.unknown
= unknown_out
;
262 int cac_LsaGetSidsFromNames(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaGetSidsFromNames
*op
) {
263 struct rpc_pipe_client
*pipe_hnd
= NULL
;
268 /*buffers for outputs*/
269 DOM_SID
*sids
= NULL
;
270 uint32
*types
= NULL
;
272 CacSidInfo
*sids_out
= NULL
;
273 char **unknown_out
= NULL
;
284 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
285 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
289 if(!mem_ctx
|| !op
|| !op
->in
.pol
|| !op
->in
.names
) {
290 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
294 num_names
= op
->in
.num_names
;
296 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
298 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
303 /*now actually lookup the names*/
304 hnd
->status
= rpccli_lsa_lookup_names( pipe_hnd
, mem_ctx
, op
->in
.pol
, num_names
,
305 (const char **)op
->in
.names
, NULL
, &sids
, &types
);
307 if(NT_STATUS_IS_OK(hnd
->status
)) {
308 /*this is the easy part, just make the out.sids array*/
309 sids_out
= TALLOC_ARRAY(mem_ctx
, CacSidInfo
, num_names
);
312 hnd
->status
= NT_STATUS_NO_MEMORY
;
316 for(i
= 0; i
< num_names
; i
++) {
317 sids_out
[i
].sid
= sids
[i
];
318 sids_out
[i
].name
= talloc_strdup(mem_ctx
, op
->in
.names
[i
]);
319 sids_out
[i
].domain
= NULL
;
322 result
= CAC_SUCCESS
;
324 else if(NT_STATUS_V(hnd
->status
) == NT_STATUS_V(STATUS_SOME_UNMAPPED
)) {
325 /*first find out how many couldn't be looked up*/
327 for(i
= 0; i
< num_names
; i
++) {
328 if(types
[i
] == SID_NAME_UNKNOWN
) {
333 if( num_unknown
>= num_names
) {
334 hnd
->status
= NT_STATUS_UNSUCCESSFUL
;
338 sids_out
= TALLOC_ARRAY(mem_ctx
, CacSidInfo
, (num_names
- num_unknown
));
341 hnd
->status
= NT_STATUS_NO_MEMORY
;
345 unknown_out
= TALLOC_ARRAY(mem_ctx
, char *, num_unknown
);
348 hnd
->status
= NT_STATUS_NO_MEMORY
;
352 unknown_idx
= found_idx
= 0;
354 /*now we can actually do the real work*/
355 for(i
= 0; i
< num_names
; i
++) {
356 if(types
[i
] != SID_NAME_UNKNOWN
) {
357 sids_out
[found_idx
].sid
= sids
[i
];
358 sids_out
[found_idx
].name
= talloc_strdup(mem_ctx
, op
->in
.names
[i
]);
359 sids_out
[found_idx
].domain
= NULL
;
363 else { /*then this one didnt work out*/
364 unknown_out
[unknown_idx
] = talloc_strdup(mem_ctx
, op
->in
.names
[i
]);
370 result
= CAC_PARTIAL_SUCCESS
;
372 else { /*then it failed for some reason*/
376 op
->out
.num_found
= num_names
- num_unknown
;
377 op
->out
.sids
= sids_out
;
378 op
->out
.unknown
= unknown_out
;
384 int cac_LsaFetchSid(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaFetchSid
*op
) {
385 struct rpc_pipe_client
*pipe_hnd
= NULL
;
391 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
] ) {
392 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
396 if(!mem_ctx
|| !op
|| !op
->in
.pol
) {
397 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
401 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
403 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
407 op
->out
.local_sid
= NULL
;
408 op
->out
.domain_sid
= NULL
;
410 if( (op
->in
.info_class
& CAC_LOCAL_INFO
) == CAC_LOCAL_INFO
) {
411 DOM_SID
*local_sid
= NULL
;
412 char *dom_name
= NULL
;
414 hnd
->status
= rpccli_lsa_query_info_policy( pipe_hnd
, mem_ctx
, op
->in
.pol
, CAC_LOCAL_INFO
, &dom_name
, &local_sid
);
416 if(!NT_STATUS_IS_OK(hnd
->status
)) {
417 result
= CAC_FAILURE
;
421 op
->out
.local_sid
= talloc(mem_ctx
, CacSidInfo
);
422 if(!op
->out
.local_sid
) {
423 hnd
->status
= NT_STATUS_NO_MEMORY
;
424 result
= CAC_FAILURE
;
428 op
->out
.local_sid
->domain
= dom_name
;
430 sid_copy(&op
->out
.local_sid
->sid
, local_sid
);
431 TALLOC_FREE(local_sid
);
436 if( (op
->in
.info_class
& CAC_DOMAIN_INFO
) == CAC_DOMAIN_INFO
) {
440 hnd
->status
= rpccli_lsa_query_info_policy( pipe_hnd
, mem_ctx
, op
->in
.pol
, CAC_DOMAIN_INFO
, &dom_name
, &domain_sid
);
441 if(!NT_STATUS_IS_OK(hnd
->status
)) {
442 /*if we succeeded above, report partial success*/
443 result
= (result
== CAC_SUCCESS
) ? CAC_PARTIAL_SUCCESS
: CAC_FAILURE
;
446 else if(result
== CAC_FAILURE
) {
447 /*if we failed above but succeded here then report partial success*/
448 result
= CAC_PARTIAL_SUCCESS
;
451 op
->out
.domain_sid
= talloc(mem_ctx
, CacSidInfo
);
452 if(!op
->out
.domain_sid
) {
453 hnd
->status
= NT_STATUS_NO_MEMORY
;
454 result
= CAC_FAILURE
;
458 op
->out
.domain_sid
->domain
= dom_name
;
459 sid_copy(&op
->out
.domain_sid
->sid
, domain_sid
);
460 TALLOC_FREE(domain_sid
);
467 int cac_LsaQueryInfoPolicy(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaQueryInfoPolicy
*op
) {
468 struct rpc_pipe_client
*pipe_hnd
= NULL
;
470 char *domain_name
= NULL
;
471 char *dns_name
= NULL
;
472 char *forest_name
= NULL
;
473 struct uuid
*domain_guid
= NULL
;
474 DOM_SID
*domain_sid
= NULL
;
479 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
480 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
485 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
489 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
491 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
495 /*only works if info_class parm is 12*/
496 hnd
->status
= rpccli_lsa_query_info_policy2(pipe_hnd
, mem_ctx
, op
->in
.pol
, 12,
497 &domain_name
, &dns_name
, &forest_name
, &domain_guid
, &domain_sid
);
499 if(!NT_STATUS_IS_OK(hnd
->status
)) {
503 op
->out
.domain_name
= domain_name
;
504 op
->out
.dns_name
= dns_name
;
505 op
->out
.forest_name
= forest_name
;
506 op
->out
.domain_guid
= domain_guid
;
507 op
->out
.domain_sid
= domain_sid
;
512 int cac_LsaEnumSids(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaEnumSids
*op
) {
513 struct rpc_pipe_client
*pipe_hnd
= NULL
;
521 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
522 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
526 if(!op
|| !op
->in
.pol
) {
527 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
531 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
533 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
537 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
);
539 if(!NT_STATUS_IS_OK(hnd
->status
)) {
543 op
->out
.num_sids
= num_sids
;
550 int cac_LsaEnumAccountRights(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaEnumAccountRights
*op
) {
551 struct rpc_pipe_client
*pipe_hnd
= NULL
;
559 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
560 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
565 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
569 if(!op
->in
.name
&& !op
->in
.sid
) {
570 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
574 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
576 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
580 if(op
->in
.name
&& !op
->in
.sid
) {
581 DOM_SID
*user_sid
= NULL
;
585 hnd
->status
= rpccli_lsa_lookup_names( pipe_hnd
, mem_ctx
, op
->in
.pol
, 1, (const char **)&(op
->in
.name
), NULL
, &user_sid
, &type
);
587 if(!NT_STATUS_IS_OK(hnd
->status
))
590 op
->in
.sid
= user_sid
;
593 hnd
->status
= rpccli_lsa_enum_account_rights( pipe_hnd
, mem_ctx
, op
->in
.pol
, op
->in
.sid
,
596 if(!NT_STATUS_IS_OK(hnd
->status
)) {
600 op
->out
.num_privs
= count
;
601 op
->out
.priv_names
= privs
;
606 int cac_LsaEnumTrustedDomains(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaEnumTrustedDomains
*op
) {
607 struct rpc_pipe_client
*pipe_hnd
;
611 DOM_SID
*domain_sids
;
616 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
617 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
622 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
626 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
628 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
632 hnd
->status
= rpccli_lsa_enum_trust_dom( pipe_hnd
, mem_ctx
, op
->in
.pol
, &(op
->out
.resume_idx
), &num_domains
, &domain_names
, &domain_sids
);
634 if(!NT_STATUS_IS_OK(hnd
->status
)) {
638 op
->out
.num_domains
= num_domains
;
639 op
->out
.domain_names
= domain_names
;
640 op
->out
.domain_sids
= domain_sids
;
645 int cac_LsaOpenTrustedDomain(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaOpenTrustedDomain
*op
) {
646 struct rpc_pipe_client
*pipe_hnd
= NULL
;
648 POLICY_HND
*dom_pol
= NULL
;
653 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
654 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
658 if(!op
->in
.pol
|| !op
->in
.access
|| !op
->in
.domain_sid
) {
659 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
663 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
665 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
669 dom_pol
= talloc(mem_ctx
, POLICY_HND
);
671 hnd
->status
= NT_STATUS_NO_MEMORY
;
676 hnd
->status
= rpccli_lsa_open_trusted_domain( pipe_hnd
, mem_ctx
, op
->in
.pol
, op
->in
.domain_sid
, op
->in
.access
, dom_pol
);
678 if(!NT_STATUS_IS_OK(hnd
->status
)) {
682 op
->out
.domain_pol
= dom_pol
;
687 int cac_LsaQueryTrustedDomainInfo(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaQueryTrustedDomainInfo
*op
) {
688 struct rpc_pipe_client
*pipe_hnd
= NULL
;
690 LSA_TRUSTED_DOMAIN_INFO
*dom_info
;
695 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
696 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
700 if(!op
->in
.pol
|| !op
->in
.info_class
) {
701 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
705 if(!op
->in
.domain_sid
&& !op
->in
.domain_name
) {
706 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
710 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
712 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
716 if(op
->in
.domain_sid
) {
717 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
);
719 else if(op
->in
.domain_name
) {
720 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
);
723 if(!NT_STATUS_IS_OK(hnd
->status
)) {
727 op
->out
.info
= dom_info
;
733 int cac_LsaEnumPrivileges(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaEnumPrivileges
*op
) {
734 struct rpc_pipe_client
*pipe_hnd
= NULL
;
745 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
746 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
750 if(!op
|| !op
->in
.pol
) {
751 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
755 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
757 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
761 hnd
->status
= rpccli_lsa_enum_privilege(pipe_hnd
, mem_ctx
, op
->in
.pol
, &(op
->out
.resume_idx
), op
->in
.pref_max_privs
,
762 &num_privs
, &priv_names
, &high_bits
, &low_bits
);
764 if(!NT_STATUS_IS_OK(hnd
->status
)) {
768 op
->out
.num_privs
= num_privs
;
769 op
->out
.priv_names
= priv_names
;
770 op
->out
.high_bits
= high_bits
;
771 op
->out
.low_bits
= low_bits
;
776 int cac_LsaOpenAccount(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaOpenAccount
*op
) {
777 struct rpc_pipe_client
*pipe_hnd
= NULL
;
779 POLICY_HND
*user_pol
= NULL
;
785 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
786 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
790 if(!op
|| !op
->in
.pol
) {
791 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
795 if(!op
->in
.sid
&& !op
->in
.name
) {
796 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
800 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
802 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
806 /*look up the user's SID if we have to*/
807 if(op
->in
.name
&& !op
->in
.sid
) {
808 DOM_SID
*user_sid
= NULL
;
812 hnd
->status
= rpccli_lsa_lookup_names( pipe_hnd
, mem_ctx
, op
->in
.pol
, 1, (const char **)&(op
->in
.name
), NULL
, &user_sid
, &type
);
814 if(!NT_STATUS_IS_OK(hnd
->status
))
817 op
->in
.sid
= user_sid
;
820 user_pol
= talloc(mem_ctx
, POLICY_HND
);
822 hnd
->status
= NT_STATUS_NO_MEMORY
;
826 hnd
->status
= rpccli_lsa_open_account(pipe_hnd
, mem_ctx
, op
->in
.pol
, op
->in
.sid
, op
->in
.access
, user_pol
);
828 if(!NT_STATUS_IS_OK(hnd
->status
)) {
829 TALLOC_FREE(user_pol
);
833 op
->out
.user
= user_pol
;
839 int cac_LsaAddPrivileges(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaAddPrivileges
*op
) {
840 struct rpc_pipe_client
*pipe_hnd
= NULL
;
842 DOM_SID
*user_sid
= NULL
;
849 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
850 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
854 if(!op
|| !op
->in
.pol
|| !op
->in
.priv_names
) {
855 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
859 if(!op
->in
.sid
&& !op
->in
.name
) {
860 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
864 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
866 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
870 if(op
->in
.name
&& !op
->in
.sid
) {
872 hnd
->status
= rpccli_lsa_lookup_names( pipe_hnd
, mem_ctx
, op
->in
.pol
, 1, (const char **)&(op
->in
.name
), NULL
, &user_sid
, &type
);
874 if(!NT_STATUS_IS_OK(hnd
->status
))
877 op
->in
.sid
= user_sid
;
880 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
);
882 if(!NT_STATUS_IS_OK(hnd
->status
)) {
889 int cac_LsaRemovePrivileges(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaRemovePrivileges
*op
) {
890 struct rpc_pipe_client
*pipe_hnd
= NULL
;
892 DOM_SID
*user_sid
= NULL
;
899 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
900 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
904 if(!op
|| !op
->in
.pol
|| !op
->in
.priv_names
) {
905 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
909 if(!op
->in
.sid
&& !op
->in
.name
) {
910 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
914 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
916 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
920 if(op
->in
.name
&& !op
->in
.sid
) {
922 hnd
->status
= rpccli_lsa_lookup_names( pipe_hnd
, mem_ctx
, op
->in
.pol
, 1, (const char **)&(op
->in
.name
), NULL
, &user_sid
, &type
);
924 if(!NT_STATUS_IS_OK(hnd
->status
))
927 op
->in
.sid
= user_sid
;
930 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
);
932 if(!NT_STATUS_IS_OK(hnd
->status
)) {
939 int cac_LsaClearPrivileges(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaClearPrivileges
*op
) {
940 struct rpc_pipe_client
*pipe_hnd
= NULL
;
942 DOM_SID
*user_sid
= NULL
;
949 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
950 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
954 if(!op
|| !op
->in
.pol
) {
955 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
959 if(!op
->in
.sid
&& !op
->in
.name
) {
960 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
964 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
966 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
970 if(op
->in
.name
&& !op
->in
.sid
) {
972 hnd
->status
= rpccli_lsa_lookup_names( pipe_hnd
, mem_ctx
, op
->in
.pol
, 1, (const char **)&(op
->in
.name
), NULL
, &user_sid
, &type
);
974 if(!NT_STATUS_IS_OK(hnd
->status
))
977 op
->in
.sid
= user_sid
;
980 hnd
->status
= rpccli_lsa_remove_account_rights( pipe_hnd
, mem_ctx
, op
->in
.pol
, *(op
->in
.sid
), True
, 0, NULL
);
982 if(!NT_STATUS_IS_OK(hnd
->status
)) {
989 int cac_LsaSetPrivileges(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaAddPrivileges
*op
) {
990 struct rpc_pipe_client
*pipe_hnd
= NULL
;
992 DOM_SID
*user_sid
= NULL
;
999 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
1000 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1004 if(!op
|| !op
->in
.pol
|| !op
->in
.priv_names
) {
1005 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1009 if(!op
->in
.sid
&& !op
->in
.name
) {
1010 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1014 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
1019 if(op
->in
.name
&& !op
->in
.sid
) {
1021 hnd
->status
= rpccli_lsa_lookup_names( pipe_hnd
, mem_ctx
, op
->in
.pol
, 1, (const char **)&(op
->in
.name
), NULL
, &user_sid
, &type
);
1023 if(!NT_STATUS_IS_OK(hnd
->status
))
1026 op
->in
.sid
= user_sid
;
1029 /*first remove all privileges*/
1030 hnd
->status
= rpccli_lsa_remove_account_rights( pipe_hnd
, mem_ctx
, op
->in
.pol
, *(op
->in
.sid
), True
, 0, NULL
);
1032 if(!NT_STATUS_IS_OK(hnd
->status
)) {
1036 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
);
1038 if(!NT_STATUS_IS_OK(hnd
->status
)) {
1045 int cac_LsaGetSecurityObject(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct LsaGetSecurityObject
*op
) {
1046 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1048 /*this is taken from rpcclient/cmd_lsarpc.c*/
1049 uint16 info_level
= 4;
1051 SEC_DESC_BUF
*sec_out
= NULL
;
1057 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_LSARPC
]) {
1058 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1062 if(!op
|| !op
->in
.pol
) {
1063 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1067 pipe_hnd
= cac_GetPipe(hnd
, PI_LSARPC
);
1069 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1073 hnd
->status
= rpccli_lsa_query_secobj( pipe_hnd
, mem_ctx
, op
->in
.pol
, info_level
, &sec_out
);
1075 if(!NT_STATUS_IS_OK(hnd
->status
))
1078 op
->out
.sec
= sec_out
;