source: vendor/3.5.0/source3/winbindd/wb_gettoken.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

File size: 6.1 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 async gettoken
4 Copyright (C) Volker Lendecke 2009
5
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.
10
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.
15
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/>.
18*/
19
20#include "includes.h"
21#include "winbindd.h"
22#include "librpc/gen_ndr/cli_wbint.h"
23
24struct wb_gettoken_state {
25 struct tevent_context *ev;
26 struct dom_sid usersid;
27 int num_sids;
28 struct dom_sid *sids;
29};
30
31static 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);
35
36static void wb_gettoken_gotgroups(struct tevent_req *subreq);
37static void wb_gettoken_gotlocalgroups(struct tevent_req *subreq);
38static void wb_gettoken_gotbuiltins(struct tevent_req *subreq);
39
40struct tevent_req *wb_gettoken_send(TALLOC_CTX *mem_ctx,
41 struct tevent_context *ev,
42 const struct dom_sid *sid)
43{
44 struct tevent_req *req, *subreq;
45 struct wb_gettoken_state *state;
46 struct winbindd_domain *domain;
47
48 req = tevent_req_create(mem_ctx, &state, struct wb_gettoken_state);
49 if (req == NULL) {
50 return NULL;
51 }
52 sid_copy(&state->usersid, sid);
53 state->ev = ev;
54
55 domain = find_domain_from_sid_noinit(sid);
56 if (domain == NULL) {
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);
61 }
62
63 if (lp_winbind_trusted_domains_only() && domain->primary) {
64 DEBUG(7, ("wb_gettoken: My domain -- rejecting getgroups() "
65 "for %s.\n", sid_string_tos(sid)));
66 tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
67 return tevent_req_post(req, ev);
68 }
69
70 subreq = wb_lookupusergroups_send(state, ev, domain, &state->usersid);
71 if (tevent_req_nomem(subreq, req)) {
72 return tevent_req_post(req, ev);
73 }
74 tevent_req_set_callback(subreq, wb_gettoken_gotgroups, req);
75 return req;
76}
77
78static void wb_gettoken_gotgroups(struct tevent_req *subreq)
79{
80 struct tevent_req *req = tevent_req_callback_data(
81 subreq, struct tevent_req);
82 struct wb_gettoken_state *state = tevent_req_data(
83 req, struct wb_gettoken_state);
84 struct dom_sid *sids;
85 struct winbindd_domain *domain;
86 NTSTATUS status;
87
88 status = wb_lookupusergroups_recv(subreq, state, &state->num_sids,
89 &state->sids);
90 TALLOC_FREE(subreq);
91 if (!NT_STATUS_IS_OK(status)) {
92 tevent_req_nterror(req, status);
93 return;
94 }
95
96 sids = talloc_realloc(state, state->sids, struct dom_sid,
97 state->num_sids + 1);
98 if (tevent_req_nomem(sids, req)) {
99 return;
100 }
101 memmove(&sids[1], &sids[0], state->num_sids * sizeof(sids[0]));
102 sid_copy(&sids[0], &state->usersid);
103 state->num_sids += 1;
104 state->sids = sids;
105
106 /*
107 * Expand our domain's aliases
108 */
109 domain = find_our_domain();
110 if (domain == NULL) {
111 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
112 return;
113 }
114
115 subreq = wb_lookupuseraliases_send(state, state->ev, domain,
116 state->num_sids, state->sids);
117 if (tevent_req_nomem(subreq, req)) {
118 return;
119 }
120 tevent_req_set_callback(subreq, wb_gettoken_gotlocalgroups, req);
121}
122
123static void wb_gettoken_gotlocalgroups(struct tevent_req *subreq)
124{
125 struct tevent_req *req = tevent_req_callback_data(
126 subreq, struct tevent_req);
127 struct wb_gettoken_state *state = tevent_req_data(
128 req, struct wb_gettoken_state);
129 uint32_t num_rids;
130 uint32_t *rids;
131 struct winbindd_domain *domain;
132 NTSTATUS status;
133
134 status = wb_lookupuseraliases_recv(subreq, state, &num_rids, &rids);
135 TALLOC_FREE(subreq);
136 if (!NT_STATUS_IS_OK(status)) {
137 tevent_req_nterror(req, status);
138 return;
139 }
140 domain = find_our_domain();
141 if (!wb_add_rids_to_sids(state, &state->num_sids, &state->sids,
142 &domain->sid, num_rids, rids)) {
143 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
144 return;
145 }
146 TALLOC_FREE(rids);
147
148 /*
149 * Now expand the builtin groups
150 */
151
152 domain = find_builtin_domain();
153 if (domain == NULL) {
154 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
155 return;
156 }
157
158 subreq = wb_lookupuseraliases_send(state, state->ev, domain,
159 state->num_sids, state->sids);
160 if (tevent_req_nomem(subreq, req)) {
161 return;
162 }
163 tevent_req_set_callback(subreq, wb_gettoken_gotbuiltins, req);
164}
165
166static void wb_gettoken_gotbuiltins(struct tevent_req *subreq)
167{
168 struct tevent_req *req = tevent_req_callback_data(
169 subreq, struct tevent_req);
170 struct wb_gettoken_state *state = tevent_req_data(
171 req, struct wb_gettoken_state);
172 uint32_t num_rids;
173 uint32_t *rids;
174 NTSTATUS status;
175
176 status = wb_lookupuseraliases_recv(subreq, state, &num_rids, &rids);
177 TALLOC_FREE(subreq);
178 if (!NT_STATUS_IS_OK(status)) {
179 tevent_req_nterror(req, status);
180 return;
181 }
182 if (!wb_add_rids_to_sids(state, &state->num_sids, &state->sids,
183 &global_sid_Builtin, num_rids, rids)) {
184 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
185 return;
186 }
187 tevent_req_done(req);
188}
189
190NTSTATUS wb_gettoken_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
191 int *num_sids, struct dom_sid **sids)
192{
193 struct wb_gettoken_state *state = tevent_req_data(
194 req, struct wb_gettoken_state);
195 NTSTATUS status;
196
197 if (tevent_req_is_nterror(req, &status)) {
198 return status;
199 }
200 *num_sids = state->num_sids;
201 *sids = talloc_move(mem_ctx, &state->sids);
202 return NT_STATUS_OK;
203}
204
205static bool wb_add_rids_to_sids(TALLOC_CTX *mem_ctx,
206 int *pnum_sids, struct dom_sid **psids,
207 const struct dom_sid *domain_sid,
208 int num_rids, uint32_t *rids)
209{
210 struct dom_sid *sids;
211 int i;
212
213 sids = talloc_realloc(mem_ctx, *psids, struct dom_sid,
214 *pnum_sids + num_rids);
215 if (sids == NULL) {
216 return false;
217 }
218 for (i=0; i<num_rids; i++) {
219 sid_compose(&sids[i+*pnum_sids], domain_sid, rids[i]);
220 }
221
222 *pnum_sids += num_rids;
223 *psids = sids;
224 return true;
225}
Note: See TracBrowser for help on using the repository browser.