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 POLICY_HND
*sam_out
= NULL
;
39 if(!hnd
->_internal
.ctx
) {
40 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
44 if(!op
|| op
->in
.access
== 0 || !mem_ctx
) {
45 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
49 srv
= cac_GetServer(hnd
);
51 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
55 /*initialize for samr pipe if we have to*/
56 if(!hnd
->_internal
.pipes
[PI_SAMR
]) {
57 if(!cli_nt_session_open(&srv
->cli
, PI_SAMR
)) {
58 hnd
->status
= NT_STATUS_UNSUCCESSFUL
;
62 hnd
->_internal
.pipes
[PI_SAMR
] = True
;
65 srv
->cli
.pipe_idx
= PI_SAMR
;
67 sam_out
= talloc(mem_ctx
, POLICY_HND
);
69 hnd
->status
= NT_STATUS_NO_MEMORY
;
73 if(hnd
->_internal
.srv_level
>= SRV_WIN_2K_SP3
) {
74 hnd
->status
= cli_samr_connect4( &(srv
->cli
), mem_ctx
, op
->in
.access
, sam_out
);
77 if(hnd
->_internal
.srv_level
< SRV_WIN_2K_SP3
|| !NT_STATUS_IS_OK(hnd
->status
)) {
78 /*if sam_connect4 failed, the use sam_connect and lower srv_level*/
80 hnd
->status
= cli_samr_connect( &(srv
->cli
), mem_ctx
, op
->in
.access
, sam_out
);
82 if(NT_STATUS_IS_OK(hnd
->status
) && hnd
->_internal
.srv_level
> SRV_WIN_2K
) {
83 hnd
->_internal
.srv_level
= SRV_WIN_2K
;
87 if(!NT_STATUS_IS_OK(hnd
->status
))
90 op
->out
.sam
= sam_out
;
95 int cac_SamClose(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*sam
) {
101 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
102 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
106 if(!sam
|| !mem_ctx
) {
107 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
111 srv
= cac_GetServer(hnd
);
113 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
117 srv
->cli
.pipe_idx
= PI_SAMR
;
119 hnd
->status
= cli_samr_close( &(srv
->cli
), mem_ctx
, sam
);
121 if(!NT_STATUS_IS_OK(hnd
->status
))
127 /*this is an internal function. Due to a circular dependency, it must be prototyped in libmsrpc.h (which I don't want to do)
128 * cac_SamOpenDomain() is the only function that calls it, so I just put the definition here
130 /*attempts to find the sid of the domain we are connected to*/
131 DOM_SID
*cac_get_domain_sid(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, uint32 des_access
) {
132 struct LsaOpenPolicy lop
;
133 struct LsaFetchSid fs
;
140 lop
.in
.access
= des_access
;
141 lop
.in
.security_qos
= True
;
143 if(!cac_LsaOpenPolicy(hnd
, mem_ctx
, &lop
))
146 fs
.in
.pol
= lop
.out
.pol
;
147 fs
.in
.info_class
= CAC_DOMAIN_INFO
;
149 if(!cac_LsaFetchSid(hnd
, mem_ctx
, &fs
))
152 cac_LsaClosePolicy(hnd
, mem_ctx
, lop
.out
.pol
);
154 if(!fs
.out
.domain_sid
)
157 sid
= talloc_memdup(mem_ctx
, &(fs
.out
.domain_sid
->sid
), sizeof(DOM_SID
));
160 hnd
->status
= NT_STATUS_NO_MEMORY
;
167 int cac_SamOpenDomain(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamOpenDomain
*op
) {
174 struct SamLookupDomain sld
;
179 if(!hnd
->_internal
.ctx
) {
180 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
184 if(!op
|| op
->in
.access
== 0 || !mem_ctx
) {
185 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
189 srv
= cac_GetServer(hnd
);
191 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
197 /*use cac_SamConnect() since it does the session setup*/
198 struct SamConnect sc
;
201 sc
.in
.access
= op
->in
.access
;
203 if(!cac_SamConnect(hnd
, mem_ctx
, &sc
)) {
207 sam_out
= sc
.out
.sam
;
210 sam_out
= op
->in
.sam
;
214 /*find the sid for the SAM's domain*/
216 /*try using cac_SamLookupDomain() first*/
219 sld
.in
.sam
= sam_out
;
220 sld
.in
.name
= hnd
->domain
;
222 if(cac_SamLookupDomain(hnd
, mem_ctx
, &sld
)) {
223 /*then we got the sid*/
224 sid_buf
= sld
.out
.sid
;
227 /*try to get it from the LSA*/
228 sid_buf
= cac_get_domain_sid(hnd
, mem_ctx
, op
->in
.access
);
232 /*we already have the sid for the domain we want*/
233 sid_buf
= op
->in
.sid
;
237 pol_out
= talloc(mem_ctx
, POLICY_HND
);
239 hnd
->status
= NT_STATUS_NO_MEMORY
;
243 /*now open the domain*/
244 hnd
->status
= cli_samr_open_domain( &(srv
->cli
), 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
) {
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 srv
= cac_GetServer(hnd
);
285 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
289 srv
->cli
.pipe_idx
= PI_SAMR
;
291 if(op
->in
.rid
== 0 && op
->in
.name
) {
292 /*lookup the name and then set rid_buf*/
294 hnd
->status
= cli_samr_lookup_names( &(srv
->cli
), mem_ctx
, op
->in
.dom_hnd
, SAMR_LOOKUP_FLAGS
, 1, (const char **)&op
->in
.name
,
295 &num_rids
, &rid_buf
, &rid_types
);
297 if(!NT_STATUS_IS_OK(hnd
->status
))
300 if(num_rids
== 0 || rid_buf
== NULL
|| rid_types
[0] == SAMR_RID_UNKNOWN
) {
301 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
305 talloc_free(rid_types
);
309 rid_buf
= &op
->in
.rid
;
312 user_out
= talloc(mem_ctx
, POLICY_HND
);
314 hnd
->status
= NT_STATUS_NO_MEMORY
;
318 hnd
->status
= cli_samr_open_user(&(srv
->cli
), mem_ctx
, op
->in
.dom_hnd
, op
->in
.access
, *rid_buf
, user_out
);
320 if(!NT_STATUS_IS_OK(hnd
->status
))
323 op
->out
.user_hnd
= user_out
;
328 int cac_SamCreateUser(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamCreateUser
*op
) {
331 POLICY_HND
*user_out
= NULL
;
334 /**found in rpcclient/cmd_samr.c*/
335 uint32 unknown
= 0xe005000b;
340 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
341 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
345 if(!op
|| !op
->in
.dom_hnd
|| !op
->in
.name
|| op
->in
.acb_mask
== 0 || !mem_ctx
) {
346 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
350 srv
= cac_GetServer(hnd
);
352 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
356 srv
->cli
.pipe_idx
= PI_SAMR
;
358 user_out
= talloc(mem_ctx
, POLICY_HND
);
360 hnd
->status
= NT_STATUS_NO_MEMORY
;
364 hnd
->status
= cli_samr_create_dom_user( &(srv
->cli
), mem_ctx
, op
->in
.dom_hnd
, op
->in
.name
, op
->in
.acb_mask
, unknown
, user_out
, &rid_out
);
366 if(!NT_STATUS_IS_OK(hnd
->status
))
369 op
->out
.user_hnd
= user_out
;
370 op
->out
.rid
= rid_out
;
375 int cac_SamDeleteUser(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*user_hnd
) {
381 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
382 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
386 if(!user_hnd
|| !mem_ctx
) {
387 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
391 srv
= cac_GetServer(hnd
);
393 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
397 srv
->cli
.pipe_idx
= PI_SAMR
;
399 hnd
->status
= cli_samr_delete_dom_user( &(srv
->cli
), mem_ctx
, user_hnd
);
401 if(!NT_STATUS_IS_OK(hnd
->status
))
407 int cac_SamEnumUsers(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamEnumUsers
*op
) {
410 uint32 resume_idx_out
= 0;
411 char **names_out
= NULL
;
412 uint32
*rids_out
= NULL
;
413 uint32 num_users_out
= 0;
418 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
419 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
423 if(!op
|| !op
->in
.dom_hnd
|| !mem_ctx
) {
424 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
428 /*this is a hack.. but is the only reliable way to know if everything has been enumerated*/
429 if(op
->out
.done
== True
)
432 srv
= cac_GetServer(hnd
);
434 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
438 srv
->cli
.pipe_idx
= PI_SAMR
;
440 resume_idx_out
= op
->out
.resume_idx
;
442 hnd
->status
= cli_samr_enum_dom_users( &(srv
->cli
), mem_ctx
, op
->in
.dom_hnd
, &resume_idx_out
, op
->in
.acb_mask
, SAMR_ENUM_MAX_SIZE
,
443 &names_out
, &rids_out
, &num_users_out
);
446 if(NT_STATUS_IS_OK(hnd
->status
))
449 /*if there are no more entries, the operation will return NT_STATUS_OK.
450 * We want to return failure if no results were returned*/
451 if(!NT_STATUS_IS_OK(hnd
->status
) && NT_STATUS_V(hnd
->status
) != NT_STATUS_V(STATUS_MORE_ENTRIES
))
454 op
->out
.resume_idx
= resume_idx_out
;
455 op
->out
.num_users
= num_users_out
;
456 op
->out
.rids
= rids_out
;
457 op
->out
.names
= names_out
;
462 int cac_SamGetNamesFromRids(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetNamesFromRids
*op
) {
465 uint32 num_names_out
;
467 uint32
*name_types_out
;
472 CacLookupRidsRecord
*map_out
;
477 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
478 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
482 if(!op
|| !op
->in
.dom_hnd
|| !mem_ctx
) {
483 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
487 if(!op
->in
.rids
&& op
->in
.num_rids
!= 0) {
488 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
492 if(op
->in
.num_rids
== 0) {
494 op
->out
.num_names
= 0;
498 srv
= cac_GetServer(hnd
);
500 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
504 srv
->cli
.pipe_idx
= PI_SAMR
;
506 hnd
->status
= cli_samr_lookup_rids( &(srv
->cli
), mem_ctx
, op
->in
.dom_hnd
, op
->in
.num_rids
, op
->in
.rids
, &num_names_out
, &names_out
, &name_types_out
);
508 if(!NT_STATUS_IS_OK(hnd
->status
) && !NT_STATUS_EQUAL(hnd
->status
, STATUS_SOME_UNMAPPED
))
511 map_out
= TALLOC_ARRAY(mem_ctx
, CacLookupRidsRecord
, num_names_out
);
513 hnd
->status
= NT_STATUS_NO_MEMORY
;
517 for(i
= 0; i
< num_names_out
; i
++) {
518 if(name_types_out
[i
] == SAMR_RID_UNKNOWN
) {
519 map_out
[i
].found
= False
;
520 map_out
[i
].name
= NULL
;
524 map_out
[i
].found
= True
;
525 map_out
[i
].name
= talloc_strdup(mem_ctx
, names_out
[i
]);
526 map_out
[i
].type
= name_types_out
[i
];
528 map_out
[i
].rid
= op
->in
.rids
[i
];
531 talloc_free(names_out
);
532 talloc_free(name_types_out
);
534 op
->out
.num_names
= num_names_out
;
535 op
->out
.map
= map_out
;
537 if(NT_STATUS_EQUAL(hnd
->status
, STATUS_SOME_UNMAPPED
))
538 return CAC_PARTIAL_SUCCESS
;
543 int cac_SamGetRidsFromNames(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetRidsFromNames
*op
) {
548 uint32
*rid_types_out
;
552 CacLookupRidsRecord
*map_out
;
557 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
558 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
562 if(!op
|| !op
->in
.dom_hnd
|| !mem_ctx
) {
563 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
567 if(!op
->in
.names
&& op
->in
.num_names
!= 0) {
568 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
572 if(op
->in
.num_names
== 0) {
573 /*then we don't have to do anything*/
574 op
->out
.num_rids
= 0;
578 srv
= cac_GetServer(hnd
);
580 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
584 srv
->cli
.pipe_idx
= PI_SAMR
;
586 hnd
->status
= cli_samr_lookup_names( &(srv
->cli
), mem_ctx
, op
->in
.dom_hnd
, SAMR_LOOKUP_FLAGS
, op
->in
.num_names
, (const char **)op
->in
.names
,
587 &num_rids_out
, &rids_out
, &rid_types_out
);
589 if(!NT_STATUS_IS_OK(hnd
->status
) && !NT_STATUS_EQUAL(hnd
->status
, STATUS_SOME_UNMAPPED
))
592 map_out
= TALLOC_ARRAY(mem_ctx
, CacLookupRidsRecord
, num_rids_out
);
594 hnd
->status
= NT_STATUS_NO_MEMORY
;
598 for(i
= 0; i
< num_rids_out
; i
++) {
600 if(rid_types_out
[i
] == SAMR_RID_UNKNOWN
) {
601 map_out
[i
].found
= False
;
606 map_out
[i
].found
= True
;
607 map_out
[i
].rid
= rids_out
[i
];
608 map_out
[i
].type
= rid_types_out
[i
];
611 map_out
[i
].name
= talloc_strdup(mem_ctx
, op
->in
.names
[i
]);
614 op
->out
.num_rids
= num_rids_out
;
615 op
->out
.map
= map_out
;
617 talloc_free(rids_out
);
618 talloc_free(rid_types_out
);
620 if(NT_STATUS_EQUAL(hnd
->status
, STATUS_SOME_UNMAPPED
))
621 return CAC_PARTIAL_SUCCESS
;
627 int cac_SamGetGroupsForUser(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetGroupsForUser
*op
) {
630 DOM_GID
*groups
= NULL
;
631 uint32 num_groups_out
= 0;
633 uint32
*rids_out
= NULL
;
634 uint32
*attr_out
= NULL
;
641 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
642 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
646 if(!op
|| !op
->in
.user_hnd
|| !mem_ctx
) {
647 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
651 srv
= cac_GetServer(hnd
);
653 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
657 srv
->cli
.pipe_idx
= PI_SAMR
;
659 hnd
->status
= cli_samr_query_usergroups(&(srv
->cli
), mem_ctx
, op
->in
.user_hnd
, &num_groups_out
, &groups
);
661 if(!NT_STATUS_IS_OK(hnd
->status
))
665 rids_out
= talloc_array(mem_ctx
, uint32
, num_groups_out
);
667 hnd
->status
= NT_STATUS_NO_MEMORY
;
671 attr_out
= talloc_array(mem_ctx
, uint32
, num_groups_out
);
673 hnd
->status
= NT_STATUS_NO_MEMORY
;
677 for(i
= 0; i
< num_groups_out
; i
++) {
678 rids_out
[i
] = groups
[i
].g_rid
;
679 attr_out
[i
] = groups
[i
].attr
;
684 op
->out
.num_groups
= num_groups_out
;
685 op
->out
.rids
= rids_out
;
686 op
->out
.attributes
= attr_out
;
692 int cac_SamOpenGroup(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamOpenGroup
*op
) {
695 POLICY_HND
*group_hnd_out
= NULL
;
700 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
701 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
705 if(!op
|| op
->in
.access
== 0 || op
->in
.rid
== 0 || !mem_ctx
) {
706 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
710 srv
= cac_GetServer(hnd
);
712 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
716 srv
->cli
.pipe_idx
= PI_SAMR
;
718 group_hnd_out
= talloc(mem_ctx
, POLICY_HND
);
720 hnd
->status
= NT_STATUS_NO_MEMORY
;
724 hnd
->status
= cli_samr_open_group( &(srv
->cli
), mem_ctx
, op
->in
.dom_hnd
, op
->in
.access
, op
->in
.rid
, group_hnd_out
);
726 if(!NT_STATUS_IS_OK(hnd
->status
))
729 op
->out
.group_hnd
= group_hnd_out
;
734 int cac_SamCreateGroup(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamCreateGroup
*op
) {
737 POLICY_HND
*group_hnd_out
= NULL
;
742 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
743 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
747 if(!op
|| !op
->in
.name
|| op
->in
.name
[0] == '\0' || op
->in
.access
== 0 || !mem_ctx
) {
748 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
752 srv
= cac_GetServer(hnd
);
754 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
758 srv
->cli
.pipe_idx
= PI_SAMR
;
760 group_hnd_out
= talloc(mem_ctx
, POLICY_HND
);
762 hnd
->status
= NT_STATUS_NO_MEMORY
;
766 hnd
->status
= cli_samr_create_dom_group( &(srv
->cli
), mem_ctx
, op
->in
.dom_hnd
, op
->in
.name
, op
->in
.access
, group_hnd_out
);
768 if(!NT_STATUS_IS_OK(hnd
->status
))
771 op
->out
.group_hnd
= group_hnd_out
;
777 int cac_SamDeleteGroup(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*group_hnd
) {
783 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
784 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
788 if(!group_hnd
|| !mem_ctx
) {
789 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
793 srv
= cac_GetServer(hnd
);
795 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
799 srv
->cli
.pipe_idx
= PI_SAMR
;
801 hnd
->status
= cli_samr_delete_dom_group( &(srv
->cli
), mem_ctx
, group_hnd
);
803 if(!NT_STATUS_IS_OK(hnd
->status
))
810 int cac_SamGetGroupMembers(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetGroupMembers
*op
) {
820 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
821 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
825 if(!op
|| !op
->in
.group_hnd
|| !mem_ctx
) {
826 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
830 srv
= cac_GetServer(hnd
);
832 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
836 srv
->cli
.pipe_idx
= PI_SAMR
;
838 hnd
->status
= cli_samr_query_groupmem( &(srv
->cli
), mem_ctx
, op
->in
.group_hnd
, &num_mem_out
, &rids_out
, &attr_out
);
840 if(!NT_STATUS_IS_OK(hnd
->status
))
843 op
->out
.num_members
= num_mem_out
;
844 op
->out
.rids
= rids_out
;
845 op
->out
.attributes
= attr_out
;
851 int cac_SamAddGroupMember(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamAddGroupMember
*op
) {
857 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
858 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
862 if(!op
|| !op
->in
.group_hnd
|| op
->in
.rid
== 0 || !mem_ctx
) {
863 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
867 srv
= cac_GetServer(hnd
);
869 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
873 srv
->cli
.pipe_idx
= PI_SAMR
;
875 hnd
->status
= cli_samr_add_groupmem( &(srv
->cli
), mem_ctx
, op
->in
.group_hnd
, op
->in
.rid
);
877 if(!NT_STATUS_IS_OK(hnd
->status
))
883 int cac_SamRemoveGroupMember(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamRemoveGroupMember
*op
) {
889 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
890 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
894 if(!op
|| !op
->in
.group_hnd
|| op
->in
.rid
== 0 || !mem_ctx
) {
895 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
899 srv
= cac_GetServer(hnd
);
901 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
905 srv
->cli
.pipe_idx
= PI_SAMR
;
907 hnd
->status
= cli_samr_del_groupmem( &(srv
->cli
), mem_ctx
, op
->in
.group_hnd
, op
->in
.rid
);
909 if(!NT_STATUS_IS_OK(hnd
->status
))
915 int cac_SamClearGroupMembers(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*group_hnd
) {
918 int result
= CAC_SUCCESS
;
931 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
932 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
936 if(!group_hnd
|| !mem_ctx
) {
937 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
941 srv
= cac_GetServer(hnd
);
943 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
947 srv
->cli
.pipe_idx
= PI_SAMR
;
949 hnd
->status
= cli_samr_query_groupmem(&(srv
->cli
), mem_ctx
, group_hnd
, &num_mem
, &rid
, &attr
);
951 if(!NT_STATUS_IS_OK(hnd
->status
))
954 /*try to delete the users one by one*/
955 for(i
= 0; i
< num_mem
&& NT_STATUS_IS_OK(hnd
->status
); i
++) {
956 hnd
->status
= cli_samr_del_groupmem(&(srv
->cli
), mem_ctx
, group_hnd
, rid
[i
]);
959 /*if not all members could be removed, then try to re-add the members that were already deleted*/
960 if(!NT_STATUS_IS_OK(hnd
->status
)) {
961 status
= NT_STATUS_OK
;
963 for(i
-= 1; i
>= 0 && NT_STATUS_IS_OK(status
); i
--) {
964 status
= cli_samr_add_groupmem( &(srv
->cli
), mem_ctx
, group_hnd
, rid
[i
]);
967 /*we return with the NTSTATUS error that we got when trying to delete users*/
968 if(!NT_STATUS_IS_OK(status
))
969 result
= CAC_FAILURE
;
977 int cac_SamSetGroupMembers(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamSetGroupMembers
*op
) {
985 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
986 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
990 if(!op
|| !op
->in
.group_hnd
|| !mem_ctx
) {
991 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
995 srv
= cac_GetServer(hnd
);
997 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1001 srv
->cli
.pipe_idx
= PI_SAMR
;
1003 /*use cac_SamClearGroupMembers() to clear them*/
1004 if(!cac_SamClearGroupMembers(hnd
, mem_ctx
, op
->in
.group_hnd
))
1005 return CAC_FAILURE
; /*hnd->status is already set*/
1008 for(i
= 0; i
< op
->in
.num_members
&& NT_STATUS_IS_OK(hnd
->status
); i
++) {
1009 hnd
->status
= cli_samr_add_groupmem( &(srv
->cli
), mem_ctx
, op
->in
.group_hnd
, op
->in
.rids
[i
]);
1012 if(!NT_STATUS_IS_OK(hnd
->status
))
1019 int cac_SamEnumGroups(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamEnumGroups
*op
) {
1020 SMBCSRV
*srv
= NULL
;
1024 uint32 resume_idx_out
= 0;
1025 char **names_out
= NULL
;
1026 char **desc_out
= NULL
;
1027 uint32
*rids_out
= NULL
;
1028 uint32 num_groups_out
= 0;
1030 struct acct_info
*acct_buf
= NULL
;
1035 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1036 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1040 if(!op
|| !op
->in
.dom_hnd
|| !mem_ctx
) {
1041 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1045 /*using this BOOL is the only reliable way to know that we are done*/
1046 if(op
->out
.done
== True
) /*we return failure so the call will break out of a loop*/
1049 srv
= cac_GetServer(hnd
);
1051 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1055 srv
->cli
.pipe_idx
= PI_SAMR
;
1057 resume_idx_out
= op
->out
.resume_idx
;
1059 hnd
->status
= cli_samr_enum_dom_groups( &(srv
->cli
), mem_ctx
, op
->in
.dom_hnd
, &resume_idx_out
, SAMR_ENUM_MAX_SIZE
,
1060 &acct_buf
, &num_groups_out
);
1063 if(NT_STATUS_IS_OK(hnd
->status
)) {
1064 op
->out
.done
= True
;
1066 else if(NT_STATUS_V(hnd
->status
) != NT_STATUS_V(STATUS_MORE_ENTRIES
)) {
1067 /*if there are no more entries, the operation will return NT_STATUS_OK.
1068 * We want to return failure if no results were returned*/
1072 names_out
= talloc_array(mem_ctx
, char *, num_groups_out
);
1074 hnd
->status
= NT_STATUS_NO_MEMORY
;
1075 talloc_free(acct_buf
);
1079 desc_out
= talloc_array(mem_ctx
, char *, num_groups_out
);
1081 hnd
->status
= NT_STATUS_NO_MEMORY
;
1082 talloc_free(acct_buf
);
1083 talloc_free(names_out
);
1087 rids_out
= talloc_array(mem_ctx
, uint32
, num_groups_out
);
1089 hnd
->status
= NT_STATUS_NO_MEMORY
;
1090 talloc_free(acct_buf
);
1091 talloc_free(names_out
);
1092 talloc_free(desc_out
);
1096 for(i
= 0; i
< num_groups_out
; i
++) {
1097 names_out
[i
] = talloc_strdup(mem_ctx
, acct_buf
[i
].acct_name
);
1098 desc_out
[i
] = talloc_strdup(mem_ctx
, acct_buf
[i
].acct_desc
);
1099 rids_out
[i
] = acct_buf
[i
].rid
;
1101 if(!names_out
[i
] || !desc_out
[i
]) {
1102 hnd
->status
= NT_STATUS_NO_MEMORY
;
1107 op
->out
.resume_idx
= resume_idx_out
;
1108 op
->out
.num_groups
= num_groups_out
;
1109 op
->out
.rids
= rids_out
;
1110 op
->out
.names
= names_out
;
1111 op
->out
.descriptions
= desc_out
;
1116 int cac_SamEnumAliases(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamEnumAliases
*op
) {
1117 SMBCSRV
*srv
= NULL
;
1121 uint32 resume_idx_out
= 0;
1122 char **names_out
= NULL
;
1123 char **desc_out
= NULL
;
1124 uint32
*rids_out
= NULL
;
1125 uint32 num_als_out
= 0;
1127 struct acct_info
*acct_buf
= NULL
;
1132 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1133 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1137 if(!op
|| !op
->in
.dom_hnd
|| !mem_ctx
) {
1138 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1142 /*this is a hack.. but is the only reliable way to know if everything has been enumerated*/
1143 if(op
->out
.done
== True
) {
1147 srv
= cac_GetServer(hnd
);
1149 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1153 srv
->cli
.pipe_idx
= PI_SAMR
;
1155 resume_idx_out
= op
->out
.resume_idx
;
1157 hnd
->status
= cli_samr_enum_als_groups( &(srv
->cli
), mem_ctx
, op
->in
.dom_hnd
, &resume_idx_out
, SAMR_ENUM_MAX_SIZE
,
1158 &acct_buf
, &num_als_out
);
1161 if(NT_STATUS_IS_OK(hnd
->status
))
1162 op
->out
.done
= True
;
1164 /*if there are no more entries, the operation will return NT_STATUS_OK.
1165 * We want to return failure if no results were returned*/
1166 if(!NT_STATUS_IS_OK(hnd
->status
) && NT_STATUS_V(hnd
->status
) != NT_STATUS_V(STATUS_MORE_ENTRIES
))
1169 names_out
= talloc_array(mem_ctx
, char *, num_als_out
);
1171 hnd
->status
= NT_STATUS_NO_MEMORY
;
1172 talloc_free(acct_buf
);
1176 desc_out
= talloc_array(mem_ctx
, char *, num_als_out
);
1178 hnd
->status
= NT_STATUS_NO_MEMORY
;
1179 talloc_free(acct_buf
);
1180 talloc_free(names_out
);
1184 rids_out
= talloc_array(mem_ctx
, uint32
, num_als_out
);
1186 hnd
->status
= NT_STATUS_NO_MEMORY
;
1187 talloc_free(acct_buf
);
1188 talloc_free(names_out
);
1189 talloc_free(desc_out
);
1193 for(i
= 0; i
< num_als_out
; i
++) {
1194 names_out
[i
] = talloc_strdup(mem_ctx
, acct_buf
[i
].acct_name
);
1195 desc_out
[i
] = talloc_strdup(mem_ctx
, acct_buf
[i
].acct_desc
);
1196 rids_out
[i
] = acct_buf
[i
].rid
;
1198 if(!names_out
[i
] || !desc_out
[i
]) {
1199 hnd
->status
= NT_STATUS_NO_MEMORY
;
1204 op
->out
.resume_idx
= resume_idx_out
;
1205 op
->out
.num_aliases
= num_als_out
;
1206 op
->out
.rids
= rids_out
;
1207 op
->out
.names
= names_out
;
1208 op
->out
.descriptions
= desc_out
;
1213 int cac_SamCreateAlias(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamCreateAlias
*op
) {
1214 SMBCSRV
*srv
= NULL
;
1216 POLICY_HND
*als_hnd_out
= NULL
;
1221 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1222 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1226 if(!op
|| !op
->in
.name
|| op
->in
.name
[0] == '\0' || !mem_ctx
) {
1227 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1231 srv
= cac_GetServer(hnd
);
1233 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1237 srv
->cli
.pipe_idx
= PI_SAMR
;
1239 als_hnd_out
= talloc(mem_ctx
, POLICY_HND
);
1241 hnd
->status
= NT_STATUS_NO_MEMORY
;
1245 hnd
->status
= cli_samr_create_dom_alias( &(srv
->cli
), mem_ctx
, op
->in
.dom_hnd
, op
->in
.name
, als_hnd_out
);
1247 if(!NT_STATUS_IS_OK(hnd
->status
))
1250 op
->out
.alias_hnd
= als_hnd_out
;
1256 int cac_SamOpenAlias(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamOpenAlias
*op
) {
1257 SMBCSRV
*srv
= NULL
;
1259 POLICY_HND
*als_hnd_out
= NULL
;
1264 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1265 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1269 if(!op
|| op
->in
.access
== 0 || op
->in
.rid
== 0 || !mem_ctx
) {
1270 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1274 srv
= cac_GetServer(hnd
);
1276 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1280 srv
->cli
.pipe_idx
= PI_SAMR
;
1282 als_hnd_out
= talloc(mem_ctx
, POLICY_HND
);
1284 hnd
->status
= NT_STATUS_NO_MEMORY
;
1288 hnd
->status
= cli_samr_open_alias( &(srv
->cli
), mem_ctx
, op
->in
.dom_hnd
, op
->in
.access
, op
->in
.rid
, als_hnd_out
);
1290 if(!NT_STATUS_IS_OK(hnd
->status
))
1293 op
->out
.alias_hnd
= als_hnd_out
;
1298 int cac_SamDeleteAlias(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*alias_hnd
) {
1299 SMBCSRV
*srv
= NULL
;
1304 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1305 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1309 if(!alias_hnd
|| !mem_ctx
) {
1310 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1314 srv
= cac_GetServer(hnd
);
1316 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1320 srv
->cli
.pipe_idx
= PI_SAMR
;
1322 hnd
->status
= cli_samr_delete_dom_alias( &(srv
->cli
), mem_ctx
, alias_hnd
);
1324 if(!NT_STATUS_IS_OK(hnd
->status
))
1331 int cac_SamAddAliasMember(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamAddAliasMember
*op
) {
1332 SMBCSRV
*srv
= NULL
;
1337 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1338 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1342 if(!op
|| !op
->in
.alias_hnd
|| !op
->in
.sid
|| !mem_ctx
) {
1343 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1347 srv
= cac_GetServer(hnd
);
1349 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1353 srv
->cli
.pipe_idx
= PI_SAMR
;
1355 hnd
->status
= cli_samr_add_aliasmem( &(srv
->cli
), mem_ctx
, op
->in
.alias_hnd
, op
->in
.sid
);
1357 if(!NT_STATUS_IS_OK(hnd
->status
))
1363 int cac_SamRemoveAliasMember(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamRemoveAliasMember
*op
) {
1364 SMBCSRV
*srv
= NULL
;
1369 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1370 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1374 if(!op
|| !op
->in
.alias_hnd
|| !op
->in
.sid
|| !mem_ctx
) {
1375 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1379 srv
= cac_GetServer(hnd
);
1381 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1385 srv
->cli
.pipe_idx
= PI_SAMR
;
1387 hnd
->status
= cli_samr_del_aliasmem( &(srv
->cli
), mem_ctx
, op
->in
.alias_hnd
, op
->in
.sid
);
1389 if(!NT_STATUS_IS_OK(hnd
->status
))
1395 int cac_SamGetAliasMembers(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetAliasMembers
*op
) {
1396 SMBCSRV
*srv
= NULL
;
1404 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1405 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1409 if(!op
|| !op
->in
.alias_hnd
|| !mem_ctx
) {
1410 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1414 srv
= cac_GetServer(hnd
);
1416 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1420 srv
->cli
.pipe_idx
= PI_SAMR
;
1422 hnd
->status
= cli_samr_query_aliasmem( &(srv
->cli
), mem_ctx
, op
->in
.alias_hnd
, &num_mem_out
, &sids_out
);
1424 if(!NT_STATUS_IS_OK(hnd
->status
))
1427 op
->out
.num_members
= num_mem_out
;
1428 op
->out
.sids
= sids_out
;
1433 int cac_SamClearAliasMembers(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*alias_hnd
) {
1434 SMBCSRV
*srv
= NULL
;
1436 int result
= CAC_SUCCESS
;
1441 DOM_SID
*sid
= NULL
;
1448 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1449 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1453 if(!alias_hnd
|| !mem_ctx
) {
1454 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1458 srv
= cac_GetServer(hnd
);
1460 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1464 srv
->cli
.pipe_idx
= PI_SAMR
;
1466 hnd
->status
= cli_samr_query_aliasmem(&(srv
->cli
), mem_ctx
, alias_hnd
, &num_mem
, &sid
);
1468 if(!NT_STATUS_IS_OK(hnd
->status
))
1471 /*try to delete the users one by one*/
1472 for(i
= 0; i
< num_mem
&& NT_STATUS_IS_OK(hnd
->status
); i
++) {
1473 hnd
->status
= cli_samr_del_aliasmem(&(srv
->cli
), mem_ctx
, alias_hnd
, &sid
[i
]);
1476 /*if not all members could be removed, then try to re-add the members that were already deleted*/
1477 if(!NT_STATUS_IS_OK(hnd
->status
)) {
1478 status
= NT_STATUS_OK
;
1480 for(i
-= 1; i
>= 0 && NT_STATUS_IS_OK(status
); i
--) {
1481 status
= cli_samr_add_aliasmem( &(srv
->cli
), mem_ctx
, alias_hnd
, &sid
[i
]);
1484 /*we return with the NTSTATUS error that we got when trying to delete users*/
1485 if(!NT_STATUS_IS_OK(status
))
1486 result
= CAC_FAILURE
;
1493 int cac_SamSetAliasMembers(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamSetAliasMembers
*op
) {
1494 SMBCSRV
*srv
= NULL
;
1501 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1502 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1506 if(!op
|| !op
->in
.alias_hnd
|| !mem_ctx
) {
1507 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1511 srv
= cac_GetServer(hnd
);
1513 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1517 srv
->cli
.pipe_idx
= PI_SAMR
;
1519 /*use cac_SamClearAliasMembers() to clear them*/
1520 if(!cac_SamClearAliasMembers(hnd
, mem_ctx
, op
->in
.alias_hnd
))
1521 return CAC_FAILURE
; /*hnd->status is already set*/
1524 for(i
= 0; i
< op
->in
.num_members
&& NT_STATUS_IS_OK(hnd
->status
); i
++) {
1525 hnd
->status
= cli_samr_add_aliasmem( &(srv
->cli
), mem_ctx
, op
->in
.alias_hnd
, &(op
->in
.sids
[i
]));
1528 if(!NT_STATUS_IS_OK(hnd
->status
))
1535 int cac_SamUserChangePasswd(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamUserChangePasswd
*op
) {
1536 SMBCSRV
*srv
= NULL
;
1541 if(!hnd
->_internal
.ctx
) {
1542 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1546 if(!op
|| !op
->in
.username
|| !op
->in
.password
|| !op
->in
.new_password
|| !mem_ctx
) {
1547 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1551 srv
= cac_GetServer(hnd
);
1553 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1557 /*open a session on SAMR if we don't have one*/
1558 if(!hnd
->_internal
.pipes
[PI_SAMR
]) {
1559 if(!cli_nt_session_open(&srv
->cli
, PI_SAMR
)) {
1560 hnd
->status
= NT_STATUS_UNSUCCESSFUL
;
1564 hnd
->_internal
.pipes
[PI_SAMR
] = True
;
1567 srv
->cli
.pipe_idx
= PI_SAMR
;
1569 hnd
->status
= cli_samr_chgpasswd_user(&(srv
->cli
), mem_ctx
, op
->in
.username
, op
->in
.new_password
, op
->in
.password
);
1571 if(!NT_STATUS_IS_OK(hnd
->status
))
1577 int cac_SamEnableUser(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*user_hnd
) {
1578 SMBCSRV
*srv
= NULL
;
1580 SAM_USERINFO_CTR
*ctr
;
1585 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1586 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1590 if(!user_hnd
|| !mem_ctx
) {
1591 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1595 srv
= cac_GetServer(hnd
);
1597 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1601 srv
->cli
.pipe_idx
= PI_SAMR
;
1603 /*info_level = 21 is the only level that I have found to work reliably. It would be nice if user_level = 10 worked.*/
1604 hnd
->status
= cli_samr_query_userinfo( &(srv
->cli
), mem_ctx
, user_hnd
, 0x10, &ctr
);
1606 if(!NT_STATUS_IS_OK(hnd
->status
))
1609 /**check the ACB mask*/
1610 if((ctr
->info
.id16
->acb_info
& ACB_DISABLED
) == ACB_DISABLED
) {
1611 /*toggle the disabled bit*/
1612 ctr
->info
.id16
->acb_info
^= ACB_DISABLED
;
1615 /*the user is already enabled so just return success*/
1619 /*now set the userinfo*/
1620 hnd
->status
= cli_samr_set_userinfo2( &(srv
->cli
), mem_ctx
, user_hnd
, 0x10, &(srv
->cli
.user_session_key
), ctr
);
1622 /*this will only work properly if we use set_userinfo2 - fail if it is not supported*/
1623 if(!NT_STATUS_IS_OK(hnd
->status
))
1629 int cac_SamDisableUser(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, POLICY_HND
*user_hnd
) {
1630 SMBCSRV
*srv
= NULL
;
1632 SAM_USERINFO_CTR
*ctr
;
1637 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1638 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1642 if(!user_hnd
|| !mem_ctx
) {
1643 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1647 srv
= cac_GetServer(hnd
);
1649 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1653 srv
->cli
.pipe_idx
= PI_SAMR
;
1655 hnd
->status
= cli_samr_query_userinfo( &(srv
->cli
), mem_ctx
, user_hnd
, 0x10, &ctr
);
1657 if(!NT_STATUS_IS_OK(hnd
->status
))
1660 if((ctr
->info
.id16
->acb_info
& ACB_DISABLED
) == ACB_DISABLED
) {
1661 /*then the user is already disabled*/
1665 /*toggle the disabled bit*/
1666 ctr
->info
.id16
->acb_info
^= ACB_DISABLED
;
1668 /*this will only work properly if we use set_userinfo2*/
1669 hnd
->status
= cli_samr_set_userinfo2( &(srv
->cli
), mem_ctx
, user_hnd
, 0x10, &(srv
->cli
.user_session_key
), ctr
);
1671 /*this will only work properly if we use set_userinfo2 fail if it is not supported*/
1672 if(!NT_STATUS_IS_OK(hnd
->status
))
1678 int cac_SamSetPassword(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamSetPassword
*op
) {
1679 SMBCSRV
*srv
= NULL
;
1681 SAM_USERINFO_CTR ctr
;
1682 SAM_USER_INFO_24 info24
;
1688 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1689 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1693 if(!op
->in
.user_hnd
|| !op
->in
.password
|| !mem_ctx
) {
1694 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1698 srv
= cac_GetServer(hnd
);
1700 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1704 srv
->cli
.pipe_idx
= PI_SAMR
;
1707 ZERO_STRUCT(info24
);
1709 encode_pw_buffer(pw
, op
->in
.password
, STR_UNICODE
);
1711 init_sam_user_info24(&info24
, (char *)pw
, 24);
1713 ctr
.switch_value
= 24;
1714 ctr
.info
.id24
= &info24
;
1716 hnd
->status
= cli_samr_set_userinfo( &(srv
->cli
), mem_ctx
, op
->in
.user_hnd
, 24, &(srv
->cli
.user_session_key
), &ctr
);
1718 if(!NT_STATUS_IS_OK(hnd
->status
))
1724 int cac_SamGetUserInfo(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetUserInfo
*op
) {
1725 SMBCSRV
*srv
= NULL
;
1727 SAM_USERINFO_CTR
*ctr
;
1732 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1733 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1737 if(!op
->in
.user_hnd
|| !mem_ctx
) {
1738 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1742 srv
= cac_GetServer(hnd
);
1744 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1748 srv
->cli
.pipe_idx
= PI_SAMR
;
1750 hnd
->status
= cli_samr_query_userinfo( &(srv
->cli
), mem_ctx
, op
->in
.user_hnd
, 21, &ctr
);
1752 if(!NT_STATUS_IS_OK(hnd
->status
))
1755 op
->out
.info
= cac_MakeUserInfo(mem_ctx
, ctr
);
1758 hnd
->status
= NT_STATUS_NO_MEMORY
;
1765 int cac_SamSetUserInfo(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamSetUserInfo
*op
) {
1766 SMBCSRV
*srv
= NULL
;
1768 SAM_USERINFO_CTR
*ctr
;
1773 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1774 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1778 if(!op
->in
.user_hnd
|| !op
->in
.info
|| !mem_ctx
) {
1779 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1783 ctr
= cac_MakeUserInfoCtr(mem_ctx
, op
->in
.info
);
1785 hnd
->status
= NT_STATUS_NO_MEMORY
;
1789 srv
= cac_GetServer(hnd
);
1791 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1795 srv
->cli
.pipe_idx
= PI_SAMR
;
1797 if(hnd
->_internal
.srv_level
>= SRV_WIN_NT4
) {
1798 hnd
->status
= cli_samr_set_userinfo2( &(srv
->cli
), mem_ctx
, op
->in
.user_hnd
, 21, &(srv
->cli
.user_session_key
), ctr
);
1801 if(hnd
->_internal
.srv_level
< SRV_WIN_NT4
|| !NT_STATUS_IS_OK(hnd
->status
)) {
1802 hnd
->status
= cli_samr_set_userinfo( &(srv
->cli
), mem_ctx
, op
->in
.user_hnd
, 21, &(srv
->cli
.user_session_key
), ctr
);
1804 if(NT_STATUS_IS_OK(hnd
->status
) && hnd
->_internal
.srv_level
> SRV_WIN_NT4
) {
1805 hnd
->_internal
.srv_level
= SRV_WIN_NT4
;
1810 if(!NT_STATUS_IS_OK(hnd
->status
))
1817 int cac_SamGetUserInfoCtr(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetUserInfoCtr
*op
) {
1818 SMBCSRV
*srv
= NULL
;
1820 SAM_USERINFO_CTR
*ctr_out
;
1825 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1826 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1830 if(!op
->in
.user_hnd
|| op
->in
.info_class
== 0 || !mem_ctx
) {
1831 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1835 srv
= cac_GetServer(hnd
);
1837 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1841 srv
->cli
.pipe_idx
= PI_SAMR
;
1843 hnd
->status
= cli_samr_query_userinfo( &(srv
->cli
), mem_ctx
, op
->in
.user_hnd
, op
->in
.info_class
, &ctr_out
);
1845 if(!NT_STATUS_IS_OK(hnd
->status
))
1848 op
->out
.ctr
= ctr_out
;
1853 int cac_SamSetUserInfoCtr(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamSetUserInfoCtr
*op
) {
1854 SMBCSRV
*srv
= NULL
;
1859 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1860 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1864 if(!op
->in
.user_hnd
|| !op
->in
.ctr
|| !mem_ctx
) {
1865 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1869 srv
= cac_GetServer(hnd
);
1871 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1875 srv
->cli
.pipe_idx
= PI_SAMR
;
1878 hnd
->status
= cli_samr_set_userinfo( &(srv
->cli
), mem_ctx
, op
->in
.user_hnd
, op
->in
.ctr
->switch_value
, &(srv
->cli
.user_session_key
), op
->in
.ctr
);
1880 if(!NT_STATUS_IS_OK(hnd
->status
))
1887 int cac_SamRenameUser(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamRenameUser
*op
) {
1888 SMBCSRV
*srv
= NULL
;
1890 SAM_USERINFO_CTR ctr
;
1891 SAM_USER_INFO_7 info7
;
1896 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1897 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1901 if(!op
->in
.user_hnd
|| !op
->in
.new_name
|| op
->in
.new_name
[0] == '\0' || !mem_ctx
) {
1902 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1906 srv
= cac_GetServer(hnd
);
1908 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1912 srv
->cli
.pipe_idx
= PI_SAMR
;
1917 init_sam_user_info7(&info7
, op
->in
.new_name
);
1919 ctr
.switch_value
= 7;
1920 ctr
.info
.id7
= &info7
;
1922 hnd
->status
= cli_samr_set_userinfo( &(srv
->cli
), mem_ctx
, op
->in
.user_hnd
, 7, &(srv
->cli
.user_session_key
), &ctr
);
1924 if(!NT_STATUS_IS_OK(hnd
->status
))
1931 int cac_SamGetGroupInfo(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetGroupInfo
*op
) {
1932 SMBCSRV
*srv
= NULL
;
1934 GROUP_INFO_CTR
*ctr
;
1939 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1940 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1944 if(!op
->in
.group_hnd
|| !mem_ctx
) {
1945 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1949 srv
= cac_GetServer(hnd
);
1951 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
1955 srv
->cli
.pipe_idx
= PI_SAMR
;
1957 /*get a GROUP_INFO_1 structure*/
1958 hnd
->status
= cli_samr_query_groupinfo( &(srv
->cli
), mem_ctx
, op
->in
.group_hnd
, 1, &ctr
);
1960 if(!NT_STATUS_IS_OK(hnd
->status
))
1963 op
->out
.info
= cac_MakeGroupInfo(mem_ctx
, ctr
);
1965 hnd
->status
= NT_STATUS_NO_MEMORY
;
1972 int cac_SamSetGroupInfo(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamSetGroupInfo
*op
) {
1973 SMBCSRV
*srv
= NULL
;
1975 GROUP_INFO_CTR
*ctr
= NULL
;
1980 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
1981 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
1985 if(!op
->in
.group_hnd
|| !op
->in
.info
|| !mem_ctx
) {
1986 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
1990 ctr
= cac_MakeGroupInfoCtr(mem_ctx
, op
->in
.info
);
1992 hnd
->status
= NT_STATUS_NO_MEMORY
;
1996 srv
= cac_GetServer(hnd
);
1998 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
2002 srv
->cli
.pipe_idx
= PI_SAMR
;
2004 hnd
->status
= cli_samr_set_groupinfo(&(srv
->cli
), mem_ctx
, op
->in
.group_hnd
, ctr
);
2006 if(!NT_STATUS_IS_OK(hnd
->status
))
2012 int cac_SamRenameGroup(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamRenameGroup
*op
) {
2013 SMBCSRV
*srv
= NULL
;
2020 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
2021 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2025 if(!op
->in
.group_hnd
|| !op
->in
.new_name
|| op
->in
.new_name
[0] == '\0' || !mem_ctx
) {
2026 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2030 srv
= cac_GetServer(hnd
);
2032 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
2036 srv
->cli
.pipe_idx
= PI_SAMR
;
2040 init_samr_group_info2(&ctr
.group
.info2
, op
->in
.new_name
);
2041 ctr
.switch_value1
= 2;
2043 hnd
->status
= cli_samr_set_groupinfo( &(srv
->cli
), mem_ctx
, op
->in
.group_hnd
, &ctr
);
2045 if(!NT_STATUS_IS_OK(hnd
->status
))
2051 int cac_SamGetAliasInfo(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetAliasInfo
*op
) {
2052 SMBCSRV
*srv
= NULL
;
2059 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
2060 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2064 if(!op
->in
.alias_hnd
|| !mem_ctx
) {
2065 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2069 srv
= cac_GetServer(hnd
);
2071 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
2075 srv
->cli
.pipe_idx
= PI_SAMR
;
2077 /*get a GROUP_INFO_1 structure*/
2078 hnd
->status
= cli_samr_query_alias_info( &(srv
->cli
), mem_ctx
, op
->in
.alias_hnd
, 1, &ctr
);
2080 if(!NT_STATUS_IS_OK(hnd
->status
))
2083 op
->out
.info
= cac_MakeAliasInfo(mem_ctx
, ctr
);
2085 hnd
->status
= NT_STATUS_NO_MEMORY
;
2093 int cac_SamSetAliasInfo(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamSetAliasInfo
*op
) {
2094 SMBCSRV
*srv
= NULL
;
2096 ALIAS_INFO_CTR
*ctr
= NULL
;
2101 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
2102 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2106 if(!op
->in
.alias_hnd
|| !op
->in
.info
|| !mem_ctx
) {
2107 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2111 ctr
= cac_MakeAliasInfoCtr(mem_ctx
, op
->in
.info
);
2113 hnd
->status
= NT_STATUS_NO_MEMORY
;
2117 srv
= cac_GetServer(hnd
);
2119 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
2123 srv
->cli
.pipe_idx
= PI_SAMR
;
2125 hnd
->status
= cli_samr_set_aliasinfo(&(srv
->cli
), mem_ctx
, op
->in
.alias_hnd
, ctr
);
2127 if(!NT_STATUS_IS_OK(hnd
->status
))
2133 int cac_SamGetDomainInfo(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetDomainInfo
*op
) {
2134 SMBCSRV
*srv
= NULL
;
2137 SAM_UNK_INFO_1 info1
;
2138 SAM_UNK_INFO_2 info2
;
2139 SAM_UNK_INFO_12 info12
;
2141 /*use this to keep track of a failed call*/
2142 NTSTATUS status_buf
= NT_STATUS_OK
;
2144 uint16 fail_count
= 0;
2150 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
2151 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2155 if(!op
->in
.dom_hnd
|| !mem_ctx
) {
2156 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2160 srv
= cac_GetServer(hnd
);
2162 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
2166 srv
->cli
.pipe_idx
= PI_SAMR
;
2168 /*first try with info 1*/
2169 hnd
->status
= cli_samr_query_dom_info( &(srv
->cli
), mem_ctx
, op
->in
.dom_hnd
, 1, &ctr
);
2171 if(NT_STATUS_IS_OK(hnd
->status
)) {
2172 /*then we buffer the SAM_UNK_INFO_1 structure*/
2173 info1
= ctr
.info
.inf1
;
2176 /*then the call failed, store the status and ZERO out the info structure*/
2178 status_buf
= hnd
->status
;
2182 /*try again for the next one*/
2183 hnd
->status
= cli_samr_query_dom_info( &(srv
->cli
), mem_ctx
, op
->in
.dom_hnd
, 2, &ctr
);
2185 if(NT_STATUS_IS_OK(hnd
->status
)) {
2187 info2
= ctr
.info
.inf2
;
2190 /*ZERO out the structure and store the bad status*/
2192 status_buf
= hnd
->status
;
2197 hnd
->status
= cli_samr_query_dom_info( &(srv
->cli
), mem_ctx
, op
->in
.dom_hnd
, 12, &ctr
);
2199 if(NT_STATUS_IS_OK(hnd
->status
)) {
2200 info12
= ctr
.info
.inf12
;
2203 ZERO_STRUCT(info12
);
2204 status_buf
= hnd
->status
;
2208 /*return failure if all 3 calls failed*/
2212 op
->out
.info
= cac_MakeDomainInfo(mem_ctx
, &info1
, &info2
, &info12
);
2215 hnd
->status
= NT_STATUS_NO_MEMORY
;
2219 if(fail_count
> 0) {
2220 hnd
->status
= status_buf
;
2221 return CAC_PARTIAL_SUCCESS
;
2227 int cac_SamGetDomainInfoCtr(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetDomainInfoCtr
*op
) {
2228 SMBCSRV
*srv
= NULL
;
2230 SAM_UNK_CTR
*ctr_out
;
2235 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
2236 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2240 if(!op
->in
.dom_hnd
|| op
->in
.info_class
== 0 || !mem_ctx
) {
2241 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2245 srv
= cac_GetServer(hnd
);
2247 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
2251 srv
->cli
.pipe_idx
= PI_SAMR
;
2253 ctr_out
= talloc(mem_ctx
, SAM_UNK_CTR
);
2255 hnd
->status
= NT_STATUS_NO_MEMORY
;
2259 hnd
->status
= cli_samr_query_dom_info( &(srv
->cli
), mem_ctx
, op
->in
.dom_hnd
, op
->in
.info_class
, ctr_out
);
2261 if(!NT_STATUS_IS_OK(hnd
->status
))
2264 op
->out
.info
= ctr_out
;
2269 int cac_SamGetDisplayInfo(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetDisplayInfo
*op
) {
2270 SMBCSRV
*srv
= NULL
;
2272 SAM_DISPINFO_CTR ctr_out
;
2274 uint32 max_entries_buf
= 0;
2275 uint32 max_size_buf
= 0;
2277 uint32 resume_idx_out
;
2278 uint32 num_entries_out
;
2283 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
2284 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2288 if(!op
->in
.dom_hnd
|| op
->in
.info_class
== 0 || !mem_ctx
) {
2289 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2293 if(op
->out
.done
== True
) /*this is done so we can use the function as a loop condition*/
2296 srv
= cac_GetServer(hnd
);
2298 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
2302 srv
->cli
.pipe_idx
= PI_SAMR
;
2304 if(op
->in
.max_entries
== 0 || op
->in
.max_size
== 0) {
2305 get_query_dispinfo_params(op
->out
.loop_count
, &max_entries_buf
, &max_size_buf
);
2308 max_entries_buf
= op
->in
.max_entries
;
2309 max_size_buf
= op
->in
.max_size
;
2312 resume_idx_out
= op
->out
.resume_idx
;
2314 hnd
->status
= cli_samr_query_dispinfo( &(srv
->cli
), mem_ctx
, op
->in
.dom_hnd
, &resume_idx_out
, op
->in
.info_class
,
2315 &num_entries_out
, max_entries_buf
, max_size_buf
, &ctr_out
);
2317 if(!NT_STATUS_IS_OK(hnd
->status
) && !NT_STATUS_EQUAL(hnd
->status
, STATUS_MORE_ENTRIES
)) {
2318 /*be defensive, maybe they'll call again without zeroing the struct*/
2319 op
->out
.loop_count
= 0;
2320 op
->out
.resume_idx
= 0;
2324 if(NT_STATUS_IS_OK(hnd
->status
)) {
2325 /*we want to quit once the function is called next. so it can be used in a loop*/
2326 op
->out
.done
= True
;
2329 op
->out
.resume_idx
= resume_idx_out
;
2330 op
->out
.num_entries
= num_entries_out
;
2331 op
->out
.ctr
= ctr_out
;
2332 op
->out
.loop_count
++;
2337 int cac_SamLookupDomain(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamLookupDomain
*op
) {
2338 SMBCSRV
*srv
= NULL
;
2340 DOM_SID
*sid_out
= NULL
;
2345 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
2346 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2350 if(!op
->in
.sam
|| !op
->in
.name
|| !mem_ctx
) {
2351 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2355 srv
= cac_GetServer(hnd
);
2357 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
2361 srv
->cli
.pipe_idx
= PI_SAMR
;
2363 sid_out
= talloc(mem_ctx
, DOM_SID
);
2365 hnd
->status
= NT_STATUS_NO_MEMORY
;
2369 hnd
->status
= cli_samr_lookup_domain( &(srv
->cli
), mem_ctx
, op
->in
.sam
, op
->in
.name
, sid_out
);
2371 if(!NT_STATUS_IS_OK(hnd
->status
))
2374 op
->out
.sid
= sid_out
;
2379 int cac_SamGetSecurityObject(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamGetSecurityObject
*op
) {
2380 SMBCSRV
*srv
= NULL
;
2382 /*this number taken from rpcclient/cmd_samr.c, I think it is the only supported level*/
2383 uint16 info_level
= 4;
2385 SEC_DESC_BUF
*sec_out
= NULL
;
2390 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
2391 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2395 if(!op
->in
.pol
|| !mem_ctx
) {
2396 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2400 srv
= cac_GetServer(hnd
);
2402 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
2406 srv
->cli
.pipe_idx
= PI_SAMR
;
2408 hnd
->status
= cli_samr_query_sec_obj(&(srv
->cli
), mem_ctx
, op
->in
.pol
, info_level
, mem_ctx
, &sec_out
);
2410 if(!NT_STATUS_IS_OK(hnd
->status
))
2413 op
->out
.sec
= sec_out
;
2418 int cac_SamFlush(CacServerHandle
*hnd
, TALLOC_CTX
*mem_ctx
, struct SamFlush
*op
) {
2419 SMBCSRV
*srv
= NULL
;
2421 struct SamOpenDomain od
;
2426 if(!hnd
->_internal
.ctx
|| !hnd
->_internal
.pipes
[PI_SAMR
]) {
2427 hnd
->status
= NT_STATUS_INVALID_HANDLE
;
2431 if(!op
|| !op
->in
.dom_hnd
|| !mem_ctx
) {
2432 hnd
->status
= NT_STATUS_INVALID_PARAMETER
;
2436 srv
= cac_GetServer(hnd
);
2438 hnd
->status
= NT_STATUS_INVALID_CONNECTION
;
2442 srv
->cli
.pipe_idx
= PI_SAMR
;
2444 if(!cac_SamClose(hnd
, mem_ctx
, op
->in
.dom_hnd
))
2448 od
.in
.access
= (op
->in
.access
) ? op
->in
.access
: MAXIMUM_ALLOWED_ACCESS
;
2449 od
.in
.sid
= op
->in
.sid
;
2451 if(!cac_SamOpenDomain(hnd
, mem_ctx
, &od
))
2454 /*this function does not use an output parameter to make it as convenient as possible to use*/
2455 *op
->in
.dom_hnd
= *od
.out
.dom_hnd
;
2457 talloc_free(od
.out
.dom_hnd
);