2 Unix SMB/CIFS implementation.
4 Connect to the SAMR pipe, and return connection and domain handles.
6 Copyright (C) Volker Lendecke 2005
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "libcli/composite/composite.h"
26 #include "libcli/security/security.h"
27 #include "librpc/gen_ndr/ndr_samr_c.h"
28 #include "winbind/wb_server.h"
29 #include "smbd/service_task.h"
32 /* Helper to initialize SAMR with a specific auth methods. Verify by opening
35 struct connect_samr_state
{
36 struct composite_context
*ctx
;
39 struct dcerpc_pipe
*samr_pipe
;
40 struct policy_handle
*connect_handle
;
41 struct policy_handle
*domain_handle
;
43 struct samr_Connect2 c
;
44 struct samr_OpenDomain o
;
47 static void connect_samr_recv_pipe(struct composite_context
*ctx
);
48 static void connect_samr_recv_conn(struct tevent_req
*subreq
);
49 static void connect_samr_recv_open(struct tevent_req
*subreq
);
51 struct composite_context
*wb_connect_samr_send(TALLOC_CTX
*mem_ctx
,
52 struct wbsrv_domain
*domain
)
54 struct composite_context
*result
, *ctx
;
55 struct connect_samr_state
*state
;
57 result
= composite_create(mem_ctx
, domain
->service
->task
->event_ctx
);
58 if (result
== NULL
) goto failed
;
60 state
= talloc(result
, struct connect_samr_state
);
61 if (state
== NULL
) goto failed
;
63 result
->private_data
= state
;
65 state
->sid
= dom_sid_dup(state
, domain
->info
->sid
);
66 if (state
->sid
== NULL
) goto failed
;
68 /* this will make the secondary connection on the same IPC$ share,
69 secured with SPNEGO, NTLMSSP or SCHANNEL */
70 ctx
= dcerpc_secondary_auth_connection_send(domain
->netlogon_pipe
,
73 domain
->libnet_ctx
->cred
,
74 domain
->libnet_ctx
->lp_ctx
);
75 composite_continue(state
->ctx
, ctx
, connect_samr_recv_pipe
, state
);
83 static void connect_samr_recv_pipe(struct composite_context
*ctx
)
85 struct connect_samr_state
*state
=
86 talloc_get_type(ctx
->async
.private_data
,
87 struct connect_samr_state
);
88 struct tevent_req
*subreq
;
90 state
->ctx
->status
= dcerpc_secondary_auth_connection_recv(ctx
, state
,
92 if (!composite_is_ok(state
->ctx
)) return;
94 state
->connect_handle
= talloc(state
, struct policy_handle
);
95 if (composite_nomem(state
->connect_handle
, state
->ctx
)) return;
97 state
->c
.in
.system_name
=
98 talloc_asprintf(state
, "\\\\%s",
99 dcerpc_server_name(state
->samr_pipe
));
100 state
->c
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
101 state
->c
.out
.connect_handle
= state
->connect_handle
;
103 subreq
= dcerpc_samr_Connect2_r_send(state
,
104 state
->ctx
->event_ctx
,
105 state
->samr_pipe
->binding_handle
,
107 if (composite_nomem(subreq
, state
->ctx
)) return;
108 tevent_req_set_callback(subreq
, connect_samr_recv_conn
, state
);
111 static void connect_samr_recv_conn(struct tevent_req
*subreq
)
113 struct connect_samr_state
*state
=
114 tevent_req_callback_data(subreq
,
115 struct connect_samr_state
);
117 state
->ctx
->status
= dcerpc_samr_Connect2_r_recv(subreq
, state
);
119 if (!composite_is_ok(state
->ctx
)) return;
120 state
->ctx
->status
= state
->c
.out
.result
;
121 if (!composite_is_ok(state
->ctx
)) return;
123 state
->domain_handle
= talloc(state
, struct policy_handle
);
124 if (composite_nomem(state
->domain_handle
, state
->ctx
)) return;
126 state
->o
.in
.connect_handle
= state
->connect_handle
;
127 state
->o
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
128 state
->o
.in
.sid
= state
->sid
;
129 state
->o
.out
.domain_handle
= state
->domain_handle
;
131 subreq
= dcerpc_samr_OpenDomain_r_send(state
,
132 state
->ctx
->event_ctx
,
133 state
->samr_pipe
->binding_handle
,
135 if (composite_nomem(subreq
, state
->ctx
)) return;
136 tevent_req_set_callback(subreq
, connect_samr_recv_open
, state
);
139 static void connect_samr_recv_open(struct tevent_req
*subreq
)
141 struct connect_samr_state
*state
=
142 tevent_req_callback_data(subreq
,
143 struct connect_samr_state
);
145 state
->ctx
->status
= dcerpc_samr_OpenDomain_r_recv(subreq
, state
);
147 if (!composite_is_ok(state
->ctx
)) return;
148 state
->ctx
->status
= state
->o
.out
.result
;
149 if (!composite_is_ok(state
->ctx
)) return;
151 composite_done(state
->ctx
);
154 NTSTATUS
wb_connect_samr_recv(struct composite_context
*c
,
156 struct dcerpc_pipe
**samr_pipe
,
157 struct policy_handle
*connect_handle
,
158 struct policy_handle
*domain_handle
)
160 NTSTATUS status
= composite_wait(c
);
161 if (NT_STATUS_IS_OK(status
)) {
162 struct connect_samr_state
*state
=
163 talloc_get_type(c
->private_data
,
164 struct connect_samr_state
);
165 *samr_pipe
= talloc_steal(mem_ctx
, state
->samr_pipe
);
166 *connect_handle
= *state
->connect_handle
;
167 *domain_handle
= *state
->domain_handle
;