r19810: more merge work....does not compile currently. Working on smbd merge
[Samba.git] / source / libmsrpc / cac_lsarpc.c
blob2e3eb276d5adb68a88641dec695e052b68141d42
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 2 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, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "libmsrpc.h"
23 #include "libsmb_internal.h"
25 int cac_LsaOpenPolicy( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
26 struct LsaOpenPolicy *op )
28 SMBCSRV *srv = NULL;
29 POLICY_HND *policy = NULL;
30 struct rpc_pipe_client *pipe_hnd = NULL;
32 if ( !hnd )
33 return CAC_FAILURE;
35 if ( !hnd->_internal.ctx ) {
36 hnd->status = NT_STATUS_INVALID_HANDLE;
37 return CAC_FAILURE;
40 if ( !mem_ctx || !op ) {
41 hnd->status = NT_STATUS_INVALID_PARAMETER;
42 return CAC_FAILURE;
45 op->out.pol = NULL;
47 srv = cac_GetServer( hnd );
48 if ( !srv ) {
49 hnd->status = NT_STATUS_INVALID_CONNECTION;
50 return CAC_FAILURE;
53 /*see if there is already an active session on this pipe, if not then open one */
54 if ( !hnd->_internal.pipes[PI_LSARPC] ) {
55 pipe_hnd =
56 cli_rpc_pipe_open_noauth( srv->cli, PI_LSARPC,
57 &hnd->status );
59 if ( !pipe_hnd ) {
60 hnd->status = NT_STATUS_UNSUCCESSFUL;
61 return CAC_FAILURE;
64 hnd->_internal.pipes[PI_LSARPC] = True;
67 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
68 if ( !pipe_hnd ) {
69 hnd->status = NT_STATUS_INVALID_HANDLE;
70 return CAC_FAILURE;
73 policy = TALLOC_P( mem_ctx, POLICY_HND );
74 if ( !policy ) {
75 errno = ENOMEM;
76 hnd->status = NT_STATUS_NO_MEMORY;
77 return CAC_FAILURE;
80 /*need to make sure that our nt status is good otherwise check might fail below */
81 hnd->status = NT_STATUS_OK;
83 if ( hnd->_internal.srv_level >= SRV_WIN_2K ) {
85 /*try using open_policy2, if this fails try again in next block using open_policy, if that works then adjust hnd->_internal.srv_level */
87 /*we shouldn't need to modify the access mask to make it work here */
88 hnd->status =
89 rpccli_lsa_open_policy2( pipe_hnd, mem_ctx,
90 op->in.security_qos,
91 op->in.access, policy );
95 if ( hnd->_internal.srv_level < SRV_WIN_2K
96 || !NT_STATUS_IS_OK( hnd->status ) ) {
97 hnd->status =
98 rpccli_lsa_open_policy( pipe_hnd, mem_ctx,
99 op->in.security_qos,
100 op->in.access, policy );
102 if ( hnd->_internal.srv_level > SRV_WIN_NT4
103 && NT_STATUS_IS_OK( hnd->status ) ) {
104 /*change the server level to 1 */
105 hnd->_internal.srv_level = SRV_WIN_NT4;
110 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
111 return CAC_FAILURE;
114 op->out.pol = policy;
116 return CAC_SUCCESS;
119 int cac_LsaClosePolicy( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
120 POLICY_HND * pol )
123 struct rpc_pipe_client *pipe_hnd = NULL;
125 if ( !hnd )
126 return CAC_FAILURE;
128 if ( !pol )
129 return CAC_SUCCESS; /*if the policy handle doesnt exist then it's already closed */
131 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
132 hnd->status = NT_STATUS_INVALID_HANDLE;
133 return CAC_FAILURE;
136 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
137 if ( !pipe_hnd ) {
138 hnd->status = NT_STATUS_INVALID_HANDLE;
139 return CAC_FAILURE;
142 hnd->status = rpccli_lsa_Close( pipe_hnd, mem_ctx, pol );
144 TALLOC_FREE( pol );
146 if ( !NT_STATUS_IS_OK( hnd->status ) )
147 return CAC_FAILURE;
149 return CAC_SUCCESS;
152 int cac_LsaGetNamesFromSids( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
153 struct LsaGetNamesFromSids *op )
155 struct rpc_pipe_client *pipe_hnd = NULL;
157 int result = -1;
159 int i;
161 /*buffers for outputs */
162 char **domains = NULL;
163 char **names = NULL;
164 enum lsa_SidType *types = NULL;
166 CacSidInfo *sids_out = NULL;
167 DOM_SID *unknown_out = NULL;
168 int num_unknown = 0;
170 int num_sids;
172 int found_idx;
173 int unknown_idx;
175 if ( !hnd )
176 return CAC_FAILURE;
178 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
179 hnd->status = NT_STATUS_INVALID_HANDLE;
180 return CAC_FAILURE;
183 if ( !mem_ctx || !op || !op->in.pol || !op->in.sids ) {
184 hnd->status = NT_STATUS_INVALID_PARAMETER;
185 return CAC_FAILURE;
188 num_sids = op->in.num_sids;
190 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
191 if ( !pipe_hnd ) {
192 hnd->status = NT_STATUS_INVALID_HANDLE;
193 return CAC_FAILURE;
198 /*now actually lookup the names */
199 hnd->status =
200 rpccli_lsa_lookup_sids( pipe_hnd, mem_ctx, op->in.pol,
201 op->in.num_sids, op->in.sids,
202 &domains, &names, &types );
204 if ( NT_STATUS_IS_OK( hnd->status ) ) {
205 /*this is the easy part, just make the out.sids array */
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;
213 for ( i = 0; i < num_sids; i++ ) {
214 sids_out[i].sid = op->in.sids[i];
215 sids_out[i].name = names[i];
216 sids_out[i].domain = domains[i];
219 result = CAC_SUCCESS;
220 } else if ( NT_STATUS_V( hnd->status ) ==
221 NT_STATUS_V( STATUS_SOME_UNMAPPED ) ) {
222 /*first find out how many couldn't be looked up */
224 for ( i = 0; i < num_sids; i++ ) {
225 if ( names[i] == NULL ) {
226 num_unknown++;
230 if ( num_unknown >= num_sids ) {
231 hnd->status = NT_STATUS_UNSUCCESSFUL;
232 return CAC_FAILURE;
235 sids_out =
236 TALLOC_ARRAY( mem_ctx, CacSidInfo,
237 ( num_sids - num_unknown ) );
238 if ( !sids_out ) {
239 errno = ENOMEM;
240 hnd->status = NT_STATUS_NO_MEMORY;
241 return CAC_FAILURE;
244 unknown_out = TALLOC_ARRAY( mem_ctx, DOM_SID, num_unknown );
245 if ( !unknown_out ) {
246 errno = ENOMEM;
247 hnd->status = NT_STATUS_NO_MEMORY;
248 return CAC_FAILURE;
251 found_idx = unknown_idx = 0;
253 /*now we can actually do the real work */
254 for ( i = 0; i < num_sids; i++ ) {
255 if ( names[i] != NULL ) {
256 sids_out[found_idx].sid = op->in.sids[i];
257 sids_out[found_idx].name = names[i];
258 sids_out[found_idx].domain = domains[i];
260 found_idx++;
261 } else { /*then this one didnt work out */
262 unknown_out[unknown_idx] = op->in.sids[i];
264 unknown_idx++;
268 result = CAC_PARTIAL_SUCCESS;
269 } else { /*then it failed for some reason */
270 return CAC_FAILURE;
273 op->out.num_found = num_sids - num_unknown;
274 op->out.sids = sids_out;
275 op->out.unknown = unknown_out;
277 return result;
281 int cac_LsaGetSidsFromNames( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
282 struct LsaGetSidsFromNames *op )
284 struct rpc_pipe_client *pipe_hnd = NULL;
285 int result = -1;
287 int i;
289 /*buffers for outputs */
290 DOM_SID *sids = NULL;
291 enum lsa_SidType *types = NULL;
293 CacSidInfo *sids_out = NULL;
294 char **unknown_out = NULL;
295 int num_unknown = 0;
297 int num_names;
299 int found_idx = 0;
300 int unknown_idx = 0;
302 if ( !hnd )
303 return CAC_FAILURE;
305 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
306 hnd->status = NT_STATUS_INVALID_HANDLE;
307 return CAC_FAILURE;
310 if ( !mem_ctx || !op || !op->in.pol || !op->in.names ) {
311 hnd->status = NT_STATUS_INVALID_PARAMETER;
312 return CAC_FAILURE;
315 num_names = op->in.num_names;
317 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
318 if ( !pipe_hnd ) {
319 hnd->status = NT_STATUS_INVALID_HANDLE;
320 return CAC_FAILURE;
324 /*now actually lookup the names */
325 hnd->status =
326 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol,
327 num_names,
328 ( const char ** ) op->in.names, NULL,
329 &sids, &types );
331 if ( NT_STATUS_IS_OK( hnd->status ) ) {
332 /*this is the easy part, just make the out.sids array */
333 sids_out = TALLOC_ARRAY( mem_ctx, CacSidInfo, num_names );
334 if ( !sids_out ) {
335 errno = ENOMEM;
336 hnd->status = NT_STATUS_NO_MEMORY;
337 return CAC_FAILURE;
340 for ( i = 0; i < num_names; i++ ) {
341 sids_out[i].sid = sids[i];
342 sids_out[i].name =
343 talloc_strdup( mem_ctx, op->in.names[i] );
344 sids_out[i].domain = NULL;
347 result = CAC_SUCCESS;
348 } else if ( NT_STATUS_V( hnd->status ) ==
349 NT_STATUS_V( STATUS_SOME_UNMAPPED ) ) {
350 /*first find out how many couldn't be looked up */
352 for ( i = 0; i < num_names; i++ ) {
353 if ( types[i] == SID_NAME_UNKNOWN ) {
354 num_unknown++;
358 if ( num_unknown >= num_names ) {
359 hnd->status = NT_STATUS_UNSUCCESSFUL;
360 return CAC_FAILURE;
363 sids_out =
364 TALLOC_ARRAY( mem_ctx, CacSidInfo,
365 ( num_names - num_unknown ) );
366 if ( !sids_out ) {
367 errno = ENOMEM;
368 hnd->status = NT_STATUS_NO_MEMORY;
369 return CAC_FAILURE;
372 unknown_out = TALLOC_ARRAY( mem_ctx, char *, num_unknown );
373 if ( !unknown_out ) {
374 errno = ENOMEM;
375 hnd->status = NT_STATUS_NO_MEMORY;
376 return CAC_FAILURE;
379 unknown_idx = found_idx = 0;
381 /*now we can actually do the real work */
382 for ( i = 0; i < num_names; i++ ) {
383 if ( types[i] != SID_NAME_UNKNOWN ) {
384 sids_out[found_idx].sid = sids[i];
385 sids_out[found_idx].name =
386 talloc_strdup( mem_ctx,
387 op->in.names[i] );
388 sids_out[found_idx].domain = NULL;
390 found_idx++;
391 } else { /*then this one didnt work out */
392 unknown_out[unknown_idx] =
393 talloc_strdup( mem_ctx,
394 op->in.names[i] );
396 unknown_idx++;
400 result = CAC_PARTIAL_SUCCESS;
401 } else { /*then it failed for some reason */
402 return CAC_FAILURE;
405 op->out.num_found = num_names - num_unknown;
406 op->out.sids = sids_out;
407 op->out.unknown = unknown_out;
409 return result;
413 int cac_LsaFetchSid( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
414 struct LsaFetchSid *op )
416 struct rpc_pipe_client *pipe_hnd = NULL;
417 int result = -1;
419 if ( !hnd )
420 return CAC_FAILURE;
422 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
423 hnd->status = NT_STATUS_INVALID_HANDLE;
424 return CAC_FAILURE;
427 if ( !mem_ctx || !op || !op->in.pol ) {
428 hnd->status = NT_STATUS_INVALID_PARAMETER;
429 return CAC_FAILURE;
432 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
433 if ( !pipe_hnd ) {
434 hnd->status = NT_STATUS_INVALID_HANDLE;
435 return CAC_FAILURE;
438 op->out.local_sid = NULL;
439 op->out.domain_sid = NULL;
441 if ( ( op->in.info_class & CAC_LOCAL_INFO ) == CAC_LOCAL_INFO ) {
442 DOM_SID *local_sid = NULL;
443 char *dom_name = NULL;
445 hnd->status =
446 rpccli_lsa_query_info_policy( pipe_hnd, mem_ctx,
447 op->in.pol,
448 CAC_LOCAL_INFO,
449 &dom_name, &local_sid );
451 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
452 result = CAC_FAILURE;
453 goto domain;
456 op->out.local_sid = talloc( mem_ctx, CacSidInfo );
457 if ( !op->out.local_sid ) {
458 hnd->status = NT_STATUS_NO_MEMORY;
459 result = CAC_FAILURE;
460 goto domain;
463 op->out.local_sid->domain = dom_name;
465 sid_copy( &op->out.local_sid->sid, local_sid );
466 TALLOC_FREE( local_sid );
469 domain:
471 if ( ( op->in.info_class & CAC_DOMAIN_INFO ) == CAC_DOMAIN_INFO ) {
472 DOM_SID *domain_sid;
473 char *dom_name;
475 hnd->status =
476 rpccli_lsa_query_info_policy( pipe_hnd, mem_ctx,
477 op->in.pol,
478 CAC_DOMAIN_INFO,
479 &dom_name,
480 &domain_sid );
481 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
482 /*if we succeeded above, report partial success */
483 result = CAC_FAILURE;
484 goto done;
485 } else if ( result == CAC_FAILURE ) {
486 /*if we failed above but succeded here then report partial success */
487 result = CAC_PARTIAL_SUCCESS;
490 op->out.domain_sid = talloc( mem_ctx, CacSidInfo );
491 if ( !op->out.domain_sid ) {
492 hnd->status = NT_STATUS_NO_MEMORY;
493 result = CAC_FAILURE;
494 goto done;
497 op->out.domain_sid->domain = dom_name;
498 sid_copy( &op->out.domain_sid->sid, domain_sid );
499 TALLOC_FREE( domain_sid );
502 done:
503 return result;
506 int cac_LsaQueryInfoPolicy( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
507 struct LsaQueryInfoPolicy *op )
509 struct rpc_pipe_client *pipe_hnd = NULL;
511 char *domain_name = NULL;
512 char *dns_name = NULL;
513 char *forest_name = NULL;
514 struct GUID *domain_guid = NULL;
515 DOM_SID *domain_sid = NULL;
517 if ( !hnd )
518 return CAC_FAILURE;
520 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
521 hnd->status = NT_STATUS_INVALID_HANDLE;
522 return CAC_FAILURE;
525 if ( !op || !op->in.pol ) {
526 hnd->status = NT_STATUS_INVALID_PARAMETER;
527 return CAC_FAILURE;
530 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
531 if ( !pipe_hnd ) {
532 hnd->status = NT_STATUS_INVALID_HANDLE;
533 return CAC_FAILURE;
536 /*only works if info_class parm is 12 */
537 hnd->status =
538 rpccli_lsa_query_info_policy2( pipe_hnd, mem_ctx, op->in.pol,
539 12, &domain_name, &dns_name,
540 &forest_name, &domain_guid,
541 &domain_sid );
543 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
544 return CAC_FAILURE;
547 op->out.domain_name = domain_name;
548 op->out.dns_name = dns_name;
549 op->out.forest_name = forest_name;
550 op->out.domain_guid = domain_guid;
551 op->out.domain_sid = domain_sid;
553 return CAC_SUCCESS;
556 int cac_LsaEnumSids( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
557 struct LsaEnumSids *op )
559 struct rpc_pipe_client *pipe_hnd = NULL;
561 uint32 num_sids;
562 DOM_SID *sids;
564 if ( !hnd )
565 return CAC_FAILURE;
567 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
568 hnd->status = NT_STATUS_INVALID_HANDLE;
569 return CAC_FAILURE;
572 if ( !op || !op->in.pol ) {
573 hnd->status = NT_STATUS_INVALID_PARAMETER;
574 return CAC_FAILURE;
577 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
578 if ( !pipe_hnd ) {
579 hnd->status = NT_STATUS_INVALID_HANDLE;
580 return CAC_FAILURE;
583 hnd->status =
584 rpccli_lsa_enum_sids( pipe_hnd, mem_ctx, op->in.pol,
585 &( op->out.resume_idx ),
586 op->in.pref_max_sids, &num_sids,
587 &sids );
589 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
590 return CAC_FAILURE;
593 op->out.num_sids = num_sids;
594 op->out.sids = sids;
596 return CAC_SUCCESS;
600 int cac_LsaEnumAccountRights( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
601 struct LsaEnumAccountRights *op )
603 struct rpc_pipe_client *pipe_hnd = NULL;
605 uint32 count = 0;
606 char **privs = NULL;
608 if ( !hnd )
609 return CAC_FAILURE;
611 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
612 hnd->status = NT_STATUS_INVALID_HANDLE;
613 return CAC_FAILURE;
616 if ( !op->in.pol ) {
617 hnd->status = NT_STATUS_INVALID_PARAMETER;
618 return CAC_FAILURE;
621 if ( !op->in.name && !op->in.sid ) {
622 hnd->status = NT_STATUS_INVALID_PARAMETER;
623 return CAC_FAILURE;
626 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
627 if ( !pipe_hnd ) {
628 hnd->status = NT_STATUS_INVALID_HANDLE;
629 return CAC_FAILURE;
632 if ( op->in.name && !op->in.sid ) {
633 DOM_SID *user_sid = NULL;
634 enum lsa_SidType *type;
636 /*lookup the SID */
637 hnd->status =
638 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
639 op->in.pol, 1,
640 ( const char ** ) &( op->in.
641 name ),
642 NULL, &user_sid, &type );
644 if ( !NT_STATUS_IS_OK( hnd->status ) )
645 return CAC_FAILURE;
647 op->in.sid = user_sid;
650 hnd->status =
651 rpccli_lsa_enum_account_rights( pipe_hnd, mem_ctx, op->in.pol,
652 op->in.sid, &count, &privs );
654 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
655 return CAC_FAILURE;
658 op->out.num_privs = count;
659 op->out.priv_names = privs;
661 return CAC_SUCCESS;
664 int cac_LsaEnumTrustedDomains( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
665 struct LsaEnumTrustedDomains *op )
667 struct rpc_pipe_client *pipe_hnd;
669 uint32 num_domains;
670 char **domain_names;
671 DOM_SID *domain_sids;
673 if ( !hnd )
674 return CAC_FAILURE;
676 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
677 hnd->status = NT_STATUS_INVALID_HANDLE;
678 return CAC_FAILURE;
681 if ( !op->in.pol ) {
682 hnd->status = NT_STATUS_INVALID_PARAMETER;
683 return CAC_FAILURE;
686 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
687 if ( !pipe_hnd ) {
688 hnd->status = NT_STATUS_INVALID_HANDLE;
689 return CAC_FAILURE;
692 hnd->status =
693 rpccli_lsa_enum_trust_dom( pipe_hnd, mem_ctx, op->in.pol,
694 &( op->out.resume_idx ),
695 &num_domains, &domain_names,
696 &domain_sids );
698 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
699 return CAC_FAILURE;
702 op->out.num_domains = num_domains;
703 op->out.domain_names = domain_names;
704 op->out.domain_sids = domain_sids;
706 return CAC_SUCCESS;
709 int cac_LsaOpenTrustedDomain( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
710 struct LsaOpenTrustedDomain *op )
712 struct rpc_pipe_client *pipe_hnd = NULL;
714 POLICY_HND *dom_pol = NULL;
716 if ( !hnd )
717 return CAC_FAILURE;
719 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
720 hnd->status = NT_STATUS_INVALID_HANDLE;
721 return CAC_FAILURE;
724 if ( !op->in.pol || !op->in.access || !op->in.domain_sid ) {
725 hnd->status = NT_STATUS_INVALID_PARAMETER;
726 return CAC_FAILURE;
729 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
730 if ( !pipe_hnd ) {
731 hnd->status = NT_STATUS_INVALID_HANDLE;
732 return CAC_FAILURE;
735 dom_pol = talloc( mem_ctx, POLICY_HND );
736 if ( !dom_pol ) {
737 hnd->status = NT_STATUS_NO_MEMORY;
738 errno = ENOMEM;
739 return CAC_FAILURE;
742 hnd->status =
743 rpccli_lsa_open_trusted_domain( pipe_hnd, mem_ctx, op->in.pol,
744 op->in.domain_sid,
745 op->in.access, dom_pol );
747 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
748 return CAC_FAILURE;
751 op->out.domain_pol = dom_pol;
753 return CAC_SUCCESS;
756 int cac_LsaQueryTrustedDomainInfo( CacServerHandle * hnd,
757 TALLOC_CTX * mem_ctx,
758 struct LsaQueryTrustedDomainInfo *op )
760 struct rpc_pipe_client *pipe_hnd = NULL;
762 LSA_TRUSTED_DOMAIN_INFO *dom_info;
764 if ( !hnd )
765 return CAC_FAILURE;
767 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
768 hnd->status = NT_STATUS_INVALID_HANDLE;
769 return CAC_FAILURE;
772 if ( !op->in.pol || !op->in.info_class ) {
773 hnd->status = NT_STATUS_INVALID_PARAMETER;
774 return CAC_FAILURE;
777 if ( !op->in.domain_sid && !op->in.domain_name ) {
778 hnd->status = NT_STATUS_INVALID_PARAMETER;
779 return CAC_FAILURE;
782 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
783 if ( !pipe_hnd ) {
784 hnd->status = NT_STATUS_INVALID_HANDLE;
785 return CAC_FAILURE;
788 if ( op->in.domain_sid ) {
789 hnd->status =
790 rpccli_lsa_query_trusted_domain_info_by_sid( pipe_hnd,
791 mem_ctx,
792 op->in.
793 pol,
794 op->in.
795 info_class,
796 op->in.
797 domain_sid,
798 &dom_info );
799 } else if ( op->in.domain_name ) {
800 hnd->status =
801 rpccli_lsa_query_trusted_domain_info_by_name
802 ( pipe_hnd, mem_ctx, op->in.pol, op->in.info_class,
803 op->in.domain_name, &dom_info );
806 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
807 return CAC_FAILURE;
810 op->out.info = dom_info;
812 return CAC_SUCCESS;
816 int cac_LsaEnumPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
817 struct LsaEnumPrivileges *op )
819 struct rpc_pipe_client *pipe_hnd = NULL;
821 uint32 num_privs;
822 char **priv_names;
823 uint32 *high_bits;
824 uint32 *low_bits;
826 if ( !hnd ) {
827 return CAC_FAILURE;
830 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
831 hnd->status = NT_STATUS_INVALID_HANDLE;
832 return CAC_FAILURE;
835 if ( !op || !op->in.pol ) {
836 hnd->status = NT_STATUS_INVALID_PARAMETER;
837 return CAC_FAILURE;
840 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
841 if ( !pipe_hnd ) {
842 hnd->status = NT_STATUS_INVALID_HANDLE;
843 return CAC_FAILURE;
846 hnd->status =
847 rpccli_lsa_enum_privilege( pipe_hnd, mem_ctx, op->in.pol,
848 &( op->out.resume_idx ),
849 op->in.pref_max_privs, &num_privs,
850 &priv_names, &high_bits,
851 &low_bits );
853 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
854 return CAC_FAILURE;
857 op->out.num_privs = num_privs;
858 op->out.priv_names = priv_names;
859 op->out.high_bits = high_bits;
860 op->out.low_bits = low_bits;
862 return CAC_SUCCESS;
865 int cac_LsaOpenAccount( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
866 struct LsaOpenAccount *op )
868 struct rpc_pipe_client *pipe_hnd = NULL;
870 POLICY_HND *user_pol = NULL;
872 if ( !hnd ) {
873 return CAC_FAILURE;
876 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
877 hnd->status = NT_STATUS_INVALID_HANDLE;
878 return CAC_FAILURE;
881 if ( !op || !op->in.pol ) {
882 hnd->status = NT_STATUS_INVALID_PARAMETER;
883 return CAC_FAILURE;
886 if ( !op->in.sid && !op->in.name ) {
887 hnd->status = NT_STATUS_INVALID_PARAMETER;
888 return CAC_FAILURE;
891 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
892 if ( !pipe_hnd ) {
893 hnd->status = NT_STATUS_INVALID_HANDLE;
894 return CAC_FAILURE;
897 /*look up the user's SID if we have to */
898 if ( op->in.name && !op->in.sid ) {
899 DOM_SID *user_sid = NULL;
900 enum lsa_SidType *type;
902 /*lookup the SID */
903 hnd->status =
904 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
905 op->in.pol, 1,
906 ( const char ** ) &( op->in.
907 name ),
908 NULL, &user_sid, &type );
910 if ( !NT_STATUS_IS_OK( hnd->status ) )
911 return CAC_FAILURE;
913 op->in.sid = user_sid;
916 user_pol = talloc( mem_ctx, POLICY_HND );
917 if ( !user_pol ) {
918 hnd->status = NT_STATUS_NO_MEMORY;
919 return CAC_FAILURE;
922 hnd->status =
923 rpccli_lsa_open_account( pipe_hnd, mem_ctx, op->in.pol,
924 op->in.sid, op->in.access,
925 user_pol );
927 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
928 TALLOC_FREE( user_pol );
929 return CAC_FAILURE;
932 op->out.user = user_pol;
934 return CAC_SUCCESS;
938 int cac_LsaAddPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
939 struct LsaAddPrivileges *op )
941 struct rpc_pipe_client *pipe_hnd = NULL;
943 DOM_SID *user_sid = NULL;
944 enum lsa_SidType *type = NULL;
946 if ( !hnd ) {
947 return CAC_FAILURE;
950 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
951 hnd->status = NT_STATUS_INVALID_HANDLE;
952 return CAC_FAILURE;
955 if ( !op || !op->in.pol || !op->in.priv_names ) {
956 hnd->status = NT_STATUS_INVALID_PARAMETER;
957 return CAC_FAILURE;
960 if ( !op->in.sid && !op->in.name ) {
961 hnd->status = NT_STATUS_INVALID_PARAMETER;
962 return CAC_FAILURE;
965 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
966 if ( !pipe_hnd ) {
967 hnd->status = NT_STATUS_INVALID_HANDLE;
968 return CAC_FAILURE;
971 if ( op->in.name && !op->in.sid ) {
972 /*lookup the SID */
973 hnd->status =
974 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
975 op->in.pol, 1,
976 ( const char ** ) &( op->in.
977 name ),
978 NULL, &user_sid, &type );
980 if ( !NT_STATUS_IS_OK( hnd->status ) )
981 return CAC_FAILURE;
983 op->in.sid = user_sid;
986 hnd->status =
987 rpccli_lsa_add_account_rights( pipe_hnd, mem_ctx, op->in.pol,
988 *( op->in.sid ),
989 op->in.num_privs,
990 ( const char ** ) op->in.
991 priv_names );
993 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
994 return CAC_FAILURE;
997 return CAC_SUCCESS;
1000 int cac_LsaRemovePrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1001 struct LsaRemovePrivileges *op )
1003 struct rpc_pipe_client *pipe_hnd = NULL;
1005 DOM_SID *user_sid = NULL;
1006 enum lsa_SidType *type = NULL;
1008 if ( !hnd ) {
1009 return CAC_FAILURE;
1012 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
1013 hnd->status = NT_STATUS_INVALID_HANDLE;
1014 return CAC_FAILURE;
1017 if ( !op || !op->in.pol || !op->in.priv_names ) {
1018 hnd->status = NT_STATUS_INVALID_PARAMETER;
1019 return CAC_FAILURE;
1022 if ( !op->in.sid && !op->in.name ) {
1023 hnd->status = NT_STATUS_INVALID_PARAMETER;
1024 return CAC_FAILURE;
1027 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
1028 if ( !pipe_hnd ) {
1029 hnd->status = NT_STATUS_INVALID_HANDLE;
1030 return CAC_FAILURE;
1033 if ( op->in.name && !op->in.sid ) {
1034 /*lookup the SID */
1035 hnd->status =
1036 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
1037 op->in.pol, 1,
1038 ( const char ** ) &( op->in.
1039 name ),
1040 NULL, &user_sid, &type );
1042 if ( !NT_STATUS_IS_OK( hnd->status ) )
1043 return CAC_FAILURE;
1045 op->in.sid = user_sid;
1048 hnd->status =
1049 rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx,
1050 op->in.pol, *( op->in.sid ),
1051 False, op->in.num_privs,
1052 ( const char ** ) op->in.
1053 priv_names );
1055 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1056 return CAC_FAILURE;
1059 return CAC_SUCCESS;
1062 int cac_LsaClearPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1063 struct LsaClearPrivileges *op )
1065 struct rpc_pipe_client *pipe_hnd = NULL;
1067 DOM_SID *user_sid = NULL;
1068 enum lsa_SidType *type = NULL;
1070 if ( !hnd ) {
1071 return CAC_FAILURE;
1074 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
1075 hnd->status = NT_STATUS_INVALID_HANDLE;
1076 return CAC_FAILURE;
1079 if ( !op || !op->in.pol ) {
1080 hnd->status = NT_STATUS_INVALID_PARAMETER;
1081 return CAC_FAILURE;
1084 if ( !op->in.sid && !op->in.name ) {
1085 hnd->status = NT_STATUS_INVALID_PARAMETER;
1086 return CAC_FAILURE;
1089 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
1090 if ( !pipe_hnd ) {
1091 hnd->status = NT_STATUS_INVALID_HANDLE;
1092 return CAC_FAILURE;
1095 if ( op->in.name && !op->in.sid ) {
1096 /*lookup the SID */
1097 hnd->status =
1098 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
1099 op->in.pol, 1,
1100 ( const char ** ) &( op->in.
1101 name ),
1102 NULL, &user_sid, &type );
1104 if ( !NT_STATUS_IS_OK( hnd->status ) )
1105 return CAC_FAILURE;
1107 op->in.sid = user_sid;
1110 hnd->status =
1111 rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx,
1112 op->in.pol, *( op->in.sid ),
1113 True, 0, NULL );
1115 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1116 return CAC_FAILURE;
1119 return CAC_SUCCESS;
1122 int cac_LsaSetPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1123 struct LsaAddPrivileges *op )
1125 struct rpc_pipe_client *pipe_hnd = NULL;
1127 DOM_SID *user_sid = NULL;
1128 enum lsa_SidType *type = NULL;
1130 if ( !hnd ) {
1131 return CAC_FAILURE;
1134 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
1135 hnd->status = NT_STATUS_INVALID_HANDLE;
1136 return CAC_FAILURE;
1139 if ( !op || !op->in.pol || !op->in.priv_names ) {
1140 hnd->status = NT_STATUS_INVALID_PARAMETER;
1141 return CAC_FAILURE;
1144 if ( !op->in.sid && !op->in.name ) {
1145 hnd->status = NT_STATUS_INVALID_PARAMETER;
1146 return CAC_FAILURE;
1149 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
1150 if ( !pipe_hnd ) {
1151 return CAC_FAILURE;
1154 if ( op->in.name && !op->in.sid ) {
1155 /*lookup the SID */
1156 hnd->status =
1157 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
1158 op->in.pol, 1,
1159 ( const char ** ) &( op->in.
1160 name ),
1161 NULL, &user_sid, &type );
1163 if ( !NT_STATUS_IS_OK( hnd->status ) )
1164 return CAC_FAILURE;
1166 op->in.sid = user_sid;
1169 /*first remove all privileges */
1170 hnd->status =
1171 rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx,
1172 op->in.pol, *( op->in.sid ),
1173 True, 0, NULL );
1175 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1176 return CAC_FAILURE;
1179 hnd->status =
1180 rpccli_lsa_add_account_rights( pipe_hnd, mem_ctx, op->in.pol,
1181 *( op->in.sid ),
1182 op->in.num_privs,
1183 ( const char ** ) op->in.
1184 priv_names );
1186 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1187 return CAC_FAILURE;
1190 return CAC_SUCCESS;
1193 int cac_LsaGetSecurityObject( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1194 struct LsaGetSecurityObject *op )
1196 struct rpc_pipe_client *pipe_hnd = NULL;
1198 /*this is taken from rpcclient/cmd_lsarpc.c */
1199 uint16 info_level = 4;
1201 SEC_DESC_BUF *sec_out = NULL;
1203 if ( !hnd ) {
1204 return CAC_FAILURE;
1207 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
1208 hnd->status = NT_STATUS_INVALID_HANDLE;
1209 return CAC_FAILURE;
1212 if ( !op || !op->in.pol ) {
1213 hnd->status = NT_STATUS_INVALID_PARAMETER;
1214 return CAC_FAILURE;
1217 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
1218 if ( !pipe_hnd ) {
1219 hnd->status = NT_STATUS_INVALID_HANDLE;
1220 return CAC_FAILURE;
1223 hnd->status =
1224 rpccli_lsa_query_secobj( pipe_hnd, mem_ctx, op->in.pol,
1225 info_level, &sec_out );
1227 if ( !NT_STATUS_IS_OK( hnd->status ) )
1228 return CAC_FAILURE;
1230 op->out.sec = sec_out;
1232 return CAC_FAILURE;