source: trunk-3.0/source/libmsrpc/cac_lsarpc.c@ 102

Last change on this file since 102 was 39, checked in by Paul Smedley, 18 years ago

Upgrade source to 3.0.25a

File size: 28.7 KB
Line 
1
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.
11 *
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.
16 *
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.
20 */
21
22#include "libmsrpc.h"
23#include "libsmb_internal.h"
24
25int cac_LsaOpenPolicy( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
26 struct LsaOpenPolicy *op )
27{
28 SMBCSRV *srv = NULL;
29 POLICY_HND *policy = NULL;
30 struct rpc_pipe_client *pipe_hnd = NULL;
31
32 if ( !hnd )
33 return CAC_FAILURE;
34
35 if ( !hnd->_internal.ctx ) {
36 hnd->status = NT_STATUS_INVALID_HANDLE;
37 return CAC_FAILURE;
38 }
39
40 if ( !mem_ctx || !op ) {
41 hnd->status = NT_STATUS_INVALID_PARAMETER;
42 return CAC_FAILURE;
43 }
44
45 op->out.pol = NULL;
46
47 srv = cac_GetServer( hnd );
48 if ( !srv ) {
49 hnd->status = NT_STATUS_INVALID_CONNECTION;
50 return CAC_FAILURE;
51 }
52
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 );
58
59 if ( !pipe_hnd ) {
60 hnd->status = NT_STATUS_UNSUCCESSFUL;
61 return CAC_FAILURE;
62 }
63
64 hnd->_internal.pipes[PI_LSARPC] = True;
65 }
66
67 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
68 if ( !pipe_hnd ) {
69 hnd->status = NT_STATUS_INVALID_HANDLE;
70 return CAC_FAILURE;
71 }
72
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;
78 }
79
80 /*need to make sure that our nt status is good otherwise check might fail below */
81 hnd->status = NT_STATUS_OK;
82
83 if ( hnd->_internal.srv_level >= SRV_WIN_2K ) {
84
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 */
86
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 );
92
93 }
94
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 );
101
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;
106 }
107
108 }
109
110 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
111 return CAC_FAILURE;
112 }
113
114 op->out.pol = policy;
115
116 return CAC_SUCCESS;
117}
118
119int cac_LsaClosePolicy( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
120 POLICY_HND * pol )
121{
122
123 struct rpc_pipe_client *pipe_hnd = NULL;
124
125 if ( !hnd )
126 return CAC_FAILURE;
127
128 if ( !pol )
129 return CAC_SUCCESS; /*if the policy handle doesnt exist then it's already closed */
130
131 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
132 hnd->status = NT_STATUS_INVALID_HANDLE;
133 return CAC_FAILURE;
134 }
135
136 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
137 if ( !pipe_hnd ) {
138 hnd->status = NT_STATUS_INVALID_HANDLE;
139 return CAC_FAILURE;
140 }
141
142 hnd->status = rpccli_lsa_close( pipe_hnd, mem_ctx, pol );
143
144 TALLOC_FREE( pol );
145
146 if ( !NT_STATUS_IS_OK( hnd->status ) )
147 return CAC_FAILURE;
148
149 return CAC_SUCCESS;
150}
151
152int cac_LsaGetNamesFromSids( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
153 struct LsaGetNamesFromSids *op )
154{
155 struct rpc_pipe_client *pipe_hnd = NULL;
156
157 int result = -1;
158
159 int i;
160
161 /*buffers for outputs */
162 char **domains = NULL;
163 char **names = NULL;
164 enum lsa_SidType *types = NULL;
165
166 CacSidInfo *sids_out = NULL;
167 DOM_SID *unknown_out = NULL;
168 int num_unknown = 0;
169
170 int num_sids;
171
172 int found_idx;
173 int unknown_idx;
174
175 if ( !hnd )
176 return CAC_FAILURE;
177
178 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
179 hnd->status = NT_STATUS_INVALID_HANDLE;
180 return CAC_FAILURE;
181 }
182
183 if ( !mem_ctx || !op || !op->in.pol || !op->in.sids ) {
184 hnd->status = NT_STATUS_INVALID_PARAMETER;
185 return CAC_FAILURE;
186 }
187
188 num_sids = op->in.num_sids;
189
190 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
191 if ( !pipe_hnd ) {
192 hnd->status = NT_STATUS_INVALID_HANDLE;
193 return CAC_FAILURE;
194 }
195
196
197
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 );
203
204 if ( NT_STATUS_IS_OK( hnd->status ) ) {
205 /*this is the easy part, just make the out.sids array */
206 if (num_sids) {
207 sids_out = TALLOC_ARRAY( mem_ctx, CacSidInfo, num_sids );
208 if ( !sids_out ) {
209 errno = ENOMEM;
210 hnd->status = NT_STATUS_NO_MEMORY;
211 return CAC_FAILURE;
212 }
213 } else {
214 sids_out = NULL;
215 }
216
217 for ( i = 0; i < num_sids; i++ ) {
218 sids_out[i].sid = op->in.sids[i];
219 sids_out[i].name = names[i];
220 sids_out[i].domain = domains[i];
221 }
222
223 result = CAC_SUCCESS;
224 } else if ( NT_STATUS_V( hnd->status ) ==
225 NT_STATUS_V( STATUS_SOME_UNMAPPED ) ) {
226 /*first find out how many couldn't be looked up */
227
228 for ( i = 0; i < num_sids; i++ ) {
229 if ( names[i] == NULL ) {
230 num_unknown++;
231 }
232 }
233
234 if ( num_unknown >= num_sids ) {
235 hnd->status = NT_STATUS_UNSUCCESSFUL;
236 return CAC_FAILURE;
237 }
238
239 if ( num_sids - num_unknown) {
240 sids_out =
241 TALLOC_ARRAY( mem_ctx, CacSidInfo,
242 ( num_sids - num_unknown ) );
243 if ( !sids_out ) {
244 errno = ENOMEM;
245 hnd->status = NT_STATUS_NO_MEMORY;
246 return CAC_FAILURE;
247 }
248 } else {
249 sids_out = NULL;
250 }
251
252 if (num_unknown) {
253 unknown_out = TALLOC_ARRAY( mem_ctx, DOM_SID, num_unknown );
254 if ( !unknown_out ) {
255 errno = ENOMEM;
256 hnd->status = NT_STATUS_NO_MEMORY;
257 return CAC_FAILURE;
258 }
259 } else {
260 unknown_out = NULL;
261 }
262 found_idx = unknown_idx = 0;
263
264 /*now we can actually do the real work */
265 for ( i = 0; i < num_sids; i++ ) {
266 if ( names[i] != NULL ) {
267 sids_out[found_idx].sid = op->in.sids[i];
268 sids_out[found_idx].name = names[i];
269 sids_out[found_idx].domain = domains[i];
270
271 found_idx++;
272 } else { /*then this one didnt work out */
273 unknown_out[unknown_idx] = op->in.sids[i];
274
275 unknown_idx++;
276 }
277 }
278
279 result = CAC_PARTIAL_SUCCESS;
280 } else { /*then it failed for some reason */
281 return CAC_FAILURE;
282 }
283
284 op->out.num_found = num_sids - num_unknown;
285 op->out.sids = sids_out;
286 op->out.unknown = unknown_out;
287
288 return result;
289
290}
291
292int cac_LsaGetSidsFromNames( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
293 struct LsaGetSidsFromNames *op )
294{
295 struct rpc_pipe_client *pipe_hnd = NULL;
296 int result = -1;
297
298 int i;
299
300 /*buffers for outputs */
301 DOM_SID *sids = NULL;
302 enum lsa_SidType *types = NULL;
303
304 CacSidInfo *sids_out = NULL;
305 char **unknown_out = NULL;
306 int num_unknown = 0;
307
308 int num_names;
309
310 int found_idx = 0;
311 int unknown_idx = 0;
312
313 if ( !hnd )
314 return CAC_FAILURE;
315
316 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
317 hnd->status = NT_STATUS_INVALID_HANDLE;
318 return CAC_FAILURE;
319 }
320
321 if ( !mem_ctx || !op || !op->in.pol || !op->in.names ) {
322 hnd->status = NT_STATUS_INVALID_PARAMETER;
323 return CAC_FAILURE;
324 }
325
326 num_names = op->in.num_names;
327
328 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
329 if ( !pipe_hnd ) {
330 hnd->status = NT_STATUS_INVALID_HANDLE;
331 return CAC_FAILURE;
332 }
333
334
335 /*now actually lookup the names */
336 hnd->status =
337 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol,
338 num_names,
339 ( const char ** ) op->in.names, NULL,
340 &sids, &types );
341
342 if ( NT_STATUS_IS_OK( hnd->status ) ) {
343 /*this is the easy part, just make the out.sids array */
344 if (num_names) {
345 sids_out = TALLOC_ARRAY( mem_ctx, CacSidInfo, num_names );
346 if ( !sids_out ) {
347 errno = ENOMEM;
348 hnd->status = NT_STATUS_NO_MEMORY;
349 return CAC_FAILURE;
350 }
351 } else {
352 sids_out = NULL;
353 }
354
355 for ( i = 0; i < num_names; i++ ) {
356 sids_out[i].sid = sids[i];
357 sids_out[i].name =
358 talloc_strdup( mem_ctx, op->in.names[i] );
359 sids_out[i].domain = NULL;
360 }
361
362 result = CAC_SUCCESS;
363 } else if ( NT_STATUS_V( hnd->status ) ==
364 NT_STATUS_V( STATUS_SOME_UNMAPPED ) ) {
365 /*first find out how many couldn't be looked up */
366
367 for ( i = 0; i < num_names; i++ ) {
368 if ( types[i] == SID_NAME_UNKNOWN ) {
369 num_unknown++;
370 }
371 }
372
373 if ( num_unknown >= num_names ) {
374 hnd->status = NT_STATUS_UNSUCCESSFUL;
375 return CAC_FAILURE;
376 }
377
378 if (num_names - num_unknown) {
379 sids_out =
380 TALLOC_ARRAY( mem_ctx, CacSidInfo,
381 ( num_names - num_unknown ) );
382 if ( !sids_out ) {
383 errno = ENOMEM;
384 hnd->status = NT_STATUS_NO_MEMORY;
385 return CAC_FAILURE;
386 }
387 } else {
388 sids_out = NULL;
389 }
390
391 if (num_unknown) {
392 unknown_out = TALLOC_ARRAY( mem_ctx, char *, num_unknown );
393 if ( !unknown_out ) {
394 errno = ENOMEM;
395 hnd->status = NT_STATUS_NO_MEMORY;
396 return CAC_FAILURE;
397 }
398 } else {
399 unknown_out = NULL;
400 }
401
402 unknown_idx = found_idx = 0;
403
404 /*now we can actually do the real work */
405 for ( i = 0; i < num_names; i++ ) {
406 if ( types[i] != SID_NAME_UNKNOWN ) {
407 sids_out[found_idx].sid = sids[i];
408 sids_out[found_idx].name =
409 talloc_strdup( mem_ctx,
410 op->in.names[i] );
411 sids_out[found_idx].domain = NULL;
412
413 found_idx++;
414 } else { /*then this one didnt work out */
415 unknown_out[unknown_idx] =
416 talloc_strdup( mem_ctx,
417 op->in.names[i] );
418
419 unknown_idx++;
420 }
421 }
422
423 result = CAC_PARTIAL_SUCCESS;
424 } else { /*then it failed for some reason */
425 return CAC_FAILURE;
426 }
427
428 op->out.num_found = num_names - num_unknown;
429 op->out.sids = sids_out;
430 op->out.unknown = unknown_out;
431
432 return result;
433
434}
435
436int cac_LsaFetchSid( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
437 struct LsaFetchSid *op )
438{
439 struct rpc_pipe_client *pipe_hnd = NULL;
440 int result = -1;
441
442 if ( !hnd )
443 return CAC_FAILURE;
444
445 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
446 hnd->status = NT_STATUS_INVALID_HANDLE;
447 return CAC_FAILURE;
448 }
449
450 if ( !mem_ctx || !op || !op->in.pol ) {
451 hnd->status = NT_STATUS_INVALID_PARAMETER;
452 return CAC_FAILURE;
453 }
454
455 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
456 if ( !pipe_hnd ) {
457 hnd->status = NT_STATUS_INVALID_HANDLE;
458 return CAC_FAILURE;
459 }
460
461 op->out.local_sid = NULL;
462 op->out.domain_sid = NULL;
463
464 if ( ( op->in.info_class & CAC_LOCAL_INFO ) == CAC_LOCAL_INFO ) {
465 DOM_SID *local_sid = NULL;
466 char *dom_name = NULL;
467
468 hnd->status =
469 rpccli_lsa_query_info_policy( pipe_hnd, mem_ctx,
470 op->in.pol,
471 CAC_LOCAL_INFO,
472 &dom_name, &local_sid );
473
474 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
475 result = CAC_FAILURE;
476 goto domain;
477 }
478
479 op->out.local_sid = talloc( mem_ctx, CacSidInfo );
480 if ( !op->out.local_sid ) {
481 hnd->status = NT_STATUS_NO_MEMORY;
482 result = CAC_FAILURE;
483 goto domain;
484 }
485
486 op->out.local_sid->domain = dom_name;
487
488 sid_copy( &op->out.local_sid->sid, local_sid );
489 TALLOC_FREE( local_sid );
490 }
491
492 domain:
493
494 if ( ( op->in.info_class & CAC_DOMAIN_INFO ) == CAC_DOMAIN_INFO ) {
495 DOM_SID *domain_sid;
496 char *dom_name;
497
498 hnd->status =
499 rpccli_lsa_query_info_policy( pipe_hnd, mem_ctx,
500 op->in.pol,
501 CAC_DOMAIN_INFO,
502 &dom_name,
503 &domain_sid );
504 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
505 /*if we succeeded above, report partial success */
506 result = CAC_FAILURE;
507 goto done;
508 } else if ( result == CAC_FAILURE ) {
509 /*if we failed above but succeded here then report partial success */
510 result = CAC_PARTIAL_SUCCESS;
511 }
512
513 op->out.domain_sid = talloc( mem_ctx, CacSidInfo );
514 if ( !op->out.domain_sid ) {
515 hnd->status = NT_STATUS_NO_MEMORY;
516 result = CAC_FAILURE;
517 goto done;
518 }
519
520 op->out.domain_sid->domain = dom_name;
521 sid_copy( &op->out.domain_sid->sid, domain_sid );
522 TALLOC_FREE( domain_sid );
523 }
524
525 done:
526 return result;
527}
528
529int cac_LsaQueryInfoPolicy( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
530 struct LsaQueryInfoPolicy *op )
531{
532 struct rpc_pipe_client *pipe_hnd = NULL;
533
534 char *domain_name = NULL;
535 char *dns_name = NULL;
536 char *forest_name = NULL;
537 struct GUID *domain_guid = NULL;
538 DOM_SID *domain_sid = NULL;
539
540 if ( !hnd )
541 return CAC_FAILURE;
542
543 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
544 hnd->status = NT_STATUS_INVALID_HANDLE;
545 return CAC_FAILURE;
546 }
547
548 if ( !op || !op->in.pol ) {
549 hnd->status = NT_STATUS_INVALID_PARAMETER;
550 return CAC_FAILURE;
551 }
552
553 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
554 if ( !pipe_hnd ) {
555 hnd->status = NT_STATUS_INVALID_HANDLE;
556 return CAC_FAILURE;
557 }
558
559 /*only works if info_class parm is 12 */
560 hnd->status =
561 rpccli_lsa_query_info_policy2( pipe_hnd, mem_ctx, op->in.pol,
562 12, &domain_name, &dns_name,
563 &forest_name, &domain_guid,
564 &domain_sid );
565
566 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
567 return CAC_FAILURE;
568 }
569
570 op->out.domain_name = domain_name;
571 op->out.dns_name = dns_name;
572 op->out.forest_name = forest_name;
573 op->out.domain_guid = domain_guid;
574 op->out.domain_sid = domain_sid;
575
576 return CAC_SUCCESS;
577}
578
579int cac_LsaEnumSids( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
580 struct LsaEnumSids *op )
581{
582 struct rpc_pipe_client *pipe_hnd = NULL;
583
584 uint32 num_sids;
585 DOM_SID *sids;
586
587 if ( !hnd )
588 return CAC_FAILURE;
589
590 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
591 hnd->status = NT_STATUS_INVALID_HANDLE;
592 return CAC_FAILURE;
593 }
594
595 if ( !op || !op->in.pol ) {
596 hnd->status = NT_STATUS_INVALID_PARAMETER;
597 return CAC_FAILURE;
598 }
599
600 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
601 if ( !pipe_hnd ) {
602 hnd->status = NT_STATUS_INVALID_HANDLE;
603 return CAC_FAILURE;
604 }
605
606 hnd->status =
607 rpccli_lsa_enum_sids( pipe_hnd, mem_ctx, op->in.pol,
608 &( op->out.resume_idx ),
609 op->in.pref_max_sids, &num_sids,
610 &sids );
611
612 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
613 return CAC_FAILURE;
614 }
615
616 op->out.num_sids = num_sids;
617 op->out.sids = sids;
618
619 return CAC_SUCCESS;
620
621}
622
623int cac_LsaEnumAccountRights( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
624 struct LsaEnumAccountRights *op )
625{
626 struct rpc_pipe_client *pipe_hnd = NULL;
627
628 uint32 count = 0;
629 char **privs = NULL;
630
631 if ( !hnd )
632 return CAC_FAILURE;
633
634 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
635 hnd->status = NT_STATUS_INVALID_HANDLE;
636 return CAC_FAILURE;
637 }
638
639 if ( !op->in.pol ) {
640 hnd->status = NT_STATUS_INVALID_PARAMETER;
641 return CAC_FAILURE;
642 }
643
644 if ( !op->in.name && !op->in.sid ) {
645 hnd->status = NT_STATUS_INVALID_PARAMETER;
646 return CAC_FAILURE;
647 }
648
649 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
650 if ( !pipe_hnd ) {
651 hnd->status = NT_STATUS_INVALID_HANDLE;
652 return CAC_FAILURE;
653 }
654
655 if ( op->in.name && !op->in.sid ) {
656 DOM_SID *user_sid = NULL;
657 enum lsa_SidType *type;
658
659 /*lookup the SID */
660 hnd->status =
661 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
662 op->in.pol, 1,
663 ( const char ** ) &( op->in.
664 name ),
665 NULL, &user_sid, &type );
666
667 if ( !NT_STATUS_IS_OK( hnd->status ) )
668 return CAC_FAILURE;
669
670 op->in.sid = user_sid;
671 }
672
673 hnd->status =
674 rpccli_lsa_enum_account_rights( pipe_hnd, mem_ctx, op->in.pol,
675 op->in.sid, &count, &privs );
676
677 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
678 return CAC_FAILURE;
679 }
680
681 op->out.num_privs = count;
682 op->out.priv_names = privs;
683
684 return CAC_SUCCESS;
685}
686
687int cac_LsaEnumTrustedDomains( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
688 struct LsaEnumTrustedDomains *op )
689{
690 struct rpc_pipe_client *pipe_hnd;
691
692 uint32 num_domains;
693 char **domain_names;
694 DOM_SID *domain_sids;
695
696 if ( !hnd )
697 return CAC_FAILURE;
698
699 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
700 hnd->status = NT_STATUS_INVALID_HANDLE;
701 return CAC_FAILURE;
702 }
703
704 if ( !op->in.pol ) {
705 hnd->status = NT_STATUS_INVALID_PARAMETER;
706 return CAC_FAILURE;
707 }
708
709 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
710 if ( !pipe_hnd ) {
711 hnd->status = NT_STATUS_INVALID_HANDLE;
712 return CAC_FAILURE;
713 }
714
715 hnd->status =
716 rpccli_lsa_enum_trust_dom( pipe_hnd, mem_ctx, op->in.pol,
717 &( op->out.resume_idx ),
718 &num_domains, &domain_names,
719 &domain_sids );
720
721 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
722 return CAC_FAILURE;
723 }
724
725 op->out.num_domains = num_domains;
726 op->out.domain_names = domain_names;
727 op->out.domain_sids = domain_sids;
728
729 return CAC_SUCCESS;
730}
731
732int cac_LsaOpenTrustedDomain( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
733 struct LsaOpenTrustedDomain *op )
734{
735 struct rpc_pipe_client *pipe_hnd = NULL;
736
737 POLICY_HND *dom_pol = NULL;
738
739 if ( !hnd )
740 return CAC_FAILURE;
741
742 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
743 hnd->status = NT_STATUS_INVALID_HANDLE;
744 return CAC_FAILURE;
745 }
746
747 if ( !op->in.pol || !op->in.access || !op->in.domain_sid ) {
748 hnd->status = NT_STATUS_INVALID_PARAMETER;
749 return CAC_FAILURE;
750 }
751
752 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
753 if ( !pipe_hnd ) {
754 hnd->status = NT_STATUS_INVALID_HANDLE;
755 return CAC_FAILURE;
756 }
757
758 dom_pol = talloc( mem_ctx, POLICY_HND );
759 if ( !dom_pol ) {
760 hnd->status = NT_STATUS_NO_MEMORY;
761 errno = ENOMEM;
762 return CAC_FAILURE;
763 }
764
765 hnd->status =
766 rpccli_lsa_open_trusted_domain( pipe_hnd, mem_ctx, op->in.pol,
767 op->in.domain_sid,
768 op->in.access, dom_pol );
769
770 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
771 return CAC_FAILURE;
772 }
773
774 op->out.domain_pol = dom_pol;
775
776 return CAC_SUCCESS;
777}
778
779int cac_LsaQueryTrustedDomainInfo( CacServerHandle * hnd,
780 TALLOC_CTX * mem_ctx,
781 struct LsaQueryTrustedDomainInfo *op )
782{
783 struct rpc_pipe_client *pipe_hnd = NULL;
784
785 LSA_TRUSTED_DOMAIN_INFO *dom_info;
786
787 if ( !hnd )
788 return CAC_FAILURE;
789
790 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
791 hnd->status = NT_STATUS_INVALID_HANDLE;
792 return CAC_FAILURE;
793 }
794
795 if ( !op->in.pol || !op->in.info_class ) {
796 hnd->status = NT_STATUS_INVALID_PARAMETER;
797 return CAC_FAILURE;
798 }
799
800 if ( !op->in.domain_sid && !op->in.domain_name ) {
801 hnd->status = NT_STATUS_INVALID_PARAMETER;
802 return CAC_FAILURE;
803 }
804
805 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
806 if ( !pipe_hnd ) {
807 hnd->status = NT_STATUS_INVALID_HANDLE;
808 return CAC_FAILURE;
809 }
810
811 if ( op->in.domain_sid ) {
812 hnd->status =
813 rpccli_lsa_query_trusted_domain_info_by_sid( pipe_hnd,
814 mem_ctx,
815 op->in.
816 pol,
817 op->in.
818 info_class,
819 op->in.
820 domain_sid,
821 &dom_info );
822 } else if ( op->in.domain_name ) {
823 hnd->status =
824 rpccli_lsa_query_trusted_domain_info_by_name
825 ( pipe_hnd, mem_ctx, op->in.pol, op->in.info_class,
826 op->in.domain_name, &dom_info );
827 }
828
829 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
830 return CAC_FAILURE;
831 }
832
833 op->out.info = dom_info;
834
835 return CAC_SUCCESS;
836
837}
838
839int cac_LsaEnumPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
840 struct LsaEnumPrivileges *op )
841{
842 struct rpc_pipe_client *pipe_hnd = NULL;
843
844 uint32 num_privs;
845 char **priv_names;
846 uint32 *high_bits;
847 uint32 *low_bits;
848
849 if ( !hnd ) {
850 return CAC_FAILURE;
851 }
852
853 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
854 hnd->status = NT_STATUS_INVALID_HANDLE;
855 return CAC_FAILURE;
856 }
857
858 if ( !op || !op->in.pol ) {
859 hnd->status = NT_STATUS_INVALID_PARAMETER;
860 return CAC_FAILURE;
861 }
862
863 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
864 if ( !pipe_hnd ) {
865 hnd->status = NT_STATUS_INVALID_HANDLE;
866 return CAC_FAILURE;
867 }
868
869 hnd->status =
870 rpccli_lsa_enum_privilege( pipe_hnd, mem_ctx, op->in.pol,
871 &( op->out.resume_idx ),
872 op->in.pref_max_privs, &num_privs,
873 &priv_names, &high_bits,
874 &low_bits );
875
876 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
877 return CAC_FAILURE;
878 }
879
880 op->out.num_privs = num_privs;
881 op->out.priv_names = priv_names;
882 op->out.high_bits = high_bits;
883 op->out.low_bits = low_bits;
884
885 return CAC_SUCCESS;
886}
887
888int cac_LsaOpenAccount( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
889 struct LsaOpenAccount *op )
890{
891 struct rpc_pipe_client *pipe_hnd = NULL;
892
893 POLICY_HND *user_pol = NULL;
894
895 if ( !hnd ) {
896 return CAC_FAILURE;
897 }
898
899 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
900 hnd->status = NT_STATUS_INVALID_HANDLE;
901 return CAC_FAILURE;
902 }
903
904 if ( !op || !op->in.pol ) {
905 hnd->status = NT_STATUS_INVALID_PARAMETER;
906 return CAC_FAILURE;
907 }
908
909 if ( !op->in.sid && !op->in.name ) {
910 hnd->status = NT_STATUS_INVALID_PARAMETER;
911 return CAC_FAILURE;
912 }
913
914 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
915 if ( !pipe_hnd ) {
916 hnd->status = NT_STATUS_INVALID_HANDLE;
917 return CAC_FAILURE;
918 }
919
920 /*look up the user's SID if we have to */
921 if ( op->in.name && !op->in.sid ) {
922 DOM_SID *user_sid = NULL;
923 enum lsa_SidType *type;
924
925 /*lookup the SID */
926 hnd->status =
927 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
928 op->in.pol, 1,
929 ( const char ** ) &( op->in.
930 name ),
931 NULL, &user_sid, &type );
932
933 if ( !NT_STATUS_IS_OK( hnd->status ) )
934 return CAC_FAILURE;
935
936 op->in.sid = user_sid;
937 }
938
939 user_pol = talloc( mem_ctx, POLICY_HND );
940 if ( !user_pol ) {
941 hnd->status = NT_STATUS_NO_MEMORY;
942 return CAC_FAILURE;
943 }
944
945 hnd->status =
946 rpccli_lsa_open_account( pipe_hnd, mem_ctx, op->in.pol,
947 op->in.sid, op->in.access,
948 user_pol );
949
950 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
951 TALLOC_FREE( user_pol );
952 return CAC_FAILURE;
953 }
954
955 op->out.user = user_pol;
956
957 return CAC_SUCCESS;
958}
959
960
961int cac_LsaAddPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
962 struct LsaAddPrivileges *op )
963{
964 struct rpc_pipe_client *pipe_hnd = NULL;
965
966 DOM_SID *user_sid = NULL;
967 enum lsa_SidType *type = NULL;
968
969 if ( !hnd ) {
970 return CAC_FAILURE;
971 }
972
973 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
974 hnd->status = NT_STATUS_INVALID_HANDLE;
975 return CAC_FAILURE;
976 }
977
978 if ( !op || !op->in.pol || !op->in.priv_names ) {
979 hnd->status = NT_STATUS_INVALID_PARAMETER;
980 return CAC_FAILURE;
981 }
982
983 if ( !op->in.sid && !op->in.name ) {
984 hnd->status = NT_STATUS_INVALID_PARAMETER;
985 return CAC_FAILURE;
986 }
987
988 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
989 if ( !pipe_hnd ) {
990 hnd->status = NT_STATUS_INVALID_HANDLE;
991 return CAC_FAILURE;
992 }
993
994 if ( op->in.name && !op->in.sid ) {
995 /*lookup the SID */
996 hnd->status =
997 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
998 op->in.pol, 1,
999 ( const char ** ) &( op->in.
1000 name ),
1001 NULL, &user_sid, &type );
1002
1003 if ( !NT_STATUS_IS_OK( hnd->status ) )
1004 return CAC_FAILURE;
1005
1006 op->in.sid = user_sid;
1007 }
1008
1009 hnd->status =
1010 rpccli_lsa_add_account_rights( pipe_hnd, mem_ctx, op->in.pol,
1011 *( op->in.sid ),
1012 op->in.num_privs,
1013 ( const char ** ) op->in.
1014 priv_names );
1015
1016 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1017 return CAC_FAILURE;
1018 }
1019
1020 return CAC_SUCCESS;
1021}
1022
1023int cac_LsaRemovePrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1024 struct LsaRemovePrivileges *op )
1025{
1026 struct rpc_pipe_client *pipe_hnd = NULL;
1027
1028 DOM_SID *user_sid = NULL;
1029 enum lsa_SidType *type = NULL;
1030
1031 if ( !hnd ) {
1032 return CAC_FAILURE;
1033 }
1034
1035 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
1036 hnd->status = NT_STATUS_INVALID_HANDLE;
1037 return CAC_FAILURE;
1038 }
1039
1040 if ( !op || !op->in.pol || !op->in.priv_names ) {
1041 hnd->status = NT_STATUS_INVALID_PARAMETER;
1042 return CAC_FAILURE;
1043 }
1044
1045 if ( !op->in.sid && !op->in.name ) {
1046 hnd->status = NT_STATUS_INVALID_PARAMETER;
1047 return CAC_FAILURE;
1048 }
1049
1050 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
1051 if ( !pipe_hnd ) {
1052 hnd->status = NT_STATUS_INVALID_HANDLE;
1053 return CAC_FAILURE;
1054 }
1055
1056 if ( op->in.name && !op->in.sid ) {
1057 /*lookup the SID */
1058 hnd->status =
1059 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
1060 op->in.pol, 1,
1061 ( const char ** ) &( op->in.
1062 name ),
1063 NULL, &user_sid, &type );
1064
1065 if ( !NT_STATUS_IS_OK( hnd->status ) )
1066 return CAC_FAILURE;
1067
1068 op->in.sid = user_sid;
1069 }
1070
1071 hnd->status =
1072 rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx,
1073 op->in.pol, *( op->in.sid ),
1074 False, op->in.num_privs,
1075 ( const char ** ) op->in.
1076 priv_names );
1077
1078 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1079 return CAC_FAILURE;
1080 }
1081
1082 return CAC_SUCCESS;
1083}
1084
1085int cac_LsaClearPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1086 struct LsaClearPrivileges *op )
1087{
1088 struct rpc_pipe_client *pipe_hnd = NULL;
1089
1090 DOM_SID *user_sid = NULL;
1091 enum lsa_SidType *type = NULL;
1092
1093 if ( !hnd ) {
1094 return CAC_FAILURE;
1095 }
1096
1097 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
1098 hnd->status = NT_STATUS_INVALID_HANDLE;
1099 return CAC_FAILURE;
1100 }
1101
1102 if ( !op || !op->in.pol ) {
1103 hnd->status = NT_STATUS_INVALID_PARAMETER;
1104 return CAC_FAILURE;
1105 }
1106
1107 if ( !op->in.sid && !op->in.name ) {
1108 hnd->status = NT_STATUS_INVALID_PARAMETER;
1109 return CAC_FAILURE;
1110 }
1111
1112 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
1113 if ( !pipe_hnd ) {
1114 hnd->status = NT_STATUS_INVALID_HANDLE;
1115 return CAC_FAILURE;
1116 }
1117
1118 if ( op->in.name && !op->in.sid ) {
1119 /*lookup the SID */
1120 hnd->status =
1121 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
1122 op->in.pol, 1,
1123 ( const char ** ) &( op->in.
1124 name ),
1125 NULL, &user_sid, &type );
1126
1127 if ( !NT_STATUS_IS_OK( hnd->status ) )
1128 return CAC_FAILURE;
1129
1130 op->in.sid = user_sid;
1131 }
1132
1133 hnd->status =
1134 rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx,
1135 op->in.pol, *( op->in.sid ),
1136 True, 0, NULL );
1137
1138 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1139 return CAC_FAILURE;
1140 }
1141
1142 return CAC_SUCCESS;
1143}
1144
1145int cac_LsaSetPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1146 struct LsaAddPrivileges *op )
1147{
1148 struct rpc_pipe_client *pipe_hnd = NULL;
1149
1150 DOM_SID *user_sid = NULL;
1151 enum lsa_SidType *type = NULL;
1152
1153 if ( !hnd ) {
1154 return CAC_FAILURE;
1155 }
1156
1157 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
1158 hnd->status = NT_STATUS_INVALID_HANDLE;
1159 return CAC_FAILURE;
1160 }
1161
1162 if ( !op || !op->in.pol || !op->in.priv_names ) {
1163 hnd->status = NT_STATUS_INVALID_PARAMETER;
1164 return CAC_FAILURE;
1165 }
1166
1167 if ( !op->in.sid && !op->in.name ) {
1168 hnd->status = NT_STATUS_INVALID_PARAMETER;
1169 return CAC_FAILURE;
1170 }
1171
1172 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
1173 if ( !pipe_hnd ) {
1174 return CAC_FAILURE;
1175 }
1176
1177 if ( op->in.name && !op->in.sid ) {
1178 /*lookup the SID */
1179 hnd->status =
1180 rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
1181 op->in.pol, 1,
1182 ( const char ** ) &( op->in.
1183 name ),
1184 NULL, &user_sid, &type );
1185
1186 if ( !NT_STATUS_IS_OK( hnd->status ) )
1187 return CAC_FAILURE;
1188
1189 op->in.sid = user_sid;
1190 }
1191
1192 /*first remove all privileges */
1193 hnd->status =
1194 rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx,
1195 op->in.pol, *( op->in.sid ),
1196 True, 0, NULL );
1197
1198 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1199 return CAC_FAILURE;
1200 }
1201
1202 hnd->status =
1203 rpccli_lsa_add_account_rights( pipe_hnd, mem_ctx, op->in.pol,
1204 *( op->in.sid ),
1205 op->in.num_privs,
1206 ( const char ** ) op->in.
1207 priv_names );
1208
1209 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1210 return CAC_FAILURE;
1211 }
1212
1213 return CAC_SUCCESS;
1214}
1215
1216int cac_LsaGetSecurityObject( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1217 struct LsaGetSecurityObject *op )
1218{
1219 struct rpc_pipe_client *pipe_hnd = NULL;
1220
1221 /*this is taken from rpcclient/cmd_lsarpc.c */
1222 uint16 info_level = 4;
1223
1224 SEC_DESC_BUF *sec_out = NULL;
1225
1226 if ( !hnd ) {
1227 return CAC_FAILURE;
1228 }
1229
1230 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
1231 hnd->status = NT_STATUS_INVALID_HANDLE;
1232 return CAC_FAILURE;
1233 }
1234
1235 if ( !op || !op->in.pol ) {
1236 hnd->status = NT_STATUS_INVALID_PARAMETER;
1237 return CAC_FAILURE;
1238 }
1239
1240 pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
1241 if ( !pipe_hnd ) {
1242 hnd->status = NT_STATUS_INVALID_HANDLE;
1243 return CAC_FAILURE;
1244 }
1245
1246 hnd->status =
1247 rpccli_lsa_query_secobj( pipe_hnd, mem_ctx, op->in.pol,
1248 info_level, &sec_out );
1249
1250 if ( !NT_STATUS_IS_OK( hnd->status ) )
1251 return CAC_FAILURE;
1252
1253 op->out.sec = sec_out;
1254
1255 return CAC_FAILURE;
1256}
Note: See TracBrowser for help on using the repository browser.