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 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
);
70 subreq
= wb_lookupusergroups_send(state
, ev
, domain
, &state
->usersid
);
71 if (tevent_req_nomem(subreq
, req
)) {
72 return tevent_req_post(req
, ev
);
74 tevent_req_set_callback(subreq
, wb_gettoken_gotgroups
, req
);
78 static void wb_gettoken_gotgroups(struct tevent_req
*subreq
)
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
);
85 struct winbindd_domain
*domain
;
88 status
= wb_lookupusergroups_recv(subreq
, state
, &state
->num_sids
,
91 if (!NT_STATUS_IS_OK(status
)) {
92 tevent_req_nterror(req
, status
);
96 sids
= talloc_realloc(state
, state
->sids
, struct dom_sid
,
98 if (tevent_req_nomem(sids
, req
)) {
101 memmove(&sids
[1], &sids
[0], state
->num_sids
* sizeof(sids
[0]));
102 sid_copy(&sids
[0], &state
->usersid
);
103 state
->num_sids
+= 1;
107 * Expand our domain's aliases
109 domain
= find_our_domain();
110 if (domain
== NULL
) {
111 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
115 subreq
= wb_lookupuseraliases_send(state
, state
->ev
, domain
,
116 state
->num_sids
, state
->sids
);
117 if (tevent_req_nomem(subreq
, req
)) {
120 tevent_req_set_callback(subreq
, wb_gettoken_gotlocalgroups
, req
);
123 static void wb_gettoken_gotlocalgroups(struct tevent_req
*subreq
)
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
);
131 struct winbindd_domain
*domain
;
134 status
= wb_lookupuseraliases_recv(subreq
, state
, &num_rids
, &rids
);
136 if (!NT_STATUS_IS_OK(status
)) {
137 tevent_req_nterror(req
, status
);
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
);
149 * Now expand the builtin groups
152 domain
= find_builtin_domain();
153 if (domain
== NULL
) {
154 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
158 subreq
= wb_lookupuseraliases_send(state
, state
->ev
, domain
,
159 state
->num_sids
, state
->sids
);
160 if (tevent_req_nomem(subreq
, req
)) {
163 tevent_req_set_callback(subreq
, wb_gettoken_gotbuiltins
, req
);
166 static void wb_gettoken_gotbuiltins(struct tevent_req
*subreq
)
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
);
176 status
= wb_lookupuseraliases_recv(subreq
, state
, &num_rids
, &rids
);
178 if (!NT_STATUS_IS_OK(status
)) {
179 tevent_req_nterror(req
, status
);
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
);
187 tevent_req_done(req
);
190 NTSTATUS
wb_gettoken_recv(struct tevent_req
*req
, TALLOC_CTX
*mem_ctx
,
191 int *num_sids
, struct dom_sid
**sids
)
193 struct wb_gettoken_state
*state
= tevent_req_data(
194 req
, struct wb_gettoken_state
);
197 if (tevent_req_is_nterror(req
, &status
)) {
200 *num_sids
= state
->num_sids
;
201 *sids
= talloc_move(mem_ctx
, &state
->sids
);
205 static 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
)
210 struct dom_sid
*sids
;
213 sids
= talloc_realloc(mem_ctx
, *psids
, struct dom_sid
,
214 *pnum_sids
+ num_rids
);
218 for (i
=0; i
<num_rids
; i
++) {
219 sid_compose(&sids
[i
+*pnum_sids
], domain_sid
, rids
[i
]);
222 *pnum_sids
+= num_rids
;