3 * Unix SMB/CIFS implementation.
4 * MS-RPC client library implementation (SAMR pipe)
5 * Copyright (C) Chris Nicholls 2005.
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.
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.
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.
23 #include "libmsrpc_internal.h"
25 /*used by cac_SamGetNamesFromRids*/
26 #define SAMR_RID_UNKNOWN 8
28 #define SAMR_ENUM_MAX_SIZE 0xffff
30 /*not sure what this is.. taken from rpcclient/cmd_samr.c*/
31 #define SAMR_LOOKUP_FLAGS 0x000003e8
33 DOM_SID
*cac_get_domain_sid( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
36 int cac_SamConnect( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
37 struct SamConnect
*op
)
40 struct rpc_pipe_client
*pipe_hnd
= NULL
;
41 POLICY_HND
*sam_out
= NULL
;
46 if ( !hnd
->_internal
.ctx
) {
47 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
51 if ( !op
|| op
->in
.access
== 0 || !mem_ctx
) {
52 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
56 srv
= cac_GetServer( hnd
);
58 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
62 /*initialize for samr pipe if we have to */
63 if ( !hnd
->_internal
.pipes
[PI_SAMR
] ) {
66 cli_rpc_pipe_open_noauth( srv
->cli
, PI_SAMR
,
71 hnd
->_internal
.pipes
[PI_SAMR
] = True
;
74 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
76 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
80 sam_out
= talloc( mem_ctx
, POLICY_HND
);
82 hnd
->status
= NT_STATUS_NO_MEMORY
;
86 if ( hnd
->_internal
.srv_level
>= SRV_WIN_2K_SP3
) {
88 rpccli_samr_connect4( pipe_hnd
, mem_ctx
,
89 op
->in
.access
, sam_out
);
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 */
97 rpccli_samr_connect( pipe_hnd
, mem_ctx
, op
->in
.access
,
100 if ( NT_STATUS_IS_OK( hnd
->status
)
101 && hnd
->_internal
.srv_level
> SRV_WIN_2K
) {
102 hnd
->_internal
.srv_level
= SRV_WIN_2K
;
106 if ( !NT_STATUS_IS_OK( hnd
->status
) )
109 op
->out
.sam
= sam_out
;
114 int cac_SamClose( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
117 struct rpc_pipe_client
*pipe_hnd
= NULL
;
122 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
123 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
127 if ( !sam
|| !mem_ctx
) {
128 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
132 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
134 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
138 hnd
->status
= rpccli_samr_close( pipe_hnd
, mem_ctx
, sam
);
140 if ( !NT_STATUS_IS_OK( hnd
->status
) )
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
150 /*attempts to find the sid of the domain we are connected to*/
151 DOM_SID
*cac_get_domain_sid( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
154 struct LsaOpenPolicy lop
;
155 struct LsaFetchSid fs
;
162 lop
.in
.access
= des_access
;
163 lop
.in
.security_qos
= True
;
165 if ( !cac_LsaOpenPolicy( hnd
, mem_ctx
, &lop
) )
168 fs
.in
.pol
= lop
.out
.pol
;
169 fs
.in
.info_class
= CAC_DOMAIN_INFO
;
171 if ( !cac_LsaFetchSid( hnd
, mem_ctx
, &fs
) )
174 cac_LsaClosePolicy( hnd
, mem_ctx
, lop
.out
.pol
);
176 if ( !fs
.out
.domain_sid
)
179 sid
= ( DOM_SID
* ) talloc_memdup( mem_ctx
,
180 &( fs
.out
.domain_sid
->sid
),
184 hnd
->status
= NT_STATUS_NO_MEMORY
;
191 int cac_SamOpenDomain( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
192 struct SamOpenDomain
*op
)
194 struct rpc_pipe_client
*pipe_hnd
= NULL
;
200 struct SamLookupDomain sld
;
205 if ( !hnd
->_internal
.ctx
) {
206 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
210 if ( !op
|| op
->in
.access
== 0 || !mem_ctx
) {
211 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
216 /*use cac_SamConnect() since it does the session setup */
217 struct SamConnect sc
;
221 sc
.in
.access
= op
->in
.access
;
223 if ( !cac_SamConnect( hnd
, mem_ctx
, &sc
) ) {
227 sam_out
= sc
.out
.sam
;
229 sam_out
= op
->in
.sam
;
233 /*find the sid for the SAM's domain */
235 /*try using cac_SamLookupDomain() first */
238 sld
.in
.sam
= sam_out
;
239 sld
.in
.name
= hnd
->domain
;
241 if ( cac_SamLookupDomain( hnd
, mem_ctx
, &sld
) ) {
242 /*then we got the sid */
243 sid_buf
= sld
.out
.sid
;
245 /*try to get it from the LSA */
247 cac_get_domain_sid( hnd
, mem_ctx
,
251 /*we already have the sid for the domain we want */
252 sid_buf
= op
->in
.sid
;
255 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
257 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
261 pol_out
= talloc( mem_ctx
, POLICY_HND
);
263 hnd
->status
= NT_STATUS_NO_MEMORY
;
267 /*now open the domain */
269 rpccli_samr_open_domain( pipe_hnd
, mem_ctx
, sam_out
,
270 op
->in
.access
, sid_buf
, pol_out
);
272 if ( !NT_STATUS_IS_OK( hnd
->status
) )
275 op
->out
.sam
= sam_out
;
276 op
->out
.dom_hnd
= pol_out
;
281 int cac_SamOpenUser( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
282 struct SamOpenUser
*op
)
284 struct rpc_pipe_client
*pipe_hnd
= NULL
;
286 uint32
*rid_buf
= NULL
;
289 uint32
*rid_types
= NULL
;
291 POLICY_HND
*user_out
= NULL
;
296 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
297 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
301 if ( !op
|| !op
->in
.dom_hnd
|| op
->in
.access
== 0 || !mem_ctx
) {
302 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
306 if ( op
->in
.rid
== 0 && op
->in
.name
== NULL
) {
307 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
311 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
313 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
317 if ( op
->in
.rid
== 0 && op
->in
.name
) {
318 /*lookup the name and then set rid_buf */
321 rpccli_samr_lookup_names( pipe_hnd
, mem_ctx
,
323 SAMR_LOOKUP_FLAGS
, 1,
324 ( const char ** ) &op
->in
.
325 name
, &num_rids
, &rid_buf
,
328 if ( !NT_STATUS_IS_OK( hnd
->status
) )
331 if ( num_rids
== 0 || rid_buf
== NULL
332 || rid_types
[0] == SAMR_RID_UNKNOWN
) {
333 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
337 TALLOC_FREE( rid_types
);
340 rid_buf
= &op
->in
.rid
;
343 user_out
= talloc( mem_ctx
, POLICY_HND
);
345 hnd
->status
= NT_STATUS_NO_MEMORY
;
350 rpccli_samr_open_user( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
,
351 op
->in
.access
, *rid_buf
, user_out
);
353 if ( !NT_STATUS_IS_OK( hnd
->status
) )
356 op
->out
.user_hnd
= user_out
;
361 int cac_SamCreateUser( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
362 struct SamCreateUser
*op
)
364 struct rpc_pipe_client
*pipe_hnd
= NULL
;
366 POLICY_HND
*user_out
= NULL
;
369 /**found in rpcclient/cmd_samr.c*/
370 uint32 unknown
= 0xe005000b;
375 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
376 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
380 if ( !op
|| !op
->in
.dom_hnd
|| !op
->in
.name
|| op
->in
.acb_mask
== 0
382 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
386 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
388 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
392 user_out
= talloc( mem_ctx
, POLICY_HND
);
394 hnd
->status
= NT_STATUS_NO_MEMORY
;
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
);
404 if ( !NT_STATUS_IS_OK( hnd
->status
) )
407 op
->out
.user_hnd
= user_out
;
408 op
->out
.rid
= rid_out
;
413 int cac_SamDeleteUser( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
414 POLICY_HND
* user_hnd
)
416 struct rpc_pipe_client
*pipe_hnd
= NULL
;
421 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
422 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
426 if ( !user_hnd
|| !mem_ctx
) {
427 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
431 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
433 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
438 rpccli_samr_delete_dom_user( pipe_hnd
, mem_ctx
, user_hnd
);
440 if ( !NT_STATUS_IS_OK( hnd
->status
) )
446 int cac_SamEnumUsers( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
447 struct SamEnumUsers
*op
)
449 struct rpc_pipe_client
*pipe_hnd
= NULL
;
451 uint32 resume_idx_out
= 0;
452 char **names_out
= NULL
;
453 uint32
*rids_out
= NULL
;
454 uint32 num_users_out
= 0;
459 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
460 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
464 if ( !op
|| !op
->in
.dom_hnd
|| !mem_ctx
) {
465 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
469 /*this is a hack.. but is the only reliable way to know if everything has been enumerated */
470 if ( op
->out
.done
== True
)
473 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
475 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
479 resume_idx_out
= op
->out
.resume_idx
;
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
);
488 if ( NT_STATUS_IS_OK( hnd
->status
) )
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
) )
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
;
506 int cac_SamGetNamesFromRids( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
507 struct SamGetNamesFromRids
*op
)
509 struct rpc_pipe_client
*pipe_hnd
= NULL
;
511 uint32 num_names_out
;
513 uint32
*name_types_out
;
518 CacLookupRidsRecord
*map_out
;
523 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
524 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
528 if ( !op
|| !op
->in
.dom_hnd
|| !mem_ctx
) {
529 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
533 if ( !op
->in
.rids
&& op
->in
.num_rids
!= 0 ) {
534 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
538 if ( op
->in
.num_rids
== 0 ) {
540 op
->out
.num_names
= 0;
544 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
546 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
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
,
556 if ( !NT_STATUS_IS_OK( hnd
->status
)
557 && !NT_STATUS_EQUAL( hnd
->status
, STATUS_SOME_UNMAPPED
) )
560 map_out
= TALLOC_ARRAY( mem_ctx
, CacLookupRidsRecord
, num_names_out
);
562 hnd
->status
= NT_STATUS_NO_MEMORY
;
566 for ( i
= 0; i
< num_names_out
; i
++ ) {
567 if ( name_types_out
[i
] == SAMR_RID_UNKNOWN
) {
568 map_out
[i
].found
= False
;
569 map_out
[i
].name
= NULL
;
572 map_out
[i
].found
= True
;
574 talloc_strdup( mem_ctx
, names_out
[i
] );
575 map_out
[i
].type
= name_types_out
[i
];
577 map_out
[i
].rid
= op
->in
.rids
[i
];
580 TALLOC_FREE( names_out
);
581 TALLOC_FREE( name_types_out
);
583 op
->out
.num_names
= num_names_out
;
584 op
->out
.map
= map_out
;
586 if ( NT_STATUS_EQUAL( hnd
->status
, STATUS_SOME_UNMAPPED
) )
587 return CAC_PARTIAL_SUCCESS
;
592 int cac_SamGetRidsFromNames( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
593 struct SamGetRidsFromNames
*op
)
595 struct rpc_pipe_client
*pipe_hnd
= NULL
;
599 uint32
*rid_types_out
;
603 CacLookupRidsRecord
*map_out
;
608 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
609 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
613 if ( !op
|| !op
->in
.dom_hnd
|| !mem_ctx
) {
614 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
618 if ( !op
->in
.names
&& op
->in
.num_names
!= 0 ) {
619 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
623 if ( op
->in
.num_names
== 0 ) {
624 /*then we don't have to do anything */
625 op
->out
.num_rids
= 0;
629 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
631 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
636 rpccli_samr_lookup_names( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
,
637 SAMR_LOOKUP_FLAGS
, op
->in
.num_names
,
638 ( const char ** ) op
->in
.names
,
639 &num_rids_out
, &rids_out
,
642 if ( !NT_STATUS_IS_OK( hnd
->status
)
643 && !NT_STATUS_EQUAL( hnd
->status
, STATUS_SOME_UNMAPPED
) )
646 map_out
= TALLOC_ARRAY( mem_ctx
, CacLookupRidsRecord
, num_rids_out
);
648 hnd
->status
= NT_STATUS_NO_MEMORY
;
652 for ( i
= 0; i
< num_rids_out
; i
++ ) {
654 if ( rid_types_out
[i
] == SAMR_RID_UNKNOWN
) {
655 map_out
[i
].found
= False
;
659 map_out
[i
].found
= True
;
660 map_out
[i
].rid
= rids_out
[i
];
661 map_out
[i
].type
= rid_types_out
[i
];
664 map_out
[i
].name
= talloc_strdup( mem_ctx
, op
->in
.names
[i
] );
667 op
->out
.num_rids
= num_rids_out
;
668 op
->out
.map
= map_out
;
670 TALLOC_FREE( rids_out
);
671 TALLOC_FREE( rid_types_out
);
673 if ( NT_STATUS_EQUAL( hnd
->status
, STATUS_SOME_UNMAPPED
) )
674 return CAC_PARTIAL_SUCCESS
;
680 int cac_SamGetGroupsForUser( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
681 struct SamGetGroupsForUser
*op
)
683 struct rpc_pipe_client
*pipe_hnd
= NULL
;
685 DOM_GID
*groups
= NULL
;
686 uint32 num_groups_out
= 0;
688 uint32
*rids_out
= NULL
;
689 uint32
*attr_out
= NULL
;
696 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
697 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
701 if ( !op
|| !op
->in
.user_hnd
|| !mem_ctx
) {
702 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
706 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
708 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
713 rpccli_samr_query_usergroups( pipe_hnd
, mem_ctx
,
715 &num_groups_out
, &groups
);
717 if ( !NT_STATUS_IS_OK( hnd
->status
) )
721 rids_out
= talloc_array( mem_ctx
, uint32
, num_groups_out
);
723 hnd
->status
= NT_STATUS_NO_MEMORY
;
727 attr_out
= talloc_array( mem_ctx
, uint32
, num_groups_out
);
729 hnd
->status
= NT_STATUS_NO_MEMORY
;
733 for ( i
= 0; i
< num_groups_out
; i
++ ) {
734 rids_out
[i
] = groups
[i
].g_rid
;
735 attr_out
[i
] = groups
[i
].attr
;
738 TALLOC_FREE( groups
);
740 op
->out
.num_groups
= num_groups_out
;
741 op
->out
.rids
= rids_out
;
742 op
->out
.attributes
= attr_out
;
748 int cac_SamOpenGroup( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
749 struct SamOpenGroup
*op
)
751 struct rpc_pipe_client
*pipe_hnd
= NULL
;
753 POLICY_HND
*group_hnd_out
= NULL
;
758 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
759 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
763 if ( !op
|| op
->in
.access
== 0 || op
->in
.rid
== 0 || !mem_ctx
) {
764 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
768 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
770 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
774 group_hnd_out
= talloc( mem_ctx
, POLICY_HND
);
775 if ( !group_hnd_out
) {
776 hnd
->status
= NT_STATUS_NO_MEMORY
;
781 rpccli_samr_open_group( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
,
782 op
->in
.access
, op
->in
.rid
,
785 if ( !NT_STATUS_IS_OK( hnd
->status
) )
788 op
->out
.group_hnd
= group_hnd_out
;
793 int cac_SamCreateGroup( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
794 struct SamCreateGroup
*op
)
796 struct rpc_pipe_client
*pipe_hnd
= NULL
;
798 POLICY_HND
*group_hnd_out
= NULL
;
803 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
804 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
808 if ( !op
|| !op
->in
.name
|| op
->in
.name
[0] == '\0'
809 || op
->in
.access
== 0 || !mem_ctx
) {
810 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
814 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
816 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
820 group_hnd_out
= talloc( mem_ctx
, POLICY_HND
);
821 if ( !group_hnd_out
) {
822 hnd
->status
= NT_STATUS_NO_MEMORY
;
827 rpccli_samr_create_dom_group( pipe_hnd
, mem_ctx
,
828 op
->in
.dom_hnd
, op
->in
.name
,
829 op
->in
.access
, group_hnd_out
);
831 if ( !NT_STATUS_IS_OK( hnd
->status
) )
834 op
->out
.group_hnd
= group_hnd_out
;
840 int cac_SamDeleteGroup( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
841 POLICY_HND
* group_hnd
)
843 struct rpc_pipe_client
*pipe_hnd
= NULL
;
848 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
849 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
853 if ( !group_hnd
|| !mem_ctx
) {
854 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
858 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
860 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
865 rpccli_samr_delete_dom_group( pipe_hnd
, mem_ctx
, group_hnd
);
867 if ( !NT_STATUS_IS_OK( hnd
->status
) )
874 int cac_SamGetGroupMembers( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
875 struct SamGetGroupMembers
*op
)
877 struct rpc_pipe_client
*pipe_hnd
= NULL
;
886 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
887 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
891 if ( !op
|| !op
->in
.group_hnd
|| !mem_ctx
) {
892 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
896 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
898 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
903 rpccli_samr_query_groupmem( pipe_hnd
, mem_ctx
,
904 op
->in
.group_hnd
, &num_mem_out
,
905 &rids_out
, &attr_out
);
907 if ( !NT_STATUS_IS_OK( hnd
->status
) )
910 op
->out
.num_members
= num_mem_out
;
911 op
->out
.rids
= rids_out
;
912 op
->out
.attributes
= attr_out
;
918 int cac_SamAddGroupMember( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
919 struct SamAddGroupMember
*op
)
921 struct rpc_pipe_client
*pipe_hnd
= NULL
;
926 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
927 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
931 if ( !op
|| !op
->in
.group_hnd
|| op
->in
.rid
== 0 || !mem_ctx
) {
932 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
936 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
938 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
943 rpccli_samr_add_groupmem( pipe_hnd
, mem_ctx
, op
->in
.group_hnd
,
946 if ( !NT_STATUS_IS_OK( hnd
->status
) )
952 int cac_SamRemoveGroupMember( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
953 struct SamRemoveGroupMember
*op
)
955 struct rpc_pipe_client
*pipe_hnd
= NULL
;
960 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
961 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
965 if ( !op
|| !op
->in
.group_hnd
|| op
->in
.rid
== 0 || !mem_ctx
) {
966 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
970 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
972 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
977 rpccli_samr_del_groupmem( pipe_hnd
, mem_ctx
, op
->in
.group_hnd
,
980 if ( !NT_STATUS_IS_OK( hnd
->status
) )
986 int cac_SamClearGroupMembers( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
987 POLICY_HND
* group_hnd
)
989 struct rpc_pipe_client
*pipe_hnd
= NULL
;
991 int result
= CAC_SUCCESS
;
1004 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
1005 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1009 if ( !group_hnd
|| !mem_ctx
) {
1010 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1014 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
1016 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1021 rpccli_samr_query_groupmem( pipe_hnd
, mem_ctx
, group_hnd
,
1022 &num_mem
, &rid
, &attr
);
1024 if ( !NT_STATUS_IS_OK( hnd
->status
) )
1027 /*try to delete the users one by one */
1028 for ( i
= 0; i
< num_mem
&& NT_STATUS_IS_OK( hnd
->status
); i
++ ) {
1030 rpccli_samr_del_groupmem( pipe_hnd
, mem_ctx
,
1031 group_hnd
, rid
[i
] );
1034 /*if not all members could be removed, then try to re-add the members that were already deleted */
1035 if ( !NT_STATUS_IS_OK( hnd
->status
) ) {
1036 status
= NT_STATUS_OK
;
1038 for ( i
-= 1; i
>= 0 && NT_STATUS_IS_OK( status
); i
-- ) {
1039 status
= rpccli_samr_add_groupmem( pipe_hnd
, mem_ctx
,
1044 /*we return with the NTSTATUS error that we got when trying to delete users */
1045 if ( !NT_STATUS_IS_OK( status
) )
1046 result
= CAC_FAILURE
;
1049 TALLOC_FREE( attr
);
1054 int cac_SamSetGroupMembers( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
1055 struct SamSetGroupMembers
*op
)
1057 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1064 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
1065 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1069 if ( !op
|| !op
->in
.group_hnd
|| !mem_ctx
) {
1070 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1074 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
1076 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1080 /*use cac_SamClearGroupMembers() to clear them */
1081 if ( !cac_SamClearGroupMembers( hnd
, mem_ctx
, op
->in
.group_hnd
) )
1082 return CAC_FAILURE
; /*hnd->status is already set */
1085 for ( i
= 0; i
< op
->in
.num_members
&& NT_STATUS_IS_OK( hnd
->status
);
1088 rpccli_samr_add_groupmem( pipe_hnd
, mem_ctx
,
1093 if ( !NT_STATUS_IS_OK( hnd
->status
) )
1100 int cac_SamEnumGroups( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
1101 struct SamEnumGroups
*op
)
1103 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1107 uint32 resume_idx_out
= 0;
1108 char **names_out
= NULL
;
1109 char **desc_out
= NULL
;
1110 uint32
*rids_out
= NULL
;
1111 uint32 num_groups_out
= 0;
1113 struct acct_info
*acct_buf
= NULL
;
1118 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
1119 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1123 if ( !op
|| !op
->in
.dom_hnd
|| !mem_ctx
) {
1124 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1128 /*using this BOOL is the only reliable way to know that we are done */
1129 if ( op
->out
.done
== True
) /*we return failure so the call will break out of a loop */
1132 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
1134 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1138 resume_idx_out
= op
->out
.resume_idx
;
1141 rpccli_samr_enum_dom_groups( pipe_hnd
, mem_ctx
,
1142 op
->in
.dom_hnd
, &resume_idx_out
,
1143 SAMR_ENUM_MAX_SIZE
, &acct_buf
,
1147 if ( NT_STATUS_IS_OK( hnd
->status
) ) {
1148 op
->out
.done
= True
;
1149 } else if ( NT_STATUS_V( hnd
->status
) !=
1150 NT_STATUS_V( STATUS_MORE_ENTRIES
) ) {
1151 /*if there are no more entries, the operation will return NT_STATUS_OK.
1152 * We want to return failure if no results were returned*/
1156 names_out
= talloc_array( mem_ctx
, char *, num_groups_out
);
1158 hnd
->status
= NT_STATUS_NO_MEMORY
;
1159 TALLOC_FREE( acct_buf
);
1163 desc_out
= talloc_array( mem_ctx
, char *, num_groups_out
);
1165 hnd
->status
= NT_STATUS_NO_MEMORY
;
1166 TALLOC_FREE( acct_buf
);
1167 TALLOC_FREE( names_out
);
1171 rids_out
= talloc_array( mem_ctx
, uint32
, num_groups_out
);
1173 hnd
->status
= NT_STATUS_NO_MEMORY
;
1174 TALLOC_FREE( acct_buf
);
1175 TALLOC_FREE( names_out
);
1176 TALLOC_FREE( desc_out
);
1180 for ( i
= 0; i
< num_groups_out
; i
++ ) {
1182 talloc_strdup( mem_ctx
, acct_buf
[i
].acct_name
);
1183 desc_out
[i
] = talloc_strdup( mem_ctx
, acct_buf
[i
].acct_desc
);
1184 rids_out
[i
] = acct_buf
[i
].rid
;
1186 if ( !names_out
[i
] || !desc_out
[i
] ) {
1187 hnd
->status
= NT_STATUS_NO_MEMORY
;
1192 op
->out
.resume_idx
= resume_idx_out
;
1193 op
->out
.num_groups
= num_groups_out
;
1194 op
->out
.rids
= rids_out
;
1195 op
->out
.names
= names_out
;
1196 op
->out
.descriptions
= desc_out
;
1201 int cac_SamEnumAliases( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
1202 struct SamEnumAliases
*op
)
1204 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1208 uint32 resume_idx_out
= 0;
1209 char **names_out
= NULL
;
1210 char **desc_out
= NULL
;
1211 uint32
*rids_out
= NULL
;
1212 uint32 num_als_out
= 0;
1214 struct acct_info
*acct_buf
= NULL
;
1219 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
1220 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1224 if ( !op
|| !op
->in
.dom_hnd
|| !mem_ctx
) {
1225 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1229 /*this is a hack.. but is the only reliable way to know if everything has been enumerated */
1230 if ( op
->out
.done
== True
) {
1234 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
1236 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1240 resume_idx_out
= op
->out
.resume_idx
;
1243 rpccli_samr_enum_als_groups( pipe_hnd
, mem_ctx
,
1244 op
->in
.dom_hnd
, &resume_idx_out
,
1245 SAMR_ENUM_MAX_SIZE
, &acct_buf
,
1249 if ( NT_STATUS_IS_OK( hnd
->status
) )
1250 op
->out
.done
= True
;
1252 /*if there are no more entries, the operation will return NT_STATUS_OK.
1253 * We want to return failure if no results were returned*/
1254 if ( !NT_STATUS_IS_OK( hnd
->status
)
1255 && NT_STATUS_V( hnd
->status
) !=
1256 NT_STATUS_V( STATUS_MORE_ENTRIES
) )
1259 names_out
= talloc_array( mem_ctx
, char *, num_als_out
);
1261 hnd
->status
= NT_STATUS_NO_MEMORY
;
1262 TALLOC_FREE( acct_buf
);
1266 desc_out
= talloc_array( mem_ctx
, char *, num_als_out
);
1268 hnd
->status
= NT_STATUS_NO_MEMORY
;
1269 TALLOC_FREE( acct_buf
);
1270 TALLOC_FREE( names_out
);
1274 rids_out
= talloc_array( mem_ctx
, uint32
, num_als_out
);
1276 hnd
->status
= NT_STATUS_NO_MEMORY
;
1277 TALLOC_FREE( acct_buf
);
1278 TALLOC_FREE( names_out
);
1279 TALLOC_FREE( desc_out
);
1283 for ( i
= 0; i
< num_als_out
; i
++ ) {
1285 talloc_strdup( mem_ctx
, acct_buf
[i
].acct_name
);
1286 desc_out
[i
] = talloc_strdup( mem_ctx
, acct_buf
[i
].acct_desc
);
1287 rids_out
[i
] = acct_buf
[i
].rid
;
1289 if ( !names_out
[i
] || !desc_out
[i
] ) {
1290 hnd
->status
= NT_STATUS_NO_MEMORY
;
1295 op
->out
.resume_idx
= resume_idx_out
;
1296 op
->out
.num_aliases
= num_als_out
;
1297 op
->out
.rids
= rids_out
;
1298 op
->out
.names
= names_out
;
1299 op
->out
.descriptions
= desc_out
;
1304 int cac_SamCreateAlias( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
1305 struct SamCreateAlias
*op
)
1307 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1309 POLICY_HND
*als_hnd_out
= NULL
;
1314 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
1315 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1319 if ( !op
|| !op
->in
.name
|| op
->in
.name
[0] == '\0' || !mem_ctx
) {
1320 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1324 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
1326 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1330 als_hnd_out
= talloc( mem_ctx
, POLICY_HND
);
1331 if ( !als_hnd_out
) {
1332 hnd
->status
= NT_STATUS_NO_MEMORY
;
1337 rpccli_samr_create_dom_alias( pipe_hnd
, mem_ctx
,
1338 op
->in
.dom_hnd
, op
->in
.name
,
1341 if ( !NT_STATUS_IS_OK( hnd
->status
) )
1344 op
->out
.alias_hnd
= als_hnd_out
;
1350 int cac_SamOpenAlias( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
1351 struct SamOpenAlias
*op
)
1353 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1355 POLICY_HND
*als_hnd_out
= NULL
;
1360 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
1361 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1365 if ( !op
|| op
->in
.access
== 0 || op
->in
.rid
== 0 || !mem_ctx
) {
1366 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1370 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
1372 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1376 als_hnd_out
= talloc( mem_ctx
, POLICY_HND
);
1377 if ( !als_hnd_out
) {
1378 hnd
->status
= NT_STATUS_NO_MEMORY
;
1383 rpccli_samr_open_alias( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
,
1384 op
->in
.access
, op
->in
.rid
,
1387 if ( !NT_STATUS_IS_OK( hnd
->status
) )
1390 op
->out
.alias_hnd
= als_hnd_out
;
1395 int cac_SamDeleteAlias( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
1396 POLICY_HND
* alias_hnd
)
1398 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1403 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
1404 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1408 if ( !alias_hnd
|| !mem_ctx
) {
1409 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1413 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
1415 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1420 rpccli_samr_delete_dom_alias( pipe_hnd
, mem_ctx
, alias_hnd
);
1422 if ( !NT_STATUS_IS_OK( hnd
->status
) )
1429 int cac_SamAddAliasMember( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
1430 struct SamAddAliasMember
*op
)
1432 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1437 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
1438 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1442 if ( !op
|| !op
->in
.alias_hnd
|| !op
->in
.sid
|| !mem_ctx
) {
1443 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1447 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
1449 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1454 rpccli_samr_add_aliasmem( pipe_hnd
, mem_ctx
, op
->in
.alias_hnd
,
1457 if ( !NT_STATUS_IS_OK( hnd
->status
) )
1463 int cac_SamRemoveAliasMember( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
1464 struct SamRemoveAliasMember
*op
)
1466 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1471 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
1472 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1476 if ( !op
|| !op
->in
.alias_hnd
|| !op
->in
.sid
|| !mem_ctx
) {
1477 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1481 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
1483 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1488 rpccli_samr_del_aliasmem( pipe_hnd
, mem_ctx
, op
->in
.alias_hnd
,
1491 if ( !NT_STATUS_IS_OK( hnd
->status
) )
1497 int cac_SamGetAliasMembers( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
1498 struct SamGetAliasMembers
*op
)
1500 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1508 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
1509 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1513 if ( !op
|| !op
->in
.alias_hnd
|| !mem_ctx
) {
1514 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1518 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
1520 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1525 rpccli_samr_query_aliasmem( pipe_hnd
, mem_ctx
,
1526 op
->in
.alias_hnd
, &num_mem_out
,
1529 if ( !NT_STATUS_IS_OK( hnd
->status
) )
1532 op
->out
.num_members
= num_mem_out
;
1533 op
->out
.sids
= sids_out
;
1538 int cac_SamClearAliasMembers( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
1539 POLICY_HND
* alias_hnd
)
1541 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1543 int result
= CAC_SUCCESS
;
1548 DOM_SID
*sid
= NULL
;
1555 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
1556 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1560 if ( !alias_hnd
|| !mem_ctx
) {
1561 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1565 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
1567 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1572 rpccli_samr_query_aliasmem( pipe_hnd
, mem_ctx
, alias_hnd
,
1575 if ( !NT_STATUS_IS_OK( hnd
->status
) )
1578 /*try to delete the users one by one */
1579 for ( i
= 0; i
< num_mem
&& NT_STATUS_IS_OK( hnd
->status
); i
++ ) {
1581 rpccli_samr_del_aliasmem( pipe_hnd
, mem_ctx
,
1582 alias_hnd
, &sid
[i
] );
1585 /*if not all members could be removed, then try to re-add the members that were already deleted */
1586 if ( !NT_STATUS_IS_OK( hnd
->status
) ) {
1587 status
= NT_STATUS_OK
;
1589 for ( i
-= 1; i
>= 0 && NT_STATUS_IS_OK( status
); i
-- ) {
1590 status
= rpccli_samr_add_aliasmem( pipe_hnd
, mem_ctx
,
1595 /*we return with the NTSTATUS error that we got when trying to delete users */
1596 if ( !NT_STATUS_IS_OK( status
) )
1597 result
= CAC_FAILURE
;
1604 int cac_SamSetAliasMembers( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
1605 struct SamSetAliasMembers
*op
)
1607 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1614 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
1615 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1619 if ( !op
|| !op
->in
.alias_hnd
|| !mem_ctx
) {
1620 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1624 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
1626 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1630 /*use cac_SamClearAliasMembers() to clear them */
1631 if ( !cac_SamClearAliasMembers( hnd
, mem_ctx
, op
->in
.alias_hnd
) )
1632 return CAC_FAILURE
; /*hnd->status is already set */
1635 for ( i
= 0; i
< op
->in
.num_members
&& NT_STATUS_IS_OK( hnd
->status
);
1638 rpccli_samr_add_aliasmem( pipe_hnd
, mem_ctx
,
1640 &( op
->in
.sids
[i
] ) );
1643 if ( !NT_STATUS_IS_OK( hnd
->status
) )
1650 int cac_SamUserChangePasswd( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
1651 struct SamUserChangePasswd
*op
)
1653 SMBCSRV
*srv
= NULL
;
1654 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1659 if ( !hnd
->_internal
.ctx
) {
1660 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1664 if ( !op
|| !op
->in
.username
|| !op
->in
.password
1665 || !op
->in
.new_password
|| !mem_ctx
) {
1666 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1670 srv
= cac_GetServer( hnd
);
1672 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1676 /*open a session on SAMR if we don't have one */
1677 if ( !hnd
->_internal
.pipes
[PI_SAMR
] ) {
1680 cli_rpc_pipe_open_noauth( srv
->cli
, PI_SAMR
,
1681 &hnd
->status
) ) ) {
1685 hnd
->_internal
.pipes
[PI_SAMR
] = True
;
1688 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
1690 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1695 rpccli_samr_chgpasswd_user( pipe_hnd
, mem_ctx
,
1697 op
->in
.new_password
,
1700 if ( !NT_STATUS_IS_OK( hnd
->status
) )
1706 int cac_SamEnableUser( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
1707 POLICY_HND
* user_hnd
)
1709 SMBCSRV
*srv
= NULL
;
1710 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1712 SAM_USERINFO_CTR
*ctr
;
1717 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
1718 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1722 if ( !user_hnd
|| !mem_ctx
) {
1723 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1727 srv
= cac_GetServer( hnd
);
1729 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1733 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
1735 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1739 /*info_level = 21 is the only level that I have found to work reliably. It would be nice if user_level = 10 worked. */
1741 rpccli_samr_query_userinfo( pipe_hnd
, mem_ctx
, user_hnd
, 0x10,
1744 if ( !NT_STATUS_IS_OK( hnd
->status
) )
1747 /**check the ACB mask*/
1748 if ( ( ctr
->info
.id16
->acb_info
& ACB_DISABLED
) == ACB_DISABLED
) {
1749 /*toggle the disabled bit */
1750 ctr
->info
.id16
->acb_info
^= ACB_DISABLED
;
1752 /*the user is already enabled so just return success */
1756 /*now set the userinfo */
1758 rpccli_samr_set_userinfo2( pipe_hnd
, mem_ctx
, user_hnd
, 0x10,
1759 &srv
->cli
->user_session_key
, ctr
);
1761 /*this will only work properly if we use set_userinfo2 - fail if it is not supported */
1762 if ( !NT_STATUS_IS_OK( hnd
->status
) )
1768 int cac_SamDisableUser( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
1769 POLICY_HND
* user_hnd
)
1771 SMBCSRV
*srv
= NULL
;
1772 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1774 SAM_USERINFO_CTR
*ctr
;
1779 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
1780 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1784 if ( !user_hnd
|| !mem_ctx
) {
1785 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1789 srv
= cac_GetServer( hnd
);
1791 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1795 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
1797 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1802 rpccli_samr_query_userinfo( pipe_hnd
, mem_ctx
, user_hnd
, 0x10,
1805 if ( !NT_STATUS_IS_OK( hnd
->status
) )
1808 if ( ( ctr
->info
.id16
->acb_info
& ACB_DISABLED
) == ACB_DISABLED
) {
1809 /*then the user is already disabled */
1813 /*toggle the disabled bit */
1814 ctr
->info
.id16
->acb_info
^= ACB_DISABLED
;
1816 /*this will only work properly if we use set_userinfo2 */
1818 rpccli_samr_set_userinfo2( pipe_hnd
, mem_ctx
, user_hnd
, 0x10,
1819 &srv
->cli
->user_session_key
, ctr
);
1821 /*this will only work properly if we use set_userinfo2 fail if it is not supported */
1822 if ( !NT_STATUS_IS_OK( hnd
->status
) )
1828 int cac_SamSetPassword( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
1829 struct SamSetPassword
*op
)
1831 SMBCSRV
*srv
= NULL
;
1832 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1834 SAM_USERINFO_CTR ctr
;
1835 SAM_USER_INFO_24 info24
;
1841 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
1842 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1846 if ( !op
->in
.user_hnd
|| !op
->in
.password
|| !mem_ctx
) {
1847 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1851 srv
= cac_GetServer( hnd
);
1853 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1857 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
1859 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1864 ZERO_STRUCT( info24
);
1866 encode_pw_buffer( pw
, op
->in
.password
, STR_UNICODE
);
1868 init_sam_user_info24( &info24
, ( char * ) pw
, 24 );
1870 ctr
.switch_value
= 24;
1871 ctr
.info
.id24
= &info24
;
1874 rpccli_samr_set_userinfo( pipe_hnd
, mem_ctx
, op
->in
.user_hnd
,
1875 24, &srv
->cli
->user_session_key
,
1878 if ( !NT_STATUS_IS_OK( hnd
->status
) )
1884 int cac_SamGetUserInfo( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
1885 struct SamGetUserInfo
*op
)
1887 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1889 SAM_USERINFO_CTR
*ctr
;
1894 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
1895 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1899 if ( !op
->in
.user_hnd
|| !mem_ctx
) {
1900 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1904 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
1906 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1911 rpccli_samr_query_userinfo( pipe_hnd
, mem_ctx
,
1912 op
->in
.user_hnd
, 21, &ctr
);
1914 if ( !NT_STATUS_IS_OK( hnd
->status
) )
1917 op
->out
.info
= cac_MakeUserInfo( mem_ctx
, ctr
);
1919 if ( !op
->out
.info
) {
1920 hnd
->status
= NT_STATUS_NO_MEMORY
;
1927 int cac_SamSetUserInfo( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
1928 struct SamSetUserInfo
*op
)
1930 SMBCSRV
*srv
= NULL
;
1931 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1933 SAM_USERINFO_CTR
*ctr
;
1938 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
1939 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1943 if ( !op
->in
.user_hnd
|| !op
->in
.info
|| !mem_ctx
) {
1944 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1948 ctr
= cac_MakeUserInfoCtr( mem_ctx
, op
->in
.info
);
1950 hnd
->status
= NT_STATUS_NO_MEMORY
;
1954 srv
= cac_GetServer( hnd
);
1956 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1960 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
1962 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1966 if ( hnd
->_internal
.srv_level
>= SRV_WIN_NT4
) {
1968 rpccli_samr_set_userinfo2( pipe_hnd
, mem_ctx
,
1969 op
->in
.user_hnd
, 21,
1971 user_session_key
, ctr
);
1974 if ( hnd
->_internal
.srv_level
< SRV_WIN_NT4
1975 || !NT_STATUS_IS_OK( hnd
->status
) ) {
1977 rpccli_samr_set_userinfo( pipe_hnd
, mem_ctx
,
1978 op
->in
.user_hnd
, 21,
1979 &srv
->cli
->user_session_key
,
1982 if ( NT_STATUS_IS_OK( hnd
->status
)
1983 && hnd
->_internal
.srv_level
> SRV_WIN_NT4
) {
1984 hnd
->_internal
.srv_level
= SRV_WIN_NT4
;
1989 if ( !NT_STATUS_IS_OK( hnd
->status
) )
1996 int cac_SamGetUserInfoCtr( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
1997 struct SamGetUserInfoCtr
*op
)
1999 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2001 SAM_USERINFO_CTR
*ctr_out
;
2006 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
2007 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2011 if ( !op
->in
.user_hnd
|| op
->in
.info_class
== 0 || !mem_ctx
) {
2012 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2016 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
2018 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2023 rpccli_samr_query_userinfo( pipe_hnd
, mem_ctx
,
2025 op
->in
.info_class
, &ctr_out
);
2027 if ( !NT_STATUS_IS_OK( hnd
->status
) )
2030 op
->out
.ctr
= ctr_out
;
2035 int cac_SamSetUserInfoCtr( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
2036 struct SamSetUserInfoCtr
*op
)
2038 SMBCSRV
*srv
= NULL
;
2039 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2044 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
2045 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2049 if ( !op
->in
.user_hnd
|| !op
->in
.ctr
|| !mem_ctx
) {
2050 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2054 srv
= cac_GetServer( hnd
);
2056 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
2060 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
2062 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2068 rpccli_samr_set_userinfo( pipe_hnd
, mem_ctx
, op
->in
.user_hnd
,
2069 op
->in
.ctr
->switch_value
,
2070 &srv
->cli
->user_session_key
,
2073 if ( !NT_STATUS_IS_OK( hnd
->status
) )
2080 int cac_SamRenameUser( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
2081 struct SamRenameUser
*op
)
2083 SMBCSRV
*srv
= NULL
;
2084 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2086 SAM_USERINFO_CTR ctr
;
2087 SAM_USER_INFO_7 info7
;
2092 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
2093 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2097 if ( !op
->in
.user_hnd
|| !op
->in
.new_name
2098 || op
->in
.new_name
[0] == '\0' || !mem_ctx
) {
2099 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2103 srv
= cac_GetServer( hnd
);
2105 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
2109 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
2111 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2116 ZERO_STRUCT( info7
);
2118 init_sam_user_info7( &info7
, op
->in
.new_name
);
2120 ctr
.switch_value
= 7;
2121 ctr
.info
.id7
= &info7
;
2124 rpccli_samr_set_userinfo( pipe_hnd
, mem_ctx
, op
->in
.user_hnd
,
2125 7, &srv
->cli
->user_session_key
,
2128 if ( !NT_STATUS_IS_OK( hnd
->status
) )
2135 int cac_SamGetGroupInfo( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
2136 struct SamGetGroupInfo
*op
)
2138 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2140 GROUP_INFO_CTR
*ctr
;
2145 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
2146 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2150 if ( !op
->in
.group_hnd
|| !mem_ctx
) {
2151 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2155 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
2157 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2162 /*get a GROUP_INFO_1 structure */
2164 rpccli_samr_query_groupinfo( pipe_hnd
, mem_ctx
,
2165 op
->in
.group_hnd
, 1, &ctr
);
2167 if ( !NT_STATUS_IS_OK( hnd
->status
) )
2170 op
->out
.info
= cac_MakeGroupInfo( mem_ctx
, ctr
);
2171 if ( !op
->out
.info
) {
2172 hnd
->status
= NT_STATUS_NO_MEMORY
;
2179 int cac_SamSetGroupInfo( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
2180 struct SamSetGroupInfo
*op
)
2182 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2184 GROUP_INFO_CTR
*ctr
= NULL
;
2189 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
2190 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2194 if ( !op
->in
.group_hnd
|| !op
->in
.info
|| !mem_ctx
) {
2195 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2199 ctr
= cac_MakeGroupInfoCtr( mem_ctx
, op
->in
.info
);
2201 hnd
->status
= NT_STATUS_NO_MEMORY
;
2205 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
2207 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2212 rpccli_samr_set_groupinfo( pipe_hnd
, mem_ctx
,
2213 op
->in
.group_hnd
, ctr
);
2215 if ( !NT_STATUS_IS_OK( hnd
->status
) )
2221 int cac_SamRenameGroup( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
2222 struct SamRenameGroup
*op
)
2224 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2231 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
2232 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2236 if ( !op
->in
.group_hnd
|| !op
->in
.new_name
2237 || op
->in
.new_name
[0] == '\0' || !mem_ctx
) {
2238 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2242 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
2244 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2250 init_samr_group_info2( &ctr
.group
.info2
, op
->in
.new_name
);
2251 ctr
.switch_value1
= 2;
2254 rpccli_samr_set_groupinfo( pipe_hnd
, mem_ctx
,
2255 op
->in
.group_hnd
, &ctr
);
2257 if ( !NT_STATUS_IS_OK( hnd
->status
) )
2263 int cac_SamGetAliasInfo( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
2264 struct SamGetAliasInfo
*op
)
2266 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2273 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
2274 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2278 if ( !op
->in
.alias_hnd
|| !mem_ctx
) {
2279 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2283 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
2285 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2289 /*get a GROUP_INFO_1 structure */
2291 rpccli_samr_query_alias_info( pipe_hnd
, mem_ctx
,
2292 op
->in
.alias_hnd
, 1, &ctr
);
2294 if ( !NT_STATUS_IS_OK( hnd
->status
) )
2297 op
->out
.info
= cac_MakeAliasInfo( mem_ctx
, ctr
);
2298 if ( !op
->out
.info
) {
2299 hnd
->status
= NT_STATUS_NO_MEMORY
;
2307 int cac_SamSetAliasInfo( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
2308 struct SamSetAliasInfo
*op
)
2310 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2312 ALIAS_INFO_CTR
*ctr
= NULL
;
2317 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
2318 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2322 if ( !op
->in
.alias_hnd
|| !op
->in
.info
|| !mem_ctx
) {
2323 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2327 ctr
= cac_MakeAliasInfoCtr( mem_ctx
, op
->in
.info
);
2329 hnd
->status
= NT_STATUS_NO_MEMORY
;
2333 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
2335 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2340 rpccli_samr_set_aliasinfo( pipe_hnd
, mem_ctx
,
2341 op
->in
.alias_hnd
, ctr
);
2343 if ( !NT_STATUS_IS_OK( hnd
->status
) )
2349 int cac_SamGetDomainInfo( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
2350 struct SamGetDomainInfo
*op
)
2352 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2355 SAM_UNK_INFO_1 info1
;
2356 SAM_UNK_INFO_2 info2
;
2357 SAM_UNK_INFO_12 info12
;
2359 /*use this to keep track of a failed call */
2360 NTSTATUS status_buf
= NT_STATUS_OK
;
2362 uint16 fail_count
= 0;
2368 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
2369 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2373 if ( !op
->in
.dom_hnd
|| !mem_ctx
) {
2374 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2378 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
2380 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2384 /*first try with info 1 */
2386 rpccli_samr_query_dom_info( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
,
2389 if ( NT_STATUS_IS_OK( hnd
->status
) ) {
2390 /*then we buffer the SAM_UNK_INFO_1 structure */
2391 info1
= ctr
.info
.inf1
;
2393 /*then the call failed, store the status and ZERO out the info structure */
2394 ZERO_STRUCT( info1
);
2395 status_buf
= hnd
->status
;
2399 /*try again for the next one */
2401 rpccli_samr_query_dom_info( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
,
2404 if ( NT_STATUS_IS_OK( hnd
->status
) ) {
2406 info2
= ctr
.info
.inf2
;
2408 /*ZERO out the structure and store the bad status */
2409 ZERO_STRUCT( info2
);
2410 status_buf
= hnd
->status
;
2416 rpccli_samr_query_dom_info( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
,
2419 if ( NT_STATUS_IS_OK( hnd
->status
) ) {
2420 info12
= ctr
.info
.inf12
;
2422 ZERO_STRUCT( info12
);
2423 status_buf
= hnd
->status
;
2427 /*return failure if all 3 calls failed */
2428 if ( fail_count
== 3 )
2431 op
->out
.info
= cac_MakeDomainInfo( mem_ctx
, &info1
, &info2
, &info12
);
2433 if ( !op
->out
.info
) {
2434 hnd
->status
= NT_STATUS_NO_MEMORY
;
2438 if ( fail_count
> 0 ) {
2439 hnd
->status
= status_buf
;
2440 return CAC_PARTIAL_SUCCESS
;
2446 int cac_SamGetDomainInfoCtr( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
2447 struct SamGetDomainInfoCtr
*op
)
2449 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2451 SAM_UNK_CTR
*ctr_out
;
2456 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
2457 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2461 if ( !op
->in
.dom_hnd
|| op
->in
.info_class
== 0 || !mem_ctx
) {
2462 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2466 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
2468 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2472 ctr_out
= talloc( mem_ctx
, SAM_UNK_CTR
);
2474 hnd
->status
= NT_STATUS_NO_MEMORY
;
2479 rpccli_samr_query_dom_info( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
,
2480 op
->in
.info_class
, ctr_out
);
2482 if ( !NT_STATUS_IS_OK( hnd
->status
) )
2485 op
->out
.info
= ctr_out
;
2490 int cac_SamGetDisplayInfo( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
2491 struct SamGetDisplayInfo
*op
)
2493 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2495 SAM_DISPINFO_CTR ctr_out
;
2497 uint32 max_entries_buf
= 0;
2498 uint32 max_size_buf
= 0;
2500 uint32 resume_idx_out
;
2501 uint32 num_entries_out
;
2506 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
2507 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2511 if ( !op
->in
.dom_hnd
|| op
->in
.info_class
== 0 || !mem_ctx
) {
2512 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2516 if ( op
->out
.done
== True
) /*this is done so we can use the function as a loop condition */
2519 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
2521 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2525 if ( op
->in
.max_entries
== 0 || op
->in
.max_size
== 0 ) {
2526 get_query_dispinfo_params( op
->out
.loop_count
,
2527 &max_entries_buf
, &max_size_buf
);
2529 max_entries_buf
= op
->in
.max_entries
;
2530 max_size_buf
= op
->in
.max_size
;
2533 resume_idx_out
= op
->out
.resume_idx
;
2536 rpccli_samr_query_dispinfo( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
,
2539 &num_entries_out
, max_entries_buf
,
2540 max_size_buf
, &ctr_out
);
2542 if ( !NT_STATUS_IS_OK( hnd
->status
)
2543 && !NT_STATUS_EQUAL( hnd
->status
, STATUS_MORE_ENTRIES
) ) {
2544 /*be defensive, maybe they'll call again without zeroing the struct */
2545 op
->out
.loop_count
= 0;
2546 op
->out
.resume_idx
= 0;
2550 if ( NT_STATUS_IS_OK( hnd
->status
) ) {
2551 /*we want to quit once the function is called next. so it can be used in a loop */
2552 op
->out
.done
= True
;
2555 op
->out
.resume_idx
= resume_idx_out
;
2556 op
->out
.num_entries
= num_entries_out
;
2557 op
->out
.ctr
= ctr_out
;
2558 op
->out
.loop_count
++;
2563 int cac_SamLookupDomain( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
2564 struct SamLookupDomain
*op
)
2566 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2568 DOM_SID
*sid_out
= NULL
;
2573 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
2574 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2578 if ( !op
->in
.sam
|| !op
->in
.name
|| !mem_ctx
) {
2579 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2583 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
2585 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2589 sid_out
= talloc( mem_ctx
, DOM_SID
);
2591 hnd
->status
= NT_STATUS_NO_MEMORY
;
2596 rpccli_samr_lookup_domain( pipe_hnd
, mem_ctx
, op
->in
.sam
,
2597 op
->in
.name
, sid_out
);
2599 if ( !NT_STATUS_IS_OK( hnd
->status
) )
2602 op
->out
.sid
= sid_out
;
2607 int cac_SamGetSecurityObject( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
2608 struct SamGetSecurityObject
*op
)
2610 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2612 /*this number taken from rpcclient/cmd_samr.c, I think it is the only supported level */
2613 uint32 sec_info
= DACL_SECURITY_INFORMATION
;
2615 SEC_DESC_BUF
*sec_out
= NULL
;
2620 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
2621 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2625 if ( !op
->in
.pol
|| !mem_ctx
) {
2626 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2630 pipe_hnd
= cac_GetPipe( hnd
, PI_SAMR
);
2632 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2637 rpccli_samr_query_sec_obj( pipe_hnd
, mem_ctx
, op
->in
.pol
,
2638 sec_info
, mem_ctx
, &sec_out
);
2640 if ( !NT_STATUS_IS_OK( hnd
->status
) )
2643 op
->out
.sec
= sec_out
;
2648 int cac_SamFlush( CacServerHandle
* hnd
, TALLOC_CTX
* mem_ctx
,
2649 struct SamFlush
*op
)
2651 struct SamOpenDomain od
;
2656 if ( !hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
] ) {
2657 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2661 if ( !op
|| !op
->in
.dom_hnd
|| !mem_ctx
) {
2662 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2666 if ( !cac_SamClose( hnd
, mem_ctx
, op
->in
.dom_hnd
) )
2671 ( op
->in
.access
) ? op
->in
.access
: MAXIMUM_ALLOWED_ACCESS
;
2672 od
.in
.sid
= op
->in
.sid
;
2674 if ( !cac_SamOpenDomain( hnd
, mem_ctx
, &od
) )
2677 /*this function does not use an output parameter to make it as convenient as possible to use */
2678 *op
->in
.dom_hnd
= *od
.out
.dom_hnd
;
2680 TALLOC_FREE( od
.out
.dom_hnd
);