r14196: Move to using talloc, not malloc for all policy handles.
[Samba/nascimento.git] / source3 / libmsrpc / cac_lsarpc.c
blob13aaa017548202d7acfcbcf631e4a4678cdf5b8a
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 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
63 if(!pipe_hnd) {
64 hnd->status = NT_STATUS_INVALID_HANDLE;
65 return CAC_FAILURE;
68 policy = TALLOC_P(mem_ctx, POLICY_HND);
69 if(!policy) {
70 errno = ENOMEM;
71 hnd->status = NT_STATUS_NO_MEMORY;
72 return CAC_FAILURE;
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)) {
98 return CAC_FAILURE;
101 op->out.pol = policy;
103 return CAC_SUCCESS;
106 int cac_LsaClosePolicy(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *pol) {
108 struct rpc_pipe_client *pipe_hnd = NULL;
110 if(!hnd)
111 return CAC_FAILURE;
113 if(!pol)
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;
118 return CAC_FAILURE;
121 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
122 if(!pipe_hnd) {
123 hnd->status = NT_STATUS_INVALID_HANDLE;
124 return CAC_FAILURE;
127 hnd->status = rpccli_lsa_close(pipe_hnd, mem_ctx, pol);
129 TALLOC_FREE(pol);
131 if(!NT_STATUS_IS_OK(hnd->status))
132 return CAC_FAILURE;
134 return CAC_SUCCESS;
137 int cac_LsaGetNamesFromSids(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaGetNamesFromSids *op) {
138 struct rpc_pipe_client *pipe_hnd = NULL;
140 int result = -1;
142 int i;
144 /*buffers for outputs*/
145 char **domains = NULL;
146 char **names = NULL;
147 uint32 *types = NULL;
149 CacSidInfo *sids_out = NULL;
150 DOM_SID *unknown_out = NULL;
151 int num_unknown = 0;
153 int num_sids;
155 int found_idx;
156 int unknown_idx;
158 if(!hnd)
159 return CAC_FAILURE;
161 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
162 hnd->status = NT_STATUS_INVALID_HANDLE;
163 return CAC_FAILURE;
166 if(!mem_ctx || !op || !op->in.pol || !op->in.sids) {
167 hnd->status = NT_STATUS_INVALID_PARAMETER;
168 return CAC_FAILURE;
171 num_sids = op->in.num_sids;
173 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
174 if(!pipe_hnd) {
175 hnd->status = NT_STATUS_INVALID_HANDLE;
176 return CAC_FAILURE;
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);
188 if(!sids_out) {
189 errno = ENOMEM;
190 hnd->status = NT_STATUS_NO_MEMORY;
191 return CAC_FAILURE;
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) {
207 num_unknown++;
211 if( num_unknown >= num_sids) {
212 hnd->status = NT_STATUS_UNSUCCESSFUL;
213 return CAC_FAILURE;
216 sids_out = TALLOC_ARRAY(mem_ctx, CacSidInfo, (num_sids - num_unknown));
217 if(!sids_out) {
218 errno = ENOMEM;
219 hnd->status = NT_STATUS_NO_MEMORY;
220 return CAC_FAILURE;
223 unknown_out = TALLOC_ARRAY(mem_ctx, DOM_SID, num_unknown);
224 if(!unknown_out) {
225 errno = ENOMEM;
226 hnd->status = NT_STATUS_NO_MEMORY;
227 return CAC_FAILURE;
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];
239 found_idx++;
241 else { /*then this one didnt work out*/
242 unknown_out[unknown_idx] = op->in.sids[i];
244 unknown_idx++;
248 result = CAC_PARTIAL_SUCCESS;
250 else { /*then it failed for some reason*/
251 return CAC_FAILURE;
254 op->out.num_found = num_sids - num_unknown;
255 op->out.sids = sids_out;
256 op->out.unknown = unknown_out;
258 return result;
262 int cac_LsaGetSidsFromNames(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaGetSidsFromNames *op) {
263 struct rpc_pipe_client *pipe_hnd = NULL;
264 int result = -1;
266 int i;
268 /*buffers for outputs*/
269 DOM_SID *sids = NULL;
270 uint32 *types = NULL;
272 CacSidInfo *sids_out = NULL;
273 char **unknown_out = NULL;
274 int num_unknown = 0;
276 int num_names;
278 int found_idx = 0;
279 int unknown_idx = 0;
281 if(!hnd)
282 return CAC_FAILURE;
284 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
285 hnd->status = NT_STATUS_INVALID_HANDLE;
286 return CAC_FAILURE;
289 if(!mem_ctx || !op || !op->in.pol || !op->in.names) {
290 hnd->status = NT_STATUS_INVALID_PARAMETER;
291 return CAC_FAILURE;
294 num_names = op->in.num_names;
296 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
297 if(!pipe_hnd) {
298 hnd->status = NT_STATUS_INVALID_HANDLE;
299 return CAC_FAILURE;
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);
310 if(!sids_out) {
311 errno = ENOMEM;
312 hnd->status = NT_STATUS_NO_MEMORY;
313 return CAC_FAILURE;
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) {
329 num_unknown++;
333 if( num_unknown >= num_names) {
334 hnd->status = NT_STATUS_UNSUCCESSFUL;
335 return CAC_FAILURE;
338 sids_out = TALLOC_ARRAY(mem_ctx, CacSidInfo, (num_names - num_unknown));
339 if(!sids_out) {
340 errno = ENOMEM;
341 hnd->status = NT_STATUS_NO_MEMORY;
342 return CAC_FAILURE;
345 unknown_out = TALLOC_ARRAY(mem_ctx, char *, num_unknown);
346 if(!unknown_out) {
347 errno = ENOMEM;
348 hnd->status = NT_STATUS_NO_MEMORY;
349 return CAC_FAILURE;
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;
361 found_idx++;
363 else { /*then this one didnt work out*/
364 unknown_out[unknown_idx] = talloc_strdup(mem_ctx, op->in.names[i]);
366 unknown_idx++;
370 result = CAC_PARTIAL_SUCCESS;
372 else { /*then it failed for some reason*/
373 return CAC_FAILURE;
376 op->out.num_found = num_names - num_unknown;
377 op->out.sids = sids_out;
378 op->out.unknown = unknown_out;
380 return result;
384 int cac_LsaFetchSid(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaFetchSid *op) {
385 struct rpc_pipe_client *pipe_hnd = NULL;
386 int result = -1;
388 if(!hnd)
389 return CAC_FAILURE;
391 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
392 hnd->status = NT_STATUS_INVALID_HANDLE;
393 return CAC_FAILURE;
396 if(!mem_ctx || !op || !op->in.pol) {
397 hnd->status = NT_STATUS_INVALID_PARAMETER;
398 return CAC_FAILURE;
401 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
402 if(!pipe_hnd) {
403 hnd->status = NT_STATUS_INVALID_HANDLE;
404 return CAC_FAILURE;
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;
418 goto domain;
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;
425 goto domain;
428 op->out.local_sid->domain = dom_name;
430 sid_copy(&op->out.local_sid->sid, local_sid);
431 TALLOC_FREE(local_sid);
434 domain:
436 if( (op->in.info_class & CAC_DOMAIN_INFO) == CAC_DOMAIN_INFO) {
437 DOM_SID *domain_sid;
438 char *dom_name;
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;
444 goto done;
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;
455 goto done;
458 op->out.domain_sid->domain = dom_name;
459 sid_copy(&op->out.domain_sid->sid, domain_sid);
460 TALLOC_FREE(domain_sid);
463 done:
464 return result;
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;
476 if(!hnd)
477 return CAC_FAILURE;
479 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
480 hnd->status = NT_STATUS_INVALID_HANDLE;
481 return CAC_FAILURE;
484 if(!op->in.pol) {
485 hnd->status = NT_STATUS_INVALID_PARAMETER;
486 return CAC_FAILURE;
489 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
490 if(!pipe_hnd) {
491 hnd->status = NT_STATUS_INVALID_HANDLE;
492 return CAC_FAILURE;
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)) {
500 return CAC_FAILURE;
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;
509 return CAC_SUCCESS;
512 int cac_LsaEnumSids(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaEnumSids *op) {
513 struct rpc_pipe_client *pipe_hnd = NULL;
515 uint32 num_sids;
516 DOM_SID *sids;
518 if(!hnd)
519 return CAC_FAILURE;
521 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
522 hnd->status = NT_STATUS_INVALID_HANDLE;
523 return CAC_FAILURE;
526 if(!op || !op->in.pol) {
527 hnd->status = NT_STATUS_INVALID_PARAMETER;
528 return CAC_FAILURE;
531 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
532 if(!pipe_hnd) {
533 hnd->status = NT_STATUS_INVALID_HANDLE;
534 return CAC_FAILURE;
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)) {
540 return CAC_FAILURE;
543 op->out.num_sids = num_sids;
544 op->out.sids = sids;
546 return CAC_SUCCESS;
550 int cac_LsaEnumAccountRights(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaEnumAccountRights *op) {
551 struct rpc_pipe_client *pipe_hnd = NULL;
553 uint32 count = 0;
554 char **privs = NULL;
556 if(!hnd)
557 return CAC_FAILURE;
559 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
560 hnd->status = NT_STATUS_INVALID_HANDLE;
561 return CAC_FAILURE;
564 if(!op->in.pol) {
565 hnd->status = NT_STATUS_INVALID_PARAMETER;
566 return CAC_FAILURE;
569 if(!op->in.name && !op->in.sid) {
570 hnd->status = NT_STATUS_INVALID_PARAMETER;
571 return CAC_FAILURE;
574 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
575 if(!pipe_hnd) {
576 hnd->status = NT_STATUS_INVALID_HANDLE;
577 return CAC_FAILURE;
580 if(op->in.name && !op->in.sid) {
581 DOM_SID *user_sid = NULL;
582 uint32 *type;
584 /*lookup the SID*/
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))
588 return CAC_FAILURE;
590 op->in.sid = user_sid;
593 hnd->status = rpccli_lsa_enum_account_rights( pipe_hnd, mem_ctx, op->in.pol, op->in.sid,
594 &count, &privs);
596 if(!NT_STATUS_IS_OK(hnd->status)) {
597 return CAC_FAILURE;
600 op->out.num_privs = count;
601 op->out.priv_names = privs;
603 return CAC_SUCCESS;
606 int cac_LsaEnumTrustedDomains(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaEnumTrustedDomains *op) {
607 struct rpc_pipe_client *pipe_hnd;
609 uint32 num_domains;
610 char **domain_names;
611 DOM_SID *domain_sids;
613 if(!hnd)
614 return CAC_FAILURE;
616 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
617 hnd->status = NT_STATUS_INVALID_HANDLE;
618 return CAC_FAILURE;
621 if(!op->in.pol) {
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 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)) {
635 return CAC_FAILURE;
638 op->out.num_domains = num_domains;
639 op->out.domain_names = domain_names;
640 op->out.domain_sids = domain_sids;
642 return CAC_SUCCESS;
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;
650 if(!hnd)
651 return CAC_FAILURE;
653 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
654 hnd->status = NT_STATUS_INVALID_HANDLE;
655 return CAC_FAILURE;
658 if(!op->in.pol || !op->in.access || !op->in.domain_sid) {
659 hnd->status = NT_STATUS_INVALID_PARAMETER;
660 return CAC_FAILURE;
663 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
664 if(!pipe_hnd) {
665 hnd->status = NT_STATUS_INVALID_HANDLE;
666 return CAC_FAILURE;
669 dom_pol = talloc(mem_ctx, POLICY_HND);
670 if(!dom_pol) {
671 hnd->status = NT_STATUS_NO_MEMORY;
672 errno = ENOMEM;
673 return CAC_FAILURE;
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)) {
679 return CAC_FAILURE;
682 op->out.domain_pol = dom_pol;
684 return CAC_SUCCESS;
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;
692 if(!hnd)
693 return CAC_FAILURE;
695 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
696 hnd->status = NT_STATUS_INVALID_HANDLE;
697 return CAC_FAILURE;
700 if(!op->in.pol || !op->in.info_class) {
701 hnd->status = NT_STATUS_INVALID_PARAMETER;
702 return CAC_FAILURE;
705 if(!op->in.domain_sid && !op->in.domain_name) {
706 hnd->status = NT_STATUS_INVALID_PARAMETER;
707 return CAC_FAILURE;
710 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
711 if(!pipe_hnd) {
712 hnd->status = NT_STATUS_INVALID_HANDLE;
713 return CAC_FAILURE;
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)) {
724 return CAC_FAILURE;
727 op->out.info = dom_info;
729 return CAC_SUCCESS;
733 int cac_LsaEnumPrivileges(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaEnumPrivileges *op) {
734 struct rpc_pipe_client *pipe_hnd = NULL;
736 uint32 num_privs;
737 char **priv_names;
738 uint32 *high_bits;
739 uint32 *low_bits;
741 if(!hnd) {
742 return CAC_FAILURE;
745 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
746 hnd->status = NT_STATUS_INVALID_HANDLE;
747 return CAC_FAILURE;
750 if(!op || !op->in.pol) {
751 hnd->status = NT_STATUS_INVALID_PARAMETER;
752 return CAC_FAILURE;
755 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
756 if(!pipe_hnd) {
757 hnd->status = NT_STATUS_INVALID_HANDLE;
758 return CAC_FAILURE;
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)) {
765 return CAC_FAILURE;
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;
773 return CAC_SUCCESS;
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;
781 if(!hnd) {
782 return CAC_FAILURE;
785 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
786 hnd->status = NT_STATUS_INVALID_HANDLE;
787 return CAC_FAILURE;
790 if(!op || !op->in.pol) {
791 hnd->status = NT_STATUS_INVALID_PARAMETER;
792 return CAC_FAILURE;
795 if(!op->in.sid && !op->in.name) {
796 hnd->status = NT_STATUS_INVALID_PARAMETER;
797 return CAC_FAILURE;
800 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
801 if(!pipe_hnd) {
802 hnd->status = NT_STATUS_INVALID_HANDLE;
803 return CAC_FAILURE;
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;
809 uint32 *type;
811 /*lookup the SID*/
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))
815 return CAC_FAILURE;
817 op->in.sid = user_sid;
820 user_pol = talloc(mem_ctx, POLICY_HND);
821 if(!user_pol) {
822 hnd->status = NT_STATUS_NO_MEMORY;
823 return CAC_FAILURE;
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);
830 return CAC_FAILURE;
833 op->out.user = user_pol;
835 return CAC_SUCCESS;
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;
843 uint32 *type = NULL;
845 if(!hnd) {
846 return CAC_FAILURE;
849 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
850 hnd->status = NT_STATUS_INVALID_HANDLE;
851 return CAC_FAILURE;
854 if(!op || !op->in.pol || !op->in.priv_names) {
855 hnd->status = NT_STATUS_INVALID_PARAMETER;
856 return CAC_FAILURE;
859 if(!op->in.sid && !op->in.name) {
860 hnd->status = NT_STATUS_INVALID_PARAMETER;
861 return CAC_FAILURE;
864 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
865 if(!pipe_hnd) {
866 hnd->status = NT_STATUS_INVALID_HANDLE;
867 return CAC_FAILURE;
870 if(op->in.name && !op->in.sid) {
871 /*lookup the 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))
875 return CAC_FAILURE;
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)) {
883 return CAC_FAILURE;
886 return CAC_SUCCESS;
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;
893 uint32 *type = NULL;
895 if(!hnd) {
896 return CAC_FAILURE;
899 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
900 hnd->status = NT_STATUS_INVALID_HANDLE;
901 return CAC_FAILURE;
904 if(!op || !op->in.pol || !op->in.priv_names) {
905 hnd->status = NT_STATUS_INVALID_PARAMETER;
906 return CAC_FAILURE;
909 if(!op->in.sid && !op->in.name) {
910 hnd->status = NT_STATUS_INVALID_PARAMETER;
911 return CAC_FAILURE;
914 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
915 if(!pipe_hnd) {
916 hnd->status = NT_STATUS_INVALID_HANDLE;
917 return CAC_FAILURE;
920 if(op->in.name && !op->in.sid) {
921 /*lookup the 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))
925 return CAC_FAILURE;
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)) {
933 return CAC_FAILURE;
936 return CAC_SUCCESS;
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;
943 uint32 *type = NULL;
945 if(!hnd) {
946 return CAC_FAILURE;
949 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
950 hnd->status = NT_STATUS_INVALID_HANDLE;
951 return CAC_FAILURE;
954 if(!op || !op->in.pol) {
955 hnd->status = NT_STATUS_INVALID_PARAMETER;
956 return CAC_FAILURE;
959 if(!op->in.sid && !op->in.name) {
960 hnd->status = NT_STATUS_INVALID_PARAMETER;
961 return CAC_FAILURE;
964 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
965 if(!pipe_hnd) {
966 hnd->status = NT_STATUS_INVALID_HANDLE;
967 return CAC_FAILURE;
970 if(op->in.name && !op->in.sid) {
971 /*lookup the 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))
975 return CAC_FAILURE;
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)) {
983 return CAC_FAILURE;
986 return CAC_SUCCESS;
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;
993 uint32 *type = NULL;
995 if(!hnd) {
996 return CAC_FAILURE;
999 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
1000 hnd->status = NT_STATUS_INVALID_HANDLE;
1001 return CAC_FAILURE;
1004 if(!op || !op->in.pol || !op->in.priv_names) {
1005 hnd->status = NT_STATUS_INVALID_PARAMETER;
1006 return CAC_FAILURE;
1009 if(!op->in.sid && !op->in.name) {
1010 hnd->status = NT_STATUS_INVALID_PARAMETER;
1011 return CAC_FAILURE;
1014 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
1015 if(!pipe_hnd) {
1016 return CAC_FAILURE;
1019 if(op->in.name && !op->in.sid) {
1020 /*lookup the 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))
1024 return CAC_FAILURE;
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)) {
1033 return CAC_FAILURE;
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)) {
1039 return CAC_FAILURE;
1042 return CAC_SUCCESS;
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;
1053 if(!hnd) {
1054 return CAC_FAILURE;
1057 if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
1058 hnd->status = NT_STATUS_INVALID_HANDLE;
1059 return CAC_FAILURE;
1062 if(!op || !op->in.pol) {
1063 hnd->status = NT_STATUS_INVALID_PARAMETER;
1064 return CAC_FAILURE;
1067 pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
1068 if(!pipe_hnd) {
1069 hnd->status = NT_STATUS_INVALID_HANDLE;
1070 return CAC_FAILURE;
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))
1076 return CAC_FAILURE;
1078 op->out.sec = sec_out;
1080 return CAC_FAILURE;