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