source: branches/samba-3.2.x/source/lib/netapi/joindomain.c

Last change on this file was 335, checked in by Herwig Bauernfeind, 16 years ago

Update 3.2 to 3.2.14 (final)

File size: 11.9 KB
Line 
1/*
2 * Unix SMB/CIFS implementation.
3 * NetApi Join Support
4 * Copyright (C) Guenther Deschner 2007-2008
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
22#include "librpc/gen_ndr/libnetapi.h"
23#include "lib/netapi/netapi.h"
24#include "lib/netapi/netapi_private.h"
25#include "lib/netapi/libnetapi.h"
26#include "libnet/libnet.h"
27
28/****************************************************************
29****************************************************************/
30
31WERROR NetJoinDomain_l(struct libnetapi_ctx *mem_ctx,
32 struct NetJoinDomain *r)
33{
34 struct libnet_JoinCtx *j = NULL;
35 WERROR werr;
36
37 if (!r->in.domain) {
38 return WERR_INVALID_PARAM;
39 }
40
41 werr = libnet_init_JoinCtx(mem_ctx, &j);
42 W_ERROR_NOT_OK_RETURN(werr);
43
44 j->in.domain_name = talloc_strdup(mem_ctx, r->in.domain);
45 W_ERROR_HAVE_NO_MEMORY(j->in.domain_name);
46
47 if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
48 NTSTATUS status;
49 struct netr_DsRGetDCNameInfo *info = NULL;
50 const char *dc = NULL;
51 uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
52 DS_WRITABLE_REQUIRED |
53 DS_RETURN_DNS_NAME;
54 status = dsgetdcname(mem_ctx, NULL, r->in.domain,
55 NULL, NULL, flags, &info);
56 if (!NT_STATUS_IS_OK(status)) {
57 libnetapi_set_error_string(mem_ctx,
58 "%s", get_friendly_nt_error_msg(status));
59 return ntstatus_to_werror(status);
60 }
61
62 dc = strip_hostname(info->dc_unc);
63 j->in.dc_name = talloc_strdup(mem_ctx, dc);
64 W_ERROR_HAVE_NO_MEMORY(j->in.dc_name);
65 }
66
67 if (r->in.account_ou) {
68 j->in.account_ou = talloc_strdup(mem_ctx, r->in.account_ou);
69 W_ERROR_HAVE_NO_MEMORY(j->in.account_ou);
70 }
71
72 if (r->in.account) {
73 j->in.admin_account = talloc_strdup(mem_ctx, r->in.account);
74 W_ERROR_HAVE_NO_MEMORY(j->in.admin_account);
75 }
76
77 if (r->in.password) {
78 j->in.admin_password = talloc_strdup(mem_ctx, r->in.password);
79 W_ERROR_HAVE_NO_MEMORY(j->in.admin_password);
80 }
81
82 j->in.join_flags = r->in.join_flags;
83 j->in.modify_config = true;
84 j->in.debug = true;
85
86 werr = libnet_Join(mem_ctx, j);
87 if (!W_ERROR_IS_OK(werr) && j->out.error_string) {
88 libnetapi_set_error_string(mem_ctx, "%s", j->out.error_string);
89 }
90 TALLOC_FREE(j);
91
92 return werr;
93}
94
95/****************************************************************
96****************************************************************/
97
98WERROR NetJoinDomain_r(struct libnetapi_ctx *ctx,
99 struct NetJoinDomain *r)
100{
101 struct cli_state *cli = NULL;
102 struct rpc_pipe_client *pipe_cli = NULL;
103 struct wkssvc_PasswordBuffer *encrypted_password = NULL;
104 NTSTATUS status;
105 WERROR werr;
106 unsigned int old_timeout = 0;
107
108 werr = libnetapi_open_ipc_connection(ctx, r->in.server, &cli);
109 if (!W_ERROR_IS_OK(werr)) {
110 goto done;
111 }
112
113 werr = libnetapi_open_pipe(ctx, cli, PI_WKSSVC, &pipe_cli);
114 if (!W_ERROR_IS_OK(werr)) {
115 goto done;
116 }
117
118 if (r->in.password) {
119 encode_wkssvc_join_password_buffer(ctx,
120 r->in.password,
121 &cli->user_session_key,
122 &encrypted_password);
123 }
124
125 old_timeout = cli_set_timeout(cli, 600000);
126
127 status = rpccli_wkssvc_NetrJoinDomain2(pipe_cli, ctx,
128 r->in.server,
129 r->in.domain,
130 r->in.account_ou,
131 r->in.account,
132 encrypted_password,
133 r->in.join_flags,
134 &werr);
135 if (!NT_STATUS_IS_OK(status)) {
136 werr = ntstatus_to_werror(status);
137 goto done;
138 }
139
140 done:
141 if (cli) {
142 if (old_timeout) {
143 cli_set_timeout(cli, old_timeout);
144 }
145 }
146
147 return werr;
148}
149/****************************************************************
150****************************************************************/
151
152WERROR NetUnjoinDomain_l(struct libnetapi_ctx *mem_ctx,
153 struct NetUnjoinDomain *r)
154{
155 struct libnet_UnjoinCtx *u = NULL;
156 struct dom_sid domain_sid;
157 const char *domain = NULL;
158 WERROR werr;
159
160 if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
161 return WERR_SETUP_NOT_JOINED;
162 }
163
164 werr = libnet_init_UnjoinCtx(mem_ctx, &u);
165 W_ERROR_NOT_OK_RETURN(werr);
166
167 if (lp_realm()) {
168 domain = lp_realm();
169 } else {
170 domain = lp_workgroup();
171 }
172
173 if (r->in.server_name) {
174 u->in.dc_name = talloc_strdup(mem_ctx, r->in.server_name);
175 W_ERROR_HAVE_NO_MEMORY(u->in.dc_name);
176 } else {
177 NTSTATUS status;
178 struct netr_DsRGetDCNameInfo *info = NULL;
179 const char *dc = NULL;
180 uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
181 DS_WRITABLE_REQUIRED |
182 DS_RETURN_DNS_NAME;
183 status = dsgetdcname(mem_ctx, NULL, domain,
184 NULL, NULL, flags, &info);
185 if (!NT_STATUS_IS_OK(status)) {
186 libnetapi_set_error_string(mem_ctx,
187 "failed to find DC for domain %s: %s",
188 domain,
189 get_friendly_nt_error_msg(status));
190 return ntstatus_to_werror(status);
191 }
192
193 dc = strip_hostname(info->dc_unc);
194 u->in.dc_name = talloc_strdup(mem_ctx, dc);
195 W_ERROR_HAVE_NO_MEMORY(u->in.dc_name);
196
197 u->in.domain_name = domain;
198 }
199
200 if (r->in.account) {
201 u->in.admin_account = talloc_strdup(mem_ctx, r->in.account);
202 W_ERROR_HAVE_NO_MEMORY(u->in.admin_account);
203 }
204
205 if (r->in.password) {
206 u->in.admin_password = talloc_strdup(mem_ctx, r->in.password);
207 W_ERROR_HAVE_NO_MEMORY(u->in.admin_password);
208 }
209
210 u->in.domain_name = domain;
211 u->in.unjoin_flags = r->in.unjoin_flags;
212 u->in.delete_machine_account = false;
213 u->in.modify_config = true;
214 u->in.debug = true;
215
216 u->in.domain_sid = &domain_sid;
217
218 werr = libnet_Unjoin(mem_ctx, u);
219 if (!W_ERROR_IS_OK(werr) && u->out.error_string) {
220 libnetapi_set_error_string(mem_ctx, "%s", u->out.error_string);
221 }
222 TALLOC_FREE(u);
223
224 return werr;
225}
226
227/****************************************************************
228****************************************************************/
229
230WERROR NetUnjoinDomain_r(struct libnetapi_ctx *ctx,
231 struct NetUnjoinDomain *r)
232{
233 struct cli_state *cli = NULL;
234 struct rpc_pipe_client *pipe_cli = NULL;
235 struct wkssvc_PasswordBuffer *encrypted_password = NULL;
236 NTSTATUS status;
237 WERROR werr;
238 unsigned int old_timeout = 0;
239
240 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
241 if (!W_ERROR_IS_OK(werr)) {
242 goto done;
243 }
244
245 werr = libnetapi_open_pipe(ctx, cli, PI_WKSSVC, &pipe_cli);
246 if (!W_ERROR_IS_OK(werr)) {
247 goto done;
248 }
249
250 if (r->in.password) {
251 encode_wkssvc_join_password_buffer(ctx,
252 r->in.password,
253 &cli->user_session_key,
254 &encrypted_password);
255 }
256
257 old_timeout = cli_set_timeout(cli, 60000);
258
259 status = rpccli_wkssvc_NetrUnjoinDomain2(pipe_cli, ctx,
260 r->in.server_name,
261 r->in.account,
262 encrypted_password,
263 r->in.unjoin_flags,
264 &werr);
265 if (!NT_STATUS_IS_OK(status)) {
266 werr = ntstatus_to_werror(status);
267 goto done;
268 }
269
270 done:
271 if (cli) {
272 if (old_timeout) {
273 cli_set_timeout(cli, old_timeout);
274 }
275 }
276
277 return werr;
278}
279
280/****************************************************************
281****************************************************************/
282
283WERROR NetGetJoinInformation_r(struct libnetapi_ctx *ctx,
284 struct NetGetJoinInformation *r)
285{
286 struct cli_state *cli = NULL;
287 struct rpc_pipe_client *pipe_cli = NULL;
288 NTSTATUS status;
289 WERROR werr;
290 const char *buffer = NULL;
291
292 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
293 if (!W_ERROR_IS_OK(werr)) {
294 goto done;
295 }
296
297 werr = libnetapi_open_pipe(ctx, cli, PI_WKSSVC, &pipe_cli);
298 if (!W_ERROR_IS_OK(werr)) {
299 goto done;
300 }
301
302 status = rpccli_wkssvc_NetrGetJoinInformation(pipe_cli, ctx,
303 r->in.server_name,
304 &buffer,
305 (enum wkssvc_NetJoinStatus *)r->out.name_type,
306 &werr);
307 if (!NT_STATUS_IS_OK(status)) {
308 werr = ntstatus_to_werror(status);
309 goto done;
310 }
311
312 *r->out.name_buffer = talloc_strdup(ctx, buffer);
313 W_ERROR_HAVE_NO_MEMORY(*r->out.name_buffer);
314
315 done:
316 return werr;
317}
318
319/****************************************************************
320****************************************************************/
321
322WERROR NetGetJoinInformation_l(struct libnetapi_ctx *ctx,
323 struct NetGetJoinInformation *r)
324{
325 if ((lp_security() == SEC_ADS) && lp_realm()) {
326 *r->out.name_buffer = talloc_strdup(ctx, lp_realm());
327 } else {
328 *r->out.name_buffer = talloc_strdup(ctx, lp_workgroup());
329 }
330 if (!*r->out.name_buffer) {
331 return WERR_NOMEM;
332 }
333
334 switch (lp_server_role()) {
335 case ROLE_DOMAIN_MEMBER:
336 case ROLE_DOMAIN_PDC:
337 case ROLE_DOMAIN_BDC:
338 *r->out.name_type = NetSetupDomainName;
339 break;
340 case ROLE_STANDALONE:
341 default:
342 *r->out.name_type = NetSetupWorkgroupName;
343 break;
344 }
345
346 return WERR_OK;
347}
348
349/****************************************************************
350****************************************************************/
351
352WERROR NetGetJoinableOUs_l(struct libnetapi_ctx *ctx,
353 struct NetGetJoinableOUs *r)
354{
355#ifdef WITH_ADS
356 NTSTATUS status;
357 ADS_STATUS ads_status;
358 ADS_STRUCT *ads = NULL;
359 struct netr_DsRGetDCNameInfo *info = NULL;
360 const char *dc = NULL;
361 uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
362 DS_RETURN_DNS_NAME;
363
364 status = dsgetdcname(ctx, NULL, r->in.domain,
365 NULL, NULL, flags, &info);
366 if (!NT_STATUS_IS_OK(status)) {
367 libnetapi_set_error_string(ctx, "%s",
368 get_friendly_nt_error_msg(status));
369 return ntstatus_to_werror(status);
370 }
371
372 dc = strip_hostname(info->dc_unc);
373
374 ads = ads_init(r->in.domain, r->in.domain, dc);
375 if (!ads) {
376 return WERR_GENERAL_FAILURE;
377 }
378
379 SAFE_FREE(ads->auth.user_name);
380 if (r->in.account) {
381 ads->auth.user_name = SMB_STRDUP(r->in.account);
382 } else if (ctx->username) {
383 ads->auth.user_name = SMB_STRDUP(ctx->username);
384 }
385
386 SAFE_FREE(ads->auth.password);
387 if (r->in.password) {
388 ads->auth.password = SMB_STRDUP(r->in.password);
389 } else if (ctx->password) {
390 ads->auth.password = SMB_STRDUP(ctx->password);
391 }
392
393 ads_status = ads_connect(ads);
394 if (!ADS_ERR_OK(ads_status)) {
395 ads_destroy(&ads);
396 return WERR_DEFAULT_JOIN_REQUIRED;
397 }
398
399 ads_status = ads_get_joinable_ous(ads, ctx,
400 (char ***)r->out.ous,
401 (size_t *)r->out.ou_count);
402 if (!ADS_ERR_OK(ads_status)) {
403 ads_destroy(&ads);
404 return WERR_DEFAULT_JOIN_REQUIRED;
405 }
406
407 ads_destroy(&ads);
408 return WERR_OK;
409#else
410 return WERR_NOT_SUPPORTED;
411#endif
412}
413
414/****************************************************************
415****************************************************************/
416
417WERROR NetGetJoinableOUs_r(struct libnetapi_ctx *ctx,
418 struct NetGetJoinableOUs *r)
419{
420 struct cli_state *cli = NULL;
421 struct rpc_pipe_client *pipe_cli = NULL;
422 struct wkssvc_PasswordBuffer *encrypted_password = NULL;
423 NTSTATUS status;
424 WERROR werr;
425
426 werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli);
427 if (!W_ERROR_IS_OK(werr)) {
428 goto done;
429 }
430
431 werr = libnetapi_open_pipe(ctx, cli, PI_WKSSVC, &pipe_cli);
432 if (!W_ERROR_IS_OK(werr)) {
433 goto done;
434 }
435
436 if (r->in.password) {
437 encode_wkssvc_join_password_buffer(ctx,
438 r->in.password,
439 &cli->user_session_key,
440 &encrypted_password);
441 }
442
443 status = rpccli_wkssvc_NetrGetJoinableOus2(pipe_cli, ctx,
444 r->in.server_name,
445 r->in.domain,
446 r->in.account,
447 encrypted_password,
448 r->out.ou_count,
449 r->out.ous,
450 &werr);
451 if (!NT_STATUS_IS_OK(status)) {
452 werr = ntstatus_to_werror(status);
453 goto done;
454 }
455
456 done:
457 if (cli) {
458 cli_shutdown(cli);
459 }
460
461 return werr;
462}
Note: See TracBrowser for help on using the repository browser.