r11161: another regression from merge; make sure to build vfs_full_audit modulebranch...
[Samba.git] / source / libmsrpc / cac_lsarpc.c
blobd2e52f01a4c5f7fc9627518ea9108124a50d3d14
1 /*
2 * Unix SMB/CIFS implementation.
3 * MS-RPC client library implementation (LSA pipe)
4 * Copyright (C) Chris Nicholls 2005.
5 *
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.
21 #include "libmsrpc.h"
22 #include "libsmb_internal.h"
24 int cac_LsaOpenPolicy(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaOpenPolicy *op) {
25 SMBCSRV *srv = NULL;
26 POLICY_HND *policy = NULL;
27 struct rpc_pipe_client *pipe_hnd = NULL;
29 if(!hnd)
30 return CAC_FAILURE;
32 if(!hnd->_internal.ctx) {
33 hnd->status = NT_STATUS_INVALID_HANDLE;
34 return CAC_FAILURE;
37 if(!mem_ctx || !op) {
38 hnd->status = NT_STATUS_INVALID_PARAMETER;
39 return CAC_FAILURE;
42 op->out.pol = NULL;
44 srv = cac_GetServer(hnd);
45 if(!srv) {
46 hnd->status = NT_STATUS_INVALID_CONNECTION;
47 return CAC_FAILURE;
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));
54 if(!pipe_hnd) {
55 hnd->status = NT_STATUS_UNSUCCESSFUL;
56 return CAC_FAILURE;
59 hnd->_internal.pipes[PI_LSARPC] = True;
62 policy = SMB_MALLOC_P(POLICY_HND);
63 if(!policy) {
64 errno = ENOMEM;
65 hnd->status = NT_STATUS_NO_MEMORY;
66 return CAC_FAILURE;
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)) {
92 SAFE_FREE(policy);
93 return CAC_FAILURE;
96 op->out.pol = policy;
98 return CAC_SUCCESS;
101 int cac_LsaClosePolicy(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *pol) {
103 struct rpc_pipe_client *pipe_hnd = NULL;
105 if(!hnd)
106 return CAC_FAILURE;
108 if(!pol)
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;
113 return CAC_FAILURE;
116 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
117 if(!pipe_hnd) {
118 hnd->status = NT_STATUS_INVALID_HANDLE;
119 return CAC_FAILURE;
123 hnd->status = rpccli_lsa_close(pipe_hnd, mem_ctx, pol);
125 if(!NT_STATUS_IS_OK(hnd->status))
126 return CAC_FAILURE;
128 SAFE_FREE(pol);
130 return CAC_SUCCESS;
133 int cac_LsaGetNamesFromSids(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaGetNamesFromSids *op) {
134 struct rpc_pipe_client *pipe_hnd = NULL;
136 int result = -1;
138 int i;
140 /*buffers for outputs*/
141 char **domains = NULL;
142 char **names = NULL;
143 uint32 *types = NULL;
145 CacSidInfo *sids_out = NULL;
146 DOM_SID *unknown_out = NULL;
147 int num_unknown = 0;
149 int num_sids;
151 int found_idx;
152 int unknown_idx;
154 if(!hnd)
155 return CAC_FAILURE;
157 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
158 hnd->status = NT_STATUS_INVALID_HANDLE;
159 return CAC_FAILURE;
162 if(!mem_ctx || !op || !op->in.pol || !op->in.sids) {
163 hnd->status = NT_STATUS_INVALID_PARAMETER;
164 return CAC_FAILURE;
167 num_sids = op->in.num_sids;
169 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
170 if(!pipe_hnd) {
171 hnd->status = NT_STATUS_INVALID_HANDLE;
172 return CAC_FAILURE;
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);
184 if(!sids_out) {
185 errno = ENOMEM;
186 hnd->status = NT_STATUS_NO_MEMORY;
187 return CAC_FAILURE;
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) {
203 num_unknown++;
207 if( num_unknown >= num_sids) {
208 hnd->status = NT_STATUS_UNSUCCESSFUL;
209 return CAC_FAILURE;
212 sids_out = TALLOC_ARRAY(mem_ctx, CacSidInfo, (num_sids - num_unknown));
213 if(!sids_out) {
214 errno = ENOMEM;
215 hnd->status = NT_STATUS_NO_MEMORY;
216 return CAC_FAILURE;
219 unknown_out = TALLOC_ARRAY(mem_ctx, DOM_SID, num_unknown);
220 if(!unknown_out) {
221 errno = ENOMEM;
222 hnd->status = NT_STATUS_NO_MEMORY;
223 return CAC_FAILURE;
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];
235 found_idx++;
237 else { /*then this one didnt work out*/
238 unknown_out[unknown_idx] = op->in.sids[i];
240 unknown_idx++;
244 result = CAC_PARTIAL_SUCCESS;
246 else { /*then it failed for some reason*/
247 return CAC_FAILURE;
250 op->out.num_found = num_sids - num_unknown;
251 op->out.sids = sids_out;
252 op->out.unknown = unknown_out;
254 return result;
258 int cac_LsaGetSidsFromNames(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaGetSidsFromNames *op) {
259 struct rpc_pipe_client *pipe_hnd = NULL;
260 int result = -1;
262 int i;
264 /*buffers for outputs*/
265 DOM_SID *sids = NULL;
266 uint32 *types = NULL;
268 CacSidInfo *sids_out = NULL;
269 char **unknown_out = NULL;
270 int num_unknown = 0;
272 int num_names;
274 int found_idx = 0;
275 int unknown_idx = 0;
277 if(!hnd)
278 return CAC_FAILURE;
280 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
281 hnd->status = NT_STATUS_INVALID_HANDLE;
282 return CAC_FAILURE;
285 if(!mem_ctx || !op || !op->in.pol || !op->in.names) {
286 hnd->status = NT_STATUS_INVALID_PARAMETER;
287 return CAC_FAILURE;
290 num_names = op->in.num_names;
292 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
293 if(!pipe_hnd) {
294 hnd->status = NT_STATUS_INVALID_HANDLE;
295 return CAC_FAILURE;
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);
306 if(!sids_out) {
307 errno = ENOMEM;
308 hnd->status = NT_STATUS_NO_MEMORY;
309 return CAC_FAILURE;
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) {
325 num_unknown++;
329 if( num_unknown >= num_names) {
330 hnd->status = NT_STATUS_UNSUCCESSFUL;
331 return CAC_FAILURE;
334 sids_out = TALLOC_ARRAY(mem_ctx, CacSidInfo, (num_names - num_unknown));
335 if(!sids_out) {
336 errno = ENOMEM;
337 hnd->status = NT_STATUS_NO_MEMORY;
338 return CAC_FAILURE;
341 unknown_out = TALLOC_ARRAY(mem_ctx, char *, num_unknown);
342 if(!unknown_out) {
343 errno = ENOMEM;
344 hnd->status = NT_STATUS_NO_MEMORY;
345 return CAC_FAILURE;
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;
357 found_idx++;
359 else { /*then this one didnt work out*/
360 unknown_out[unknown_idx] = talloc_strdup(mem_ctx, op->in.names[i]);
362 unknown_idx++;
366 result = CAC_PARTIAL_SUCCESS;
368 else { /*then it failed for some reason*/
369 return CAC_FAILURE;
372 op->out.num_found = num_names - num_unknown;
373 op->out.sids = sids_out;
374 op->out.unknown = unknown_out;
376 return result;
380 int cac_LsaFetchSid(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaFetchSid *op) {
381 struct rpc_pipe_client *pipe_hnd = NULL;
382 int result = -1;
384 if(!hnd)
385 return CAC_FAILURE;
387 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
388 hnd->status = NT_STATUS_INVALID_HANDLE;
389 return CAC_FAILURE;
392 if(!mem_ctx || !op || !op->in.pol) {
393 hnd->status = NT_STATUS_INVALID_PARAMETER;
394 return CAC_FAILURE;
397 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
398 if(!pipe_hnd) {
399 hnd->status = NT_STATUS_INVALID_HANDLE;
400 return CAC_FAILURE;
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;
414 goto domain;
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;
421 goto domain;
424 op->out.local_sid->domain = dom_name;
426 sid_copy(&op->out.local_sid->sid, local_sid);
427 talloc_free(local_sid);
430 domain:
432 if( (op->in.info_class & CAC_DOMAIN_INFO) == CAC_DOMAIN_INFO) {
433 DOM_SID *domain_sid;
434 char *dom_name;
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;
440 goto done;
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;
451 goto done;
454 op->out.domain_sid->domain = dom_name;
455 sid_copy(&op->out.domain_sid->sid, domain_sid);
456 talloc_free(domain_sid);
459 done:
460 return result;
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;
472 if(!hnd)
473 return CAC_FAILURE;
475 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
476 hnd->status = NT_STATUS_INVALID_HANDLE;
477 return CAC_FAILURE;
480 if(!op->in.pol) {
481 hnd->status = NT_STATUS_INVALID_PARAMETER;
482 return CAC_FAILURE;
485 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
486 if(!pipe_hnd) {
487 hnd->status = NT_STATUS_INVALID_HANDLE;
488 return CAC_FAILURE;
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)) {
496 return CAC_FAILURE;
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;
505 return CAC_SUCCESS;
508 int cac_LsaEnumSids(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaEnumSids *op) {
509 struct rpc_pipe_client *pipe_hnd = NULL;
511 uint32 num_sids;
512 DOM_SID *sids;
514 if(!hnd)
515 return CAC_FAILURE;
517 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
518 hnd->status = NT_STATUS_INVALID_HANDLE;
519 return CAC_FAILURE;
522 if(!op || !op->in.pol) {
523 hnd->status = NT_STATUS_INVALID_PARAMETER;
526 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
527 if(!pipe_hnd) {
528 hnd->status = NT_STATUS_INVALID_HANDLE;
529 return CAC_FAILURE;
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)) {
535 return CAC_FAILURE;
538 op->out.num_sids = num_sids;
539 op->out.sids = sids;
541 return CAC_SUCCESS;
545 int cac_LsaEnumAccountRights(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaEnumAccountRights *op) {
546 struct rpc_pipe_client *pipe_hnd = NULL;
548 uint32 count = 0;
549 char **privs = NULL;
551 if(!hnd)
552 return CAC_FAILURE;
554 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
555 hnd->status = NT_STATUS_INVALID_HANDLE;
556 return CAC_FAILURE;
559 if(!op->in.pol) {
560 hnd->status = NT_STATUS_INVALID_PARAMETER;
561 return CAC_FAILURE;
564 if(!op->in.name && !op->in.sid) {
565 hnd->status = NT_STATUS_INVALID_PARAMETER;
566 return CAC_FAILURE;
569 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
570 if(!pipe_hnd) {
571 hnd->status = NT_STATUS_INVALID_HANDLE;
572 return CAC_FAILURE;
575 if(op->in.name && !op->in.sid) {
576 DOM_SID *user_sid = NULL;
577 uint32 *type;
579 /*lookup the SID*/
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))
583 return CAC_FAILURE;
585 op->in.sid = user_sid;
588 hnd->status = rpccli_lsa_enum_account_rights( pipe_hnd, mem_ctx, op->in.pol, op->in.sid,
589 &count, &privs);
591 if(!NT_STATUS_IS_OK(hnd->status)) {
592 return CAC_FAILURE;
595 op->out.num_privs = count;
596 op->out.priv_names = privs;
598 return CAC_SUCCESS;
601 int cac_LsaEnumTrustedDomains(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaEnumTrustedDomains *op) {
602 struct rpc_pipe_client *pipe_hnd;
604 uint32 num_domains;
605 char **domain_names;
606 DOM_SID *domain_sids;
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 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
622 if(!pipe_hnd) {
623 hnd->status = NT_STATUS_INVALID_HANDLE;
624 return CAC_FAILURE;
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)) {
630 return CAC_FAILURE;
633 op->out.num_domains = num_domains;
634 op->out.domain_names = domain_names;
635 op->out.domain_sids = domain_sids;
637 return CAC_SUCCESS;
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;
645 if(!hnd)
646 return CAC_FAILURE;
648 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
649 hnd->status = NT_STATUS_INVALID_HANDLE;
650 return CAC_FAILURE;
653 if(!op->in.pol || !op->in.access || !op->in.domain_sid) {
654 hnd->status = NT_STATUS_INVALID_PARAMETER;
655 return CAC_FAILURE;
658 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
659 if(!pipe_hnd) {
660 hnd->status = NT_STATUS_INVALID_HANDLE;
661 return CAC_FAILURE;
664 dom_pol = talloc(mem_ctx, POLICY_HND);
665 if(!dom_pol) {
666 hnd->status = NT_STATUS_NO_MEMORY;
667 errno = ENOMEM;
668 return CAC_FAILURE;
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)) {
674 return CAC_FAILURE;
677 op->out.domain_pol = dom_pol;
679 return CAC_SUCCESS;
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;
687 if(!hnd)
688 return CAC_FAILURE;
690 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
691 hnd->status = NT_STATUS_INVALID_HANDLE;
692 return CAC_FAILURE;
695 if(!op->in.pol || !op->in.info_class) {
696 hnd->status = NT_STATUS_INVALID_PARAMETER;
697 return CAC_FAILURE;
700 if(!op->in.domain_sid && !op->in.domain_name) {
701 hnd->status = NT_STATUS_INVALID_PARAMETER;
702 return CAC_FAILURE;
705 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
706 if(!pipe_hnd) {
707 hnd->status = NT_STATUS_INVALID_HANDLE;
708 return CAC_FAILURE;
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)) {
719 return CAC_FAILURE;
722 op->out.info = dom_info;
724 return CAC_SUCCESS;
728 int cac_LsaEnumPrivileges(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaEnumPrivileges *op) {
729 struct rpc_pipe_client *pipe_hnd = NULL;
731 uint32 num_privs;
732 char **priv_names;
733 uint32 *high_bits;
734 uint32 *low_bits;
736 if(!hnd) {
737 return CAC_FAILURE;
740 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
741 hnd->status = NT_STATUS_INVALID_HANDLE;
742 return CAC_FAILURE;
745 if(!op || !op->in.pol) {
746 hnd->status = NT_STATUS_INVALID_PARAMETER;
747 return CAC_FAILURE;
750 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
751 if(!pipe_hnd) {
752 hnd->status = NT_STATUS_INVALID_HANDLE;
753 return CAC_FAILURE;
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)) {
760 return CAC_FAILURE;
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;
768 return CAC_SUCCESS;
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;
776 if(!hnd) {
777 return CAC_FAILURE;
780 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
781 hnd->status = NT_STATUS_INVALID_HANDLE;
782 return CAC_FAILURE;
785 if(!op || !op->in.pol) {
786 hnd->status = NT_STATUS_INVALID_PARAMETER;
787 return CAC_FAILURE;
790 if(!op->in.sid && !op->in.name) {
791 hnd->status = NT_STATUS_INVALID_PARAMETER;
792 return CAC_FAILURE;
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;
799 uint32 *type;
801 /*lookup the SID*/
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))
805 return CAC_FAILURE;
807 op->in.sid = user_sid;
810 user_pol = talloc(mem_ctx, POLICY_HND);
811 if(!user_pol) {
812 hnd->status = NT_STATUS_NO_MEMORY;
813 return CAC_FAILURE;
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);
820 return CAC_FAILURE;
823 op->out.user = user_pol;
825 return CAC_SUCCESS;
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;
833 uint32 *type = NULL;
835 if(!hnd) {
836 return CAC_FAILURE;
839 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
840 hnd->status = NT_STATUS_INVALID_HANDLE;
841 return CAC_FAILURE;
844 if(!op || !op->in.pol || !op->in.priv_names) {
845 hnd->status = NT_STATUS_INVALID_PARAMETER;
846 return CAC_FAILURE;
849 if(!op->in.sid && !op->in.name) {
850 hnd->status = NT_STATUS_INVALID_PARAMETER;
851 return CAC_FAILURE;
854 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
855 if(!pipe_hnd) {
856 hnd->status = NT_STATUS_INVALID_HANDLE;
857 return CAC_FAILURE;
860 if(op->in.name && !op->in.sid) {
861 /*lookup the 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))
865 return CAC_FAILURE;
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)) {
873 return CAC_FAILURE;
876 return CAC_SUCCESS;
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;
883 uint32 *type = NULL;
885 if(!hnd) {
886 return CAC_FAILURE;
889 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
890 hnd->status = NT_STATUS_INVALID_HANDLE;
891 return CAC_FAILURE;
894 if(!op || !op->in.pol || !op->in.priv_names) {
895 hnd->status = NT_STATUS_INVALID_PARAMETER;
896 return CAC_FAILURE;
899 if(!op->in.sid && !op->in.name) {
900 hnd->status = NT_STATUS_INVALID_PARAMETER;
901 return CAC_FAILURE;
904 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
905 if(!pipe_hnd) {
906 hnd->status = NT_STATUS_INVALID_HANDLE;
907 return CAC_FAILURE;
910 if(op->in.name && !op->in.sid) {
911 /*lookup the 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))
915 return CAC_FAILURE;
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)) {
923 return CAC_FAILURE;
926 return CAC_SUCCESS;
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;
933 uint32 *type = NULL;
935 if(!hnd) {
936 return CAC_FAILURE;
939 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
940 hnd->status = NT_STATUS_INVALID_HANDLE;
941 return CAC_FAILURE;
944 if(!op || !op->in.pol) {
945 hnd->status = NT_STATUS_INVALID_PARAMETER;
946 return CAC_FAILURE;
949 if(!op->in.sid && !op->in.name) {
950 hnd->status = NT_STATUS_INVALID_PARAMETER;
951 return CAC_FAILURE;
954 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
955 if(!pipe_hnd) {
956 hnd->status = NT_STATUS_INVALID_HANDLE;
957 return CAC_FAILURE;
960 if(op->in.name && !op->in.sid) {
961 /*lookup the 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))
965 return CAC_FAILURE;
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)) {
973 return CAC_FAILURE;
976 return CAC_SUCCESS;
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;
983 uint32 *type = NULL;
985 if(!hnd) {
986 return CAC_FAILURE;
989 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
990 hnd->status = NT_STATUS_INVALID_HANDLE;
991 return CAC_FAILURE;
994 if(!op || !op->in.pol || !op->in.priv_names) {
995 hnd->status = NT_STATUS_INVALID_PARAMETER;
996 return CAC_FAILURE;
999 if(!op->in.sid && !op->in.name) {
1000 hnd->status = NT_STATUS_INVALID_PARAMETER;
1001 return CAC_FAILURE;
1004 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
1005 if(!pipe_hnd) {
1006 return CAC_FAILURE;
1009 if(op->in.name && !op->in.sid) {
1010 /*lookup the 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))
1014 return CAC_FAILURE;
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)) {
1023 return CAC_FAILURE;
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)) {
1029 return CAC_FAILURE;
1032 return CAC_SUCCESS;
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;
1043 if(!hnd) {
1044 return CAC_FAILURE;
1047 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
1048 hnd->status = NT_STATUS_INVALID_HANDLE;
1049 return CAC_FAILURE;
1052 if(!op || !op->in.pol) {
1053 hnd->status = NT_STATUS_INVALID_PARAMETER;
1054 return CAC_FAILURE;
1057 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
1058 if(!pipe_hnd) {
1059 hnd->status = NT_STATUS_INVALID_HANDLE;
1060 return CAC_FAILURE;
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))
1066 return CAC_FAILURE;
1068 op->out.sec = sec_out;
1070 return CAC_FAILURE;