2 Unix SMB/CIFS implementation.
4 Copyright (C) Volker Lendecke 2009
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 3 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, see <http://www.gnu.org/licenses/>.
22 #include "librpc/gen_ndr/cli_wbint.h"
24 struct wb_gettoken_state
{
25 struct tevent_context
*ev
;
26 struct dom_sid usersid
;
31 static bool wb_add_rids_to_sids(TALLOC_CTX
*mem_ctx
,
32 int *pnum_sids
, struct dom_sid
**psids
,
33 const struct dom_sid
*domain_sid
,
34 int num_rids
, uint32_t *rids
);
36 static void wb_gettoken_gotgroups(struct tevent_req
*subreq
);
37 static void wb_gettoken_gotlocalgroups(struct tevent_req
*subreq
);
38 static void wb_gettoken_gotbuiltins(struct tevent_req
*subreq
);
40 struct tevent_req
*wb_gettoken_send(TALLOC_CTX
*mem_ctx
,
41 struct tevent_context
*ev
,
42 const struct dom_sid
*sid
)
44 struct tevent_req
*req
, *subreq
;
45 struct wb_gettoken_state
*state
;
46 struct winbindd_domain
*domain
;
48 req
= tevent_req_create(mem_ctx
, &state
, struct wb_gettoken_state
);
52 sid_copy(&state
->usersid
, sid
);
55 domain
= find_domain_from_sid_noinit(sid
);
57 DEBUG(5, ("Could not find domain from SID %s\n",
58 sid_string_dbg(sid
)));
59 tevent_req_nterror(req
, NT_STATUS_NO_SUCH_USER
);
60 return tevent_req_post(req
, ev
);
63 subreq
= wb_lookupusergroups_send(state
, ev
, domain
, &state
->usersid
);
64 if (tevent_req_nomem(subreq
, req
)) {
65 return tevent_req_post(req
, ev
);
67 tevent_req_set_callback(subreq
, wb_gettoken_gotgroups
, req
);
71 static void wb_gettoken_gotgroups(struct tevent_req
*subreq
)
73 struct tevent_req
*req
= tevent_req_callback_data(
74 subreq
, struct tevent_req
);
75 struct wb_gettoken_state
*state
= tevent_req_data(
76 req
, struct wb_gettoken_state
);
78 struct winbindd_domain
*domain
;
81 status
= wb_lookupusergroups_recv(subreq
, state
, &state
->num_sids
,
84 if (!NT_STATUS_IS_OK(status
)) {
85 tevent_req_nterror(req
, status
);
89 sids
= talloc_realloc(state
, state
->sids
, struct dom_sid
,
91 if (tevent_req_nomem(sids
, req
)) {
94 memmove(&sids
[1], &sids
[0], state
->num_sids
* sizeof(sids
[0]));
95 sid_copy(&sids
[0], &state
->usersid
);
100 * Expand our domain's aliases
102 domain
= find_our_domain();
103 if (domain
== NULL
) {
104 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
108 subreq
= wb_lookupuseraliases_send(state
, state
->ev
, domain
,
109 state
->num_sids
, state
->sids
);
110 if (tevent_req_nomem(subreq
, req
)) {
113 tevent_req_set_callback(subreq
, wb_gettoken_gotlocalgroups
, req
);
116 static void wb_gettoken_gotlocalgroups(struct tevent_req
*subreq
)
118 struct tevent_req
*req
= tevent_req_callback_data(
119 subreq
, struct tevent_req
);
120 struct wb_gettoken_state
*state
= tevent_req_data(
121 req
, struct wb_gettoken_state
);
124 struct winbindd_domain
*domain
;
127 status
= wb_lookupuseraliases_recv(subreq
, state
, &num_rids
, &rids
);
129 if (!NT_STATUS_IS_OK(status
)) {
130 tevent_req_nterror(req
, status
);
133 domain
= find_our_domain();
134 if (!wb_add_rids_to_sids(state
, &state
->num_sids
, &state
->sids
,
135 &domain
->sid
, num_rids
, rids
)) {
136 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
142 * Now expand the builtin groups
145 domain
= find_builtin_domain();
146 if (domain
== NULL
) {
147 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
151 subreq
= wb_lookupuseraliases_send(state
, state
->ev
, domain
,
152 state
->num_sids
, state
->sids
);
153 if (tevent_req_nomem(subreq
, req
)) {
156 tevent_req_set_callback(subreq
, wb_gettoken_gotbuiltins
, req
);
159 static void wb_gettoken_gotbuiltins(struct tevent_req
*subreq
)
161 struct tevent_req
*req
= tevent_req_callback_data(
162 subreq
, struct tevent_req
);
163 struct wb_gettoken_state
*state
= tevent_req_data(
164 req
, struct wb_gettoken_state
);
169 status
= wb_lookupuseraliases_recv(subreq
, state
, &num_rids
, &rids
);
171 if (!NT_STATUS_IS_OK(status
)) {
172 tevent_req_nterror(req
, status
);
175 if (!wb_add_rids_to_sids(state
, &state
->num_sids
, &state
->sids
,
176 &global_sid_Builtin
, num_rids
, rids
)) {
177 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
180 tevent_req_done(req
);
183 NTSTATUS
wb_gettoken_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
184 int *num_sids
, struct dom_sid
**sids
)
186 struct wb_gettoken_state
*state
= tevent_req_data(
187 req
, struct wb_gettoken_state
);
190 if (tevent_req_is_nterror(req
, &status
)) {
193 *num_sids
= state
->num_sids
;
194 *sids
= talloc_move(mem_ctx
, &state
->sids
);
198 static bool wb_add_rids_to_sids(TALLOC_CTX
*mem_ctx
,
199 int *pnum_sids
, struct dom_sid
**psids
,
200 const struct dom_sid
*domain_sid
,
201 int num_rids
, uint32_t *rids
)
203 struct dom_sid
*sids
;
206 sids
= talloc_realloc(mem_ctx
, *psids
, struct dom_sid
,
207 *pnum_sids
+ num_rids
);
211 for (i
=0; i
<num_rids
; i
++) {
212 sid_compose(&sids
[i
+*pnum_sids
], domain_sid
, rids
[i
]);
215 *pnum_sids
+= num_rids
;