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

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

Update 3.3 to 3.3.7

File size: 13.1 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_pipe(ctx, r->in.server,
109 &ndr_table_wkssvc.syntax_id,
110 &cli,
111 &pipe_cli);
112 if (!W_ERROR_IS_OK(werr)) {
113 goto done;
114 }
115
116 if (r->in.password) {
117 encode_wkssvc_join_password_buffer(ctx,
118 r->in.password,
119 &cli->user_session_key,
120 &encrypted_password);
121 }
122
123 old_timeout = cli_set_timeout(cli, 600000);
124
125 status = rpccli_wkssvc_NetrJoinDomain2(pipe_cli, ctx,
126 r->in.server,
127 r->in.domain,
128 r->in.account_ou,
129 r->in.account,
130 encrypted_password,
131 r->in.join_flags,
132 &werr);
133 if (!NT_STATUS_IS_OK(status)) {
134 werr = ntstatus_to_werror(status);
135 goto done;
136 }
137
138 done:
139 if (cli) {
140 if (old_timeout) {
141 cli_set_timeout(cli, old_timeout);
142 }
143 }
144
145 return werr;
146}
147/****************************************************************
148****************************************************************/
149
150WERROR NetUnjoinDomain_l(struct libnetapi_ctx *mem_ctx,
151 struct NetUnjoinDomain *r)
152{
153 struct libnet_UnjoinCtx *u = NULL;
154 struct dom_sid domain_sid;
155 const char *domain = NULL;
156 WERROR werr;
157
158 if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
159 return WERR_SETUP_NOT_JOINED;
160 }
161
162 werr = libnet_init_UnjoinCtx(mem_ctx, &u);
163 W_ERROR_NOT_OK_RETURN(werr);
164
165 if (lp_realm()) {
166 domain = lp_realm();
167 } else {
168 domain = lp_workgroup();
169 }
170
171 if (r->in.server_name) {
172 u->in.dc_name = talloc_strdup(mem_ctx, r->in.server_name);
173 W_ERROR_HAVE_NO_MEMORY(u->in.dc_name);
174 } else {
175 NTSTATUS status;
176 struct netr_DsRGetDCNameInfo *info = NULL;
177 const char *dc = NULL;
178 uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
179 DS_WRITABLE_REQUIRED |
180 DS_RETURN_DNS_NAME;
181 status = dsgetdcname(mem_ctx, NULL, domain,
182 NULL, NULL, flags, &info);
183 if (!NT_STATUS_IS_OK(status)) {
184 libnetapi_set_error_string(mem_ctx,
185 "failed to find DC for domain %s: %s",
186 domain,
187 get_friendly_nt_error_msg(status));
188 return ntstatus_to_werror(status);
189 }
190
191 dc = strip_hostname(info->dc_unc);
192 u->in.dc_name = talloc_strdup(mem_ctx, dc);
193 W_ERROR_HAVE_NO_MEMORY(u->in.dc_name);
194
195 u->in.domain_name = domain;
196 }
197
198 if (r->in.account) {
199 u->in.admin_account = talloc_strdup(mem_ctx, r->in.account);
200 W_ERROR_HAVE_NO_MEMORY(u->in.admin_account);
201 }
202
203 if (r->in.password) {
204 u->in.admin_password = talloc_strdup(mem_ctx, r->in.password);
205 W_ERROR_HAVE_NO_MEMORY(u->in.admin_password);
206 }
207
208 u->in.domain_name = domain;
209 u->in.unjoin_flags = r->in.unjoin_flags;
210 u->in.delete_machine_account = false;
211 u->in.modify_config = true;
212 u->in.debug = true;
213
214 u->in.domain_sid = &domain_sid;
215
216 werr = libnet_Unjoin(mem_ctx, u);
217 if (!W_ERROR_IS_OK(werr) && u->out.error_string) {
218 libnetapi_set_error_string(mem_ctx, "%s", u->out.error_string);
219 }
220 TALLOC_FREE(u);
221
222 return werr;
223}
224
225/****************************************************************
226****************************************************************/
227
228WERROR NetUnjoinDomain_r(struct libnetapi_ctx *ctx,
229 struct NetUnjoinDomain *r)
230{
231 struct cli_state *cli = NULL;
232 struct rpc_pipe_client *pipe_cli = NULL;
233 struct wkssvc_PasswordBuffer *encrypted_password = NULL;
234 NTSTATUS status;
235 WERROR werr;
236 unsigned int old_timeout = 0;
237
238 werr = libnetapi_open_pipe(ctx, r->in.server_name,
239 &ndr_table_wkssvc.syntax_id,
240 &cli,
241 &pipe_cli);
242 if (!W_ERROR_IS_OK(werr)) {
243 goto done;
244 }
245
246 if (r->in.password) {
247 encode_wkssvc_join_password_buffer(ctx,
248 r->in.password,
249 &cli->user_session_key,
250 &encrypted_password);
251 }
252
253 old_timeout = cli_set_timeout(cli, 60000);
254
255 status = rpccli_wkssvc_NetrUnjoinDomain2(pipe_cli, ctx,
256 r->in.server_name,
257 r->in.account,
258 encrypted_password,
259 r->in.unjoin_flags,
260 &werr);
261 if (!NT_STATUS_IS_OK(status)) {
262 werr = ntstatus_to_werror(status);
263 goto done;
264 }
265
266 done:
267 if (cli) {
268 if (old_timeout) {
269 cli_set_timeout(cli, old_timeout);
270 }
271 }
272
273 return werr;
274}
275
276/****************************************************************
277****************************************************************/
278
279WERROR NetGetJoinInformation_r(struct libnetapi_ctx *ctx,
280 struct NetGetJoinInformation *r)
281{
282 struct cli_state *cli = NULL;
283 struct rpc_pipe_client *pipe_cli = NULL;
284 NTSTATUS status;
285 WERROR werr;
286 const char *buffer = NULL;
287
288 werr = libnetapi_open_pipe(ctx, r->in.server_name,
289 &ndr_table_wkssvc.syntax_id,
290 &cli,
291 &pipe_cli);
292 if (!W_ERROR_IS_OK(werr)) {
293 goto done;
294 }
295
296 status = rpccli_wkssvc_NetrGetJoinInformation(pipe_cli, ctx,
297 r->in.server_name,
298 &buffer,
299 (enum wkssvc_NetJoinStatus *)r->out.name_type,
300 &werr);
301 if (!NT_STATUS_IS_OK(status)) {
302 werr = ntstatus_to_werror(status);
303 goto done;
304 }
305
306 *r->out.name_buffer = talloc_strdup(ctx, buffer);
307 W_ERROR_HAVE_NO_MEMORY(*r->out.name_buffer);
308
309 done:
310 return werr;
311}
312
313/****************************************************************
314****************************************************************/
315
316WERROR NetGetJoinInformation_l(struct libnetapi_ctx *ctx,
317 struct NetGetJoinInformation *r)
318{
319 if ((lp_security() == SEC_ADS) && lp_realm()) {
320 *r->out.name_buffer = talloc_strdup(ctx, lp_realm());
321 } else {
322 *r->out.name_buffer = talloc_strdup(ctx, lp_workgroup());
323 }
324 if (!*r->out.name_buffer) {
325 return WERR_NOMEM;
326 }
327
328 switch (lp_server_role()) {
329 case ROLE_DOMAIN_MEMBER:
330 case ROLE_DOMAIN_PDC:
331 case ROLE_DOMAIN_BDC:
332 *r->out.name_type = NetSetupDomainName;
333 break;
334 case ROLE_STANDALONE:
335 default:
336 *r->out.name_type = NetSetupWorkgroupName;
337 break;
338 }
339
340 return WERR_OK;
341}
342
343/****************************************************************
344****************************************************************/
345
346WERROR NetGetJoinableOUs_l(struct libnetapi_ctx *ctx,
347 struct NetGetJoinableOUs *r)
348{
349#ifdef WITH_ADS
350 NTSTATUS status;
351 ADS_STATUS ads_status;
352 ADS_STRUCT *ads = NULL;
353 struct netr_DsRGetDCNameInfo *info = NULL;
354 const char *dc = NULL;
355 uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
356 DS_RETURN_DNS_NAME;
357
358 status = dsgetdcname(ctx, NULL, r->in.domain,
359 NULL, NULL, flags, &info);
360 if (!NT_STATUS_IS_OK(status)) {
361 libnetapi_set_error_string(ctx, "%s",
362 get_friendly_nt_error_msg(status));
363 return ntstatus_to_werror(status);
364 }
365
366 dc = strip_hostname(info->dc_unc);
367
368 ads = ads_init(info->domain_name, info->domain_name, dc);
369 if (!ads) {
370 return WERR_GENERAL_FAILURE;
371 }
372
373 SAFE_FREE(ads->auth.user_name);
374 if (r->in.account) {
375 ads->auth.user_name = SMB_STRDUP(r->in.account);
376 } else if (ctx->username) {
377 ads->auth.user_name = SMB_STRDUP(ctx->username);
378 }
379
380 SAFE_FREE(ads->auth.password);
381 if (r->in.password) {
382 ads->auth.password = SMB_STRDUP(r->in.password);
383 } else if (ctx->password) {
384 ads->auth.password = SMB_STRDUP(ctx->password);
385 }
386
387 ads_status = ads_connect_user_creds(ads);
388 if (!ADS_ERR_OK(ads_status)) {
389 ads_destroy(&ads);
390 return WERR_DEFAULT_JOIN_REQUIRED;
391 }
392
393 ads_status = ads_get_joinable_ous(ads, ctx,
394 (char ***)r->out.ous,
395 (size_t *)r->out.ou_count);
396 if (!ADS_ERR_OK(ads_status)) {
397 ads_destroy(&ads);
398 return WERR_DEFAULT_JOIN_REQUIRED;
399 }
400
401 ads_destroy(&ads);
402 return WERR_OK;
403#else
404 return WERR_NOT_SUPPORTED;
405#endif
406}
407
408/****************************************************************
409****************************************************************/
410
411WERROR NetGetJoinableOUs_r(struct libnetapi_ctx *ctx,
412 struct NetGetJoinableOUs *r)
413{
414 struct cli_state *cli = NULL;
415 struct rpc_pipe_client *pipe_cli = NULL;
416 struct wkssvc_PasswordBuffer *encrypted_password = NULL;
417 NTSTATUS status;
418 WERROR werr;
419
420 werr = libnetapi_open_pipe(ctx, r->in.server_name,
421 &ndr_table_wkssvc.syntax_id,
422 &cli,
423 &pipe_cli);
424 if (!W_ERROR_IS_OK(werr)) {
425 goto done;
426 }
427
428 if (r->in.password) {
429 encode_wkssvc_join_password_buffer(ctx,
430 r->in.password,
431 &cli->user_session_key,
432 &encrypted_password);
433 }
434
435 status = rpccli_wkssvc_NetrGetJoinableOus2(pipe_cli, ctx,
436 r->in.server_name,
437 r->in.domain,
438 r->in.account,
439 encrypted_password,
440 r->out.ou_count,
441 r->out.ous,
442 &werr);
443 if (!NT_STATUS_IS_OK(status)) {
444 werr = ntstatus_to_werror(status);
445 goto done;
446 }
447
448 done:
449 return werr;
450}
451
452/****************************************************************
453****************************************************************/
454
455WERROR NetRenameMachineInDomain_r(struct libnetapi_ctx *ctx,
456 struct NetRenameMachineInDomain *r)
457{
458 struct cli_state *cli = NULL;
459 struct rpc_pipe_client *pipe_cli = NULL;
460 struct wkssvc_PasswordBuffer *encrypted_password = NULL;
461 NTSTATUS status;
462 WERROR werr;
463
464 werr = libnetapi_open_pipe(ctx, r->in.server_name,
465 &ndr_table_wkssvc.syntax_id,
466 &cli,
467 &pipe_cli);
468 if (!W_ERROR_IS_OK(werr)) {
469 goto done;
470 }
471
472 if (r->in.password) {
473 encode_wkssvc_join_password_buffer(ctx,
474 r->in.password,
475 &cli->user_session_key,
476 &encrypted_password);
477 }
478
479 status = rpccli_wkssvc_NetrRenameMachineInDomain2(pipe_cli, ctx,
480 r->in.server_name,
481 r->in.new_machine_name,
482 r->in.account,
483 encrypted_password,
484 r->in.rename_options,
485 &werr);
486 if (!NT_STATUS_IS_OK(status)) {
487 werr = ntstatus_to_werror(status);
488 goto done;
489 }
490
491 done:
492 return werr;
493}
494
495/****************************************************************
496****************************************************************/
497
498WERROR NetRenameMachineInDomain_l(struct libnetapi_ctx *ctx,
499 struct NetRenameMachineInDomain *r)
500{
501 LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetRenameMachineInDomain);
502}
Note: See TracBrowser for help on using the repository browser.