r25598: Add missing become_root/unbecome_root around calls of add_aliases.
[Samba/gbeck.git] / source3 / libmsrpc / cac_lsarpc.c
blob5ff8f5142cc679bded81a070a53632e3ec9bb71d
2 /*
3 * Unix SMB/CIFS implementation.
4 * MS-RPC client library implementation (LSA pipe)
5 * Copyright (C) Chris Nicholls 2005.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "libmsrpc.h"
22 #include "libsmb_internal.h"
24 int cac_LsaOpenPolicy( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
25 struct LsaOpenPolicy *op )
27 SMBCSRV *srv = NULL;
28 POLICY_HND *policy = NULL;
29 struct rpc_pipe_client *pipe_hnd = NULL;
31 if ( !hnd )
32 return CAC_FAILURE;
34 if ( !hnd->_internal.ctx ) {
35 hnd->status = NT_STATUS_INVALID_HANDLE;
36 return CAC_FAILURE;
39 if ( !mem_ctx || !op ) {
40 hnd->status = NT_STATUS_INVALID_PARAMETER;
41 return CAC_FAILURE;
44 op->out.pol = NULL;
46 srv = cac_GetServer( hnd );
47 if ( !srv ) {
48 hnd->status = NT_STATUS_INVALID_CONNECTION;
49 return CAC_FAILURE;
52 /*see if there is already an active session on this pipe, if not then open one */
53 if ( !hnd->_internal.pipes[PI_LSARPC] ) {
54 pipe_hnd =
55 cli_rpc_pipe_open_noauth( srv->cli, PI_LSARPC,
56 &hnd->status );
58 if ( !pipe_hnd ) {
59 hnd->status = NT_STATUS_UNSUCCESSFUL;
60 return CAC_FAILURE;
63 hnd->_internal.pipes[PI_LSARPC] = True;
66 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
67 if ( !pipe_hnd ) {
68 hnd->status = NT_STATUS_INVALID_HANDLE;
69 return CAC_FAILURE;
72 policy = TALLOC_P( mem_ctx, POLICY_HND );
73 if ( !policy ) {
74 errno = ENOMEM;
75 hnd->status = NT_STATUS_NO_MEMORY;
76 return CAC_FAILURE;
79 /*need to make sure that our nt status is good otherwise check might fail below */
80 hnd->status = NT_STATUS_OK;
82 if ( hnd->_internal.srv_level >= SRV_WIN_2K ) {
84 /*try using open_policy2, if this fails try again in next block using open_policy, if that works then adjust hnd->_internal.srv_level */
86 /*we shouldn't need to modify the access mask to make it work here */
87 hnd->status =
88 rpccli_lsa_open_policy2( pipe_hnd, mem_ctx,
89 op->in.security_qos,
90 op->in.access, policy );
94 if ( hnd->_internal.srv_level < SRV_WIN_2K
95 || !NT_STATUS_IS_OK( hnd->status ) ) {
96 hnd->status =
97 rpccli_lsa_open_policy( pipe_hnd, mem_ctx,
98 op->in.security_qos,
99 op->in.access, policy );
101 if ( hnd->_internal.srv_level > SRV_WIN_NT4
102 && NT_STATUS_IS_OK( hnd->status ) ) {
103 /*change the server level to 1 */
104 hnd->_internal.srv_level = SRV_WIN_NT4;
109 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
110 return CAC_FAILURE;
113 op->out.pol = policy;
115 return CAC_SUCCESS;
118 int cac_LsaClosePolicy( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
119 POLICY_HND * pol )
122 struct rpc_pipe_client *pipe_hnd = NULL;
124 if ( !hnd )
125 return CAC_FAILURE;
127 if ( !pol )
128 return CAC_SUCCESS; /*if the policy handle doesnt exist then it's already closed */
130 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
131 hnd->status = NT_STATUS_INVALID_HANDLE;
132 return CAC_FAILURE;
135 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
136 if ( !pipe_hnd ) {
137 hnd->status = NT_STATUS_INVALID_HANDLE;
138 return CAC_FAILURE;
141 hnd->status = rpccli_lsa_Close( pipe_hnd, mem_ctx, pol );
143 TALLOC_FREE( pol );
145 if ( !NT_STATUS_IS_OK( hnd->status ) )
146 return CAC_FAILURE;
148 return CAC_SUCCESS;
151 int cac_LsaGetNamesFromSids( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
152 struct LsaGetNamesFromSids *op )
154 struct rpc_pipe_client *pipe_hnd = NULL;
156 int result = -1;
158 int i;
160 /*buffers for outputs */
161 char **domains = NULL;
162 char **names = NULL;
163 enum lsa_SidType *types = NULL;
165 CacSidInfo *sids_out = NULL;
166 DOM_SID *unknown_out = NULL;
167 int num_unknown = 0;
169 int num_sids;
171 int found_idx;
172 int unknown_idx;
174 if ( !hnd )
175 return CAC_FAILURE;
177 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
178 hnd->status = NT_STATUS_INVALID_HANDLE;
179 return CAC_FAILURE;
182 if ( !mem_ctx || !op || !op->in.pol || !op->in.sids ) {
183 hnd->status = NT_STATUS_INVALID_PARAMETER;
184 return CAC_FAILURE;
187 num_sids = op->in.num_sids;
189 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
190 if ( !pipe_hnd ) {
191 hnd->status = NT_STATUS_INVALID_HANDLE;
192 return CAC_FAILURE;
197 /*now actually lookup the names */
198 hnd->status =
199 rpccli_lsa_lookup_sids( pipe_hnd, mem_ctx, op->in.pol,
200 op->in.num_sids, op->in.sids,
201 &domains, &names, &types );
203 if ( NT_STATUS_IS_OK( hnd->status ) ) {
204 /*this is the easy part, just make the out.sids array */
205 if (num_sids) {
206 sids_out = TALLOC_ARRAY( mem_ctx, CacSidInfo, num_sids );
207 if ( !sids_out ) {
208 errno = ENOMEM;
209 hnd->status = NT_STATUS_NO_MEMORY;
210 return CAC_FAILURE;
212 } else {
213 sids_out = NULL;
216 for ( i = 0; i < num_sids; i++ ) {
217 sids_out[i].sid = op->in.sids[i];
218 sids_out[i].name = names[i];
219 sids_out[i].domain = domains[i];
222 result = CAC_SUCCESS;
223 } else if ( NT_STATUS_V( hnd->status ) ==
224 NT_STATUS_V( STATUS_SOME_UNMAPPED ) ) {
225 /*first find out how many couldn't be looked up */
227 for ( i = 0; i < num_sids; i++ ) {
228 if ( names[i] == NULL ) {
229 num_unknown++;
233 if ( num_unknown >= num_sids ) {
234 hnd->status = NT_STATUS_UNSUCCESSFUL;
235 return CAC_FAILURE;
238 if ( num_sids - num_unknown) {
239 sids_out =
240 TALLOC_ARRAY( mem_ctx, CacSidInfo,
241 ( num_sids - num_unknown ) );
242 if ( !sids_out ) {
243 errno = ENOMEM;
244 hnd->status = NT_STATUS_NO_MEMORY;
245 return CAC_FAILURE;
247 } else {
248 sids_out = NULL;
251 if (num_unknown) {
252 unknown_out = TALLOC_ARRAY( mem_ctx, DOM_SID, num_unknown );
253 if ( !unknown_out ) {
254 errno = ENOMEM;
255 hnd->status = NT_STATUS_NO_MEMORY;
256 return CAC_FAILURE;
258 } else {
259 unknown_out = NULL;
261 found_idx = unknown_idx = 0;
263 /*now we can actually do the real work */
264 for ( i = 0; i < num_sids; i++ ) {
265 if ( names[i] != NULL ) {
266 sids_out[found_idx].sid = op->in.sids[i];
267 sids_out[found_idx].name = names[i];
268 sids_out[found_idx].domain = domains[i];
270 found_idx++;
271 } else { /*then this one didnt work out */
272 unknown_out[unknown_idx] = op->in.sids[i];
274 unknown_idx++;
278 result = CAC_PARTIAL_SUCCESS;
279 } else { /*then it failed for some reason */
280 return CAC_FAILURE;
283 op->out.num_found = num_sids - num_unknown;
284 op->out.sids = sids_out;
285 op->out.unknown = unknown_out;
287 return result;
291 int cac_LsaGetSidsFromNames( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
292 struct LsaGetSidsFromNames *op )
294 struct rpc_pipe_client *pipe_hnd = NULL;
295 int result = -1;
297 int i;
299 /*buffers for outputs */
300 DOM_SID *sids = NULL;
301 enum lsa_SidType *types = NULL;
303 CacSidInfo *sids_out = NULL;
304 char **unknown_out = NULL;
305 int num_unknown = 0;
307 int num_names;
309 int found_idx = 0;
310 int unknown_idx = 0;
312 if ( !hnd )
313 return CAC_FAILURE;
315 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
316 hnd->status = NT_STATUS_INVALID_HANDLE;
317 return CAC_FAILURE;
320 if ( !mem_ctx || !op || !op->in.pol || !op->in.names ) {
321 hnd->status = NT_STATUS_INVALID_PARAMETER;
322 return CAC_FAILURE;
325 num_names = op->in.num_names;
327 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
328 if ( !pipe_hnd ) {
329 hnd->status = NT_STATUS_INVALID_HANDLE;
330 return CAC_FAILURE;
334 /*now actually lookup the names */
335 hnd->status =
336 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol,
337 num_names,
338 ( const char ** ) op->in.names, NULL,
339 1, &sids, &types );
341 if ( NT_STATUS_IS_OK( hnd->status ) ) {
342 /*this is the easy part, just make the out.sids array */
343 if (num_names) {
344 sids_out = TALLOC_ARRAY( mem_ctx, CacSidInfo, num_names );
345 if ( !sids_out ) {
346 errno = ENOMEM;
347 hnd->status = NT_STATUS_NO_MEMORY;
348 return CAC_FAILURE;
350 } else {
351 sids_out = NULL;
354 for ( i = 0; i < num_names; i++ ) {
355 sids_out[i].sid = sids[i];
356 sids_out[i].name =
357 talloc_strdup( mem_ctx, op->in.names[i] );
358 sids_out[i].domain = NULL;
361 result = CAC_SUCCESS;
362 } else if ( NT_STATUS_V( hnd->status ) ==
363 NT_STATUS_V( STATUS_SOME_UNMAPPED ) ) {
364 /*first find out how many couldn't be looked up */
366 for ( i = 0; i < num_names; i++ ) {
367 if ( types[i] == SID_NAME_UNKNOWN ) {
368 num_unknown++;
372 if ( num_unknown >= num_names ) {
373 hnd->status = NT_STATUS_UNSUCCESSFUL;
374 return CAC_FAILURE;
377 if (num_names - num_unknown) {
378 sids_out =
379 TALLOC_ARRAY( mem_ctx, CacSidInfo,
380 ( num_names - num_unknown ) );
381 if ( !sids_out ) {
382 errno = ENOMEM;
383 hnd->status = NT_STATUS_NO_MEMORY;
384 return CAC_FAILURE;
386 } else {
387 sids_out = NULL;
390 if (num_unknown) {
391 unknown_out = TALLOC_ARRAY( mem_ctx, char *, num_unknown );
392 if ( !unknown_out ) {
393 errno = ENOMEM;
394 hnd->status = NT_STATUS_NO_MEMORY;
395 return CAC_FAILURE;
397 } else {
398 unknown_out = NULL;
401 unknown_idx = found_idx = 0;
403 /*now we can actually do the real work */
404 for ( i = 0; i < num_names; i++ ) {
405 if ( types[i] != SID_NAME_UNKNOWN ) {
406 sids_out[found_idx].sid = sids[i];
407 sids_out[found_idx].name =
408 talloc_strdup( mem_ctx,
409 op->in.names[i] );
410 sids_out[found_idx].domain = NULL;
412 found_idx++;
413 } else { /*then this one didnt work out */
414 unknown_out[unknown_idx] =
415 talloc_strdup( mem_ctx,
416 op->in.names[i] );
418 unknown_idx++;
422 result = CAC_PARTIAL_SUCCESS;
423 } else { /*then it failed for some reason */
424 return CAC_FAILURE;
427 op->out.num_found = num_names - num_unknown;
428 op->out.sids = sids_out;
429 op->out.unknown = unknown_out;
431 return result;
435 int cac_LsaFetchSid( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
436 struct LsaFetchSid *op )
438 struct rpc_pipe_client *pipe_hnd = NULL;
439 int result = -1;
441 if ( !hnd )
442 return CAC_FAILURE;
444 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
445 hnd->status = NT_STATUS_INVALID_HANDLE;
446 return CAC_FAILURE;
449 if ( !mem_ctx || !op || !op->in.pol ) {
450 hnd->status = NT_STATUS_INVALID_PARAMETER;
451 return CAC_FAILURE;
454 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
455 if ( !pipe_hnd ) {
456 hnd->status = NT_STATUS_INVALID_HANDLE;
457 return CAC_FAILURE;
460 op->out.local_sid = NULL;
461 op->out.domain_sid = NULL;
463 if ( ( op->in.info_class & CAC_LOCAL_INFO ) == CAC_LOCAL_INFO ) {
464 DOM_SID *local_sid = NULL;
465 char *dom_name = NULL;
467 hnd->status =
468 rpccli_lsa_query_info_policy( pipe_hnd, mem_ctx,
469 op->in.pol,
470 CAC_LOCAL_INFO,
471 &dom_name, &local_sid );
473 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
474 result = CAC_FAILURE;
475 goto domain;
478 op->out.local_sid = talloc( mem_ctx, CacSidInfo );
479 if ( !op->out.local_sid ) {
480 hnd->status = NT_STATUS_NO_MEMORY;
481 result = CAC_FAILURE;
482 goto domain;
485 op->out.local_sid->domain = dom_name;
487 sid_copy( &op->out.local_sid->sid, local_sid );
488 TALLOC_FREE( local_sid );
491 domain:
493 if ( ( op->in.info_class & CAC_DOMAIN_INFO ) == CAC_DOMAIN_INFO ) {
494 DOM_SID *domain_sid;
495 char *dom_name;
497 hnd->status =
498 rpccli_lsa_query_info_policy( pipe_hnd, mem_ctx,
499 op->in.pol,
500 CAC_DOMAIN_INFO,
501 &dom_name,
502 &domain_sid );
503 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
504 /*if we succeeded above, report partial success */
505 result = CAC_FAILURE;
506 goto done;
507 } else if ( result == CAC_FAILURE ) {
508 /*if we failed above but succeded here then report partial success */
509 result = CAC_PARTIAL_SUCCESS;
512 op->out.domain_sid = talloc( mem_ctx, CacSidInfo );
513 if ( !op->out.domain_sid ) {
514 hnd->status = NT_STATUS_NO_MEMORY;
515 result = CAC_FAILURE;
516 goto done;
519 op->out.domain_sid->domain = dom_name;
520 sid_copy( &op->out.domain_sid->sid, domain_sid );
521 TALLOC_FREE( domain_sid );
524 done:
525 return result;
528 int cac_LsaQueryInfoPolicy( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
529 struct LsaQueryInfoPolicy *op )
531 struct rpc_pipe_client *pipe_hnd = NULL;
533 char *domain_name = NULL;
534 char *dns_name = NULL;
535 char *forest_name = NULL;
536 struct GUID *domain_guid = NULL;
537 DOM_SID *domain_sid = NULL;
539 if ( !hnd )
540 return CAC_FAILURE;
542 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
543 hnd->status = NT_STATUS_INVALID_HANDLE;
544 return CAC_FAILURE;
547 if ( !op || !op->in.pol ) {
548 hnd->status = NT_STATUS_INVALID_PARAMETER;
549 return CAC_FAILURE;
552 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
553 if ( !pipe_hnd ) {
554 hnd->status = NT_STATUS_INVALID_HANDLE;
555 return CAC_FAILURE;
558 /*only works if info_class parm is 12 */
559 hnd->status =
560 rpccli_lsa_query_info_policy2( pipe_hnd, mem_ctx, op->in.pol,
561 12, &domain_name, &dns_name,
562 &forest_name, &domain_guid,
563 &domain_sid );
565 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
566 return CAC_FAILURE;
569 op->out.domain_name = domain_name;
570 op->out.dns_name = dns_name;
571 op->out.forest_name = forest_name;
572 op->out.domain_guid = domain_guid;
573 op->out.domain_sid = domain_sid;
575 return CAC_SUCCESS;
578 int cac_LsaEnumSids( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
579 struct LsaEnumSids *op )
581 struct rpc_pipe_client *pipe_hnd = NULL;
583 uint32 num_sids;
584 DOM_SID *sids;
586 if ( !hnd )
587 return CAC_FAILURE;
589 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
590 hnd->status = NT_STATUS_INVALID_HANDLE;
591 return CAC_FAILURE;
594 if ( !op || !op->in.pol ) {
595 hnd->status = NT_STATUS_INVALID_PARAMETER;
596 return CAC_FAILURE;
599 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
600 if ( !pipe_hnd ) {
601 hnd->status = NT_STATUS_INVALID_HANDLE;
602 return CAC_FAILURE;
605 hnd->status =
606 rpccli_lsa_enum_sids( pipe_hnd, mem_ctx, op->in.pol,
607 &( op->out.resume_idx ),
608 op->in.pref_max_sids, &num_sids,
609 &sids );
611 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
612 return CAC_FAILURE;
615 op->out.num_sids = num_sids;
616 op->out.sids = sids;
618 return CAC_SUCCESS;
622 int cac_LsaEnumAccountRights( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
623 struct LsaEnumAccountRights *op )
625 struct rpc_pipe_client *pipe_hnd = NULL;
627 uint32 count = 0;
628 char **privs = NULL;
630 if ( !hnd )
631 return CAC_FAILURE;
633 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
634 hnd->status = NT_STATUS_INVALID_HANDLE;
635 return CAC_FAILURE;
638 if ( !op->in.pol ) {
639 hnd->status = NT_STATUS_INVALID_PARAMETER;
640 return CAC_FAILURE;
643 if ( !op->in.name && !op->in.sid ) {
644 hnd->status = NT_STATUS_INVALID_PARAMETER;
645 return CAC_FAILURE;
648 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
649 if ( !pipe_hnd ) {
650 hnd->status = NT_STATUS_INVALID_HANDLE;
651 return CAC_FAILURE;
654 if ( op->in.name && !op->in.sid ) {
655 DOM_SID *user_sid = NULL;
656 enum lsa_SidType *type;
658 /*lookup the SID */
659 hnd->status =
660 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
661 op->in.pol, 1,
662 ( const char ** ) &( op->in.
663 name ),
664 NULL, 1, &user_sid, &type );
666 if ( !NT_STATUS_IS_OK( hnd->status ) )
667 return CAC_FAILURE;
669 op->in.sid = user_sid;
672 hnd->status =
673 rpccli_lsa_enum_account_rights( pipe_hnd, mem_ctx, op->in.pol,
674 op->in.sid, &count, &privs );
676 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
677 return CAC_FAILURE;
680 op->out.num_privs = count;
681 op->out.priv_names = privs;
683 return CAC_SUCCESS;
686 int cac_LsaEnumTrustedDomains( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
687 struct LsaEnumTrustedDomains *op )
689 struct rpc_pipe_client *pipe_hnd;
691 uint32 num_domains;
692 char **domain_names;
693 DOM_SID *domain_sids;
695 if ( !hnd )
696 return CAC_FAILURE;
698 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
699 hnd->status = NT_STATUS_INVALID_HANDLE;
700 return CAC_FAILURE;
703 if ( !op->in.pol ) {
704 hnd->status = NT_STATUS_INVALID_PARAMETER;
705 return CAC_FAILURE;
708 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
709 if ( !pipe_hnd ) {
710 hnd->status = NT_STATUS_INVALID_HANDLE;
711 return CAC_FAILURE;
714 hnd->status =
715 rpccli_lsa_enum_trust_dom( pipe_hnd, mem_ctx, op->in.pol,
716 &( op->out.resume_idx ),
717 &num_domains, &domain_names,
718 &domain_sids );
720 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
721 return CAC_FAILURE;
724 op->out.num_domains = num_domains;
725 op->out.domain_names = domain_names;
726 op->out.domain_sids = domain_sids;
728 return CAC_SUCCESS;
731 int cac_LsaOpenTrustedDomain( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
732 struct LsaOpenTrustedDomain *op )
734 struct rpc_pipe_client *pipe_hnd = NULL;
736 POLICY_HND *dom_pol = NULL;
738 if ( !hnd )
739 return CAC_FAILURE;
741 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
742 hnd->status = NT_STATUS_INVALID_HANDLE;
743 return CAC_FAILURE;
746 if ( !op->in.pol || !op->in.access || !op->in.domain_sid ) {
747 hnd->status = NT_STATUS_INVALID_PARAMETER;
748 return CAC_FAILURE;
751 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
752 if ( !pipe_hnd ) {
753 hnd->status = NT_STATUS_INVALID_HANDLE;
754 return CAC_FAILURE;
757 dom_pol = talloc( mem_ctx, POLICY_HND );
758 if ( !dom_pol ) {
759 hnd->status = NT_STATUS_NO_MEMORY;
760 errno = ENOMEM;
761 return CAC_FAILURE;
764 hnd->status =
765 rpccli_lsa_open_trusted_domain( pipe_hnd, mem_ctx, op->in.pol,
766 op->in.domain_sid,
767 op->in.access, dom_pol );
769 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
770 return CAC_FAILURE;
773 op->out.domain_pol = dom_pol;
775 return CAC_SUCCESS;
778 int cac_LsaQueryTrustedDomainInfo( CacServerHandle * hnd,
779 TALLOC_CTX * mem_ctx,
780 struct LsaQueryTrustedDomainInfo *op )
782 struct rpc_pipe_client *pipe_hnd = NULL;
784 LSA_TRUSTED_DOMAIN_INFO *dom_info;
786 if ( !hnd )
787 return CAC_FAILURE;
789 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
790 hnd->status = NT_STATUS_INVALID_HANDLE;
791 return CAC_FAILURE;
794 if ( !op->in.pol || !op->in.info_class ) {
795 hnd->status = NT_STATUS_INVALID_PARAMETER;
796 return CAC_FAILURE;
799 if ( !op->in.domain_sid && !op->in.domain_name ) {
800 hnd->status = NT_STATUS_INVALID_PARAMETER;
801 return CAC_FAILURE;
804 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
805 if ( !pipe_hnd ) {
806 hnd->status = NT_STATUS_INVALID_HANDLE;
807 return CAC_FAILURE;
810 if ( op->in.domain_sid ) {
811 hnd->status =
812 rpccli_lsa_query_trusted_domain_info_by_sid( pipe_hnd,
813 mem_ctx,
814 op->in.
815 pol,
816 op->in.
817 info_class,
818 op->in.
819 domain_sid,
820 &dom_info );
821 } else if ( op->in.domain_name ) {
822 hnd->status =
823 rpccli_lsa_query_trusted_domain_info_by_name
824 ( pipe_hnd, mem_ctx, op->in.pol, op->in.info_class,
825 op->in.domain_name, &dom_info );
828 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
829 return CAC_FAILURE;
832 op->out.info = dom_info;
834 return CAC_SUCCESS;
838 int cac_LsaEnumPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
839 struct LsaEnumPrivileges *op )
841 struct rpc_pipe_client *pipe_hnd = NULL;
843 uint32 num_privs;
844 char **priv_names;
845 uint32 *high_bits;
846 uint32 *low_bits;
848 if ( !hnd ) {
849 return CAC_FAILURE;
852 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
853 hnd->status = NT_STATUS_INVALID_HANDLE;
854 return CAC_FAILURE;
857 if ( !op || !op->in.pol ) {
858 hnd->status = NT_STATUS_INVALID_PARAMETER;
859 return CAC_FAILURE;
862 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
863 if ( !pipe_hnd ) {
864 hnd->status = NT_STATUS_INVALID_HANDLE;
865 return CAC_FAILURE;
868 hnd->status =
869 rpccli_lsa_enum_privilege( pipe_hnd, mem_ctx, op->in.pol,
870 &( op->out.resume_idx ),
871 op->in.pref_max_privs, &num_privs,
872 &priv_names, &high_bits,
873 &low_bits );
875 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
876 return CAC_FAILURE;
879 op->out.num_privs = num_privs;
880 op->out.priv_names = priv_names;
881 op->out.high_bits = high_bits;
882 op->out.low_bits = low_bits;
884 return CAC_SUCCESS;
887 int cac_LsaOpenAccount( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
888 struct LsaOpenAccount *op )
890 struct rpc_pipe_client *pipe_hnd = NULL;
892 POLICY_HND *user_pol = NULL;
894 if ( !hnd ) {
895 return CAC_FAILURE;
898 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
899 hnd->status = NT_STATUS_INVALID_HANDLE;
900 return CAC_FAILURE;
903 if ( !op || !op->in.pol ) {
904 hnd->status = NT_STATUS_INVALID_PARAMETER;
905 return CAC_FAILURE;
908 if ( !op->in.sid && !op->in.name ) {
909 hnd->status = NT_STATUS_INVALID_PARAMETER;
910 return CAC_FAILURE;
913 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
914 if ( !pipe_hnd ) {
915 hnd->status = NT_STATUS_INVALID_HANDLE;
916 return CAC_FAILURE;
919 /*look up the user's SID if we have to */
920 if ( op->in.name && !op->in.sid ) {
921 DOM_SID *user_sid = NULL;
922 enum lsa_SidType *type;
924 /*lookup the SID */
925 hnd->status =
926 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
927 op->in.pol, 1,
928 ( const char ** ) &( op->in.
929 name ),
930 NULL, 1, &user_sid, &type );
932 if ( !NT_STATUS_IS_OK( hnd->status ) )
933 return CAC_FAILURE;
935 op->in.sid = user_sid;
938 user_pol = talloc( mem_ctx, POLICY_HND );
939 if ( !user_pol ) {
940 hnd->status = NT_STATUS_NO_MEMORY;
941 return CAC_FAILURE;
944 hnd->status =
945 rpccli_lsa_open_account( pipe_hnd, mem_ctx, op->in.pol,
946 op->in.sid, op->in.access,
947 user_pol );
949 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
950 TALLOC_FREE( user_pol );
951 return CAC_FAILURE;
954 op->out.user = user_pol;
956 return CAC_SUCCESS;
960 int cac_LsaAddPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
961 struct LsaAddPrivileges *op )
963 struct rpc_pipe_client *pipe_hnd = NULL;
965 DOM_SID *user_sid = NULL;
966 enum lsa_SidType *type = NULL;
968 if ( !hnd ) {
969 return CAC_FAILURE;
972 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
973 hnd->status = NT_STATUS_INVALID_HANDLE;
974 return CAC_FAILURE;
977 if ( !op || !op->in.pol || !op->in.priv_names ) {
978 hnd->status = NT_STATUS_INVALID_PARAMETER;
979 return CAC_FAILURE;
982 if ( !op->in.sid && !op->in.name ) {
983 hnd->status = NT_STATUS_INVALID_PARAMETER;
984 return CAC_FAILURE;
987 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
988 if ( !pipe_hnd ) {
989 hnd->status = NT_STATUS_INVALID_HANDLE;
990 return CAC_FAILURE;
993 if ( op->in.name && !op->in.sid ) {
994 /*lookup the SID */
995 hnd->status =
996 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
997 op->in.pol, 1,
998 ( const char ** ) &( op->in.
999 name ),
1000 NULL, 1, &user_sid, &type );
1002 if ( !NT_STATUS_IS_OK( hnd->status ) )
1003 return CAC_FAILURE;
1005 op->in.sid = user_sid;
1008 hnd->status =
1009 rpccli_lsa_add_account_rights( pipe_hnd, mem_ctx, op->in.pol,
1010 *( op->in.sid ),
1011 op->in.num_privs,
1012 ( const char ** ) op->in.
1013 priv_names );
1015 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1016 return CAC_FAILURE;
1019 return CAC_SUCCESS;
1022 int cac_LsaRemovePrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1023 struct LsaRemovePrivileges *op )
1025 struct rpc_pipe_client *pipe_hnd = NULL;
1027 DOM_SID *user_sid = NULL;
1028 enum lsa_SidType *type = NULL;
1030 if ( !hnd ) {
1031 return CAC_FAILURE;
1034 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
1035 hnd->status = NT_STATUS_INVALID_HANDLE;
1036 return CAC_FAILURE;
1039 if ( !op || !op->in.pol || !op->in.priv_names ) {
1040 hnd->status = NT_STATUS_INVALID_PARAMETER;
1041 return CAC_FAILURE;
1044 if ( !op->in.sid && !op->in.name ) {
1045 hnd->status = NT_STATUS_INVALID_PARAMETER;
1046 return CAC_FAILURE;
1049 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
1050 if ( !pipe_hnd ) {
1051 hnd->status = NT_STATUS_INVALID_HANDLE;
1052 return CAC_FAILURE;
1055 if ( op->in.name && !op->in.sid ) {
1056 /*lookup the SID */
1057 hnd->status =
1058 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
1059 op->in.pol, 1,
1060 ( const char ** ) &( op->in.
1061 name ),
1062 NULL, 1, &user_sid, &type );
1064 if ( !NT_STATUS_IS_OK( hnd->status ) )
1065 return CAC_FAILURE;
1067 op->in.sid = user_sid;
1070 hnd->status =
1071 rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx,
1072 op->in.pol, *( op->in.sid ),
1073 False, op->in.num_privs,
1074 ( const char ** ) op->in.
1075 priv_names );
1077 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1078 return CAC_FAILURE;
1081 return CAC_SUCCESS;
1084 int cac_LsaClearPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1085 struct LsaClearPrivileges *op )
1087 struct rpc_pipe_client *pipe_hnd = NULL;
1089 DOM_SID *user_sid = NULL;
1090 enum lsa_SidType *type = NULL;
1092 if ( !hnd ) {
1093 return CAC_FAILURE;
1096 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
1097 hnd->status = NT_STATUS_INVALID_HANDLE;
1098 return CAC_FAILURE;
1101 if ( !op || !op->in.pol ) {
1102 hnd->status = NT_STATUS_INVALID_PARAMETER;
1103 return CAC_FAILURE;
1106 if ( !op->in.sid && !op->in.name ) {
1107 hnd->status = NT_STATUS_INVALID_PARAMETER;
1108 return CAC_FAILURE;
1111 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
1112 if ( !pipe_hnd ) {
1113 hnd->status = NT_STATUS_INVALID_HANDLE;
1114 return CAC_FAILURE;
1117 if ( op->in.name && !op->in.sid ) {
1118 /*lookup the SID */
1119 hnd->status =
1120 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
1121 op->in.pol, 1,
1122 ( const char ** ) &( op->in.
1123 name ),
1124 NULL, 1, &user_sid, &type );
1126 if ( !NT_STATUS_IS_OK( hnd->status ) )
1127 return CAC_FAILURE;
1129 op->in.sid = user_sid;
1132 hnd->status =
1133 rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx,
1134 op->in.pol, *( op->in.sid ),
1135 True, 0, NULL );
1137 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1138 return CAC_FAILURE;
1141 return CAC_SUCCESS;
1144 int cac_LsaSetPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1145 struct LsaAddPrivileges *op )
1147 struct rpc_pipe_client *pipe_hnd = NULL;
1149 DOM_SID *user_sid = NULL;
1150 enum lsa_SidType *type = NULL;
1152 if ( !hnd ) {
1153 return CAC_FAILURE;
1156 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
1157 hnd->status = NT_STATUS_INVALID_HANDLE;
1158 return CAC_FAILURE;
1161 if ( !op || !op->in.pol || !op->in.priv_names ) {
1162 hnd->status = NT_STATUS_INVALID_PARAMETER;
1163 return CAC_FAILURE;
1166 if ( !op->in.sid && !op->in.name ) {
1167 hnd->status = NT_STATUS_INVALID_PARAMETER;
1168 return CAC_FAILURE;
1171 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
1172 if ( !pipe_hnd ) {
1173 return CAC_FAILURE;
1176 if ( op->in.name && !op->in.sid ) {
1177 /*lookup the SID */
1178 hnd->status =
1179 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
1180 op->in.pol, 1,
1181 ( const char ** ) &( op->in.
1182 name ),
1183 NULL, 1, &user_sid, &type );
1185 if ( !NT_STATUS_IS_OK( hnd->status ) )
1186 return CAC_FAILURE;
1188 op->in.sid = user_sid;
1191 /*first remove all privileges */
1192 hnd->status =
1193 rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx,
1194 op->in.pol, *( op->in.sid ),
1195 True, 0, NULL );
1197 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1198 return CAC_FAILURE;
1201 hnd->status =
1202 rpccli_lsa_add_account_rights( pipe_hnd, mem_ctx, op->in.pol,
1203 *( op->in.sid ),
1204 op->in.num_privs,
1205 ( const char ** ) op->in.
1206 priv_names );
1208 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1209 return CAC_FAILURE;
1212 return CAC_SUCCESS;
1215 int cac_LsaGetSecurityObject( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1216 struct LsaGetSecurityObject *op )
1218 struct rpc_pipe_client *pipe_hnd = NULL;
1220 /*this is taken from rpcclient/cmd_lsarpc.c */
1221 uint16 info_level = 4;
1223 SEC_DESC_BUF *sec_out = NULL;
1225 if ( !hnd ) {
1226 return CAC_FAILURE;
1229 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
1230 hnd->status = NT_STATUS_INVALID_HANDLE;
1231 return CAC_FAILURE;
1234 if ( !op || !op->in.pol ) {
1235 hnd->status = NT_STATUS_INVALID_PARAMETER;
1236 return CAC_FAILURE;
1239 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
1240 if ( !pipe_hnd ) {
1241 hnd->status = NT_STATUS_INVALID_HANDLE;
1242 return CAC_FAILURE;
1245 hnd->status =
1246 rpccli_lsa_query_secobj( pipe_hnd, mem_ctx, op->in.pol,
1247 info_level, &sec_out );
1249 if ( !NT_STATUS_IS_OK( hnd->status ) )
1250 return CAC_FAILURE;
1252 op->out.sec = sec_out;
1254 return CAC_FAILURE;