Add NetUserDel to libnetapi.
[Samba/gbeck.git] / source / lib / netapi / joindomain.c
blob48a6a91888d0c8d66e3aca4e4270a182c756c6e1
1 /*
2 * Unix SMB/CIFS implementation.
3 * NetApi Join Support
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/>.
20 #include "includes.h"
22 #include "librpc/gen_ndr/libnetapi.h"
23 #include "lib/netapi/netapi.h"
24 #include "lib/netapi/libnetapi.h"
25 #include "libnet/libnet.h"
27 /****************************************************************
28 ****************************************************************/
30 WERROR NetJoinDomain_l(struct libnetapi_ctx *mem_ctx,
31 struct NetJoinDomain *r)
33 struct libnet_JoinCtx *j = NULL;
34 WERROR werr;
36 if (!r->in.domain) {
37 return WERR_INVALID_PARAM;
40 werr = libnet_init_JoinCtx(mem_ctx, &j);
41 W_ERROR_NOT_OK_RETURN(werr);
43 j->in.domain_name = talloc_strdup(mem_ctx, r->in.domain);
44 W_ERROR_HAVE_NO_MEMORY(j->in.domain_name);
46 if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
47 NTSTATUS status;
48 struct netr_DsRGetDCNameInfo *info = NULL;
49 uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
50 DS_WRITABLE_REQUIRED |
51 DS_RETURN_DNS_NAME;
52 status = dsgetdcname(mem_ctx, r->in.domain,
53 NULL, NULL, flags, &info);
54 if (!NT_STATUS_IS_OK(status)) {
55 libnetapi_set_error_string(mem_ctx,
56 "%s", get_friendly_nt_error_msg(status));
57 return ntstatus_to_werror(status);
59 j->in.dc_name = talloc_strdup(mem_ctx,
60 info->dc_unc);
61 W_ERROR_HAVE_NO_MEMORY(j->in.dc_name);
64 if (r->in.account_ou) {
65 j->in.account_ou = talloc_strdup(mem_ctx, r->in.account_ou);
66 W_ERROR_HAVE_NO_MEMORY(j->in.account_ou);
69 if (r->in.account) {
70 j->in.admin_account = talloc_strdup(mem_ctx, r->in.account);
71 W_ERROR_HAVE_NO_MEMORY(j->in.admin_account);
74 if (r->in.password) {
75 j->in.admin_password = talloc_strdup(mem_ctx, r->in.password);
76 W_ERROR_HAVE_NO_MEMORY(j->in.admin_password);
79 j->in.join_flags = r->in.join_flags;
80 j->in.modify_config = true;
81 j->in.debug = true;
83 werr = libnet_Join(mem_ctx, j);
84 if (!W_ERROR_IS_OK(werr) && j->out.error_string) {
85 libnetapi_set_error_string(mem_ctx, "%s", j->out.error_string);
87 TALLOC_FREE(j);
89 return werr;
92 /****************************************************************
93 ****************************************************************/
95 WERROR NetJoinDomain_r(struct libnetapi_ctx *ctx,
96 struct NetJoinDomain *r)
98 struct cli_state *cli = NULL;
99 struct rpc_pipe_client *pipe_cli = NULL;
100 struct wkssvc_PasswordBuffer *encrypted_password = NULL;
101 NTSTATUS status;
102 WERROR werr;
103 unsigned int old_timeout = 0;
105 status = cli_full_connection(&cli, NULL, r->in.server,
106 NULL, 0,
107 "IPC$", "IPC",
108 ctx->username,
109 ctx->workgroup,
110 ctx->password,
111 CLI_FULL_CONNECTION_USE_KERBEROS |
112 CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS,
113 Undefined, NULL);
115 if (!NT_STATUS_IS_OK(status)) {
116 werr = ntstatus_to_werror(status);
117 goto done;
120 pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_WKSSVC,
121 &status);
122 if (!pipe_cli) {
123 werr = ntstatus_to_werror(status);
124 goto done;
127 if (r->in.password) {
128 encode_wkssvc_join_password_buffer(ctx,
129 r->in.password,
130 &cli->user_session_key,
131 &encrypted_password);
134 old_timeout = cli_set_timeout(cli, 600000);
136 status = rpccli_wkssvc_NetrJoinDomain2(pipe_cli, ctx,
137 r->in.server,
138 r->in.domain,
139 r->in.account_ou,
140 r->in.account,
141 encrypted_password,
142 r->in.join_flags,
143 &werr);
144 if (!NT_STATUS_IS_OK(status)) {
145 werr = ntstatus_to_werror(status);
146 goto done;
149 done:
150 if (cli) {
151 if (old_timeout) {
152 cli_set_timeout(cli, old_timeout);
154 cli_shutdown(cli);
157 return werr;
159 /****************************************************************
160 ****************************************************************/
162 WERROR NetUnjoinDomain_l(struct libnetapi_ctx *mem_ctx,
163 struct NetUnjoinDomain *r)
165 struct libnet_UnjoinCtx *u = NULL;
166 struct dom_sid domain_sid;
167 const char *domain = NULL;
168 WERROR werr;
170 if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
171 return WERR_SETUP_NOT_JOINED;
174 werr = libnet_init_UnjoinCtx(mem_ctx, &u);
175 W_ERROR_NOT_OK_RETURN(werr);
177 if (lp_realm()) {
178 domain = lp_realm();
179 } else {
180 domain = lp_workgroup();
183 if (r->in.server_name) {
184 u->in.dc_name = talloc_strdup(mem_ctx, r->in.server_name);
185 W_ERROR_HAVE_NO_MEMORY(u->in.dc_name);
186 } else {
187 NTSTATUS status;
188 struct netr_DsRGetDCNameInfo *info = NULL;
189 uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
190 DS_WRITABLE_REQUIRED |
191 DS_RETURN_DNS_NAME;
192 status = dsgetdcname(mem_ctx, domain,
193 NULL, NULL, flags, &info);
194 if (!NT_STATUS_IS_OK(status)) {
195 libnetapi_set_error_string(mem_ctx,
196 "failed to find DC for domain %s: %s",
197 domain,
198 get_friendly_nt_error_msg(status));
199 return ntstatus_to_werror(status);
201 u->in.dc_name = talloc_strdup(mem_ctx,
202 info->dc_unc);
203 W_ERROR_HAVE_NO_MEMORY(u->in.dc_name);
205 u->in.domain_name = domain;
208 if (r->in.account) {
209 u->in.admin_account = talloc_strdup(mem_ctx, r->in.account);
210 W_ERROR_HAVE_NO_MEMORY(u->in.admin_account);
213 if (r->in.password) {
214 u->in.admin_password = talloc_strdup(mem_ctx, r->in.password);
215 W_ERROR_HAVE_NO_MEMORY(u->in.admin_password);
218 u->in.domain_name = domain;
219 u->in.unjoin_flags = r->in.unjoin_flags;
220 u->in.modify_config = true;
221 u->in.debug = true;
223 u->in.domain_sid = &domain_sid;
225 werr = libnet_Unjoin(mem_ctx, u);
226 if (!W_ERROR_IS_OK(werr) && u->out.error_string) {
227 libnetapi_set_error_string(mem_ctx, "%s", u->out.error_string);
229 TALLOC_FREE(u);
231 return werr;
234 /****************************************************************
235 ****************************************************************/
237 WERROR NetUnjoinDomain_r(struct libnetapi_ctx *ctx,
238 struct NetUnjoinDomain *r)
240 struct cli_state *cli = NULL;
241 struct rpc_pipe_client *pipe_cli = NULL;
242 struct wkssvc_PasswordBuffer *encrypted_password = NULL;
243 NTSTATUS status;
244 WERROR werr;
245 unsigned int old_timeout = 0;
247 status = cli_full_connection(&cli, NULL, r->in.server_name,
248 NULL, 0,
249 "IPC$", "IPC",
250 ctx->username,
251 ctx->workgroup,
252 ctx->password,
253 CLI_FULL_CONNECTION_USE_KERBEROS |
254 CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS,
255 Undefined, NULL);
257 if (!NT_STATUS_IS_OK(status)) {
258 werr = ntstatus_to_werror(status);
259 goto done;
262 pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_WKSSVC,
263 &status);
264 if (!pipe_cli) {
265 werr = ntstatus_to_werror(status);
266 goto done;
269 if (r->in.password) {
270 encode_wkssvc_join_password_buffer(ctx,
271 r->in.password,
272 &cli->user_session_key,
273 &encrypted_password);
276 old_timeout = cli_set_timeout(cli, 60000);
278 status = rpccli_wkssvc_NetrUnjoinDomain2(pipe_cli, ctx,
279 r->in.server_name,
280 r->in.account,
281 encrypted_password,
282 r->in.unjoin_flags,
283 &werr);
284 if (!NT_STATUS_IS_OK(status)) {
285 werr = ntstatus_to_werror(status);
286 goto done;
289 done:
290 if (cli) {
291 cli_set_timeout(cli, old_timeout);
292 cli_shutdown(cli);
295 return werr;
298 /****************************************************************
299 ****************************************************************/
301 WERROR NetGetJoinInformation_r(struct libnetapi_ctx *ctx,
302 struct NetGetJoinInformation *r)
304 struct cli_state *cli = NULL;
305 struct rpc_pipe_client *pipe_cli = NULL;
306 NTSTATUS status;
307 WERROR werr;
309 status = cli_full_connection(&cli, NULL, r->in.server_name,
310 NULL, 0,
311 "IPC$", "IPC",
312 ctx->username,
313 ctx->workgroup,
314 ctx->password,
315 CLI_FULL_CONNECTION_USE_KERBEROS |
316 CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS,
317 Undefined, NULL);
319 if (!NT_STATUS_IS_OK(status)) {
320 werr = ntstatus_to_werror(status);
321 goto done;
324 pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_WKSSVC,
325 &status);
326 if (!pipe_cli) {
327 werr = ntstatus_to_werror(status);
328 goto done;
331 status = rpccli_wkssvc_NetrGetJoinInformation(pipe_cli, ctx,
332 r->in.server_name,
333 r->out.name_buffer,
334 (enum wkssvc_NetJoinStatus *)r->out.name_type,
335 &werr);
336 if (!NT_STATUS_IS_OK(status)) {
337 werr = ntstatus_to_werror(status);
338 goto done;
341 done:
342 if (cli) {
343 cli_shutdown(cli);
346 return werr;
349 /****************************************************************
350 ****************************************************************/
352 WERROR NetGetJoinInformation_l(struct libnetapi_ctx *ctx,
353 struct NetGetJoinInformation *r)
355 if ((lp_security() == SEC_ADS) && lp_realm()) {
356 *r->out.name_buffer = talloc_strdup(ctx, lp_realm());
357 } else {
358 *r->out.name_buffer = talloc_strdup(ctx, lp_workgroup());
360 if (!*r->out.name_buffer) {
361 return WERR_NOMEM;
364 switch (lp_server_role()) {
365 case ROLE_DOMAIN_MEMBER:
366 case ROLE_DOMAIN_PDC:
367 case ROLE_DOMAIN_BDC:
368 *r->out.name_type = NetSetupDomainName;
369 break;
370 case ROLE_STANDALONE:
371 default:
372 *r->out.name_type = NetSetupWorkgroupName;
373 break;
376 return WERR_OK;
379 /****************************************************************
380 ****************************************************************/
382 WERROR NetGetJoinableOUs_l(struct libnetapi_ctx *ctx,
383 struct NetGetJoinableOUs *r)
385 #ifdef WITH_ADS
386 NTSTATUS status;
387 ADS_STATUS ads_status;
388 ADS_STRUCT *ads = NULL;
389 struct netr_DsRGetDCNameInfo *info = NULL;
390 uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
391 DS_RETURN_DNS_NAME;
393 status = dsgetdcname(ctx, r->in.domain,
394 NULL, NULL, flags, &info);
395 if (!NT_STATUS_IS_OK(status)) {
396 libnetapi_set_error_string(ctx, "%s",
397 get_friendly_nt_error_msg(status));
398 return ntstatus_to_werror(status);
401 ads = ads_init(r->in.domain, r->in.domain, info->dc_unc);
402 if (!ads) {
403 return WERR_GENERAL_FAILURE;
406 SAFE_FREE(ads->auth.user_name);
407 if (r->in.account) {
408 ads->auth.user_name = SMB_STRDUP(r->in.account);
409 } else if (ctx->username) {
410 ads->auth.user_name = SMB_STRDUP(ctx->username);
413 SAFE_FREE(ads->auth.password);
414 if (r->in.password) {
415 ads->auth.password = SMB_STRDUP(r->in.password);
416 } else if (ctx->password) {
417 ads->auth.password = SMB_STRDUP(ctx->password);
420 ads_status = ads_connect(ads);
421 if (!ADS_ERR_OK(ads_status)) {
422 ads_destroy(&ads);
423 return WERR_DEFAULT_JOIN_REQUIRED;
426 ads_status = ads_get_joinable_ous(ads, ctx,
427 (char ***)r->out.ous,
428 (size_t *)r->out.ou_count);
429 if (!ADS_ERR_OK(ads_status)) {
430 ads_destroy(&ads);
431 return WERR_DEFAULT_JOIN_REQUIRED;
434 ads_destroy(&ads);
435 return WERR_OK;
436 #else
437 return WERR_NOT_SUPPORTED;
438 #endif
441 /****************************************************************
442 ****************************************************************/
444 WERROR NetGetJoinableOUs_r(struct libnetapi_ctx *ctx,
445 struct NetGetJoinableOUs *r)
447 struct cli_state *cli = NULL;
448 struct rpc_pipe_client *pipe_cli = NULL;
449 struct wkssvc_PasswordBuffer *encrypted_password = NULL;
450 NTSTATUS status;
451 WERROR werr;
453 status = cli_full_connection(&cli, NULL, r->in.server_name,
454 NULL, 0,
455 "IPC$", "IPC",
456 ctx->username,
457 ctx->workgroup,
458 ctx->password,
459 CLI_FULL_CONNECTION_USE_KERBEROS |
460 CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS,
461 Undefined, NULL);
463 if (!NT_STATUS_IS_OK(status)) {
464 werr = ntstatus_to_werror(status);
465 goto done;
468 pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_WKSSVC,
469 &status);
470 if (!pipe_cli) {
471 werr = ntstatus_to_werror(status);
472 goto done;
475 if (r->in.password) {
476 encode_wkssvc_join_password_buffer(ctx,
477 r->in.password,
478 &cli->user_session_key,
479 &encrypted_password);
482 status = rpccli_wkssvc_NetrGetJoinableOus2(pipe_cli, ctx,
483 r->in.server_name,
484 r->in.domain,
485 r->in.account,
486 encrypted_password,
487 r->out.ou_count,
488 r->out.ous,
489 &werr);
490 if (!NT_STATUS_IS_OK(status)) {
491 werr = ntstatus_to_werror(status);
492 goto done;
495 done:
496 if (cli) {
497 cli_shutdown(cli);
500 return werr;