2
Unix SMB/CIFS implementation.
4
Find and init a domain struct for a SID
6
Copyright (C) Volker Lendecke 2005
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program. If not, see <http://www.gnu.org/licenses/>.
23
#include "libcli/composite/composite.h"
24
#include "winbind/wb_server.h"
25
#include "smbd/service_task.h"
26
#include "winbind/wb_async_helpers.h"
27
#include "libcli/security/security.h"
28
#include "../lib/util/dlinklist.h"
29
#include "param/param.h"
31
static struct wbsrv_domain *find_domain_from_sid(struct wbsrv_service *service,
32
const struct dom_sid *sid)
34
struct wbsrv_domain *domain;
36
for (domain = service->domains; domain!=NULL; domain = domain->next) {
37
if (dom_sid_equal(domain->info->sid, sid)) {
40
if (dom_sid_in_domain(domain->info->sid, sid)) {
47
struct sid2domain_state {
48
struct composite_context *ctx;
49
struct wbsrv_service *service;
52
struct wbsrv_domain *domain;
55
static void sid2domain_recv_dom_info(struct composite_context *ctx);
56
static void sid2domain_recv_name(struct composite_context *ctx);
57
static void sid2domain_recv_trusted_dom_info(struct composite_context *ctx);
58
static void sid2domain_recv_init(struct composite_context *ctx);
60
struct composite_context *wb_sid2domain_send(TALLOC_CTX *mem_ctx,
61
struct wbsrv_service *service,
62
const struct dom_sid *sid)
64
struct composite_context *result, *ctx;
65
struct sid2domain_state *state;
67
result = composite_create(mem_ctx, service->task->event_ctx);
68
if (result == NULL) goto failed;
70
state = talloc(result, struct sid2domain_state);
71
if (state == NULL) goto failed;
73
result->private_data = state;
75
state->service = service;
76
state->sid = dom_sid_dup(state, sid);
77
if (state->sid == NULL) goto failed;
79
state->domain = find_domain_from_sid(service, sid);
80
if (state->domain != NULL) {
81
result->status = NT_STATUS_OK;
82
composite_done(result);
86
if (dom_sid_equal(service->primary_sid, sid) ||
87
dom_sid_in_domain(service->primary_sid, sid)) {
88
ctx = wb_get_dom_info_send(state, service, lp_workgroup(service->task->lp_ctx),
89
service->primary_sid);
90
if (ctx == NULL) goto failed;
91
ctx->async.fn = sid2domain_recv_dom_info;
92
ctx->async.private_data = state;
96
ctx = wb_cmd_lookupsid_send(state, service, state->sid);
97
if (ctx == NULL) goto failed;
98
composite_continue(result, ctx, sid2domain_recv_name, state);
108
static void sid2domain_recv_dom_info(struct composite_context *ctx)
110
struct sid2domain_state *state =
111
talloc_get_type(ctx->async.private_data,
112
struct sid2domain_state);
113
struct wb_dom_info *info;
115
state->ctx->status = wb_get_dom_info_recv(ctx, state, &info);
116
if (!composite_is_ok(state->ctx)) return;
118
ctx = wb_init_domain_send(state, state->service, info);
120
composite_continue(state->ctx, ctx, sid2domain_recv_init, state);
123
static void sid2domain_recv_name(struct composite_context *ctx)
125
struct sid2domain_state *state =
126
talloc_get_type(ctx->async.private_data,
127
struct sid2domain_state);
128
struct wb_sid_object *name;
130
state->ctx->status = wb_cmd_lookupsid_recv(ctx, state, &name);
131
if (!composite_is_ok(state->ctx)) return;
133
if (name->type == SID_NAME_UNKNOWN) {
134
composite_error(state->ctx, NT_STATUS_NO_SUCH_DOMAIN);
138
if (name->type != SID_NAME_DOMAIN) {
139
state->sid->num_auths -= 1;
142
ctx = wb_trusted_dom_info_send(state, state->service, name->domain,
145
composite_continue(state->ctx, ctx, sid2domain_recv_trusted_dom_info,
149
static void sid2domain_recv_trusted_dom_info(struct composite_context *ctx)
151
struct sid2domain_state *state =
152
talloc_get_type(ctx->async.private_data,
153
struct sid2domain_state);
154
struct wb_dom_info *info;
156
state->ctx->status = wb_trusted_dom_info_recv(ctx, state, &info);
157
if (!composite_is_ok(state->ctx)) return;
159
ctx = wb_init_domain_send(state, state->service, info);
161
composite_continue(state->ctx, ctx, sid2domain_recv_init, state);
164
static void sid2domain_recv_init(struct composite_context *ctx)
166
struct sid2domain_state *state =
167
talloc_get_type(ctx->async.private_data,
168
struct sid2domain_state);
169
struct wbsrv_domain *existing;
171
state->ctx->status = wb_init_domain_recv(ctx, state,
173
if (!composite_is_ok(state->ctx)) {
174
DEBUG(10, ("Could not init domain\n"));
178
existing = find_domain_from_sid(state->service, state->sid);
179
if (existing != NULL) {
180
DEBUG(5, ("Initialized domain twice, dropping second one\n"));
181
talloc_free(state->domain);
182
state->domain = existing;
185
talloc_steal(state->service, state->domain);
186
DLIST_ADD(state->service->domains, state->domain);
188
composite_done(state->ctx);
191
NTSTATUS wb_sid2domain_recv(struct composite_context *ctx,
192
struct wbsrv_domain **result)
194
NTSTATUS status = composite_wait(ctx);
195
if (NT_STATUS_IS_OK(status)) {
196
struct sid2domain_state *state =
197
talloc_get_type(ctx->private_data,
198
struct sid2domain_state);
199
*result = state->domain;
205
NTSTATUS wb_sid2domain(TALLOC_CTX *mem_ctx, struct wbsrv_service *service,
206
const struct dom_sid *sid,
207
struct wbsrv_domain **result)
209
struct composite_context *c = wb_sid2domain_send(mem_ctx, service,
211
return wb_sid2domain_recv(c, result);