source: branches/samba-3.0/source/libmsrpc/cac_samr.c

Last change on this file was 124, checked in by Paul Smedley, 17 years ago

Update source to 3.0.28a

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