2 * Unix SMB/CIFS implementation.
4 * Copyright (C) Guenther Deschner 2007-2008
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.
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.
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/>.
22 #include "lib/netapi/netapi.h"
23 #include "libnet/libnet.h"
25 static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx,
26 const char *server_name,
27 const char *domain_name,
28 const char *account_ou,
33 struct libnet_JoinCtx *r = NULL;
36 werr = libnet_init_JoinCtx(mem_ctx, &r);
37 W_ERROR_NOT_OK_RETURN(werr);
40 return WERR_INVALID_PARAM;
43 r->in.domain_name = talloc_strdup(mem_ctx, domain_name);
44 W_ERROR_HAVE_NO_MEMORY(r->in.domain_name);
46 if (join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
48 struct DS_DOMAIN_CONTROLLER_INFO *info = NULL;
49 uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
50 DS_WRITABLE_REQUIRED |
52 status = DsGetDcName(mem_ctx, NULL, domain_name,
53 NULL, NULL, flags, &info);
54 if (!NT_STATUS_IS_OK(status)) {
55 return ntstatus_to_werror(status);
57 r->in.dc_name = talloc_strdup(mem_ctx,
58 info->domain_controller_name);
59 W_ERROR_HAVE_NO_MEMORY(r->in.dc_name);
63 r->in.account_ou = talloc_strdup(mem_ctx, account_ou);
64 W_ERROR_HAVE_NO_MEMORY(r->in.account_ou);
68 r->in.admin_account = talloc_strdup(mem_ctx, Account);
69 W_ERROR_HAVE_NO_MEMORY(r->in.admin_account);
73 r->in.admin_password = talloc_strdup(mem_ctx, password);
74 W_ERROR_HAVE_NO_MEMORY(r->in.admin_password);
77 r->in.join_flags = join_flags;
78 r->in.modify_config = true;
80 return libnet_Join(mem_ctx, r);
83 static WERROR NetJoinDomainRemote(struct libnetapi_ctx *ctx,
84 const char *server_name,
85 const char *domain_name,
86 const char *account_ou,
91 struct cli_state *cli = NULL;
92 struct rpc_pipe_client *pipe_cli = NULL;
93 struct wkssvc_PasswordBuffer *encrypted_password = NULL;
96 unsigned int old_timeout = 0;
98 status = cli_full_connection(&cli, NULL, server_name,
106 if (!NT_STATUS_IS_OK(status)) {
107 werr = ntstatus_to_werror(status);
111 pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_WKSSVC,
114 werr = ntstatus_to_werror(status);
119 encode_wkssvc_join_password_buffer(ctx,
121 &cli->user_session_key,
122 &encrypted_password);
125 old_timeout = cli_set_timeout(cli, 60000);
127 status = rpccli_wkssvc_NetrJoinDomain2(pipe_cli, ctx,
128 server_name, domain_name,
132 if (!NT_STATUS_IS_OK(status)) {
133 werr = ntstatus_to_werror(status);
139 cli_set_timeout(cli, old_timeout);
146 static WERROR libnetapi_NetJoinDomain(struct libnetapi_ctx *ctx,
147 const char *server_name,
148 const char *domain_name,
149 const char *account_ou,
151 const char *password,
155 return WERR_INVALID_PARAM;
158 if (!server_name || is_myname_or_ipaddr(server_name)) {
160 return NetJoinDomainLocal(ctx,
169 return NetJoinDomainRemote(ctx,
178 NET_API_STATUS NetJoinDomain(const char *server_name,
179 const char *domain_name,
180 const char *account_ou,
182 const char *password,
185 struct libnetapi_ctx *ctx = NULL;
186 NET_API_STATUS status;
189 status = libnetapi_getctx(&ctx);
194 werr = libnetapi_NetJoinDomain(ctx,
201 if (!W_ERROR_IS_OK(werr)) {
202 return W_ERROR_V(werr);
208 static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx,
209 const char *server_name,
211 const char *password,
212 uint32_t unjoin_flags)
214 struct libnet_UnjoinCtx *r = NULL;
215 struct dom_sid domain_sid;
218 if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
219 return WERR_SETUP_NOT_JOINED;
222 werr = libnet_init_UnjoinCtx(mem_ctx, &r);
223 W_ERROR_NOT_OK_RETURN(werr);
226 r->in.dc_name = talloc_strdup(mem_ctx, server_name);
227 W_ERROR_HAVE_NO_MEMORY(r->in.dc_name);
231 const char *domain = NULL;
232 struct DS_DOMAIN_CONTROLLER_INFO *info = NULL;
233 uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
234 DS_WRITABLE_REQUIRED |
239 domain = lp_workgroup();
241 status = DsGetDcName(mem_ctx, NULL, domain,
242 NULL, NULL, flags, &info);
243 if (!NT_STATUS_IS_OK(status)) {
244 return ntstatus_to_werror(status);
246 r->in.dc_name = talloc_strdup(mem_ctx,
247 info->domain_controller_name);
248 W_ERROR_HAVE_NO_MEMORY(r->in.dc_name);
252 r->in.admin_account = talloc_strdup(mem_ctx, account);
253 W_ERROR_HAVE_NO_MEMORY(r->in.admin_account);
257 r->in.admin_password = talloc_strdup(mem_ctx, password);
258 W_ERROR_HAVE_NO_MEMORY(r->in.admin_password);
261 r->in.unjoin_flags = unjoin_flags;
262 r->in.modify_config = true;
264 r->in.domain_sid = &domain_sid;
266 return libnet_Unjoin(mem_ctx, r);
270 static WERROR NetUnjoinDomainRemote(struct libnetapi_ctx *ctx,
271 const char *server_name,
273 const char *password,
274 uint32_t unjoin_flags)
276 struct cli_state *cli = NULL;
277 struct rpc_pipe_client *pipe_cli = NULL;
278 struct wkssvc_PasswordBuffer *encrypted_password = NULL;
281 unsigned int old_timeout = 0;
283 status = cli_full_connection(&cli, NULL, server_name,
291 if (!NT_STATUS_IS_OK(status)) {
292 werr = ntstatus_to_werror(status);
296 pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_WKSSVC,
299 werr = ntstatus_to_werror(status);
304 encode_wkssvc_join_password_buffer(ctx,
306 &cli->user_session_key,
307 &encrypted_password);
310 old_timeout = cli_set_timeout(cli, 60000);
312 status = rpccli_wkssvc_NetrUnjoinDomain2(pipe_cli, ctx,
318 if (!NT_STATUS_IS_OK(status)) {
319 werr = ntstatus_to_werror(status);
325 cli_set_timeout(cli, old_timeout);
332 static WERROR libnetapi_NetUnjoinDomain(struct libnetapi_ctx *ctx,
333 const char *server_name,
335 const char *password,
336 uint32_t unjoin_flags)
338 if (!server_name || is_myname_or_ipaddr(server_name)) {
340 return NetUnjoinDomainLocal(ctx,
347 return NetUnjoinDomainRemote(ctx,
354 NET_API_STATUS NetUnjoinDomain(const char *server_name,
356 const char *password,
357 uint32_t unjoin_flags)
359 struct libnetapi_ctx *ctx = NULL;
360 NET_API_STATUS status;
363 status = libnetapi_getctx(&ctx);
368 werr = libnetapi_NetUnjoinDomain(ctx,
373 if (!W_ERROR_IS_OK(werr)) {
374 return W_ERROR_V(werr);
380 static WERROR NetGetJoinInformationRemote(struct libnetapi_ctx *ctx,
381 const char *server_name,
382 const char **name_buffer,
385 struct cli_state *cli = NULL;
386 struct rpc_pipe_client *pipe_cli = NULL;
390 status = cli_full_connection(&cli, NULL, server_name,
398 if (!NT_STATUS_IS_OK(status)) {
399 werr = ntstatus_to_werror(status);
403 pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_WKSSVC,
406 werr = ntstatus_to_werror(status);
410 status = rpccli_wkssvc_NetrGetJoinInformation(pipe_cli, ctx,
413 (enum wkssvc_NetJoinStatus *)name_type,
415 if (!NT_STATUS_IS_OK(status)) {
416 werr = ntstatus_to_werror(status);
428 static WERROR NetGetJoinInformationLocal(struct libnetapi_ctx *ctx,
429 const char *server_name,
430 const char **name_buffer,
433 if ((lp_security() == SEC_ADS) && lp_realm()) {
434 *name_buffer = SMB_STRDUP(lp_realm());
436 *name_buffer = SMB_STRDUP(lp_workgroup());
442 switch (lp_server_role()) {
443 case ROLE_DOMAIN_MEMBER:
444 case ROLE_DOMAIN_PDC:
445 case ROLE_DOMAIN_BDC:
446 *name_type = NetSetupDomainName;
448 case ROLE_STANDALONE:
450 *name_type = NetSetupWorkgroupName;
457 static WERROR libnetapi_NetGetJoinInformation(struct libnetapi_ctx *ctx,
458 const char *server_name,
459 const char **name_buffer,
462 if (!server_name || is_myname_or_ipaddr(server_name)) {
463 return NetGetJoinInformationLocal(ctx,
469 return NetGetJoinInformationRemote(ctx,
475 NET_API_STATUS NetGetJoinInformation(const char *server_name,
476 const char **name_buffer,
479 struct libnetapi_ctx *ctx = NULL;
480 NET_API_STATUS status;
483 status = libnetapi_getctx(&ctx);
488 werr = libnetapi_NetGetJoinInformation(ctx,
492 if (!W_ERROR_IS_OK(werr)) {
493 return W_ERROR_V(werr);