source: trunk-3.0/source/libmsrpc/cac_samr.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: 62.9 KB
Line 
1
2/*
3 * Unix SMB/CIFS implementation.
4 * MS-RPC client library implementation (SAMR 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 "libmsrpc_internal.h"
24
25/*used by cac_SamGetNamesFromRids*/
26#define SAMR_RID_UNKNOWN 8
27
28#define SAMR_ENUM_MAX_SIZE 0xffff
29
30/*not sure what this is.. taken from rpcclient/cmd_samr.c*/
31#define SAMR_LOOKUP_FLAGS 0x000003e8
32
33DOM_SID *cac_get_domain_sid( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
34 uint32 des_access );
35
36int cac_SamConnect( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
37 struct SamConnect *op )
38{
39 SMBCSRV *srv = NULL;
40 struct rpc_pipe_client *pipe_hnd = NULL;
41 POLICY_HND *sam_out = NULL;
42
43 if ( !hnd )
44 return CAC_FAILURE;
45
46 if ( !hnd->_internal.ctx ) {
47 hnd->status = NT_STATUS_INVALID_HANDLE;
48 return CAC_FAILURE;
49 }
50
51 if ( !op || op->in.access == 0 || !mem_ctx ) {
52 hnd->status = NT_STATUS_INVALID_PARAMETER;
53 return CAC_FAILURE;
54 }
55
56 srv = cac_GetServer( hnd );
57 if ( !srv ) {
58 hnd->status = NT_STATUS_INVALID_CONNECTION;
59 return CAC_FAILURE;
60 }
61
62 /*initialize for samr pipe if we have to */
63 if ( !hnd->_internal.pipes[PI_SAMR] ) {
64 if ( !
65 ( pipe_hnd =
66 cli_rpc_pipe_open_noauth( srv->cli, PI_SAMR,
67 &hnd->status ) ) ) {
68 return CAC_FAILURE;
69 }
70
71 hnd->_internal.pipes[PI_SAMR] = True;
72 }
73
74 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
75 if ( !pipe_hnd ) {
76 hnd->status = NT_STATUS_INVALID_HANDLE;
77 return CAC_FAILURE;
78 }
79
80 sam_out = talloc( mem_ctx, POLICY_HND );
81 if ( !sam_out ) {
82 hnd->status = NT_STATUS_NO_MEMORY;
83 return CAC_FAILURE;
84 }
85
86 if ( hnd->_internal.srv_level >= SRV_WIN_2K_SP3 ) {
87 hnd->status =
88 rpccli_samr_connect4( pipe_hnd, mem_ctx,
89 op->in.access, sam_out );
90 }
91
92 if ( hnd->_internal.srv_level < SRV_WIN_2K_SP3
93 || !NT_STATUS_IS_OK( hnd->status ) ) {
94 /*if sam_connect4 failed, the use sam_connect and lower srv_level */
95
96 hnd->status =
97 rpccli_samr_connect( pipe_hnd, mem_ctx, op->in.access,
98 sam_out );
99
100 if ( NT_STATUS_IS_OK( hnd->status )
101 && hnd->_internal.srv_level > SRV_WIN_2K ) {
102 hnd->_internal.srv_level = SRV_WIN_2K;
103 }
104 }
105
106 if ( !NT_STATUS_IS_OK( hnd->status ) )
107 return CAC_FAILURE;
108
109 op->out.sam = sam_out;
110
111 return CAC_SUCCESS;
112}
113
114int cac_SamClose( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
115 POLICY_HND * sam )
116{
117 struct rpc_pipe_client *pipe_hnd = NULL;
118
119 if ( !hnd )
120 return CAC_FAILURE;
121
122 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
123 hnd->status = NT_STATUS_INVALID_HANDLE;
124 return CAC_FAILURE;
125 }
126
127 if ( !sam || !mem_ctx ) {
128 hnd->status = NT_STATUS_INVALID_PARAMETER;
129 return CAC_FAILURE;
130 }
131
132 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
133 if ( !pipe_hnd ) {
134 hnd->status = NT_STATUS_INVALID_HANDLE;
135 return CAC_FAILURE;
136 }
137
138 hnd->status = rpccli_samr_close( pipe_hnd, mem_ctx, sam );
139
140 if ( !NT_STATUS_IS_OK( hnd->status ) )
141 return CAC_FAILURE;
142
143 return CAC_SUCCESS;
144}
145
146/*this is an internal function. Due to a circular dependency, it must be prototyped in libmsrpc.h (which I don't want to do)
147 * cac_SamOpenDomain() is the only function that calls it, so I just put the definition here
148 */
149
150/*attempts to find the sid of the domain we are connected to*/
151DOM_SID *cac_get_domain_sid( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
152 uint32 des_access )
153{
154 struct LsaOpenPolicy lop;
155 struct LsaFetchSid fs;
156
157 DOM_SID *sid;
158
159 ZERO_STRUCT( lop );
160 ZERO_STRUCT( fs );
161
162 lop.in.access = des_access;
163 lop.in.security_qos = True;
164
165 if ( !cac_LsaOpenPolicy( hnd, mem_ctx, &lop ) )
166 return NULL;
167
168 fs.in.pol = lop.out.pol;
169 fs.in.info_class = CAC_DOMAIN_INFO;
170
171 if ( !cac_LsaFetchSid( hnd, mem_ctx, &fs ) )
172 return NULL;
173
174 cac_LsaClosePolicy( hnd, mem_ctx, lop.out.pol );
175
176 if ( !fs.out.domain_sid )
177 return NULL;
178
179 sid = ( DOM_SID * ) TALLOC_MEMDUP( mem_ctx,
180 &( fs.out.domain_sid->sid ),
181 sizeof( DOM_SID ) );
182
183 if ( !sid ) {
184 hnd->status = NT_STATUS_NO_MEMORY;
185 }
186
187 return sid;
188
189}
190
191int cac_SamOpenDomain( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
192 struct SamOpenDomain *op )
193{
194 struct rpc_pipe_client *pipe_hnd = NULL;
195
196 DOM_SID *sid_buf;
197 POLICY_HND *sam_out;
198 POLICY_HND *pol_out;
199
200 struct SamLookupDomain sld;
201
202 if ( !hnd )
203 return CAC_FAILURE;
204
205 if ( !hnd->_internal.ctx ) {
206 hnd->status = NT_STATUS_INVALID_HANDLE;
207 return CAC_FAILURE;
208 }
209
210 if ( !op || op->in.access == 0 || !mem_ctx ) {
211 hnd->status = NT_STATUS_INVALID_PARAMETER;
212 return CAC_FAILURE;
213 }
214
215 if ( !op->in.sam ) {
216 /*use cac_SamConnect() since it does the session setup */
217 struct SamConnect sc;
218
219 ZERO_STRUCT( sc );
220
221 sc.in.access = op->in.access;
222
223 if ( !cac_SamConnect( hnd, mem_ctx, &sc ) ) {
224 return CAC_FAILURE;
225 }
226
227 sam_out = sc.out.sam;
228 } else {
229 sam_out = op->in.sam;
230 }
231
232 if ( !op->in.sid ) {
233 /*find the sid for the SAM's domain */
234
235 /*try using cac_SamLookupDomain() first */
236 ZERO_STRUCT( sld );
237
238 sld.in.sam = sam_out;
239 sld.in.name = hnd->domain;
240
241 if ( cac_SamLookupDomain( hnd, mem_ctx, &sld ) ) {
242 /*then we got the sid */
243 sid_buf = sld.out.sid;
244 } else {
245 /*try to get it from the LSA */
246 sid_buf =
247 cac_get_domain_sid( hnd, mem_ctx,
248 op->in.access );
249 }
250 } else {
251 /*we already have the sid for the domain we want */
252 sid_buf = op->in.sid;
253 }
254
255 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
256 if ( !pipe_hnd ) {
257 hnd->status = NT_STATUS_INVALID_HANDLE;
258 return CAC_FAILURE;
259 }
260
261 pol_out = talloc( mem_ctx, POLICY_HND );
262 if ( !pol_out ) {
263 hnd->status = NT_STATUS_NO_MEMORY;
264 return CAC_FAILURE;
265 }
266
267 /*now open the domain */
268 hnd->status =
269 rpccli_samr_open_domain( pipe_hnd, mem_ctx, sam_out,
270 op->in.access, sid_buf, pol_out );
271
272 if ( !NT_STATUS_IS_OK( hnd->status ) )
273 return CAC_FAILURE;
274
275 op->out.sam = sam_out;
276 op->out.dom_hnd = pol_out;
277
278 return CAC_SUCCESS;
279}
280
281int cac_SamOpenUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
282 struct SamOpenUser *op )
283{
284 struct rpc_pipe_client *pipe_hnd = NULL;
285
286 uint32 *rid_buf = NULL;
287
288 uint32 num_rids = 0;
289 uint32 *rid_types = NULL;
290
291 POLICY_HND *user_out = NULL;
292
293 if ( !hnd )
294 return CAC_FAILURE;
295
296 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
297 hnd->status = NT_STATUS_INVALID_HANDLE;
298 return CAC_FAILURE;
299 }
300
301 if ( !op || !op->in.dom_hnd || op->in.access == 0 || !mem_ctx ) {
302 hnd->status = NT_STATUS_INVALID_PARAMETER;
303 return CAC_FAILURE;
304 }
305
306 if ( op->in.rid == 0 && op->in.name == NULL ) {
307 hnd->status = NT_STATUS_INVALID_PARAMETER;
308 return CAC_FAILURE;
309 }
310
311 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
312 if ( !pipe_hnd ) {
313 hnd->status = NT_STATUS_INVALID_HANDLE;
314 return CAC_FAILURE;
315 }
316
317 if ( op->in.rid == 0 && op->in.name ) {
318 /*lookup the name and then set rid_buf */
319
320 hnd->status =
321 rpccli_samr_lookup_names( pipe_hnd, mem_ctx,
322 op->in.dom_hnd,
323 SAMR_LOOKUP_FLAGS, 1,
324 ( const char ** ) &op->in.
325 name, &num_rids, &rid_buf,
326 &rid_types );
327
328 if ( !NT_STATUS_IS_OK( hnd->status ) )
329 return CAC_FAILURE;
330
331 if ( num_rids == 0 || rid_buf == NULL
332 || rid_types[0] == SAMR_RID_UNKNOWN ) {
333 hnd->status = NT_STATUS_INVALID_PARAMETER;
334 return CAC_FAILURE;
335 }
336
337 TALLOC_FREE( rid_types );
338
339 } else {
340 rid_buf = &op->in.rid;
341 }
342
343 user_out = talloc( mem_ctx, POLICY_HND );
344 if ( !user_out ) {
345 hnd->status = NT_STATUS_NO_MEMORY;
346 return CAC_FAILURE;
347 }
348
349 hnd->status =
350 rpccli_samr_open_user( pipe_hnd, mem_ctx, op->in.dom_hnd,
351 op->in.access, *rid_buf, user_out );
352
353 if ( !NT_STATUS_IS_OK( hnd->status ) )
354 return CAC_FAILURE;
355
356 op->out.user_hnd = user_out;
357
358 return CAC_SUCCESS;
359}
360
361int cac_SamCreateUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
362 struct SamCreateUser *op )
363{
364 struct rpc_pipe_client *pipe_hnd = NULL;
365
366 POLICY_HND *user_out = NULL;
367 uint32 rid_out;
368
369 /**found in rpcclient/cmd_samr.c*/
370 uint32 unknown = 0xe005000b;
371
372 if ( !hnd )
373 return CAC_FAILURE;
374
375 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
376 hnd->status = NT_STATUS_INVALID_HANDLE;
377 return CAC_FAILURE;
378 }
379
380 if ( !op || !op->in.dom_hnd || !op->in.name || op->in.acb_mask == 0
381 || !mem_ctx ) {
382 hnd->status = NT_STATUS_INVALID_PARAMETER;
383 return CAC_FAILURE;
384 }
385
386 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
387 if ( !pipe_hnd ) {
388 hnd->status = NT_STATUS_INVALID_HANDLE;
389 return CAC_FAILURE;
390 }
391
392 user_out = talloc( mem_ctx, POLICY_HND );
393 if ( !user_out ) {
394 hnd->status = NT_STATUS_NO_MEMORY;
395 return CAC_FAILURE;
396 }
397
398 hnd->status =
399 rpccli_samr_create_dom_user( pipe_hnd, mem_ctx,
400 op->in.dom_hnd, op->in.name,
401 op->in.acb_mask, unknown,
402 user_out, &rid_out );
403
404 if ( !NT_STATUS_IS_OK( hnd->status ) )
405 return CAC_FAILURE;
406
407 op->out.user_hnd = user_out;
408 op->out.rid = rid_out;
409
410 return CAC_SUCCESS;
411}
412
413int cac_SamDeleteUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
414 POLICY_HND * user_hnd )
415{
416 struct rpc_pipe_client *pipe_hnd = NULL;
417
418 if ( !hnd )
419 return CAC_FAILURE;
420
421 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
422 hnd->status = NT_STATUS_INVALID_HANDLE;
423 return CAC_FAILURE;
424 }
425
426 if ( !user_hnd || !mem_ctx ) {
427 hnd->status = NT_STATUS_INVALID_PARAMETER;
428 return CAC_FAILURE;
429 }
430
431 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
432 if ( !pipe_hnd ) {
433 hnd->status = NT_STATUS_INVALID_HANDLE;
434 return CAC_FAILURE;
435 }
436
437 hnd->status =
438 rpccli_samr_delete_dom_user( pipe_hnd, mem_ctx, user_hnd );
439
440 if ( !NT_STATUS_IS_OK( hnd->status ) )
441 return CAC_FAILURE;
442
443 return CAC_SUCCESS;
444}
445
446int cac_SamEnumUsers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
447 struct SamEnumUsers *op )
448{
449 struct rpc_pipe_client *pipe_hnd = NULL;
450
451 uint32 resume_idx_out = 0;
452 char **names_out = NULL;
453 uint32 *rids_out = NULL;
454 uint32 num_users_out = 0;
455
456 if ( !hnd )
457 return CAC_FAILURE;
458
459 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
460 hnd->status = NT_STATUS_INVALID_HANDLE;
461 return CAC_FAILURE;
462 }
463
464 if ( !op || !op->in.dom_hnd || !mem_ctx ) {
465 hnd->status = NT_STATUS_INVALID_PARAMETER;
466 return CAC_FAILURE;
467 }
468
469 /*this is a hack.. but is the only reliable way to know if everything has been enumerated */
470 if ( op->out.done == True )
471 return CAC_FAILURE;
472
473 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
474 if ( !pipe_hnd ) {
475 hnd->status = NT_STATUS_INVALID_HANDLE;
476 return CAC_FAILURE;
477 }
478
479 resume_idx_out = op->out.resume_idx;
480
481 hnd->status =
482 rpccli_samr_enum_dom_users( pipe_hnd, mem_ctx, op->in.dom_hnd,
483 &resume_idx_out, op->in.acb_mask,
484 SAMR_ENUM_MAX_SIZE, &names_out,
485 &rids_out, &num_users_out );
486
487
488 if ( NT_STATUS_IS_OK( hnd->status ) )
489 op->out.done = True;
490
491 /*if there are no more entries, the operation will return NT_STATUS_OK.
492 * We want to return failure if no results were returned*/
493 if ( !NT_STATUS_IS_OK( hnd->status )
494 && NT_STATUS_V( hnd->status ) !=
495 NT_STATUS_V( STATUS_MORE_ENTRIES ) )
496 return CAC_FAILURE;
497
498 op->out.resume_idx = resume_idx_out;
499 op->out.num_users = num_users_out;
500 op->out.rids = rids_out;
501 op->out.names = names_out;
502
503 return CAC_SUCCESS;
504}
505
506int cac_SamGetNamesFromRids( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
507 struct SamGetNamesFromRids *op )
508{
509 struct rpc_pipe_client *pipe_hnd = NULL;
510
511 uint32 num_names_out;
512 char **names_out;
513 uint32 *name_types_out;
514
515
516 uint32 i = 0;
517
518 CacLookupRidsRecord *map_out;
519
520 if ( !hnd )
521 return CAC_FAILURE;
522
523 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
524 hnd->status = NT_STATUS_INVALID_HANDLE;
525 return CAC_FAILURE;
526 }
527
528 if ( !op || !op->in.dom_hnd || !mem_ctx ) {
529 hnd->status = NT_STATUS_INVALID_PARAMETER;
530 return CAC_FAILURE;
531 }
532
533 if ( !op->in.rids && op->in.num_rids != 0 ) {
534 hnd->status = NT_STATUS_INVALID_PARAMETER;
535 return CAC_FAILURE;
536 }
537
538 if ( op->in.num_rids == 0 ) {
539 /*nothing to do */
540 op->out.num_names = 0;
541 return CAC_SUCCESS;
542 }
543
544 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
545 if ( !pipe_hnd ) {
546 hnd->status = NT_STATUS_INVALID_HANDLE;
547 return CAC_FAILURE;
548 }
549
550 hnd->status =
551 rpccli_samr_lookup_rids( pipe_hnd, mem_ctx, op->in.dom_hnd,
552 op->in.num_rids, op->in.rids,
553 &num_names_out, &names_out,
554 &name_types_out );
555
556 if ( !NT_STATUS_IS_OK( hnd->status )
557 && !NT_STATUS_EQUAL( hnd->status, STATUS_SOME_UNMAPPED ) )
558 return CAC_FAILURE;
559
560 if (num_names_out) {
561 map_out = TALLOC_ARRAY( mem_ctx, CacLookupRidsRecord, num_names_out );
562 if ( !map_out ) {
563 hnd->status = NT_STATUS_NO_MEMORY;
564 return CAC_FAILURE;
565 }
566 } else {
567 map_out = NULL;
568 }
569
570 for ( i = 0; i < num_names_out; i++ ) {
571 if ( name_types_out[i] == SAMR_RID_UNKNOWN ) {
572 map_out[i].found = False;
573 map_out[i].name = NULL;
574 map_out[i].type = 0;
575 } else {
576 map_out[i].found = True;
577 map_out[i].name =
578 talloc_strdup( mem_ctx, names_out[i] );
579 map_out[i].type = name_types_out[i];
580 }
581 map_out[i].rid = op->in.rids[i];
582 }
583
584 TALLOC_FREE( names_out );
585 TALLOC_FREE( name_types_out );
586
587 op->out.num_names = num_names_out;
588 op->out.map = map_out;
589
590 if ( NT_STATUS_EQUAL( hnd->status, STATUS_SOME_UNMAPPED ) )
591 return CAC_PARTIAL_SUCCESS;
592
593 return CAC_SUCCESS;
594}
595
596int cac_SamGetRidsFromNames( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
597 struct SamGetRidsFromNames *op )
598{
599 struct rpc_pipe_client *pipe_hnd = NULL;
600
601 uint32 num_rids_out;
602 uint32 *rids_out;
603 uint32 *rid_types_out;
604
605 uint32 i = 0;
606
607 CacLookupRidsRecord *map_out;
608
609 if ( !hnd )
610 return CAC_FAILURE;
611
612 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
613 hnd->status = NT_STATUS_INVALID_HANDLE;
614 return CAC_FAILURE;
615 }
616
617 if ( !op || !op->in.dom_hnd || !mem_ctx ) {
618 hnd->status = NT_STATUS_INVALID_PARAMETER;
619 return CAC_FAILURE;
620 }
621
622 if ( !op->in.names && op->in.num_names != 0 ) {
623 hnd->status = NT_STATUS_INVALID_PARAMETER;
624 return CAC_FAILURE;
625 }
626
627 if ( op->in.num_names == 0 ) {
628 /*then we don't have to do anything */
629 op->out.num_rids = 0;
630 return CAC_SUCCESS;
631 }
632
633 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
634 if ( !pipe_hnd ) {
635 hnd->status = NT_STATUS_INVALID_HANDLE;
636 return CAC_FAILURE;
637 }
638
639 hnd->status =
640 rpccli_samr_lookup_names( pipe_hnd, mem_ctx, op->in.dom_hnd,
641 SAMR_LOOKUP_FLAGS, op->in.num_names,
642 ( const char ** ) op->in.names,
643 &num_rids_out, &rids_out,
644 &rid_types_out );
645
646 if ( !NT_STATUS_IS_OK( hnd->status )
647 && !NT_STATUS_EQUAL( hnd->status, STATUS_SOME_UNMAPPED ) )
648 return CAC_FAILURE;
649
650 if (num_rids_out) {
651 map_out = TALLOC_ARRAY( mem_ctx, CacLookupRidsRecord, num_rids_out );
652 if ( !map_out ) {
653 hnd->status = NT_STATUS_NO_MEMORY;
654 return CAC_FAILURE;
655 }
656 } else {
657 map_out = NULL;
658 }
659
660 for ( i = 0; i < num_rids_out; i++ ) {
661
662 if ( rid_types_out[i] == SAMR_RID_UNKNOWN ) {
663 map_out[i].found = False;
664 map_out[i].rid = 0;
665 map_out[i].type = 0;
666 } else {
667 map_out[i].found = True;
668 map_out[i].rid = rids_out[i];
669 map_out[i].type = rid_types_out[i];
670 }
671
672 map_out[i].name = talloc_strdup( mem_ctx, op->in.names[i] );
673 }
674
675 op->out.num_rids = num_rids_out;
676 op->out.map = map_out;
677
678 TALLOC_FREE( rids_out );
679 TALLOC_FREE( rid_types_out );
680
681 if ( NT_STATUS_EQUAL( hnd->status, STATUS_SOME_UNMAPPED ) )
682 return CAC_PARTIAL_SUCCESS;
683
684 return CAC_SUCCESS;
685}
686
687
688int cac_SamGetGroupsForUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
689 struct SamGetGroupsForUser *op )
690{
691 struct rpc_pipe_client *pipe_hnd = NULL;
692
693 DOM_GID *groups = NULL;
694 uint32 num_groups_out = 0;
695
696 uint32 *rids_out = NULL;
697 uint32 *attr_out = NULL;
698
699 uint32 i;
700
701 if ( !hnd )
702 return CAC_FAILURE;
703
704 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
705 hnd->status = NT_STATUS_INVALID_HANDLE;
706 return CAC_FAILURE;
707 }
708
709 if ( !op || !op->in.user_hnd || !mem_ctx ) {
710 hnd->status = NT_STATUS_INVALID_PARAMETER;
711 return CAC_FAILURE;
712 }
713
714 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
715 if ( !pipe_hnd ) {
716 hnd->status = NT_STATUS_INVALID_HANDLE;
717 return CAC_FAILURE;
718 }
719
720 hnd->status =
721 rpccli_samr_query_usergroups( pipe_hnd, mem_ctx,
722 op->in.user_hnd,
723 &num_groups_out, &groups );
724
725 if ( !NT_STATUS_IS_OK( hnd->status ) )
726 return CAC_FAILURE;
727
728
729 if (num_groups_out) {
730 rids_out = TALLOC_ARRAY( mem_ctx, uint32, num_groups_out );
731 if ( !rids_out ) {
732 hnd->status = NT_STATUS_NO_MEMORY;
733 return CAC_FAILURE;
734 }
735 attr_out = TALLOC_ARRAY( mem_ctx, uint32, num_groups_out );
736 if ( !attr_out ) {
737 hnd->status = NT_STATUS_NO_MEMORY;
738 return CAC_FAILURE;
739 }
740 } else {
741 rids_out = NULL;
742 attr_out = NULL;
743 }
744
745 for ( i = 0; i < num_groups_out; i++ ) {
746 rids_out[i] = groups[i].g_rid;
747 attr_out[i] = groups[i].attr;
748 }
749
750 TALLOC_FREE( groups );
751
752 op->out.num_groups = num_groups_out;
753 op->out.rids = rids_out;
754 op->out.attributes = attr_out;
755
756 return CAC_SUCCESS;
757}
758
759
760int cac_SamOpenGroup( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
761 struct SamOpenGroup *op )
762{
763 struct rpc_pipe_client *pipe_hnd = NULL;
764
765 POLICY_HND *group_hnd_out = NULL;
766
767 if ( !hnd )
768 return CAC_FAILURE;
769
770 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
771 hnd->status = NT_STATUS_INVALID_HANDLE;
772 return CAC_FAILURE;
773 }
774
775 if ( !op || op->in.access == 0 || op->in.rid == 0 || !mem_ctx ) {
776 hnd->status = NT_STATUS_INVALID_PARAMETER;
777 return CAC_FAILURE;
778 }
779
780 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
781 if ( !pipe_hnd ) {
782 hnd->status = NT_STATUS_INVALID_HANDLE;
783 return CAC_FAILURE;
784 }
785
786 group_hnd_out = talloc( mem_ctx, POLICY_HND );
787 if ( !group_hnd_out ) {
788 hnd->status = NT_STATUS_NO_MEMORY;
789 return CAC_FAILURE;
790 }
791
792 hnd->status =
793 rpccli_samr_open_group( pipe_hnd, mem_ctx, op->in.dom_hnd,
794 op->in.access, op->in.rid,
795 group_hnd_out );
796
797 if ( !NT_STATUS_IS_OK( hnd->status ) )
798 return CAC_FAILURE;
799
800 op->out.group_hnd = group_hnd_out;
801
802 return CAC_SUCCESS;
803}
804
805int cac_SamCreateGroup( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
806 struct SamCreateGroup *op )
807{
808 struct rpc_pipe_client *pipe_hnd = NULL;
809
810 POLICY_HND *group_hnd_out = NULL;
811
812 if ( !hnd )
813 return CAC_FAILURE;
814
815 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
816 hnd->status = NT_STATUS_INVALID_HANDLE;
817 return CAC_FAILURE;
818 }
819
820 if ( !op || !op->in.name || op->in.name[0] == '\0'
821 || op->in.access == 0 || !mem_ctx ) {
822 hnd->status = NT_STATUS_INVALID_PARAMETER;
823 return CAC_FAILURE;
824 }
825
826 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
827 if ( !pipe_hnd ) {
828 hnd->status = NT_STATUS_INVALID_HANDLE;
829 return CAC_FAILURE;
830 }
831
832 group_hnd_out = talloc( mem_ctx, POLICY_HND );
833 if ( !group_hnd_out ) {
834 hnd->status = NT_STATUS_NO_MEMORY;
835 return CAC_FAILURE;
836 }
837
838 hnd->status =
839 rpccli_samr_create_dom_group( pipe_hnd, mem_ctx,
840 op->in.dom_hnd, op->in.name,
841 op->in.access, group_hnd_out );
842
843 if ( !NT_STATUS_IS_OK( hnd->status ) )
844 return CAC_FAILURE;
845
846 op->out.group_hnd = group_hnd_out;
847
848 return CAC_SUCCESS;
849
850}
851
852int cac_SamDeleteGroup( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
853 POLICY_HND * group_hnd )
854{
855 struct rpc_pipe_client *pipe_hnd = NULL;
856
857 if ( !hnd )
858 return CAC_FAILURE;
859
860 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
861 hnd->status = NT_STATUS_INVALID_HANDLE;
862 return CAC_FAILURE;
863 }
864
865 if ( !group_hnd || !mem_ctx ) {
866 hnd->status = NT_STATUS_INVALID_PARAMETER;
867 return CAC_FAILURE;
868 }
869
870 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
871 if ( !pipe_hnd ) {
872 hnd->status = NT_STATUS_INVALID_HANDLE;
873 return CAC_FAILURE;
874 }
875
876 hnd->status =
877 rpccli_samr_delete_dom_group( pipe_hnd, mem_ctx, group_hnd );
878
879 if ( !NT_STATUS_IS_OK( hnd->status ) )
880 return CAC_FAILURE;
881
882 return CAC_SUCCESS;
883
884}
885
886int cac_SamGetGroupMembers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
887 struct SamGetGroupMembers *op )
888{
889 struct rpc_pipe_client *pipe_hnd = NULL;
890
891 uint32 num_mem_out;
892 uint32 *rids_out;
893 uint32 *attr_out;
894
895 if ( !hnd )
896 return CAC_FAILURE;
897
898 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
899 hnd->status = NT_STATUS_INVALID_HANDLE;
900 return CAC_FAILURE;
901 }
902
903 if ( !op || !op->in.group_hnd || !mem_ctx ) {
904 hnd->status = NT_STATUS_INVALID_PARAMETER;
905 return CAC_FAILURE;
906 }
907
908 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
909 if ( !pipe_hnd ) {
910 hnd->status = NT_STATUS_INVALID_HANDLE;
911 return CAC_FAILURE;
912 }
913
914 hnd->status =
915 rpccli_samr_query_groupmem( pipe_hnd, mem_ctx,
916 op->in.group_hnd, &num_mem_out,
917 &rids_out, &attr_out );
918
919 if ( !NT_STATUS_IS_OK( hnd->status ) )
920 return CAC_FAILURE;
921
922 op->out.num_members = num_mem_out;
923 op->out.rids = rids_out;
924 op->out.attributes = attr_out;
925
926 return CAC_SUCCESS;
927}
928
929
930int cac_SamAddGroupMember( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
931 struct SamAddGroupMember *op )
932{
933 struct rpc_pipe_client *pipe_hnd = NULL;
934
935 if ( !hnd )
936 return CAC_FAILURE;
937
938 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
939 hnd->status = NT_STATUS_INVALID_HANDLE;
940 return CAC_FAILURE;
941 }
942
943 if ( !op || !op->in.group_hnd || op->in.rid == 0 || !mem_ctx ) {
944 hnd->status = NT_STATUS_INVALID_PARAMETER;
945 return CAC_FAILURE;
946 }
947
948 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
949 if ( !pipe_hnd ) {
950 hnd->status = NT_STATUS_INVALID_HANDLE;
951 return CAC_FAILURE;
952 }
953
954 hnd->status =
955 rpccli_samr_add_groupmem( pipe_hnd, mem_ctx, op->in.group_hnd,
956 op->in.rid );
957
958 if ( !NT_STATUS_IS_OK( hnd->status ) )
959 return CAC_FAILURE;
960
961 return CAC_SUCCESS;
962}
963
964int cac_SamRemoveGroupMember( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
965 struct SamRemoveGroupMember *op )
966{
967 struct rpc_pipe_client *pipe_hnd = NULL;
968
969 if ( !hnd )
970 return CAC_FAILURE;
971
972 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
973 hnd->status = NT_STATUS_INVALID_HANDLE;
974 return CAC_FAILURE;
975 }
976
977 if ( !op || !op->in.group_hnd || op->in.rid == 0 || !mem_ctx ) {
978 hnd->status = NT_STATUS_INVALID_PARAMETER;
979 return CAC_FAILURE;
980 }
981
982 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
983 if ( !pipe_hnd ) {
984 hnd->status = NT_STATUS_INVALID_HANDLE;
985 return CAC_FAILURE;
986 }
987
988 hnd->status =
989 rpccli_samr_del_groupmem( pipe_hnd, mem_ctx, op->in.group_hnd,
990 op->in.rid );
991
992 if ( !NT_STATUS_IS_OK( hnd->status ) )
993 return CAC_FAILURE;
994
995 return CAC_SUCCESS;
996}
997
998int cac_SamClearGroupMembers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
999 POLICY_HND * group_hnd )
1000{
1001 struct rpc_pipe_client *pipe_hnd = NULL;
1002
1003 int result = CAC_SUCCESS;
1004
1005 int i = 0;
1006
1007 uint32 num_mem = 0;
1008 uint32 *rid = NULL;
1009 uint32 *attr = NULL;
1010
1011 NTSTATUS status;
1012
1013 if ( !hnd )
1014 return CAC_FAILURE;
1015
1016 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
1017 hnd->status = NT_STATUS_INVALID_HANDLE;
1018 return CAC_FAILURE;
1019 }
1020
1021 if ( !group_hnd || !mem_ctx ) {
1022 hnd->status = NT_STATUS_INVALID_PARAMETER;
1023 return CAC_FAILURE;
1024 }
1025
1026 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
1027 if ( !pipe_hnd ) {
1028 hnd->status = NT_STATUS_INVALID_HANDLE;
1029 return CAC_FAILURE;
1030 }
1031
1032 hnd->status =
1033 rpccli_samr_query_groupmem( pipe_hnd, mem_ctx, group_hnd,
1034 &num_mem, &rid, &attr );
1035
1036 if ( !NT_STATUS_IS_OK( hnd->status ) )
1037 return CAC_FAILURE;
1038
1039 /*try to delete the users one by one */
1040 for ( i = 0; i < num_mem && NT_STATUS_IS_OK( hnd->status ); i++ ) {
1041 hnd->status =
1042 rpccli_samr_del_groupmem( pipe_hnd, mem_ctx,
1043 group_hnd, rid[i] );
1044 }
1045
1046 /*if not all members could be removed, then try to re-add the members that were already deleted */
1047 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1048 status = NT_STATUS_OK;
1049
1050 for ( i -= 1; i >= 0 && NT_STATUS_IS_OK( status ); i-- ) {
1051 status = rpccli_samr_add_groupmem( pipe_hnd, mem_ctx,
1052 group_hnd,
1053 rid[i] );
1054 }
1055
1056 /*we return with the NTSTATUS error that we got when trying to delete users */
1057 if ( !NT_STATUS_IS_OK( status ) )
1058 result = CAC_FAILURE;
1059 }
1060
1061 TALLOC_FREE( attr );
1062
1063 return result;
1064}
1065
1066int cac_SamSetGroupMembers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1067 struct SamSetGroupMembers *op )
1068{
1069 struct rpc_pipe_client *pipe_hnd = NULL;
1070
1071 uint32 i = 0;
1072
1073 if ( !hnd )
1074 return CAC_FAILURE;
1075
1076 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
1077 hnd->status = NT_STATUS_INVALID_HANDLE;
1078 return CAC_FAILURE;
1079 }
1080
1081 if ( !op || !op->in.group_hnd || !mem_ctx ) {
1082 hnd->status = NT_STATUS_INVALID_PARAMETER;
1083 return CAC_FAILURE;
1084 }
1085
1086 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
1087 if ( !pipe_hnd ) {
1088 hnd->status = NT_STATUS_INVALID_HANDLE;
1089 return CAC_FAILURE;
1090 }
1091
1092 /*use cac_SamClearGroupMembers() to clear them */
1093 if ( !cac_SamClearGroupMembers( hnd, mem_ctx, op->in.group_hnd ) )
1094 return CAC_FAILURE; /*hnd->status is already set */
1095
1096
1097 for ( i = 0; i < op->in.num_members && NT_STATUS_IS_OK( hnd->status );
1098 i++ ) {
1099 hnd->status =
1100 rpccli_samr_add_groupmem( pipe_hnd, mem_ctx,
1101 op->in.group_hnd,
1102 op->in.rids[i] );
1103 }
1104
1105 if ( !NT_STATUS_IS_OK( hnd->status ) )
1106 return CAC_FAILURE;
1107
1108 return CAC_SUCCESS;
1109
1110}
1111
1112int cac_SamEnumGroups( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1113 struct SamEnumGroups *op )
1114{
1115 struct rpc_pipe_client *pipe_hnd = NULL;
1116
1117 uint32 i = 0;
1118
1119 uint32 resume_idx_out = 0;
1120 char **names_out = NULL;
1121 char **desc_out = NULL;
1122 uint32 *rids_out = NULL;
1123 uint32 num_groups_out = 0;
1124
1125 struct acct_info *acct_buf = NULL;
1126
1127 if ( !hnd )
1128 return CAC_FAILURE;
1129
1130 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
1131 hnd->status = NT_STATUS_INVALID_HANDLE;
1132 return CAC_FAILURE;
1133 }
1134
1135 if ( !op || !op->in.dom_hnd || !mem_ctx ) {
1136 hnd->status = NT_STATUS_INVALID_PARAMETER;
1137 return CAC_FAILURE;
1138 }
1139
1140 /*using this BOOL is the only reliable way to know that we are done */
1141 if ( op->out.done == True ) /*we return failure so the call will break out of a loop */
1142 return CAC_FAILURE;
1143
1144 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
1145 if ( !pipe_hnd ) {
1146 hnd->status = NT_STATUS_INVALID_HANDLE;
1147 return CAC_FAILURE;
1148 }
1149
1150 resume_idx_out = op->out.resume_idx;
1151
1152 hnd->status =
1153 rpccli_samr_enum_dom_groups( pipe_hnd, mem_ctx,
1154 op->in.dom_hnd, &resume_idx_out,
1155 SAMR_ENUM_MAX_SIZE, &acct_buf,
1156 &num_groups_out );
1157
1158
1159 if ( NT_STATUS_IS_OK( hnd->status ) ) {
1160 op->out.done = True;
1161 } else if ( NT_STATUS_V( hnd->status ) !=
1162 NT_STATUS_V( STATUS_MORE_ENTRIES ) ) {
1163 /*if there are no more entries, the operation will return NT_STATUS_OK.
1164 * We want to return failure if no results were returned*/
1165 return CAC_FAILURE;
1166 }
1167
1168 if (num_groups_out) {
1169 names_out = TALLOC_ARRAY( mem_ctx, char *, num_groups_out );
1170 if ( !names_out ) {
1171 hnd->status = NT_STATUS_NO_MEMORY;
1172 TALLOC_FREE( acct_buf );
1173 return CAC_FAILURE;
1174 }
1175
1176 desc_out = TALLOC_ARRAY( mem_ctx, char *, num_groups_out );
1177 if ( !desc_out ) {
1178 hnd->status = NT_STATUS_NO_MEMORY;
1179 TALLOC_FREE( acct_buf );
1180 TALLOC_FREE( names_out );
1181 return CAC_FAILURE;
1182 }
1183
1184 rids_out = TALLOC_ARRAY( mem_ctx, uint32, num_groups_out );
1185 if ( !rids_out ) {
1186 hnd->status = NT_STATUS_NO_MEMORY;
1187 TALLOC_FREE( acct_buf );
1188 TALLOC_FREE( names_out );
1189 TALLOC_FREE( desc_out );
1190 return CAC_FAILURE;
1191 }
1192 } else {
1193 names_out = NULL;
1194 desc_out = NULL;
1195 rids_out = NULL;
1196 }
1197
1198 for ( i = 0; i < num_groups_out; i++ ) {
1199 names_out[i] =
1200 talloc_strdup( mem_ctx, acct_buf[i].acct_name );
1201 desc_out[i] = talloc_strdup( mem_ctx, acct_buf[i].acct_desc );
1202 rids_out[i] = acct_buf[i].rid;
1203
1204 if ( !names_out[i] || !desc_out[i] ) {
1205 hnd->status = NT_STATUS_NO_MEMORY;
1206 return CAC_FAILURE;
1207 }
1208 }
1209
1210 op->out.resume_idx = resume_idx_out;
1211 op->out.num_groups = num_groups_out;
1212 op->out.rids = rids_out;
1213 op->out.names = names_out;
1214 op->out.descriptions = desc_out;
1215
1216 return CAC_SUCCESS;
1217}
1218
1219int cac_SamEnumAliases( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1220 struct SamEnumAliases *op )
1221{
1222 struct rpc_pipe_client *pipe_hnd = NULL;
1223
1224 uint32 i = 0;
1225
1226 uint32 resume_idx_out = 0;
1227 char **names_out = NULL;
1228 char **desc_out = NULL;
1229 uint32 *rids_out = NULL;
1230 uint32 num_als_out = 0;
1231
1232 struct acct_info *acct_buf = NULL;
1233
1234 if ( !hnd )
1235 return CAC_FAILURE;
1236
1237 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
1238 hnd->status = NT_STATUS_INVALID_HANDLE;
1239 return CAC_FAILURE;
1240 }
1241
1242 if ( !op || !op->in.dom_hnd || !mem_ctx ) {
1243 hnd->status = NT_STATUS_INVALID_PARAMETER;
1244 return CAC_FAILURE;
1245 }
1246
1247 /*this is a hack.. but is the only reliable way to know if everything has been enumerated */
1248 if ( op->out.done == True ) {
1249 return CAC_FAILURE;
1250 }
1251
1252 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
1253 if ( !pipe_hnd ) {
1254 hnd->status = NT_STATUS_INVALID_HANDLE;
1255 return CAC_FAILURE;
1256 }
1257
1258 resume_idx_out = op->out.resume_idx;
1259
1260 hnd->status =
1261 rpccli_samr_enum_als_groups( pipe_hnd, mem_ctx,
1262 op->in.dom_hnd, &resume_idx_out,
1263 SAMR_ENUM_MAX_SIZE, &acct_buf,
1264 &num_als_out );
1265
1266
1267 if ( NT_STATUS_IS_OK( hnd->status ) )
1268 op->out.done = True;
1269
1270 /*if there are no more entries, the operation will return NT_STATUS_OK.
1271 * We want to return failure if no results were returned*/
1272 if ( !NT_STATUS_IS_OK( hnd->status )
1273 && NT_STATUS_V( hnd->status ) !=
1274 NT_STATUS_V( STATUS_MORE_ENTRIES ) )
1275 return CAC_FAILURE;
1276
1277 if (num_als_out) {
1278 names_out = TALLOC_ARRAY( mem_ctx, char *, num_als_out );
1279 if ( !names_out ) {
1280 hnd->status = NT_STATUS_NO_MEMORY;
1281 TALLOC_FREE( acct_buf );
1282 return CAC_FAILURE;
1283 }
1284
1285 desc_out = TALLOC_ARRAY( mem_ctx, char *, num_als_out );
1286 if ( !desc_out ) {
1287 hnd->status = NT_STATUS_NO_MEMORY;
1288 TALLOC_FREE( acct_buf );
1289 TALLOC_FREE( names_out );
1290 return CAC_FAILURE;
1291 }
1292
1293 rids_out = TALLOC_ARRAY( mem_ctx, uint32, num_als_out );
1294 if ( !rids_out ) {
1295 hnd->status = NT_STATUS_NO_MEMORY;
1296 TALLOC_FREE( acct_buf );
1297 TALLOC_FREE( names_out );
1298 TALLOC_FREE( desc_out );
1299 return CAC_FAILURE;
1300 }
1301 } else {
1302 names_out = NULL;
1303 desc_out = NULL;
1304 rids_out = NULL;
1305 }
1306
1307 for ( i = 0; i < num_als_out; i++ ) {
1308 names_out[i] =
1309 talloc_strdup( mem_ctx, acct_buf[i].acct_name );
1310 desc_out[i] = talloc_strdup( mem_ctx, acct_buf[i].acct_desc );
1311 rids_out[i] = acct_buf[i].rid;
1312
1313 if ( !names_out[i] || !desc_out[i] ) {
1314 hnd->status = NT_STATUS_NO_MEMORY;
1315 return CAC_FAILURE;
1316 }
1317 }
1318
1319 op->out.resume_idx = resume_idx_out;
1320 op->out.num_aliases = num_als_out;
1321 op->out.rids = rids_out;
1322 op->out.names = names_out;
1323 op->out.descriptions = desc_out;
1324
1325 return CAC_SUCCESS;
1326}
1327
1328int cac_SamCreateAlias( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1329 struct SamCreateAlias *op )
1330{
1331 struct rpc_pipe_client *pipe_hnd = NULL;
1332
1333 POLICY_HND *als_hnd_out = NULL;
1334
1335 if ( !hnd )
1336 return CAC_FAILURE;
1337
1338 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
1339 hnd->status = NT_STATUS_INVALID_HANDLE;
1340 return CAC_FAILURE;
1341 }
1342
1343 if ( !op || !op->in.name || op->in.name[0] == '\0' || !mem_ctx ) {
1344 hnd->status = NT_STATUS_INVALID_PARAMETER;
1345 return CAC_FAILURE;
1346 }
1347
1348 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
1349 if ( !pipe_hnd ) {
1350 hnd->status = NT_STATUS_INVALID_HANDLE;
1351 return CAC_FAILURE;
1352 }
1353
1354 als_hnd_out = talloc( mem_ctx, POLICY_HND );
1355 if ( !als_hnd_out ) {
1356 hnd->status = NT_STATUS_NO_MEMORY;
1357 return CAC_FAILURE;
1358 }
1359
1360 hnd->status =
1361 rpccli_samr_create_dom_alias( pipe_hnd, mem_ctx,
1362 op->in.dom_hnd, op->in.name,
1363 als_hnd_out );
1364
1365 if ( !NT_STATUS_IS_OK( hnd->status ) )
1366 return CAC_FAILURE;
1367
1368 op->out.alias_hnd = als_hnd_out;
1369
1370 return CAC_SUCCESS;
1371
1372}
1373
1374int cac_SamOpenAlias( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1375 struct SamOpenAlias *op )
1376{
1377 struct rpc_pipe_client *pipe_hnd = NULL;
1378
1379 POLICY_HND *als_hnd_out = NULL;
1380
1381 if ( !hnd )
1382 return CAC_FAILURE;
1383
1384 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
1385 hnd->status = NT_STATUS_INVALID_HANDLE;
1386 return CAC_FAILURE;
1387 }
1388
1389 if ( !op || op->in.access == 0 || op->in.rid == 0 || !mem_ctx ) {
1390 hnd->status = NT_STATUS_INVALID_PARAMETER;
1391 return CAC_FAILURE;
1392 }
1393
1394 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
1395 if ( !pipe_hnd ) {
1396 hnd->status = NT_STATUS_INVALID_HANDLE;
1397 return CAC_FAILURE;
1398 }
1399
1400 als_hnd_out = talloc( mem_ctx, POLICY_HND );
1401 if ( !als_hnd_out ) {
1402 hnd->status = NT_STATUS_NO_MEMORY;
1403 return CAC_FAILURE;
1404 }
1405
1406 hnd->status =
1407 rpccli_samr_open_alias( pipe_hnd, mem_ctx, op->in.dom_hnd,
1408 op->in.access, op->in.rid,
1409 als_hnd_out );
1410
1411 if ( !NT_STATUS_IS_OK( hnd->status ) )
1412 return CAC_FAILURE;
1413
1414 op->out.alias_hnd = als_hnd_out;
1415
1416 return CAC_SUCCESS;
1417}
1418
1419int cac_SamDeleteAlias( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1420 POLICY_HND * alias_hnd )
1421{
1422 struct rpc_pipe_client *pipe_hnd = NULL;
1423
1424 if ( !hnd )
1425 return CAC_FAILURE;
1426
1427 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
1428 hnd->status = NT_STATUS_INVALID_HANDLE;
1429 return CAC_FAILURE;
1430 }
1431
1432 if ( !alias_hnd || !mem_ctx ) {
1433 hnd->status = NT_STATUS_INVALID_PARAMETER;
1434 return CAC_FAILURE;
1435 }
1436
1437 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
1438 if ( !pipe_hnd ) {
1439 hnd->status = NT_STATUS_INVALID_HANDLE;
1440 return CAC_FAILURE;
1441 }
1442
1443 hnd->status =
1444 rpccli_samr_delete_dom_alias( pipe_hnd, mem_ctx, alias_hnd );
1445
1446 if ( !NT_STATUS_IS_OK( hnd->status ) )
1447 return CAC_FAILURE;
1448
1449 return CAC_SUCCESS;
1450
1451}
1452
1453int cac_SamAddAliasMember( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1454 struct SamAddAliasMember *op )
1455{
1456 struct rpc_pipe_client *pipe_hnd = NULL;
1457
1458 if ( !hnd )
1459 return CAC_FAILURE;
1460
1461 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
1462 hnd->status = NT_STATUS_INVALID_HANDLE;
1463 return CAC_FAILURE;
1464 }
1465
1466 if ( !op || !op->in.alias_hnd || !op->in.sid || !mem_ctx ) {
1467 hnd->status = NT_STATUS_INVALID_PARAMETER;
1468 return CAC_FAILURE;
1469 }
1470
1471 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
1472 if ( !pipe_hnd ) {
1473 hnd->status = NT_STATUS_INVALID_HANDLE;
1474 return CAC_FAILURE;
1475 }
1476
1477 hnd->status =
1478 rpccli_samr_add_aliasmem( pipe_hnd, mem_ctx, op->in.alias_hnd,
1479 op->in.sid );
1480
1481 if ( !NT_STATUS_IS_OK( hnd->status ) )
1482 return CAC_FAILURE;
1483
1484 return CAC_SUCCESS;
1485}
1486
1487int cac_SamRemoveAliasMember( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1488 struct SamRemoveAliasMember *op )
1489{
1490 struct rpc_pipe_client *pipe_hnd = NULL;
1491
1492 if ( !hnd )
1493 return CAC_FAILURE;
1494
1495 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
1496 hnd->status = NT_STATUS_INVALID_HANDLE;
1497 return CAC_FAILURE;
1498 }
1499
1500 if ( !op || !op->in.alias_hnd || !op->in.sid || !mem_ctx ) {
1501 hnd->status = NT_STATUS_INVALID_PARAMETER;
1502 return CAC_FAILURE;
1503 }
1504
1505 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
1506 if ( !pipe_hnd ) {
1507 hnd->status = NT_STATUS_INVALID_HANDLE;
1508 return CAC_FAILURE;
1509 }
1510
1511 hnd->status =
1512 rpccli_samr_del_aliasmem( pipe_hnd, mem_ctx, op->in.alias_hnd,
1513 op->in.sid );
1514
1515 if ( !NT_STATUS_IS_OK( hnd->status ) )
1516 return CAC_FAILURE;
1517
1518 return CAC_SUCCESS;
1519}
1520
1521int cac_SamGetAliasMembers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1522 struct SamGetAliasMembers *op )
1523{
1524 struct rpc_pipe_client *pipe_hnd = NULL;
1525
1526 uint32 num_mem_out;
1527 DOM_SID *sids_out;
1528
1529 if ( !hnd )
1530 return CAC_FAILURE;
1531
1532 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
1533 hnd->status = NT_STATUS_INVALID_HANDLE;
1534 return CAC_FAILURE;
1535 }
1536
1537 if ( !op || !op->in.alias_hnd || !mem_ctx ) {
1538 hnd->status = NT_STATUS_INVALID_PARAMETER;
1539 return CAC_FAILURE;
1540 }
1541
1542 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
1543 if ( !pipe_hnd ) {
1544 hnd->status = NT_STATUS_INVALID_HANDLE;
1545 return CAC_FAILURE;
1546 }
1547
1548 hnd->status =
1549 rpccli_samr_query_aliasmem( pipe_hnd, mem_ctx,
1550 op->in.alias_hnd, &num_mem_out,
1551 &sids_out );
1552
1553 if ( !NT_STATUS_IS_OK( hnd->status ) )
1554 return CAC_FAILURE;
1555
1556 op->out.num_members = num_mem_out;
1557 op->out.sids = sids_out;
1558
1559 return CAC_SUCCESS;
1560}
1561
1562int cac_SamClearAliasMembers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1563 POLICY_HND * alias_hnd )
1564{
1565 struct rpc_pipe_client *pipe_hnd = NULL;
1566
1567 int result = CAC_SUCCESS;
1568
1569 int i = 0;
1570
1571 uint32 num_mem = 0;
1572 DOM_SID *sid = NULL;
1573
1574 NTSTATUS status;
1575
1576 if ( !hnd )
1577 return CAC_FAILURE;
1578
1579 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
1580 hnd->status = NT_STATUS_INVALID_HANDLE;
1581 return CAC_FAILURE;
1582 }
1583
1584 if ( !alias_hnd || !mem_ctx ) {
1585 hnd->status = NT_STATUS_INVALID_PARAMETER;
1586 return CAC_FAILURE;
1587 }
1588
1589 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
1590 if ( !pipe_hnd ) {
1591 hnd->status = NT_STATUS_INVALID_HANDLE;
1592 return CAC_FAILURE;
1593 }
1594
1595 hnd->status =
1596 rpccli_samr_query_aliasmem( pipe_hnd, mem_ctx, alias_hnd,
1597 &num_mem, &sid );
1598
1599 if ( !NT_STATUS_IS_OK( hnd->status ) )
1600 return CAC_FAILURE;
1601
1602 /*try to delete the users one by one */
1603 for ( i = 0; i < num_mem && NT_STATUS_IS_OK( hnd->status ); i++ ) {
1604 hnd->status =
1605 rpccli_samr_del_aliasmem( pipe_hnd, mem_ctx,
1606 alias_hnd, &sid[i] );
1607 }
1608
1609 /*if not all members could be removed, then try to re-add the members that were already deleted */
1610 if ( !NT_STATUS_IS_OK( hnd->status ) ) {
1611 status = NT_STATUS_OK;
1612
1613 for ( i -= 1; i >= 0 && NT_STATUS_IS_OK( status ); i-- ) {
1614 status = rpccli_samr_add_aliasmem( pipe_hnd, mem_ctx,
1615 alias_hnd,
1616 &sid[i] );
1617 }
1618
1619 /*we return with the NTSTATUS error that we got when trying to delete users */
1620 if ( !NT_STATUS_IS_OK( status ) )
1621 result = CAC_FAILURE;
1622 }
1623
1624 TALLOC_FREE( sid );
1625 return result;
1626}
1627
1628int cac_SamSetAliasMembers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1629 struct SamSetAliasMembers *op )
1630{
1631 struct rpc_pipe_client *pipe_hnd = NULL;
1632
1633 uint32 i = 0;
1634
1635 if ( !hnd )
1636 return CAC_FAILURE;
1637
1638 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
1639 hnd->status = NT_STATUS_INVALID_HANDLE;
1640 return CAC_FAILURE;
1641 }
1642
1643 if ( !op || !op->in.alias_hnd || !mem_ctx ) {
1644 hnd->status = NT_STATUS_INVALID_PARAMETER;
1645 return CAC_FAILURE;
1646 }
1647
1648 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
1649 if ( !pipe_hnd ) {
1650 hnd->status = NT_STATUS_INVALID_HANDLE;
1651 return CAC_FAILURE;
1652 }
1653
1654 /*use cac_SamClearAliasMembers() to clear them */
1655 if ( !cac_SamClearAliasMembers( hnd, mem_ctx, op->in.alias_hnd ) )
1656 return CAC_FAILURE; /*hnd->status is already set */
1657
1658
1659 for ( i = 0; i < op->in.num_members && NT_STATUS_IS_OK( hnd->status );
1660 i++ ) {
1661 hnd->status =
1662 rpccli_samr_add_aliasmem( pipe_hnd, mem_ctx,
1663 op->in.alias_hnd,
1664 &( op->in.sids[i] ) );
1665 }
1666
1667 if ( !NT_STATUS_IS_OK( hnd->status ) )
1668 return CAC_FAILURE;
1669
1670 return CAC_SUCCESS;
1671
1672}
1673
1674int cac_SamUserChangePasswd( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1675 struct SamUserChangePasswd *op )
1676{
1677 SMBCSRV *srv = NULL;
1678 struct rpc_pipe_client *pipe_hnd = NULL;
1679
1680 if ( !hnd )
1681 return CAC_FAILURE;
1682
1683 if ( !hnd->_internal.ctx ) {
1684 hnd->status = NT_STATUS_INVALID_HANDLE;
1685 return CAC_FAILURE;
1686 }
1687
1688 if ( !op || !op->in.username || !op->in.password
1689 || !op->in.new_password || !mem_ctx ) {
1690 hnd->status = NT_STATUS_INVALID_PARAMETER;
1691 return CAC_FAILURE;
1692 }
1693
1694 srv = cac_GetServer( hnd );
1695 if ( !srv ) {
1696 hnd->status = NT_STATUS_INVALID_CONNECTION;
1697 return CAC_FAILURE;
1698 }
1699
1700 /*open a session on SAMR if we don't have one */
1701 if ( !hnd->_internal.pipes[PI_SAMR] ) {
1702 if ( !
1703 ( pipe_hnd =
1704 cli_rpc_pipe_open_noauth( srv->cli, PI_SAMR,
1705 &hnd->status ) ) ) {
1706 return CAC_FAILURE;
1707 }
1708
1709 hnd->_internal.pipes[PI_SAMR] = True;
1710 }
1711
1712 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
1713 if ( !pipe_hnd ) {
1714 hnd->status = NT_STATUS_INVALID_HANDLE;
1715 return CAC_FAILURE;
1716 }
1717
1718 hnd->status =
1719 rpccli_samr_chgpasswd_user( pipe_hnd, mem_ctx,
1720 op->in.username,
1721 op->in.new_password,
1722 op->in.password );
1723
1724 if ( !NT_STATUS_IS_OK( hnd->status ) )
1725 return CAC_FAILURE;
1726
1727 return CAC_SUCCESS;
1728}
1729
1730int cac_SamEnableUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1731 POLICY_HND * user_hnd )
1732{
1733 SMBCSRV *srv = NULL;
1734 struct rpc_pipe_client *pipe_hnd = NULL;
1735
1736 SAM_USERINFO_CTR *ctr;
1737
1738 if ( !hnd )
1739 return CAC_FAILURE;
1740
1741 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
1742 hnd->status = NT_STATUS_INVALID_HANDLE;
1743 return CAC_FAILURE;
1744 }
1745
1746 if ( !user_hnd || !mem_ctx ) {
1747 hnd->status = NT_STATUS_INVALID_PARAMETER;
1748 return CAC_FAILURE;
1749 }
1750
1751 srv = cac_GetServer( hnd );
1752 if ( !srv ) {
1753 hnd->status = NT_STATUS_INVALID_CONNECTION;
1754 return CAC_FAILURE;
1755 }
1756
1757 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
1758 if ( !pipe_hnd ) {
1759 hnd->status = NT_STATUS_INVALID_HANDLE;
1760 return CAC_FAILURE;
1761 }
1762
1763 /*info_level = 21 is the only level that I have found to work reliably. It would be nice if user_level = 10 worked. */
1764 hnd->status =
1765 rpccli_samr_query_userinfo( pipe_hnd, mem_ctx, user_hnd, 0x10,
1766 &ctr );
1767
1768 if ( !NT_STATUS_IS_OK( hnd->status ) )
1769 return CAC_FAILURE;
1770
1771 /**check the ACB mask*/
1772 if ( ( ctr->info.id16->acb_info & ACB_DISABLED ) == ACB_DISABLED ) {
1773 /*toggle the disabled bit */
1774 ctr->info.id16->acb_info ^= ACB_DISABLED;
1775 } else {
1776 /*the user is already enabled so just return success */
1777 return CAC_SUCCESS;
1778 }
1779
1780 /*now set the userinfo */
1781 hnd->status =
1782 rpccli_samr_set_userinfo2( pipe_hnd, mem_ctx, user_hnd, 0x10,
1783 &srv->cli->user_session_key, ctr );
1784
1785 /*this will only work properly if we use set_userinfo2 - fail if it is not supported */
1786 if ( !NT_STATUS_IS_OK( hnd->status ) )
1787 return CAC_FAILURE;
1788
1789 return CAC_SUCCESS;
1790}
1791
1792int cac_SamDisableUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1793 POLICY_HND * user_hnd )
1794{
1795 SMBCSRV *srv = NULL;
1796 struct rpc_pipe_client *pipe_hnd = NULL;
1797
1798 SAM_USERINFO_CTR *ctr;
1799
1800 if ( !hnd )
1801 return CAC_FAILURE;
1802
1803 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
1804 hnd->status = NT_STATUS_INVALID_HANDLE;
1805 return CAC_FAILURE;
1806 }
1807
1808 if ( !user_hnd || !mem_ctx ) {
1809 hnd->status = NT_STATUS_INVALID_PARAMETER;
1810 return CAC_FAILURE;
1811 }
1812
1813 srv = cac_GetServer( hnd );
1814 if ( !srv ) {
1815 hnd->status = NT_STATUS_INVALID_CONNECTION;
1816 return CAC_FAILURE;
1817 }
1818
1819 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
1820 if ( !pipe_hnd ) {
1821 hnd->status = NT_STATUS_INVALID_HANDLE;
1822 return CAC_FAILURE;
1823 }
1824
1825 hnd->status =
1826 rpccli_samr_query_userinfo( pipe_hnd, mem_ctx, user_hnd, 0x10,
1827 &ctr );
1828
1829 if ( !NT_STATUS_IS_OK( hnd->status ) )
1830 return CAC_FAILURE;
1831
1832 if ( ( ctr->info.id16->acb_info & ACB_DISABLED ) == ACB_DISABLED ) {
1833 /*then the user is already disabled */
1834 return CAC_SUCCESS;
1835 }
1836
1837 /*toggle the disabled bit */
1838 ctr->info.id16->acb_info ^= ACB_DISABLED;
1839
1840 /*this will only work properly if we use set_userinfo2 */
1841 hnd->status =
1842 rpccli_samr_set_userinfo2( pipe_hnd, mem_ctx, user_hnd, 0x10,
1843 &srv->cli->user_session_key, ctr );
1844
1845 /*this will only work properly if we use set_userinfo2 fail if it is not supported */
1846 if ( !NT_STATUS_IS_OK( hnd->status ) )
1847 return CAC_FAILURE;
1848
1849 return CAC_SUCCESS;
1850}
1851
1852int cac_SamSetPassword( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1853 struct SamSetPassword *op )
1854{
1855 SMBCSRV *srv = NULL;
1856 struct rpc_pipe_client *pipe_hnd = NULL;
1857
1858 SAM_USERINFO_CTR ctr;
1859 SAM_USER_INFO_24 info24;
1860 uint8 pw[516];
1861
1862 if ( !hnd )
1863 return CAC_FAILURE;
1864
1865 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
1866 hnd->status = NT_STATUS_INVALID_HANDLE;
1867 return CAC_FAILURE;
1868 }
1869
1870 if ( !op->in.user_hnd || !op->in.password || !mem_ctx ) {
1871 hnd->status = NT_STATUS_INVALID_PARAMETER;
1872 return CAC_FAILURE;
1873 }
1874
1875 srv = cac_GetServer( hnd );
1876 if ( !srv ) {
1877 hnd->status = NT_STATUS_INVALID_CONNECTION;
1878 return CAC_FAILURE;
1879 }
1880
1881 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
1882 if ( !pipe_hnd ) {
1883 hnd->status = NT_STATUS_INVALID_HANDLE;
1884 return CAC_FAILURE;
1885 }
1886
1887 ZERO_STRUCT( ctr );
1888 ZERO_STRUCT( info24 );
1889
1890 encode_pw_buffer( pw, op->in.password, STR_UNICODE );
1891
1892 init_sam_user_info24( &info24, ( char * ) pw, 24 );
1893
1894 ctr.switch_value = 24;
1895 ctr.info.id24 = &info24;
1896
1897 hnd->status =
1898 rpccli_samr_set_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd,
1899 24, &srv->cli->user_session_key,
1900 &ctr );
1901
1902 if ( !NT_STATUS_IS_OK( hnd->status ) )
1903 return CAC_FAILURE;
1904
1905 return CAC_SUCCESS;
1906}
1907
1908int cac_SamGetUserInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1909 struct SamGetUserInfo *op )
1910{
1911 struct rpc_pipe_client *pipe_hnd = NULL;
1912
1913 SAM_USERINFO_CTR *ctr;
1914
1915 if ( !hnd )
1916 return CAC_FAILURE;
1917
1918 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
1919 hnd->status = NT_STATUS_INVALID_HANDLE;
1920 return CAC_FAILURE;
1921 }
1922
1923 if ( !op->in.user_hnd || !mem_ctx ) {
1924 hnd->status = NT_STATUS_INVALID_PARAMETER;
1925 return CAC_FAILURE;
1926 }
1927
1928 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
1929 if ( !pipe_hnd ) {
1930 hnd->status = NT_STATUS_INVALID_HANDLE;
1931 return CAC_FAILURE;
1932 }
1933
1934 hnd->status =
1935 rpccli_samr_query_userinfo( pipe_hnd, mem_ctx,
1936 op->in.user_hnd, 21, &ctr );
1937
1938 if ( !NT_STATUS_IS_OK( hnd->status ) )
1939 return CAC_FAILURE;
1940
1941 op->out.info = cac_MakeUserInfo( mem_ctx, ctr );
1942
1943 if ( !op->out.info ) {
1944 hnd->status = NT_STATUS_NO_MEMORY;
1945 return CAC_FAILURE;
1946 }
1947
1948 return CAC_SUCCESS;
1949}
1950
1951int cac_SamSetUserInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
1952 struct SamSetUserInfo *op )
1953{
1954 SMBCSRV *srv = NULL;
1955 struct rpc_pipe_client *pipe_hnd = NULL;
1956
1957 SAM_USERINFO_CTR *ctr;
1958
1959 if ( !hnd )
1960 return CAC_FAILURE;
1961
1962 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
1963 hnd->status = NT_STATUS_INVALID_HANDLE;
1964 return CAC_FAILURE;
1965 }
1966
1967 if ( !op->in.user_hnd || !op->in.info || !mem_ctx ) {
1968 hnd->status = NT_STATUS_INVALID_PARAMETER;
1969 return CAC_FAILURE;
1970 }
1971
1972 ctr = cac_MakeUserInfoCtr( mem_ctx, op->in.info );
1973 if ( !ctr ) {
1974 hnd->status = NT_STATUS_NO_MEMORY;
1975 return CAC_FAILURE;
1976 }
1977
1978 srv = cac_GetServer( hnd );
1979 if ( !srv ) {
1980 hnd->status = NT_STATUS_INVALID_CONNECTION;
1981 return CAC_FAILURE;
1982 }
1983
1984 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
1985 if ( !pipe_hnd ) {
1986 hnd->status = NT_STATUS_INVALID_HANDLE;
1987 return CAC_FAILURE;
1988 }
1989
1990 if ( hnd->_internal.srv_level >= SRV_WIN_NT4 ) {
1991 hnd->status =
1992 rpccli_samr_set_userinfo2( pipe_hnd, mem_ctx,
1993 op->in.user_hnd, 21,
1994 &srv->cli->
1995 user_session_key, ctr );
1996 }
1997
1998 if ( hnd->_internal.srv_level < SRV_WIN_NT4
1999 || !NT_STATUS_IS_OK( hnd->status ) ) {
2000 hnd->status =
2001 rpccli_samr_set_userinfo( pipe_hnd, mem_ctx,
2002 op->in.user_hnd, 21,
2003 &srv->cli->user_session_key,
2004 ctr );
2005
2006 if ( NT_STATUS_IS_OK( hnd->status )
2007 && hnd->_internal.srv_level > SRV_WIN_NT4 ) {
2008 hnd->_internal.srv_level = SRV_WIN_NT4;
2009 }
2010 }
2011
2012
2013 if ( !NT_STATUS_IS_OK( hnd->status ) )
2014 return CAC_FAILURE;
2015
2016 return CAC_SUCCESS;
2017}
2018
2019
2020int cac_SamGetUserInfoCtr( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
2021 struct SamGetUserInfoCtr *op )
2022{
2023 struct rpc_pipe_client *pipe_hnd = NULL;
2024
2025 SAM_USERINFO_CTR *ctr_out;
2026
2027 if ( !hnd )
2028 return CAC_FAILURE;
2029
2030 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
2031 hnd->status = NT_STATUS_INVALID_HANDLE;
2032 return CAC_FAILURE;
2033 }
2034
2035 if ( !op->in.user_hnd || op->in.info_class == 0 || !mem_ctx ) {
2036 hnd->status = NT_STATUS_INVALID_PARAMETER;
2037 return CAC_FAILURE;
2038 }
2039
2040 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
2041 if ( !pipe_hnd ) {
2042 hnd->status = NT_STATUS_INVALID_HANDLE;
2043 return CAC_FAILURE;
2044 }
2045
2046 hnd->status =
2047 rpccli_samr_query_userinfo( pipe_hnd, mem_ctx,
2048 op->in.user_hnd,
2049 op->in.info_class, &ctr_out );
2050
2051 if ( !NT_STATUS_IS_OK( hnd->status ) )
2052 return CAC_FAILURE;
2053
2054 op->out.ctr = ctr_out;
2055
2056 return CAC_SUCCESS;
2057}
2058
2059int cac_SamSetUserInfoCtr( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
2060 struct SamSetUserInfoCtr *op )
2061{
2062 SMBCSRV *srv = NULL;
2063 struct rpc_pipe_client *pipe_hnd = NULL;
2064
2065 if ( !hnd )
2066 return CAC_FAILURE;
2067
2068 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
2069 hnd->status = NT_STATUS_INVALID_HANDLE;
2070 return CAC_FAILURE;
2071 }
2072
2073 if ( !op->in.user_hnd || !op->in.ctr || !mem_ctx ) {
2074 hnd->status = NT_STATUS_INVALID_PARAMETER;
2075 return CAC_FAILURE;
2076 }
2077
2078 srv = cac_GetServer( hnd );
2079 if ( !srv ) {
2080 hnd->status = NT_STATUS_INVALID_CONNECTION;
2081 return CAC_FAILURE;
2082 }
2083
2084 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
2085 if ( !pipe_hnd ) {
2086 hnd->status = NT_STATUS_INVALID_HANDLE;
2087 return CAC_FAILURE;
2088 }
2089
2090
2091 hnd->status =
2092 rpccli_samr_set_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd,
2093 op->in.ctr->switch_value,
2094 &srv->cli->user_session_key,
2095 op->in.ctr );
2096
2097 if ( !NT_STATUS_IS_OK( hnd->status ) )
2098 return CAC_FAILURE;
2099
2100 return CAC_SUCCESS;
2101
2102}
2103
2104int cac_SamRenameUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
2105 struct SamRenameUser *op )
2106{
2107 SMBCSRV *srv = NULL;
2108 struct rpc_pipe_client *pipe_hnd = NULL;
2109
2110 SAM_USERINFO_CTR ctr;
2111 SAM_USER_INFO_7 info7;
2112
2113 if ( !hnd )
2114 return CAC_FAILURE;
2115
2116 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
2117 hnd->status = NT_STATUS_INVALID_HANDLE;
2118 return CAC_FAILURE;
2119 }
2120
2121 if ( !op->in.user_hnd || !op->in.new_name
2122 || op->in.new_name[0] == '\0' || !mem_ctx ) {
2123 hnd->status = NT_STATUS_INVALID_PARAMETER;
2124 return CAC_FAILURE;
2125 }
2126
2127 srv = cac_GetServer( hnd );
2128 if ( !srv ) {
2129 hnd->status = NT_STATUS_INVALID_CONNECTION;
2130 return CAC_FAILURE;
2131 }
2132
2133 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
2134 if ( !pipe_hnd ) {
2135 hnd->status = NT_STATUS_INVALID_HANDLE;
2136 return CAC_FAILURE;
2137 }
2138
2139 ZERO_STRUCT( ctr );
2140 ZERO_STRUCT( info7 );
2141
2142 init_sam_user_info7( &info7, op->in.new_name );
2143
2144 ctr.switch_value = 7;
2145 ctr.info.id7 = &info7;
2146
2147 hnd->status =
2148 rpccli_samr_set_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd,
2149 7, &srv->cli->user_session_key,
2150 &ctr );
2151
2152 if ( !NT_STATUS_IS_OK( hnd->status ) )
2153 return CAC_FAILURE;
2154
2155 return CAC_SUCCESS;
2156}
2157
2158
2159int cac_SamGetGroupInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
2160 struct SamGetGroupInfo *op )
2161{
2162 struct rpc_pipe_client *pipe_hnd = NULL;
2163
2164 GROUP_INFO_CTR *ctr;
2165
2166 if ( !hnd )
2167 return CAC_FAILURE;
2168
2169 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
2170 hnd->status = NT_STATUS_INVALID_HANDLE;
2171 return CAC_FAILURE;
2172 }
2173
2174 if ( !op->in.group_hnd || !mem_ctx ) {
2175 hnd->status = NT_STATUS_INVALID_PARAMETER;
2176 return CAC_FAILURE;
2177 }
2178
2179 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
2180 if ( !pipe_hnd ) {
2181 hnd->status = NT_STATUS_INVALID_HANDLE;
2182 return CAC_FAILURE;
2183 }
2184
2185
2186 /*get a GROUP_INFO_1 structure */
2187 hnd->status =
2188 rpccli_samr_query_groupinfo( pipe_hnd, mem_ctx,
2189 op->in.group_hnd, 1, &ctr );
2190
2191 if ( !NT_STATUS_IS_OK( hnd->status ) )
2192 return CAC_FAILURE;
2193
2194 op->out.info = cac_MakeGroupInfo( mem_ctx, ctr );
2195 if ( !op->out.info ) {
2196 hnd->status = NT_STATUS_NO_MEMORY;
2197 return CAC_FAILURE;
2198 }
2199
2200 return CAC_SUCCESS;
2201}
2202
2203int cac_SamSetGroupInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
2204 struct SamSetGroupInfo *op )
2205{
2206 struct rpc_pipe_client *pipe_hnd = NULL;
2207
2208 GROUP_INFO_CTR *ctr = NULL;
2209
2210 if ( !hnd )
2211 return CAC_FAILURE;
2212
2213 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
2214 hnd->status = NT_STATUS_INVALID_HANDLE;
2215 return CAC_FAILURE;
2216 }
2217
2218 if ( !op->in.group_hnd || !op->in.info || !mem_ctx ) {
2219 hnd->status = NT_STATUS_INVALID_PARAMETER;
2220 return CAC_FAILURE;
2221 }
2222
2223 ctr = cac_MakeGroupInfoCtr( mem_ctx, op->in.info );
2224 if ( !ctr ) {
2225 hnd->status = NT_STATUS_NO_MEMORY;
2226 return CAC_FAILURE;
2227 }
2228
2229 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
2230 if ( !pipe_hnd ) {
2231 hnd->status = NT_STATUS_INVALID_HANDLE;
2232 return CAC_FAILURE;
2233 }
2234
2235 hnd->status =
2236 rpccli_samr_set_groupinfo( pipe_hnd, mem_ctx,
2237 op->in.group_hnd, ctr );
2238
2239 if ( !NT_STATUS_IS_OK( hnd->status ) )
2240 return CAC_FAILURE;
2241
2242 return CAC_SUCCESS;
2243}
2244
2245int cac_SamRenameGroup( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
2246 struct SamRenameGroup *op )
2247{
2248 struct rpc_pipe_client *pipe_hnd = NULL;
2249
2250 GROUP_INFO_CTR ctr;
2251
2252 if ( !hnd )
2253 return CAC_FAILURE;
2254
2255 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
2256 hnd->status = NT_STATUS_INVALID_HANDLE;
2257 return CAC_FAILURE;
2258 }
2259
2260 if ( !op->in.group_hnd || !op->in.new_name
2261 || op->in.new_name[0] == '\0' || !mem_ctx ) {
2262 hnd->status = NT_STATUS_INVALID_PARAMETER;
2263 return CAC_FAILURE;
2264 }
2265
2266 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
2267 if ( !pipe_hnd ) {
2268 hnd->status = NT_STATUS_INVALID_HANDLE;
2269 return CAC_FAILURE;
2270 }
2271
2272 ZERO_STRUCT( ctr );
2273
2274 init_samr_group_info2( &ctr.group.info2, op->in.new_name );
2275 ctr.switch_value1 = 2;
2276
2277 hnd->status =
2278 rpccli_samr_set_groupinfo( pipe_hnd, mem_ctx,
2279 op->in.group_hnd, &ctr );
2280
2281 if ( !NT_STATUS_IS_OK( hnd->status ) )
2282 return CAC_FAILURE;
2283
2284 return CAC_SUCCESS;
2285}
2286
2287int cac_SamGetAliasInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
2288 struct SamGetAliasInfo *op )
2289{
2290 struct rpc_pipe_client *pipe_hnd = NULL;
2291
2292 ALIAS_INFO_CTR ctr;
2293
2294 if ( !hnd )
2295 return CAC_FAILURE;
2296
2297 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
2298 hnd->status = NT_STATUS_INVALID_HANDLE;
2299 return CAC_FAILURE;
2300 }
2301
2302 if ( !op->in.alias_hnd || !mem_ctx ) {
2303 hnd->status = NT_STATUS_INVALID_PARAMETER;
2304 return CAC_FAILURE;
2305 }
2306
2307 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
2308 if ( !pipe_hnd ) {
2309 hnd->status = NT_STATUS_INVALID_HANDLE;
2310 return CAC_FAILURE;
2311 }
2312
2313 /*get a GROUP_INFO_1 structure */
2314 hnd->status =
2315 rpccli_samr_query_alias_info( pipe_hnd, mem_ctx,
2316 op->in.alias_hnd, 1, &ctr );
2317
2318 if ( !NT_STATUS_IS_OK( hnd->status ) )
2319 return CAC_FAILURE;
2320
2321 op->out.info = cac_MakeAliasInfo( mem_ctx, ctr );
2322 if ( !op->out.info ) {
2323 hnd->status = NT_STATUS_NO_MEMORY;
2324 return CAC_FAILURE;
2325 }
2326
2327 return CAC_SUCCESS;
2328
2329}
2330
2331int cac_SamSetAliasInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
2332 struct SamSetAliasInfo *op )
2333{
2334 struct rpc_pipe_client *pipe_hnd = NULL;
2335
2336 ALIAS_INFO_CTR *ctr = NULL;
2337
2338 if ( !hnd )
2339 return CAC_FAILURE;
2340
2341 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
2342 hnd->status = NT_STATUS_INVALID_HANDLE;
2343 return CAC_FAILURE;
2344 }
2345
2346 if ( !op->in.alias_hnd || !op->in.info || !mem_ctx ) {
2347 hnd->status = NT_STATUS_INVALID_PARAMETER;
2348 return CAC_FAILURE;
2349 }
2350
2351 ctr = cac_MakeAliasInfoCtr( mem_ctx, op->in.info );
2352 if ( !ctr ) {
2353 hnd->status = NT_STATUS_NO_MEMORY;
2354 return CAC_FAILURE;
2355 }
2356
2357 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
2358 if ( !pipe_hnd ) {
2359 hnd->status = NT_STATUS_INVALID_HANDLE;
2360 return CAC_FAILURE;
2361 }
2362
2363 hnd->status =
2364 rpccli_samr_set_aliasinfo( pipe_hnd, mem_ctx,
2365 op->in.alias_hnd, ctr );
2366
2367 if ( !NT_STATUS_IS_OK( hnd->status ) )
2368 return CAC_FAILURE;
2369
2370 return CAC_SUCCESS;
2371}
2372
2373int cac_SamGetDomainInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
2374 struct SamGetDomainInfo *op )
2375{
2376 struct rpc_pipe_client *pipe_hnd = NULL;
2377
2378 SAM_UNK_CTR ctr;
2379 SAM_UNK_INFO_1 info1;
2380 SAM_UNK_INFO_2 info2;
2381 SAM_UNK_INFO_12 info12;
2382
2383 /*use this to keep track of a failed call */
2384 NTSTATUS status_buf = NT_STATUS_OK;
2385
2386 uint16 fail_count = 0;
2387
2388
2389 if ( !hnd )
2390 return CAC_FAILURE;
2391
2392 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
2393 hnd->status = NT_STATUS_INVALID_HANDLE;
2394 return CAC_FAILURE;
2395 }
2396
2397 if ( !op->in.dom_hnd || !mem_ctx ) {
2398 hnd->status = NT_STATUS_INVALID_PARAMETER;
2399 return CAC_FAILURE;
2400 }
2401
2402 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
2403 if ( !pipe_hnd ) {
2404 hnd->status = NT_STATUS_INVALID_HANDLE;
2405 return CAC_FAILURE;
2406 }
2407
2408 /*first try with info 1 */
2409 hnd->status =
2410 rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd,
2411 1, &ctr );
2412
2413 if ( NT_STATUS_IS_OK( hnd->status ) ) {
2414 /*then we buffer the SAM_UNK_INFO_1 structure */
2415 info1 = ctr.info.inf1;
2416 } else {
2417 /*then the call failed, store the status and ZERO out the info structure */
2418 ZERO_STRUCT( info1 );
2419 status_buf = hnd->status;
2420 fail_count++;
2421 }
2422
2423 /*try again for the next one */
2424 hnd->status =
2425 rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd,
2426 2, &ctr );
2427
2428 if ( NT_STATUS_IS_OK( hnd->status ) ) {
2429 /*store the info */
2430 info2 = ctr.info.inf2;
2431 } else {
2432 /*ZERO out the structure and store the bad status */
2433 ZERO_STRUCT( info2 );
2434 status_buf = hnd->status;
2435 fail_count++;
2436 }
2437
2438 /*once more */
2439 hnd->status =
2440 rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd,
2441 12, &ctr );
2442
2443 if ( NT_STATUS_IS_OK( hnd->status ) ) {
2444 info12 = ctr.info.inf12;
2445 } else {
2446 ZERO_STRUCT( info12 );
2447 status_buf = hnd->status;
2448 fail_count++;
2449 }
2450
2451 /*return failure if all 3 calls failed */
2452 if ( fail_count == 3 )
2453 return CAC_FAILURE;
2454
2455 op->out.info = cac_MakeDomainInfo( mem_ctx, &info1, &info2, &info12 );
2456
2457 if ( !op->out.info ) {
2458 hnd->status = NT_STATUS_NO_MEMORY;
2459 return CAC_FAILURE;
2460 }
2461
2462 if ( fail_count > 0 ) {
2463 hnd->status = status_buf;
2464 return CAC_PARTIAL_SUCCESS;
2465 }
2466
2467 return CAC_SUCCESS;
2468}
2469
2470int cac_SamGetDomainInfoCtr( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
2471 struct SamGetDomainInfoCtr *op )
2472{
2473 struct rpc_pipe_client *pipe_hnd = NULL;
2474
2475 SAM_UNK_CTR *ctr_out;
2476
2477 if ( !hnd )
2478 return CAC_FAILURE;
2479
2480 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
2481 hnd->status = NT_STATUS_INVALID_HANDLE;
2482 return CAC_FAILURE;
2483 }
2484
2485 if ( !op->in.dom_hnd || op->in.info_class == 0 || !mem_ctx ) {
2486 hnd->status = NT_STATUS_INVALID_PARAMETER;
2487 return CAC_FAILURE;
2488 }
2489
2490 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
2491 if ( !pipe_hnd ) {
2492 hnd->status = NT_STATUS_INVALID_HANDLE;
2493 return CAC_FAILURE;
2494 }
2495
2496 ctr_out = talloc( mem_ctx, SAM_UNK_CTR );
2497 if ( !ctr_out ) {
2498 hnd->status = NT_STATUS_NO_MEMORY;
2499 return CAC_FAILURE;
2500 }
2501
2502 hnd->status =
2503 rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd,
2504 op->in.info_class, ctr_out );
2505
2506 if ( !NT_STATUS_IS_OK( hnd->status ) )
2507 return CAC_FAILURE;
2508
2509 op->out.info = ctr_out;
2510
2511 return CAC_SUCCESS;
2512}
2513
2514int cac_SamGetDisplayInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
2515 struct SamGetDisplayInfo *op )
2516{
2517 struct rpc_pipe_client *pipe_hnd = NULL;
2518
2519 SAM_DISPINFO_CTR ctr_out;
2520
2521 uint32 max_entries_buf = 0;
2522 uint32 max_size_buf = 0;
2523
2524 uint32 resume_idx_out;
2525 uint32 num_entries_out;
2526
2527 if ( !hnd )
2528 return CAC_FAILURE;
2529
2530 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
2531 hnd->status = NT_STATUS_INVALID_HANDLE;
2532 return CAC_FAILURE;
2533 }
2534
2535 if ( !op->in.dom_hnd || op->in.info_class == 0 || !mem_ctx ) {
2536 hnd->status = NT_STATUS_INVALID_PARAMETER;
2537 return CAC_FAILURE;
2538 }
2539
2540 if ( op->out.done == True ) /*this is done so we can use the function as a loop condition */
2541 return CAC_FAILURE;
2542
2543 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
2544 if ( !pipe_hnd ) {
2545 hnd->status = NT_STATUS_INVALID_HANDLE;
2546 return CAC_FAILURE;
2547 }
2548
2549 if ( op->in.max_entries == 0 || op->in.max_size == 0 ) {
2550 get_query_dispinfo_params( op->out.loop_count,
2551 &max_entries_buf, &max_size_buf );
2552 } else {
2553 max_entries_buf = op->in.max_entries;
2554 max_size_buf = op->in.max_size;
2555 }
2556
2557 resume_idx_out = op->out.resume_idx;
2558
2559 hnd->status =
2560 rpccli_samr_query_dispinfo( pipe_hnd, mem_ctx, op->in.dom_hnd,
2561 &resume_idx_out,
2562 op->in.info_class,
2563 &num_entries_out, max_entries_buf,
2564 max_size_buf, &ctr_out );
2565
2566 if ( !NT_STATUS_IS_OK( hnd->status )
2567 && !NT_STATUS_EQUAL( hnd->status, STATUS_MORE_ENTRIES ) ) {
2568 /*be defensive, maybe they'll call again without zeroing the struct */
2569 op->out.loop_count = 0;
2570 op->out.resume_idx = 0;
2571 return CAC_FAILURE;
2572 }
2573
2574 if ( NT_STATUS_IS_OK( hnd->status ) ) {
2575 /*we want to quit once the function is called next. so it can be used in a loop */
2576 op->out.done = True;
2577 }
2578
2579 op->out.resume_idx = resume_idx_out;
2580 op->out.num_entries = num_entries_out;
2581 op->out.ctr = ctr_out;
2582 op->out.loop_count++;
2583
2584 return CAC_SUCCESS;
2585}
2586
2587int cac_SamLookupDomain( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
2588 struct SamLookupDomain *op )
2589{
2590 struct rpc_pipe_client *pipe_hnd = NULL;
2591
2592 DOM_SID *sid_out = NULL;
2593
2594 if ( !hnd )
2595 return CAC_FAILURE;
2596
2597 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
2598 hnd->status = NT_STATUS_INVALID_HANDLE;
2599 return CAC_FAILURE;
2600 }
2601
2602 if ( !op->in.sam || !op->in.name || !mem_ctx ) {
2603 hnd->status = NT_STATUS_INVALID_PARAMETER;
2604 return CAC_FAILURE;
2605 }
2606
2607 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
2608 if ( !pipe_hnd ) {
2609 hnd->status = NT_STATUS_INVALID_HANDLE;
2610 return CAC_FAILURE;
2611 }
2612
2613 sid_out = talloc( mem_ctx, DOM_SID );
2614 if ( !sid_out ) {
2615 hnd->status = NT_STATUS_NO_MEMORY;
2616 return CAC_FAILURE;
2617 }
2618
2619 hnd->status =
2620 rpccli_samr_lookup_domain( pipe_hnd, mem_ctx, op->in.sam,
2621 op->in.name, sid_out );
2622
2623 if ( !NT_STATUS_IS_OK( hnd->status ) )
2624 return CAC_FAILURE;
2625
2626 op->out.sid = sid_out;
2627
2628 return CAC_SUCCESS;
2629}
2630
2631int cac_SamGetSecurityObject( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
2632 struct SamGetSecurityObject *op )
2633{
2634 struct rpc_pipe_client *pipe_hnd = NULL;
2635
2636 /*this number taken from rpcclient/cmd_samr.c, I think it is the only supported level */
2637 uint32 sec_info = DACL_SECURITY_INFORMATION;
2638
2639 SEC_DESC_BUF *sec_out = NULL;
2640
2641 if ( !hnd )
2642 return CAC_FAILURE;
2643
2644 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
2645 hnd->status = NT_STATUS_INVALID_HANDLE;
2646 return CAC_FAILURE;
2647 }
2648
2649 if ( !op->in.pol || !mem_ctx ) {
2650 hnd->status = NT_STATUS_INVALID_PARAMETER;
2651 return CAC_FAILURE;
2652 }
2653
2654 pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
2655 if ( !pipe_hnd ) {
2656 hnd->status = NT_STATUS_INVALID_HANDLE;
2657 return CAC_FAILURE;
2658 }
2659
2660 hnd->status =
2661 rpccli_samr_query_sec_obj( pipe_hnd, mem_ctx, op->in.pol,
2662 sec_info, mem_ctx, &sec_out );
2663
2664 if ( !NT_STATUS_IS_OK( hnd->status ) )
2665 return CAC_FAILURE;
2666
2667 op->out.sec = sec_out;
2668
2669 return CAC_SUCCESS;
2670}
2671
2672int cac_SamFlush( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
2673 struct SamFlush *op )
2674{
2675 struct SamOpenDomain od;
2676
2677 if ( !hnd )
2678 return CAC_FAILURE;
2679
2680 if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
2681 hnd->status = NT_STATUS_INVALID_HANDLE;
2682 return CAC_FAILURE;
2683 }
2684
2685 if ( !op || !op->in.dom_hnd || !mem_ctx ) {
2686 hnd->status = NT_STATUS_INVALID_PARAMETER;
2687 return CAC_FAILURE;
2688 }
2689
2690 if ( !cac_SamClose( hnd, mem_ctx, op->in.dom_hnd ) )
2691 return CAC_FAILURE;
2692
2693 ZERO_STRUCT( od );
2694 od.in.access =
2695 ( op->in.access ) ? op->in.access : MAXIMUM_ALLOWED_ACCESS;
2696 od.in.sid = op->in.sid;
2697
2698 if ( !cac_SamOpenDomain( hnd, mem_ctx, &od ) )
2699 return CAC_FAILURE;
2700
2701 /*this function does not use an output parameter to make it as convenient as possible to use */
2702 *op->in.dom_hnd = *od.out.dom_hnd;
2703
2704 TALLOC_FREE( od.out.dom_hnd );
2705
2706 return CAC_SUCCESS;
2707}
Note: See TracBrowser for help on using the repository browser.