auth/spnego: call gensec_spnego_create_negTokenInit() directly in gensec_spnego_updat...
[Samba.git] / source3 / winbindd / wb_gettoken.c
bloba393b0f09e773739ee4e440886f952c7b9a6a68f
1 /*
2 Unix SMB/CIFS implementation.
3 async gettoken
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/>.
20 #include "includes.h"
21 #include "winbindd.h"
22 #include "librpc/gen_ndr/ndr_winbind_c.h"
23 #include "../libcli/security/security.h"
24 #include "passdb/machine_sid.h"
26 struct wb_gettoken_state {
27 struct tevent_context *ev;
28 struct dom_sid usersid;
29 bool expand_local_aliases;
30 uint32_t num_sids;
31 struct dom_sid *sids;
34 static NTSTATUS wb_add_rids_to_sids(TALLOC_CTX *mem_ctx,
35 uint32_t *pnum_sids,
36 struct dom_sid **psids,
37 const struct dom_sid *domain_sid,
38 int num_rids, uint32_t *rids);
40 static void wb_gettoken_gotuser(struct tevent_req *subreq);
41 static void wb_gettoken_gotgroups(struct tevent_req *subreq);
42 static void wb_gettoken_gotlocalgroups(struct tevent_req *subreq);
43 static void wb_gettoken_gotbuiltins(struct tevent_req *subreq);
45 struct tevent_req *wb_gettoken_send(TALLOC_CTX *mem_ctx,
46 struct tevent_context *ev,
47 const struct dom_sid *sid,
48 bool expand_local_aliases)
50 struct tevent_req *req, *subreq;
51 struct wb_gettoken_state *state;
53 req = tevent_req_create(mem_ctx, &state, struct wb_gettoken_state);
54 if (req == NULL) {
55 return NULL;
57 sid_copy(&state->usersid, sid);
58 state->ev = ev;
59 state->expand_local_aliases = expand_local_aliases;
61 subreq = wb_queryuser_send(state, ev, &state->usersid);
62 if (tevent_req_nomem(subreq, req)) {
63 return tevent_req_post(req, ev);
65 tevent_req_set_callback(subreq, wb_gettoken_gotuser, req);
66 return req;
69 static void wb_gettoken_gotuser(struct tevent_req *subreq)
71 struct tevent_req *req = tevent_req_callback_data(
72 subreq, struct tevent_req);
73 struct wb_gettoken_state *state = tevent_req_data(
74 req, struct wb_gettoken_state);
75 struct wbint_userinfo *info;
76 NTSTATUS status;
78 status = wb_queryuser_recv(subreq, state, &info);
79 TALLOC_FREE(subreq);
80 if (tevent_req_nterror(req, status)) {
81 return;
84 state->sids = talloc_array(state, struct dom_sid, 2);
85 if (tevent_req_nomem(state->sids, req)) {
86 return;
88 state->num_sids = 2;
90 sid_copy(&state->sids[0], &info->user_sid);
91 sid_copy(&state->sids[1], &info->group_sid);
93 subreq = wb_lookupusergroups_send(state, state->ev, &info->user_sid);
94 if (tevent_req_nomem(subreq, req)) {
95 return;
97 tevent_req_set_callback(subreq, wb_gettoken_gotgroups, req);
100 static void wb_gettoken_gotgroups(struct tevent_req *subreq)
102 struct tevent_req *req = tevent_req_callback_data(
103 subreq, struct tevent_req);
104 struct wb_gettoken_state *state = tevent_req_data(
105 req, struct wb_gettoken_state);
106 int i, num_groups;
107 struct dom_sid *groups;
108 struct winbindd_domain *domain;
109 NTSTATUS status;
111 status = wb_lookupusergroups_recv(subreq, state, &num_groups, &groups);
112 TALLOC_FREE(subreq);
113 if (!NT_STATUS_IS_OK(status)) {
114 tevent_req_done(req);
115 return;
118 for (i=0; i<num_groups; i++) {
119 status = add_sid_to_array_unique(
120 state, &groups[i], &state->sids, &state->num_sids);
122 if (tevent_req_nterror(req, status)) {
123 return;
127 if (!state->expand_local_aliases) {
128 tevent_req_done(req);
129 return;
133 * Expand our domain's aliases
135 domain = find_domain_from_sid_noinit(get_global_sam_sid());
136 if (domain == NULL) {
137 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
138 return;
141 subreq = wb_lookupuseraliases_send(state, state->ev, domain,
142 state->num_sids, state->sids);
143 if (tevent_req_nomem(subreq, req)) {
144 return;
146 tevent_req_set_callback(subreq, wb_gettoken_gotlocalgroups, req);
149 static void wb_gettoken_gotlocalgroups(struct tevent_req *subreq)
151 struct tevent_req *req = tevent_req_callback_data(
152 subreq, struct tevent_req);
153 struct wb_gettoken_state *state = tevent_req_data(
154 req, struct wb_gettoken_state);
155 uint32_t num_rids;
156 uint32_t *rids;
157 struct winbindd_domain *domain;
158 NTSTATUS status;
160 status = wb_lookupuseraliases_recv(subreq, state, &num_rids, &rids);
161 TALLOC_FREE(subreq);
162 if (tevent_req_nterror(req, status)) {
163 return;
166 status = wb_add_rids_to_sids(state, &state->num_sids, &state->sids,
167 get_global_sam_sid(), num_rids, rids);
168 if (tevent_req_nterror(req, status)) {
169 return;
171 TALLOC_FREE(rids);
174 * Now expand the builtin groups
177 domain = find_domain_from_sid(&global_sid_Builtin);
178 if (domain == NULL) {
179 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
180 return;
183 subreq = wb_lookupuseraliases_send(state, state->ev, domain,
184 state->num_sids, state->sids);
185 if (tevent_req_nomem(subreq, req)) {
186 return;
188 tevent_req_set_callback(subreq, wb_gettoken_gotbuiltins, req);
191 static void wb_gettoken_gotbuiltins(struct tevent_req *subreq)
193 struct tevent_req *req = tevent_req_callback_data(
194 subreq, struct tevent_req);
195 struct wb_gettoken_state *state = tevent_req_data(
196 req, struct wb_gettoken_state);
197 uint32_t num_rids;
198 uint32_t *rids;
199 NTSTATUS status;
201 status = wb_lookupuseraliases_recv(subreq, state, &num_rids, &rids);
202 TALLOC_FREE(subreq);
203 if (tevent_req_nterror(req, status)) {
204 return;
206 status = wb_add_rids_to_sids(state, &state->num_sids, &state->sids,
207 &global_sid_Builtin, num_rids, rids);
208 if (tevent_req_nterror(req, status)) {
209 return;
211 tevent_req_done(req);
214 NTSTATUS wb_gettoken_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
215 int *num_sids, struct dom_sid **sids)
217 struct wb_gettoken_state *state = tevent_req_data(
218 req, struct wb_gettoken_state);
219 NTSTATUS status;
221 if (tevent_req_is_nterror(req, &status)) {
222 return status;
224 *num_sids = state->num_sids;
225 *sids = talloc_move(mem_ctx, &state->sids);
226 return NT_STATUS_OK;
229 static NTSTATUS wb_add_rids_to_sids(TALLOC_CTX *mem_ctx,
230 uint32_t *pnum_sids,
231 struct dom_sid **psids,
232 const struct dom_sid *domain_sid,
233 int num_rids, uint32_t *rids)
235 int i;
237 for (i=0; i<num_rids; i++) {
238 NTSTATUS status;
239 struct dom_sid sid;
241 sid_compose(&sid, domain_sid, rids[i]);
243 status = add_sid_to_array_unique(
244 mem_ctx, &sid, psids, pnum_sids);
245 if (!NT_STATUS_IS_OK(status)) {
246 return status;
250 return NT_STATUS_OK;