2 * Unix SMB/CIFS implementation.
3 * MS-RPC client library implementation (SAMR pipe)
4 * Copyright (C) Chris Nicholls 2005.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "libmsrpc_internal.h"
24 /*used by cac_SamGetNamesFromRids*/
25 #define SAMR_RID_UNKNOWN 8
27 #define SAMR_ENUM_MAX_SIZE 0xffff
29 /*not sure what this is.. taken from rpcclient/cmd_samr.c*/
30 #define SAMR_LOOKUP_FLAGS 0x000003e8
32 int cac_SamConnect(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamConnect
*op
) {
34 struct rpc_pipe_client
*pipe_hnd
= NULL
;
35 POLICY_HND
*sam_out
= NULL
;
40 if(!hnd
->_internal
.ctx
) {
41 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
45 if(!op
|| op
->in
.access
== 0 || !mem_ctx
) {
46 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
50 srv
= cac_GetServer(hnd
);
52 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
56 /*initialize for samr pipe if we have to*/
57 if(!hnd
->_internal
.pipes
[PI_SAMR
]) {
58 if(!(pipe_hnd
= cli_rpc_pipe_open_noauth(&srv
->cli
, PI_SAMR
, &(hnd
->status
)))) {
62 hnd
->_internal
.pipes
[PI_SAMR
] = True
;
65 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
67 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
71 sam_out
= talloc(mem_ctx
, POLICY_HND
);
73 hnd
->status
= NT_STATUS_NO_MEMORY
;
77 if(hnd
->_internal
.srv_level
>= SRV_WIN_2K_SP3
) {
78 hnd
->status
= rpccli_samr_connect4( pipe_hnd
, mem_ctx
, op
->in
.access
, sam_out
);
81 if(hnd
->_internal
.srv_level
< SRV_WIN_2K_SP3
|| !NT_STATUS_IS_OK(hnd
->status
)) {
82 /*if sam_connect4 failed, the use sam_connect and lower srv_level*/
84 hnd
->status
= rpccli_samr_connect( pipe_hnd
, mem_ctx
, op
->in
.access
, sam_out
);
86 if(NT_STATUS_IS_OK(hnd
->status
) && hnd
->_internal
.srv_level
> SRV_WIN_2K
) {
87 hnd
->_internal
.srv_level
= SRV_WIN_2K
;
91 if(!NT_STATUS_IS_OK(hnd
->status
))
94 op
->out
.sam
= sam_out
;
99 int cac_SamClose(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*sam
) {
100 struct rpc_pipe_client
*pipe_hnd
= NULL
;
105 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
106 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
110 if(!sam
|| !mem_ctx
) {
111 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
115 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
117 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
121 hnd
->status
= rpccli_samr_close( pipe_hnd
, mem_ctx
, sam
);
123 if(!NT_STATUS_IS_OK(hnd
->status
))
129 /*this is an internal function. Due to a circular dependency, it must be prototyped in libmsrpc.h (which I don't want to do)
130 * cac_SamOpenDomain() is the only function that calls it, so I just put the definition here
132 /*attempts to find the sid of the domain we are connected to*/
133 DOM_SID
*cac_get_domain_sid(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, uint32 des_access
) {
134 struct LsaOpenPolicy lop
;
135 struct LsaFetchSid fs
;
142 lop
.in
.access
= des_access
;
143 lop
.in
.security_qos
= True
;
145 if(!cac_LsaOpenPolicy(hnd
, mem_ctx
, &lop
))
148 fs
.in
.pol
= lop
.out
.pol
;
149 fs
.in
.info_class
= CAC_DOMAIN_INFO
;
151 if(!cac_LsaFetchSid(hnd
, mem_ctx
, &fs
))
154 cac_LsaClosePolicy(hnd
, mem_ctx
, lop
.out
.pol
);
156 if(!fs
.out
.domain_sid
)
159 sid
= talloc_memdup(mem_ctx
, &(fs
.out
.domain_sid
->sid
), sizeof(DOM_SID
));
162 hnd
->status
= NT_STATUS_NO_MEMORY
;
169 int cac_SamOpenDomain(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamOpenDomain
*op
) {
170 struct rpc_pipe_client
*pipe_hnd
= NULL
;
176 struct SamLookupDomain sld
;
181 if(!hnd
->_internal
.ctx
) {
182 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
186 if(!op
|| op
->in
.access
== 0 || !mem_ctx
) {
187 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
192 /*use cac_SamConnect() since it does the session setup*/
193 struct SamConnect sc
;
196 sc
.in
.access
= op
->in
.access
;
198 if(!cac_SamConnect(hnd
, mem_ctx
, &sc
)) {
202 sam_out
= sc
.out
.sam
;
205 sam_out
= op
->in
.sam
;
209 /*find the sid for the SAM's domain*/
211 /*try using cac_SamLookupDomain() first*/
214 sld
.in
.sam
= sam_out
;
215 sld
.in
.name
= hnd
->domain
;
217 if(cac_SamLookupDomain(hnd
, mem_ctx
, &sld
)) {
218 /*then we got the sid*/
219 sid_buf
= sld
.out
.sid
;
222 /*try to get it from the LSA*/
223 sid_buf
= cac_get_domain_sid(hnd
, mem_ctx
, op
->in
.access
);
227 /*we already have the sid for the domain we want*/
228 sid_buf
= op
->in
.sid
;
231 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
233 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
237 pol_out
= talloc(mem_ctx
, POLICY_HND
);
239 hnd
->status
= NT_STATUS_NO_MEMORY
;
243 /*now open the domain*/
244 hnd
->status
= rpccli_samr_open_domain( pipe_hnd
, mem_ctx
, sam_out
, op
->in
.access
, sid_buf
, pol_out
);
246 if(!NT_STATUS_IS_OK(hnd
->status
))
249 op
->out
.sam
= sam_out
;
250 op
->out
.dom_hnd
= pol_out
;
255 int cac_SamOpenUser(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamOpenUser
*op
) {
256 struct rpc_pipe_client
*pipe_hnd
= NULL
;
258 uint32
*rid_buf
= NULL
;
261 uint32
*rid_types
= NULL
;
263 POLICY_HND
*user_out
= NULL
;
268 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
269 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
273 if(!op
|| !op
->in
.dom_hnd
|| op
->in
.access
== 0 || !mem_ctx
) {
274 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
278 if(op
->in
.rid
== 0 && op
->in
.name
== NULL
) {
279 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
283 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
285 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
289 if(op
->in
.rid
== 0 && op
->in
.name
) {
290 /*lookup the name and then set rid_buf*/
292 hnd
->status
= rpccli_samr_lookup_names( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
, SAMR_LOOKUP_FLAGS
, 1, (const char **)&op
->in
.name
,
293 &num_rids
, &rid_buf
, &rid_types
);
295 if(!NT_STATUS_IS_OK(hnd
->status
))
298 if(num_rids
== 0 || rid_buf
== NULL
|| rid_types
[0] == SAMR_RID_UNKNOWN
) {
299 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
303 talloc_free(rid_types
);
307 rid_buf
= &op
->in
.rid
;
310 user_out
= talloc(mem_ctx
, POLICY_HND
);
312 hnd
->status
= NT_STATUS_NO_MEMORY
;
316 hnd
->status
= rpccli_samr_open_user(pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
, op
->in
.access
, *rid_buf
, user_out
);
318 if(!NT_STATUS_IS_OK(hnd
->status
))
321 op
->out
.user_hnd
= user_out
;
326 int cac_SamCreateUser(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamCreateUser
*op
) {
327 struct rpc_pipe_client
*pipe_hnd
= NULL
;
329 POLICY_HND
*user_out
= NULL
;
332 /**found in rpcclient/cmd_samr.c*/
333 uint32 unknown
= 0xe005000b;
338 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
339 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
343 if(!op
|| !op
->in
.dom_hnd
|| !op
->in
.name
|| op
->in
.acb_mask
== 0 || !mem_ctx
) {
344 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
348 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
350 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
354 user_out
= talloc(mem_ctx
, POLICY_HND
);
356 hnd
->status
= NT_STATUS_NO_MEMORY
;
360 hnd
->status
= rpccli_samr_create_dom_user( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
, op
->in
.name
, op
->in
.acb_mask
, unknown
, user_out
, &rid_out
);
362 if(!NT_STATUS_IS_OK(hnd
->status
))
365 op
->out
.user_hnd
= user_out
;
366 op
->out
.rid
= rid_out
;
371 int cac_SamDeleteUser(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*user_hnd
) {
372 struct rpc_pipe_client
*pipe_hnd
= NULL
;
377 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
378 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
382 if(!user_hnd
|| !mem_ctx
) {
383 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
387 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
389 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
393 hnd
->status
= rpccli_samr_delete_dom_user( pipe_hnd
, mem_ctx
, user_hnd
);
395 if(!NT_STATUS_IS_OK(hnd
->status
))
401 int cac_SamEnumUsers(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamEnumUsers
*op
) {
402 struct rpc_pipe_client
*pipe_hnd
= NULL
;
404 uint32 resume_idx_out
= 0;
405 char **names_out
= NULL
;
406 uint32
*rids_out
= NULL
;
407 uint32 num_users_out
= 0;
412 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
413 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
417 if(!op
|| !op
->in
.dom_hnd
|| !mem_ctx
) {
418 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
422 /*this is a hack.. but is the only reliable way to know if everything has been enumerated*/
423 if(op
->out
.done
== True
)
426 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
428 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
432 resume_idx_out
= op
->out
.resume_idx
;
434 hnd
->status
= rpccli_samr_enum_dom_users( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
, &resume_idx_out
, op
->in
.acb_mask
, SAMR_ENUM_MAX_SIZE
,
435 &names_out
, &rids_out
, &num_users_out
);
438 if(NT_STATUS_IS_OK(hnd
->status
))
441 /*if there are no more entries, the operation will return NT_STATUS_OK.
442 * We want to return failure if no results were returned*/
443 if(!NT_STATUS_IS_OK(hnd
->status
) && NT_STATUS_V(hnd
->status
) != NT_STATUS_V(STATUS_MORE_ENTRIES
))
446 op
->out
.resume_idx
= resume_idx_out
;
447 op
->out
.num_users
= num_users_out
;
448 op
->out
.rids
= rids_out
;
449 op
->out
.names
= names_out
;
454 int cac_SamGetNamesFromRids(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetNamesFromRids
*op
) {
455 struct rpc_pipe_client
*pipe_hnd
= NULL
;
457 uint32 num_names_out
;
459 uint32
*name_types_out
;
464 CacLookupRidsRecord
*map_out
;
469 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
470 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
474 if(!op
|| !op
->in
.dom_hnd
|| !mem_ctx
) {
475 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
479 if(!op
->in
.rids
&& op
->in
.num_rids
!= 0) {
480 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
484 if(op
->in
.num_rids
== 0) {
486 op
->out
.num_names
= 0;
490 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
492 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
496 hnd
->status
= rpccli_samr_lookup_rids( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
, op
->in
.num_rids
, op
->in
.rids
, &num_names_out
, &names_out
, &name_types_out
);
498 if(!NT_STATUS_IS_OK(hnd
->status
) && !NT_STATUS_EQUAL(hnd
->status
, STATUS_SOME_UNMAPPED
))
501 map_out
= TALLOC_ARRAY(mem_ctx
, CacLookupRidsRecord
, num_names_out
);
503 hnd
->status
= NT_STATUS_NO_MEMORY
;
507 for(i
= 0; i
< num_names_out
; i
++) {
508 if(name_types_out
[i
] == SAMR_RID_UNKNOWN
) {
509 map_out
[i
].found
= False
;
510 map_out
[i
].name
= NULL
;
514 map_out
[i
].found
= True
;
515 map_out
[i
].name
= talloc_strdup(mem_ctx
, names_out
[i
]);
516 map_out
[i
].type
= name_types_out
[i
];
518 map_out
[i
].rid
= op
->in
.rids
[i
];
521 talloc_free(names_out
);
522 talloc_free(name_types_out
);
524 op
->out
.num_names
= num_names_out
;
525 op
->out
.map
= map_out
;
527 if(NT_STATUS_EQUAL(hnd
->status
, STATUS_SOME_UNMAPPED
))
528 return CAC_PARTIAL_SUCCESS
;
533 int cac_SamGetRidsFromNames(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetRidsFromNames
*op
) {
534 struct rpc_pipe_client
*pipe_hnd
= NULL
;
538 uint32
*rid_types_out
;
542 CacLookupRidsRecord
*map_out
;
547 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
548 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
552 if(!op
|| !op
->in
.dom_hnd
|| !mem_ctx
) {
553 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
557 if(!op
->in
.names
&& op
->in
.num_names
!= 0) {
558 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
562 if(op
->in
.num_names
== 0) {
563 /*then we don't have to do anything*/
564 op
->out
.num_rids
= 0;
568 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
570 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
574 hnd
->status
= rpccli_samr_lookup_names( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
, SAMR_LOOKUP_FLAGS
, op
->in
.num_names
, (const char **)op
->in
.names
,
575 &num_rids_out
, &rids_out
, &rid_types_out
);
577 if(!NT_STATUS_IS_OK(hnd
->status
) && !NT_STATUS_EQUAL(hnd
->status
, STATUS_SOME_UNMAPPED
))
580 map_out
= TALLOC_ARRAY(mem_ctx
, CacLookupRidsRecord
, num_rids_out
);
582 hnd
->status
= NT_STATUS_NO_MEMORY
;
586 for(i
= 0; i
< num_rids_out
; i
++) {
588 if(rid_types_out
[i
] == SAMR_RID_UNKNOWN
) {
589 map_out
[i
].found
= False
;
594 map_out
[i
].found
= True
;
595 map_out
[i
].rid
= rids_out
[i
];
596 map_out
[i
].type
= rid_types_out
[i
];
599 map_out
[i
].name
= talloc_strdup(mem_ctx
, op
->in
.names
[i
]);
602 op
->out
.num_rids
= num_rids_out
;
603 op
->out
.map
= map_out
;
605 talloc_free(rids_out
);
606 talloc_free(rid_types_out
);
608 if(NT_STATUS_EQUAL(hnd
->status
, STATUS_SOME_UNMAPPED
))
609 return CAC_PARTIAL_SUCCESS
;
615 int cac_SamGetGroupsForUser(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetGroupsForUser
*op
) {
616 struct rpc_pipe_client
*pipe_hnd
= NULL
;
618 DOM_GID
*groups
= NULL
;
619 uint32 num_groups_out
= 0;
621 uint32
*rids_out
= NULL
;
622 uint32
*attr_out
= NULL
;
629 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
630 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
634 if(!op
|| !op
->in
.user_hnd
|| !mem_ctx
) {
635 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
639 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
641 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
645 hnd
->status
= rpccli_samr_query_usergroups(pipe_hnd
, mem_ctx
, op
->in
.user_hnd
, &num_groups_out
, &groups
);
647 if(!NT_STATUS_IS_OK(hnd
->status
))
651 rids_out
= talloc_array(mem_ctx
, uint32
, num_groups_out
);
653 hnd
->status
= NT_STATUS_NO_MEMORY
;
657 attr_out
= talloc_array(mem_ctx
, uint32
, num_groups_out
);
659 hnd
->status
= NT_STATUS_NO_MEMORY
;
663 for(i
= 0; i
< num_groups_out
; i
++) {
664 rids_out
[i
] = groups
[i
].g_rid
;
665 attr_out
[i
] = groups
[i
].attr
;
670 op
->out
.num_groups
= num_groups_out
;
671 op
->out
.rids
= rids_out
;
672 op
->out
.attributes
= attr_out
;
678 int cac_SamOpenGroup(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamOpenGroup
*op
) {
679 struct rpc_pipe_client
*pipe_hnd
= NULL
;
681 POLICY_HND
*group_hnd_out
= NULL
;
686 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
687 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
691 if(!op
|| op
->in
.access
== 0 || op
->in
.rid
== 0 || !mem_ctx
) {
692 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
696 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
698 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
702 group_hnd_out
= talloc(mem_ctx
, POLICY_HND
);
704 hnd
->status
= NT_STATUS_NO_MEMORY
;
708 hnd
->status
= rpccli_samr_open_group( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
, op
->in
.access
, op
->in
.rid
, group_hnd_out
);
710 if(!NT_STATUS_IS_OK(hnd
->status
))
713 op
->out
.group_hnd
= group_hnd_out
;
718 int cac_SamCreateGroup(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamCreateGroup
*op
) {
719 struct rpc_pipe_client
*pipe_hnd
= NULL
;
721 POLICY_HND
*group_hnd_out
= NULL
;
726 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
727 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
731 if(!op
|| !op
->in
.name
|| op
->in
.name
[0] == '\0' || op
->in
.access
== 0 || !mem_ctx
) {
732 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
736 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
738 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
742 group_hnd_out
= talloc(mem_ctx
, POLICY_HND
);
744 hnd
->status
= NT_STATUS_NO_MEMORY
;
748 hnd
->status
= rpccli_samr_create_dom_group( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
, op
->in
.name
, op
->in
.access
, group_hnd_out
);
750 if(!NT_STATUS_IS_OK(hnd
->status
))
753 op
->out
.group_hnd
= group_hnd_out
;
759 int cac_SamDeleteGroup(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*group_hnd
) {
760 struct rpc_pipe_client
*pipe_hnd
= NULL
;
765 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
766 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
770 if(!group_hnd
|| !mem_ctx
) {
771 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
775 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
777 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
781 hnd
->status
= rpccli_samr_delete_dom_group( pipe_hnd
, mem_ctx
, group_hnd
);
783 if(!NT_STATUS_IS_OK(hnd
->status
))
790 int cac_SamGetGroupMembers(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetGroupMembers
*op
) {
791 struct rpc_pipe_client
*pipe_hnd
= NULL
;
800 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
801 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
805 if(!op
|| !op
->in
.group_hnd
|| !mem_ctx
) {
806 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
810 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
812 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
816 hnd
->status
= rpccli_samr_query_groupmem( pipe_hnd
, mem_ctx
, op
->in
.group_hnd
, &num_mem_out
, &rids_out
, &attr_out
);
818 if(!NT_STATUS_IS_OK(hnd
->status
))
821 op
->out
.num_members
= num_mem_out
;
822 op
->out
.rids
= rids_out
;
823 op
->out
.attributes
= attr_out
;
829 int cac_SamAddGroupMember(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamAddGroupMember
*op
) {
830 struct rpc_pipe_client
*pipe_hnd
= NULL
;
835 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
836 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
840 if(!op
|| !op
->in
.group_hnd
|| op
->in
.rid
== 0 || !mem_ctx
) {
841 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
845 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
847 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
851 hnd
->status
= rpccli_samr_add_groupmem( pipe_hnd
, mem_ctx
, op
->in
.group_hnd
, op
->in
.rid
);
853 if(!NT_STATUS_IS_OK(hnd
->status
))
859 int cac_SamRemoveGroupMember(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamRemoveGroupMember
*op
) {
860 struct rpc_pipe_client
*pipe_hnd
= NULL
;
865 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
866 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
870 if(!op
|| !op
->in
.group_hnd
|| op
->in
.rid
== 0 || !mem_ctx
) {
871 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
875 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
877 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
881 hnd
->status
= rpccli_samr_del_groupmem( pipe_hnd
, mem_ctx
, op
->in
.group_hnd
, op
->in
.rid
);
883 if(!NT_STATUS_IS_OK(hnd
->status
))
889 int cac_SamClearGroupMembers(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*group_hnd
) {
890 struct rpc_pipe_client
*pipe_hnd
= NULL
;
892 int result
= CAC_SUCCESS
;
905 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
906 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
910 if(!group_hnd
|| !mem_ctx
) {
911 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
915 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
917 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
921 hnd
->status
= rpccli_samr_query_groupmem(pipe_hnd
, mem_ctx
, group_hnd
, &num_mem
, &rid
, &attr
);
923 if(!NT_STATUS_IS_OK(hnd
->status
))
926 /*try to delete the users one by one*/
927 for(i
= 0; i
< num_mem
&& NT_STATUS_IS_OK(hnd
->status
); i
++) {
928 hnd
->status
= rpccli_samr_del_groupmem(pipe_hnd
, mem_ctx
, group_hnd
, rid
[i
]);
931 /*if not all members could be removed, then try to re-add the members that were already deleted*/
932 if(!NT_STATUS_IS_OK(hnd
->status
)) {
933 status
= NT_STATUS_OK
;
935 for(i
-= 1; i
>= 0 && NT_STATUS_IS_OK(status
); i
--) {
936 status
= rpccli_samr_add_groupmem( pipe_hnd
, mem_ctx
, group_hnd
, rid
[i
]);
939 /*we return with the NTSTATUS error that we got when trying to delete users*/
940 if(!NT_STATUS_IS_OK(status
))
941 result
= CAC_FAILURE
;
949 int cac_SamSetGroupMembers(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamSetGroupMembers
*op
) {
950 struct rpc_pipe_client
*pipe_hnd
= NULL
;
957 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
958 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
962 if(!op
|| !op
->in
.group_hnd
|| !mem_ctx
) {
963 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
967 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
969 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
973 /*use cac_SamClearGroupMembers() to clear them*/
974 if(!cac_SamClearGroupMembers(hnd
, mem_ctx
, op
->in
.group_hnd
))
975 return CAC_FAILURE
; /*hnd->status is already set*/
978 for(i
= 0; i
< op
->in
.num_members
&& NT_STATUS_IS_OK(hnd
->status
); i
++) {
979 hnd
->status
= rpccli_samr_add_groupmem( pipe_hnd
, mem_ctx
, op
->in
.group_hnd
, op
->in
.rids
[i
]);
982 if(!NT_STATUS_IS_OK(hnd
->status
))
989 int cac_SamEnumGroups(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamEnumGroups
*op
) {
990 struct rpc_pipe_client
*pipe_hnd
= NULL
;
994 uint32 resume_idx_out
= 0;
995 char **names_out
= NULL
;
996 char **desc_out
= NULL
;
997 uint32
*rids_out
= NULL
;
998 uint32 num_groups_out
= 0;
1000 struct acct_info
*acct_buf
= NULL
;
1005 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1006 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1010 if(!op
|| !op
->in
.dom_hnd
|| !mem_ctx
) {
1011 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1015 /*using this BOOL is the only reliable way to know that we are done*/
1016 if(op
->out
.done
== True
) /*we return failure so the call will break out of a loop*/
1019 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1021 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1025 resume_idx_out
= op
->out
.resume_idx
;
1027 hnd
->status
= rpccli_samr_enum_dom_groups( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
, &resume_idx_out
, SAMR_ENUM_MAX_SIZE
,
1028 &acct_buf
, &num_groups_out
);
1031 if(NT_STATUS_IS_OK(hnd
->status
)) {
1032 op
->out
.done
= True
;
1034 else if(NT_STATUS_V(hnd
->status
) != NT_STATUS_V(STATUS_MORE_ENTRIES
)) {
1035 /*if there are no more entries, the operation will return NT_STATUS_OK.
1036 * We want to return failure if no results were returned*/
1040 names_out
= talloc_array(mem_ctx
, char *, num_groups_out
);
1042 hnd
->status
= NT_STATUS_NO_MEMORY
;
1043 talloc_free(acct_buf
);
1047 desc_out
= talloc_array(mem_ctx
, char *, num_groups_out
);
1049 hnd
->status
= NT_STATUS_NO_MEMORY
;
1050 talloc_free(acct_buf
);
1051 talloc_free(names_out
);
1055 rids_out
= talloc_array(mem_ctx
, uint32
, num_groups_out
);
1057 hnd
->status
= NT_STATUS_NO_MEMORY
;
1058 talloc_free(acct_buf
);
1059 talloc_free(names_out
);
1060 talloc_free(desc_out
);
1064 for(i
= 0; i
< num_groups_out
; i
++) {
1065 names_out
[i
] = talloc_strdup(mem_ctx
, acct_buf
[i
].acct_name
);
1066 desc_out
[i
] = talloc_strdup(mem_ctx
, acct_buf
[i
].acct_desc
);
1067 rids_out
[i
] = acct_buf
[i
].rid
;
1069 if(!names_out
[i
] || !desc_out
[i
]) {
1070 hnd
->status
= NT_STATUS_NO_MEMORY
;
1075 op
->out
.resume_idx
= resume_idx_out
;
1076 op
->out
.num_groups
= num_groups_out
;
1077 op
->out
.rids
= rids_out
;
1078 op
->out
.names
= names_out
;
1079 op
->out
.descriptions
= desc_out
;
1084 int cac_SamEnumAliases(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamEnumAliases
*op
) {
1085 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1089 uint32 resume_idx_out
= 0;
1090 char **names_out
= NULL
;
1091 char **desc_out
= NULL
;
1092 uint32
*rids_out
= NULL
;
1093 uint32 num_als_out
= 0;
1095 struct acct_info
*acct_buf
= NULL
;
1100 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1101 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1105 if(!op
|| !op
->in
.dom_hnd
|| !mem_ctx
) {
1106 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1110 /*this is a hack.. but is the only reliable way to know if everything has been enumerated*/
1111 if(op
->out
.done
== True
) {
1115 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1117 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1121 resume_idx_out
= op
->out
.resume_idx
;
1123 hnd
->status
= rpccli_samr_enum_als_groups( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
, &resume_idx_out
, SAMR_ENUM_MAX_SIZE
,
1124 &acct_buf
, &num_als_out
);
1127 if(NT_STATUS_IS_OK(hnd
->status
))
1128 op
->out
.done
= True
;
1130 /*if there are no more entries, the operation will return NT_STATUS_OK.
1131 * We want to return failure if no results were returned*/
1132 if(!NT_STATUS_IS_OK(hnd
->status
) && NT_STATUS_V(hnd
->status
) != NT_STATUS_V(STATUS_MORE_ENTRIES
))
1135 names_out
= talloc_array(mem_ctx
, char *, num_als_out
);
1137 hnd
->status
= NT_STATUS_NO_MEMORY
;
1138 talloc_free(acct_buf
);
1142 desc_out
= talloc_array(mem_ctx
, char *, num_als_out
);
1144 hnd
->status
= NT_STATUS_NO_MEMORY
;
1145 talloc_free(acct_buf
);
1146 talloc_free(names_out
);
1150 rids_out
= talloc_array(mem_ctx
, uint32
, num_als_out
);
1152 hnd
->status
= NT_STATUS_NO_MEMORY
;
1153 talloc_free(acct_buf
);
1154 talloc_free(names_out
);
1155 talloc_free(desc_out
);
1159 for(i
= 0; i
< num_als_out
; i
++) {
1160 names_out
[i
] = talloc_strdup(mem_ctx
, acct_buf
[i
].acct_name
);
1161 desc_out
[i
] = talloc_strdup(mem_ctx
, acct_buf
[i
].acct_desc
);
1162 rids_out
[i
] = acct_buf
[i
].rid
;
1164 if(!names_out
[i
] || !desc_out
[i
]) {
1165 hnd
->status
= NT_STATUS_NO_MEMORY
;
1170 op
->out
.resume_idx
= resume_idx_out
;
1171 op
->out
.num_aliases
= num_als_out
;
1172 op
->out
.rids
= rids_out
;
1173 op
->out
.names
= names_out
;
1174 op
->out
.descriptions
= desc_out
;
1179 int cac_SamCreateAlias(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamCreateAlias
*op
) {
1180 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1182 POLICY_HND
*als_hnd_out
= NULL
;
1187 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1188 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1192 if(!op
|| !op
->in
.name
|| op
->in
.name
[0] == '\0' || !mem_ctx
) {
1193 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1197 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1199 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1203 als_hnd_out
= talloc(mem_ctx
, POLICY_HND
);
1205 hnd
->status
= NT_STATUS_NO_MEMORY
;
1209 hnd
->status
= rpccli_samr_create_dom_alias( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
, op
->in
.name
, als_hnd_out
);
1211 if(!NT_STATUS_IS_OK(hnd
->status
))
1214 op
->out
.alias_hnd
= als_hnd_out
;
1220 int cac_SamOpenAlias(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamOpenAlias
*op
) {
1221 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1223 POLICY_HND
*als_hnd_out
= NULL
;
1228 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1229 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1233 if(!op
|| op
->in
.access
== 0 || op
->in
.rid
== 0 || !mem_ctx
) {
1234 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1238 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1240 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1244 als_hnd_out
= talloc(mem_ctx
, POLICY_HND
);
1246 hnd
->status
= NT_STATUS_NO_MEMORY
;
1250 hnd
->status
= rpccli_samr_open_alias( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
, op
->in
.access
, op
->in
.rid
, als_hnd_out
);
1252 if(!NT_STATUS_IS_OK(hnd
->status
))
1255 op
->out
.alias_hnd
= als_hnd_out
;
1260 int cac_SamDeleteAlias(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*alias_hnd
) {
1261 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1266 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1267 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1271 if(!alias_hnd
|| !mem_ctx
) {
1272 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1276 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1278 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1282 hnd
->status
= rpccli_samr_delete_dom_alias( pipe_hnd
, mem_ctx
, alias_hnd
);
1284 if(!NT_STATUS_IS_OK(hnd
->status
))
1291 int cac_SamAddAliasMember(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamAddAliasMember
*op
) {
1292 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1297 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1298 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1302 if(!op
|| !op
->in
.alias_hnd
|| !op
->in
.sid
|| !mem_ctx
) {
1303 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1307 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1309 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1313 hnd
->status
= rpccli_samr_add_aliasmem( pipe_hnd
, mem_ctx
, op
->in
.alias_hnd
, op
->in
.sid
);
1315 if(!NT_STATUS_IS_OK(hnd
->status
))
1321 int cac_SamRemoveAliasMember(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamRemoveAliasMember
*op
) {
1322 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1327 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1328 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1332 if(!op
|| !op
->in
.alias_hnd
|| !op
->in
.sid
|| !mem_ctx
) {
1333 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1337 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1339 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1343 hnd
->status
= rpccli_samr_del_aliasmem( pipe_hnd
, mem_ctx
, op
->in
.alias_hnd
, op
->in
.sid
);
1345 if(!NT_STATUS_IS_OK(hnd
->status
))
1351 int cac_SamGetAliasMembers(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetAliasMembers
*op
) {
1352 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1360 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1361 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1365 if(!op
|| !op
->in
.alias_hnd
|| !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 hnd
->status
= rpccli_samr_query_aliasmem( pipe_hnd
, mem_ctx
, op
->in
.alias_hnd
, &num_mem_out
, &sids_out
);
1378 if(!NT_STATUS_IS_OK(hnd
->status
))
1381 op
->out
.num_members
= num_mem_out
;
1382 op
->out
.sids
= sids_out
;
1387 int cac_SamClearAliasMembers(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*alias_hnd
) {
1388 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1390 int result
= CAC_SUCCESS
;
1395 DOM_SID
*sid
= NULL
;
1402 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1403 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1407 if(!alias_hnd
|| !mem_ctx
) {
1408 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1412 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1414 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1418 hnd
->status
= rpccli_samr_query_aliasmem(pipe_hnd
, mem_ctx
, alias_hnd
, &num_mem
, &sid
);
1420 if(!NT_STATUS_IS_OK(hnd
->status
))
1423 /*try to delete the users one by one*/
1424 for(i
= 0; i
< num_mem
&& NT_STATUS_IS_OK(hnd
->status
); i
++) {
1425 hnd
->status
= rpccli_samr_del_aliasmem(pipe_hnd
, mem_ctx
, alias_hnd
, &sid
[i
]);
1428 /*if not all members could be removed, then try to re-add the members that were already deleted*/
1429 if(!NT_STATUS_IS_OK(hnd
->status
)) {
1430 status
= NT_STATUS_OK
;
1432 for(i
-= 1; i
>= 0 && NT_STATUS_IS_OK(status
); i
--) {
1433 status
= rpccli_samr_add_aliasmem( pipe_hnd
, mem_ctx
, alias_hnd
, &sid
[i
]);
1436 /*we return with the NTSTATUS error that we got when trying to delete users*/
1437 if(!NT_STATUS_IS_OK(status
))
1438 result
= CAC_FAILURE
;
1445 int cac_SamSetAliasMembers(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamSetAliasMembers
*op
) {
1446 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1453 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1454 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1458 if(!op
|| !op
->in
.alias_hnd
|| !mem_ctx
) {
1459 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1463 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1465 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1469 /*use cac_SamClearAliasMembers() to clear them*/
1470 if(!cac_SamClearAliasMembers(hnd
, mem_ctx
, op
->in
.alias_hnd
))
1471 return CAC_FAILURE
; /*hnd->status is already set*/
1474 for(i
= 0; i
< op
->in
.num_members
&& NT_STATUS_IS_OK(hnd
->status
); i
++) {
1475 hnd
->status
= rpccli_samr_add_aliasmem( pipe_hnd
, mem_ctx
, op
->in
.alias_hnd
, &(op
->in
.sids
[i
]));
1478 if(!NT_STATUS_IS_OK(hnd
->status
))
1485 int cac_SamUserChangePasswd(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamUserChangePasswd
*op
) {
1486 SMBCSRV
*srv
= NULL
;
1487 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1492 if(!hnd
->_internal
.ctx
) {
1493 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1497 if(!op
|| !op
->in
.username
|| !op
->in
.password
|| !op
->in
.new_password
|| !mem_ctx
) {
1498 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1502 srv
= cac_GetServer(hnd
);
1504 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1508 /*open a session on SAMR if we don't have one*/
1509 if(!hnd
->_internal
.pipes
[PI_SAMR
]) {
1510 if(!(pipe_hnd
= cli_rpc_pipe_open_noauth(&srv
->cli
, PI_SAMR
, &(hnd
->status
)))) {
1514 hnd
->_internal
.pipes
[PI_SAMR
] = True
;
1517 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1519 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1523 hnd
->status
= rpccli_samr_chgpasswd_user(pipe_hnd
, mem_ctx
, op
->in
.username
, op
->in
.new_password
, op
->in
.password
);
1525 if(!NT_STATUS_IS_OK(hnd
->status
))
1531 int cac_SamEnableUser(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*user_hnd
) {
1532 SMBCSRV
*srv
= NULL
;
1533 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1535 SAM_USERINFO_CTR
*ctr
;
1540 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1541 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1545 if(!user_hnd
|| !mem_ctx
) {
1546 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1550 srv
= cac_GetServer(hnd
);
1552 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1556 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1558 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1562 /*info_level = 21 is the only level that I have found to work reliably. It would be nice if user_level = 10 worked.*/
1563 hnd
->status
= rpccli_samr_query_userinfo( pipe_hnd
, mem_ctx
, user_hnd
, 0x10, &ctr
);
1565 if(!NT_STATUS_IS_OK(hnd
->status
))
1568 /**check the ACB mask*/
1569 if((ctr
->info
.id16
->acb_info
& ACB_DISABLED
) == ACB_DISABLED
) {
1570 /*toggle the disabled bit*/
1571 ctr
->info
.id16
->acb_info
^= ACB_DISABLED
;
1574 /*the user is already enabled so just return success*/
1578 /*now set the userinfo*/
1579 hnd
->status
= rpccli_samr_set_userinfo2( pipe_hnd
, mem_ctx
, user_hnd
, 0x10, &(srv
->cli
.user_session_key
), ctr
);
1581 /*this will only work properly if we use set_userinfo2 - fail if it is not supported*/
1582 if(!NT_STATUS_IS_OK(hnd
->status
))
1588 int cac_SamDisableUser(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*user_hnd
) {
1589 SMBCSRV
*srv
= NULL
;
1590 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1592 SAM_USERINFO_CTR
*ctr
;
1597 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1598 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1602 if(!user_hnd
|| !mem_ctx
) {
1603 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1607 srv
= cac_GetServer(hnd
);
1609 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1613 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1615 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1619 hnd
->status
= rpccli_samr_query_userinfo( pipe_hnd
, mem_ctx
, user_hnd
, 0x10, &ctr
);
1621 if(!NT_STATUS_IS_OK(hnd
->status
))
1624 if((ctr
->info
.id16
->acb_info
& ACB_DISABLED
) == ACB_DISABLED
) {
1625 /*then the user is already disabled*/
1629 /*toggle the disabled bit*/
1630 ctr
->info
.id16
->acb_info
^= ACB_DISABLED
;
1632 /*this will only work properly if we use set_userinfo2*/
1633 hnd
->status
= rpccli_samr_set_userinfo2( pipe_hnd
, mem_ctx
, user_hnd
, 0x10, &(srv
->cli
.user_session_key
), ctr
);
1635 /*this will only work properly if we use set_userinfo2 fail if it is not supported*/
1636 if(!NT_STATUS_IS_OK(hnd
->status
))
1642 int cac_SamSetPassword(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamSetPassword
*op
) {
1643 SMBCSRV
*srv
= NULL
;
1644 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1646 SAM_USERINFO_CTR ctr
;
1647 SAM_USER_INFO_24 info24
;
1653 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1654 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1658 if(!op
->in
.user_hnd
|| !op
->in
.password
|| !mem_ctx
) {
1659 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1663 srv
= cac_GetServer(hnd
);
1665 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1669 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1671 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1676 ZERO_STRUCT(info24
);
1678 encode_pw_buffer(pw
, op
->in
.password
, STR_UNICODE
);
1680 init_sam_user_info24(&info24
, (char *)pw
, 24);
1682 ctr
.switch_value
= 24;
1683 ctr
.info
.id24
= &info24
;
1685 hnd
->status
= rpccli_samr_set_userinfo( pipe_hnd
, mem_ctx
, op
->in
.user_hnd
, 24, &(srv
->cli
.user_session_key
), &ctr
);
1687 if(!NT_STATUS_IS_OK(hnd
->status
))
1693 int cac_SamGetUserInfo(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetUserInfo
*op
) {
1694 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1696 SAM_USERINFO_CTR
*ctr
;
1701 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1702 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1706 if(!op
->in
.user_hnd
|| !mem_ctx
) {
1707 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1711 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1713 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1717 hnd
->status
= rpccli_samr_query_userinfo( pipe_hnd
, mem_ctx
, op
->in
.user_hnd
, 21, &ctr
);
1719 if(!NT_STATUS_IS_OK(hnd
->status
))
1722 op
->out
.info
= cac_MakeUserInfo(mem_ctx
, ctr
);
1725 hnd
->status
= NT_STATUS_NO_MEMORY
;
1732 int cac_SamSetUserInfo(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamSetUserInfo
*op
) {
1733 SMBCSRV
*srv
= NULL
;
1734 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1736 SAM_USERINFO_CTR
*ctr
;
1741 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1742 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1746 if(!op
->in
.user_hnd
|| !op
->in
.info
|| !mem_ctx
) {
1747 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1751 ctr
= cac_MakeUserInfoCtr(mem_ctx
, op
->in
.info
);
1753 hnd
->status
= NT_STATUS_NO_MEMORY
;
1757 srv
= cac_GetServer(hnd
);
1759 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1763 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1765 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1769 if(hnd
->_internal
.srv_level
>= SRV_WIN_NT4
) {
1770 hnd
->status
= rpccli_samr_set_userinfo2( pipe_hnd
, mem_ctx
, op
->in
.user_hnd
, 21, &(srv
->cli
.user_session_key
), ctr
);
1773 if(hnd
->_internal
.srv_level
< SRV_WIN_NT4
|| !NT_STATUS_IS_OK(hnd
->status
)) {
1774 hnd
->status
= rpccli_samr_set_userinfo( pipe_hnd
, mem_ctx
, op
->in
.user_hnd
, 21, &(srv
->cli
.user_session_key
), ctr
);
1776 if(NT_STATUS_IS_OK(hnd
->status
) && hnd
->_internal
.srv_level
> SRV_WIN_NT4
) {
1777 hnd
->_internal
.srv_level
= SRV_WIN_NT4
;
1782 if(!NT_STATUS_IS_OK(hnd
->status
))
1789 int cac_SamGetUserInfoCtr(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetUserInfoCtr
*op
) {
1790 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1792 SAM_USERINFO_CTR
*ctr_out
;
1797 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1798 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1802 if(!op
->in
.user_hnd
|| op
->in
.info_class
== 0 || !mem_ctx
) {
1803 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1807 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1809 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1813 hnd
->status
= rpccli_samr_query_userinfo( pipe_hnd
, mem_ctx
, op
->in
.user_hnd
, op
->in
.info_class
, &ctr_out
);
1815 if(!NT_STATUS_IS_OK(hnd
->status
))
1818 op
->out
.ctr
= ctr_out
;
1823 int cac_SamSetUserInfoCtr(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamSetUserInfoCtr
*op
) {
1824 SMBCSRV
*srv
= NULL
;
1825 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1830 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1831 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1835 if(!op
->in
.user_hnd
|| !op
->in
.ctr
|| !mem_ctx
) {
1836 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1840 srv
= cac_GetServer(hnd
);
1842 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1846 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1848 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1853 hnd
->status
= rpccli_samr_set_userinfo( pipe_hnd
, mem_ctx
, op
->in
.user_hnd
, op
->in
.ctr
->switch_value
, &(srv
->cli
.user_session_key
), op
->in
.ctr
);
1855 if(!NT_STATUS_IS_OK(hnd
->status
))
1862 int cac_SamRenameUser(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamRenameUser
*op
) {
1863 SMBCSRV
*srv
= NULL
;
1864 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1866 SAM_USERINFO_CTR ctr
;
1867 SAM_USER_INFO_7 info7
;
1872 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1873 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1877 if(!op
->in
.user_hnd
|| !op
->in
.new_name
|| op
->in
.new_name
[0] == '\0' || !mem_ctx
) {
1878 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1882 srv
= cac_GetServer(hnd
);
1884 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1888 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1890 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1897 init_sam_user_info7(&info7
, op
->in
.new_name
);
1899 ctr
.switch_value
= 7;
1900 ctr
.info
.id7
= &info7
;
1902 hnd
->status
= rpccli_samr_set_userinfo( pipe_hnd
, mem_ctx
, op
->in
.user_hnd
, 7, &(srv
->cli
.user_session_key
), &ctr
);
1904 if(!NT_STATUS_IS_OK(hnd
->status
))
1911 int cac_SamGetGroupInfo(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetGroupInfo
*op
) {
1912 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1914 GROUP_INFO_CTR
*ctr
;
1919 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1920 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1924 if(!op
->in
.group_hnd
|| !mem_ctx
) {
1925 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1929 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1931 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1936 /*get a GROUP_INFO_1 structure*/
1937 hnd
->status
= rpccli_samr_query_groupinfo( pipe_hnd
, mem_ctx
, op
->in
.group_hnd
, 1, &ctr
);
1939 if(!NT_STATUS_IS_OK(hnd
->status
))
1942 op
->out
.info
= cac_MakeGroupInfo(mem_ctx
, ctr
);
1944 hnd
->status
= NT_STATUS_NO_MEMORY
;
1951 int cac_SamSetGroupInfo(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamSetGroupInfo
*op
) {
1952 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1954 GROUP_INFO_CTR
*ctr
= NULL
;
1959 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1960 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1964 if(!op
->in
.group_hnd
|| !op
->in
.info
|| !mem_ctx
) {
1965 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1969 ctr
= cac_MakeGroupInfoCtr(mem_ctx
, op
->in
.info
);
1971 hnd
->status
= NT_STATUS_NO_MEMORY
;
1975 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
1977 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1981 hnd
->status
= rpccli_samr_set_groupinfo(pipe_hnd
, mem_ctx
, op
->in
.group_hnd
, ctr
);
1983 if(!NT_STATUS_IS_OK(hnd
->status
))
1989 int cac_SamRenameGroup(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamRenameGroup
*op
) {
1990 struct rpc_pipe_client
*pipe_hnd
= NULL
;
1997 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1998 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2002 if(!op
->in
.group_hnd
|| !op
->in
.new_name
|| op
->in
.new_name
[0] == '\0' || !mem_ctx
) {
2003 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2007 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
2009 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2015 init_samr_group_info2(&ctr
.group
.info2
, op
->in
.new_name
);
2016 ctr
.switch_value1
= 2;
2018 hnd
->status
= rpccli_samr_set_groupinfo( pipe_hnd
, mem_ctx
, op
->in
.group_hnd
, &ctr
);
2020 if(!NT_STATUS_IS_OK(hnd
->status
))
2026 int cac_SamGetAliasInfo(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetAliasInfo
*op
) {
2027 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2034 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
2035 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2039 if(!op
->in
.alias_hnd
|| !mem_ctx
) {
2040 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2044 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
2046 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2050 /*get a GROUP_INFO_1 structure*/
2051 hnd
->status
= rpccli_samr_query_alias_info( pipe_hnd
, mem_ctx
, op
->in
.alias_hnd
, 1, &ctr
);
2053 if(!NT_STATUS_IS_OK(hnd
->status
))
2056 op
->out
.info
= cac_MakeAliasInfo(mem_ctx
, ctr
);
2058 hnd
->status
= NT_STATUS_NO_MEMORY
;
2066 int cac_SamSetAliasInfo(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamSetAliasInfo
*op
) {
2067 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2069 ALIAS_INFO_CTR
*ctr
= NULL
;
2074 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
2075 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2079 if(!op
->in
.alias_hnd
|| !op
->in
.info
|| !mem_ctx
) {
2080 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2084 ctr
= cac_MakeAliasInfoCtr(mem_ctx
, op
->in
.info
);
2086 hnd
->status
= NT_STATUS_NO_MEMORY
;
2090 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
2092 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2096 hnd
->status
= rpccli_samr_set_aliasinfo(pipe_hnd
, mem_ctx
, op
->in
.alias_hnd
, ctr
);
2098 if(!NT_STATUS_IS_OK(hnd
->status
))
2104 int cac_SamGetDomainInfo(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetDomainInfo
*op
) {
2105 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2108 SAM_UNK_INFO_1 info1
;
2109 SAM_UNK_INFO_2 info2
;
2110 SAM_UNK_INFO_12 info12
;
2112 /*use this to keep track of a failed call*/
2113 NTSTATUS status_buf
= NT_STATUS_OK
;
2115 uint16 fail_count
= 0;
2121 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
2122 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2126 if(!op
->in
.dom_hnd
|| !mem_ctx
) {
2127 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2131 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
2133 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2137 /*first try with info 1*/
2138 hnd
->status
= rpccli_samr_query_dom_info( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
, 1, &ctr
);
2140 if(NT_STATUS_IS_OK(hnd
->status
)) {
2141 /*then we buffer the SAM_UNK_INFO_1 structure*/
2142 info1
= ctr
.info
.inf1
;
2145 /*then the call failed, store the status and ZERO out the info structure*/
2147 status_buf
= hnd
->status
;
2151 /*try again for the next one*/
2152 hnd
->status
= rpccli_samr_query_dom_info( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
, 2, &ctr
);
2154 if(NT_STATUS_IS_OK(hnd
->status
)) {
2156 info2
= ctr
.info
.inf2
;
2159 /*ZERO out the structure and store the bad status*/
2161 status_buf
= hnd
->status
;
2166 hnd
->status
= rpccli_samr_query_dom_info( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
, 12, &ctr
);
2168 if(NT_STATUS_IS_OK(hnd
->status
)) {
2169 info12
= ctr
.info
.inf12
;
2172 ZERO_STRUCT(info12
);
2173 status_buf
= hnd
->status
;
2177 /*return failure if all 3 calls failed*/
2181 op
->out
.info
= cac_MakeDomainInfo(mem_ctx
, &info1
, &info2
, &info12
);
2184 hnd
->status
= NT_STATUS_NO_MEMORY
;
2188 if(fail_count
> 0) {
2189 hnd
->status
= status_buf
;
2190 return CAC_PARTIAL_SUCCESS
;
2196 int cac_SamGetDomainInfoCtr(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetDomainInfoCtr
*op
) {
2197 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2199 SAM_UNK_CTR
*ctr_out
;
2204 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
2205 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2209 if(!op
->in
.dom_hnd
|| op
->in
.info_class
== 0 || !mem_ctx
) {
2210 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2214 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
2216 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2220 ctr_out
= talloc(mem_ctx
, SAM_UNK_CTR
);
2222 hnd
->status
= NT_STATUS_NO_MEMORY
;
2226 hnd
->status
= rpccli_samr_query_dom_info( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
, op
->in
.info_class
, ctr_out
);
2228 if(!NT_STATUS_IS_OK(hnd
->status
))
2231 op
->out
.info
= ctr_out
;
2236 int cac_SamGetDisplayInfo(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetDisplayInfo
*op
) {
2237 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2239 SAM_DISPINFO_CTR ctr_out
;
2241 uint32 max_entries_buf
= 0;
2242 uint32 max_size_buf
= 0;
2244 uint32 resume_idx_out
;
2245 uint32 num_entries_out
;
2250 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
2251 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2255 if(!op
->in
.dom_hnd
|| op
->in
.info_class
== 0 || !mem_ctx
) {
2256 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2260 if(op
->out
.done
== True
) /*this is done so we can use the function as a loop condition*/
2263 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
2265 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2269 if(op
->in
.max_entries
== 0 || op
->in
.max_size
== 0) {
2270 get_query_dispinfo_params(op
->out
.loop_count
, &max_entries_buf
, &max_size_buf
);
2273 max_entries_buf
= op
->in
.max_entries
;
2274 max_size_buf
= op
->in
.max_size
;
2277 resume_idx_out
= op
->out
.resume_idx
;
2279 hnd
->status
= rpccli_samr_query_dispinfo( pipe_hnd
, mem_ctx
, op
->in
.dom_hnd
, &resume_idx_out
, op
->in
.info_class
,
2280 &num_entries_out
, max_entries_buf
, max_size_buf
, &ctr_out
);
2282 if(!NT_STATUS_IS_OK(hnd
->status
) && !NT_STATUS_EQUAL(hnd
->status
, STATUS_MORE_ENTRIES
)) {
2283 /*be defensive, maybe they'll call again without zeroing the struct*/
2284 op
->out
.loop_count
= 0;
2285 op
->out
.resume_idx
= 0;
2289 if(NT_STATUS_IS_OK(hnd
->status
)) {
2290 /*we want to quit once the function is called next. so it can be used in a loop*/
2291 op
->out
.done
= True
;
2294 op
->out
.resume_idx
= resume_idx_out
;
2295 op
->out
.num_entries
= num_entries_out
;
2296 op
->out
.ctr
= ctr_out
;
2297 op
->out
.loop_count
++;
2302 int cac_SamLookupDomain(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamLookupDomain
*op
) {
2303 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2305 DOM_SID
*sid_out
= NULL
;
2310 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
2311 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2315 if(!op
->in
.sam
|| !op
->in
.name
|| !mem_ctx
) {
2316 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2320 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
2322 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2326 sid_out
= talloc(mem_ctx
, DOM_SID
);
2328 hnd
->status
= NT_STATUS_NO_MEMORY
;
2332 hnd
->status
= rpccli_samr_lookup_domain( pipe_hnd
, mem_ctx
, op
->in
.sam
, op
->in
.name
, sid_out
);
2334 if(!NT_STATUS_IS_OK(hnd
->status
))
2337 op
->out
.sid
= sid_out
;
2342 int cac_SamGetSecurityObject(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetSecurityObject
*op
) {
2343 struct rpc_pipe_client
*pipe_hnd
= NULL
;
2345 /*this number taken from rpcclient/cmd_samr.c, I think it is the only supported level*/
2346 uint16 info_level
= 4;
2348 SEC_DESC_BUF
*sec_out
= NULL
;
2353 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
2354 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2358 if(!op
->in
.pol
|| !mem_ctx
) {
2359 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2363 pipe_hnd
= cac_GetPipe(hnd
, PI_SAMR
);
2365 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2369 hnd
->status
= rpccli_samr_query_sec_obj(pipe_hnd
, mem_ctx
, op
->in
.pol
, info_level
, mem_ctx
, &sec_out
);
2371 if(!NT_STATUS_IS_OK(hnd
->status
))
2374 op
->out
.sec
= sec_out
;
2379 int cac_SamFlush(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamFlush
*op
) {
2380 struct SamOpenDomain od
;
2385 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
2386 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2390 if(!op
|| !op
->in
.dom_hnd
|| !mem_ctx
) {
2391 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2395 if(!cac_SamClose(hnd
, mem_ctx
, op
->in
.dom_hnd
))
2399 od
.in
.access
= (op
->in
.access
) ? op
->in
.access
: MAXIMUM_ALLOWED_ACCESS
;
2400 od
.in
.sid
= op
->in
.sid
;
2402 if(!cac_SamOpenDomain(hnd
, mem_ctx
, &od
))
2405 /*this function does not use an output parameter to make it as convenient as possible to use*/
2406 *op
->in
.dom_hnd
= *od
.out
.dom_hnd
;
2408 talloc_free(od
.out
.dom_hnd
);