Second part of fix for bug #8663 - deleting a symlink fails if the symlink target...
[kai/samba.git] / source3 / utils / net_rpc_join.c
1 /*
2    Samba Unix/Linux SMB client library
3    Distributed SMB/CIFS Server Management Utility
4    Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
5    Copyright (C) Tim Potter     2001
6    Copyright (C) 2008 Guenther Deschner
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
21 #include "includes.h"
22 #include "utils/net.h"
23 #include "rpc_client/cli_pipe.h"
24 #include "../libcli/auth/libcli_auth.h"
25 #include "../librpc/gen_ndr/ndr_lsa_c.h"
26 #include "rpc_client/cli_lsarpc.h"
27 #include "../librpc/gen_ndr/ndr_samr_c.h"
28 #include "rpc_client/init_samr.h"
29 #include "../librpc/gen_ndr/ndr_netlogon.h"
30 #include "rpc_client/cli_netlogon.h"
31 #include "secrets.h"
32 #include "rpc_client/init_lsa.h"
33 #include "libsmb/libsmb.h"
34
35 /* Macro for checking RPC error codes to make things more readable */
36
37 #define CHECK_RPC_ERR(rpc, msg) \
38         if (!NT_STATUS_IS_OK(status = rpc)) { \
39                 DEBUG(0, (msg ": %s\n", nt_errstr(status))); \
40                 goto done; \
41         }
42
43 #define CHECK_DCERPC_ERR(rpc, msg) \
44         if (!NT_STATUS_IS_OK(status = rpc)) { \
45                 DEBUG(0, (msg ": %s\n", nt_errstr(status))); \
46                 goto done; \
47         } \
48         if (!NT_STATUS_IS_OK(result)) { \
49                 status = result; \
50                 DEBUG(0, (msg ": %s\n", nt_errstr(result))); \
51                 goto done; \
52         }
53
54
55 #define CHECK_RPC_ERR_DEBUG(rpc, debug_args) \
56         if (!NT_STATUS_IS_OK(status = rpc)) { \
57                 DEBUG(0, debug_args); \
58                 goto done; \
59         }
60
61 #define CHECK_DCERPC_ERR_DEBUG(rpc, debug_args) \
62         if (!NT_STATUS_IS_OK(status = rpc)) { \
63                 DEBUG(0, debug_args); \
64                 goto done; \
65         } \
66         if (!NT_STATUS_IS_OK(result)) { \
67                 status = result; \
68                 DEBUG(0, debug_args); \
69                 goto done; \
70         }
71
72
73 /**
74  * confirm that a domain join is still valid
75  *
76  * @return A shell status integer (0 for success)
77  *
78  **/
79 NTSTATUS net_rpc_join_ok(struct net_context *c, const char *domain,
80                          const char *server,
81                          const struct sockaddr_storage *server_ss)
82 {
83         enum security_types sec;
84         unsigned int conn_flags = NET_FLAGS_PDC;
85         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
86         struct cli_state *cli = NULL;
87         struct rpc_pipe_client *pipe_hnd = NULL;
88         struct rpc_pipe_client *netlogon_pipe = NULL;
89         NTSTATUS ntret = NT_STATUS_UNSUCCESSFUL;
90
91         sec = (enum security_types)lp_security();
92
93         if (sec == SEC_ADS) {
94                 /* Connect to IPC$ using machine account's credentials. We don't use anonymous
95                    connection here, as it may be denied by server's local policy. */
96                 net_use_machine_account(c);
97
98         } else {
99                 /* some servers (e.g. WinNT) don't accept machine-authenticated
100                    smb connections */
101                 conn_flags |= NET_FLAGS_ANONYMOUS;
102         }
103
104         /* Connect to remote machine */
105         ntret = net_make_ipc_connection_ex(c, domain, server, server_ss,
106                                            conn_flags, &cli);
107         if (!NT_STATUS_IS_OK(ntret)) {
108                 return ntret;
109         }
110
111         /* Setup the creds as though we're going to do schannel... */
112         ntret = get_schannel_session_key(cli, domain, &neg_flags,
113                                          &netlogon_pipe);
114
115         /* We return NT_STATUS_INVALID_NETWORK_RESPONSE if the server is refusing
116            to negotiate schannel, but the creds were set up ok. That'll have to do. */
117
118         if (!NT_STATUS_IS_OK(ntret)) {
119                 if (NT_STATUS_EQUAL(ntret, NT_STATUS_INVALID_NETWORK_RESPONSE)) {
120                         cli_shutdown(cli);
121                         return NT_STATUS_OK;
122                 } else {
123                         DEBUG(0,("net_rpc_join_ok: failed to get schannel session "
124                                         "key from server %s for domain %s. Error was %s\n",
125                                 cli_state_remote_name(cli), domain, nt_errstr(ntret) ));
126                         cli_shutdown(cli);
127                         return ntret;
128                 }
129         }
130
131         /* Only do the rest of the schannel test if the client is allowed to do this. */
132         if (!lp_client_schannel()) {
133                 cli_shutdown(cli);
134                 /* We're good... */
135                 return ntret;
136         }
137
138         ntret = cli_rpc_pipe_open_schannel_with_key(
139                 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
140                 DCERPC_AUTH_LEVEL_PRIVACY,
141                 domain, &netlogon_pipe->dc, &pipe_hnd);
142
143         if (!NT_STATUS_IS_OK(ntret)) {
144                 DEBUG(0,("net_rpc_join_ok: failed to open schannel session "
145                                 "on netlogon pipe to server %s for domain %s. Error was %s\n",
146                         cli_state_remote_name(cli), domain, nt_errstr(ntret) ));
147                 /*
148                  * Note: here, we have:
149                  * (pipe_hnd != NULL) if and only if NT_STATUS_IS_OK(ntret)
150                  */
151         }
152
153         cli_shutdown(cli);
154         return ntret;
155 }
156
157 /**
158  * Join a domain using the administrator username and password
159  *
160  * @param argc  Standard main() style argc
161  * @param argc  Standard main() style argv.  Initial components are already
162  *              stripped.  Currently not used.
163  * @return A shell status integer (0 for success)
164  *
165  **/
166
167 int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv)
168 {
169
170         /* libsmb variables */
171
172         struct cli_state *cli;
173         TALLOC_CTX *mem_ctx;
174         uint32 acb_info = ACB_WSTRUST;
175         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
176         enum netr_SchannelType sec_channel_type;
177         struct rpc_pipe_client *pipe_hnd = NULL;
178         struct dcerpc_binding_handle *b = NULL;
179
180         /* rpc variables */
181
182         struct policy_handle lsa_pol, sam_pol, domain_pol, user_pol;
183         struct dom_sid *domain_sid;
184         uint32 user_rid;
185
186         /* Password stuff */
187
188         char *clear_trust_password = NULL;
189         struct samr_CryptPassword crypt_pwd;
190         uchar md4_trust_password[16];
191         union samr_UserInfo set_info;
192
193         /* Misc */
194
195         NTSTATUS status, result;
196         int retval = 1;
197         const char *domain = NULL;
198         char *acct_name;
199         struct lsa_String lsa_acct_name;
200         uint32 acct_flags=0;
201         uint32_t access_granted = 0;
202         union lsa_PolicyInformation *info = NULL;
203         struct samr_Ids user_rids;
204         struct samr_Ids name_types;
205
206
207         /* check what type of join */
208         if (argc >= 0) {
209                 sec_channel_type = get_sec_channel_type(argv[0]);
210         } else {
211                 sec_channel_type = get_sec_channel_type(NULL);
212         }
213
214         switch (sec_channel_type) {
215         case SEC_CHAN_WKSTA:
216                 acb_info = ACB_WSTRUST;
217                 break;
218         case SEC_CHAN_BDC:
219                 acb_info = ACB_SVRTRUST;
220                 break;
221 #if 0
222         case SEC_CHAN_DOMAIN:
223                 acb_info = ACB_DOMTRUST;
224                 break;
225 #endif
226         default:
227                 DEBUG(0,("secure channel type %d not yet supported\n",
228                         sec_channel_type));
229                 break;
230         }
231
232         /* Make authenticated connection to remote machine */
233
234         status = net_make_ipc_connection(c, NET_FLAGS_PDC, &cli);
235         if (!NT_STATUS_IS_OK(status)) {
236                 return 1;
237         }
238
239         if (!(mem_ctx = talloc_init("net_rpc_join_newstyle"))) {
240                 DEBUG(0, ("Could not initialise talloc context\n"));
241                 goto done;
242         }
243
244         /* Fetch domain sid */
245
246         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
247                                           &pipe_hnd);
248         if (!NT_STATUS_IS_OK(status)) {
249                 DEBUG(0, ("Error connecting to LSA pipe. Error was %s\n",
250                         nt_errstr(status) ));
251                 goto done;
252         }
253
254         b = pipe_hnd->binding_handle;
255
256         CHECK_RPC_ERR(rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true,
257                                           SEC_FLAG_MAXIMUM_ALLOWED,
258                                           &lsa_pol),
259                       "error opening lsa policy handle");
260
261         CHECK_DCERPC_ERR(dcerpc_lsa_QueryInfoPolicy(b, mem_ctx,
262                                                     &lsa_pol,
263                                                     LSA_POLICY_INFO_ACCOUNT_DOMAIN,
264                                                     &info,
265                                                     &result),
266                       "error querying info policy");
267
268         domain = info->account_domain.name.string;
269         domain_sid = info->account_domain.sid;
270
271         dcerpc_lsa_Close(b, mem_ctx, &lsa_pol, &result);
272         TALLOC_FREE(pipe_hnd); /* Done with this pipe */
273
274         /* Bail out if domain didn't get set. */
275         if (!domain) {
276                 DEBUG(0, ("Could not get domain name.\n"));
277                 goto done;
278         }
279
280         /* Create domain user */
281         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_samr.syntax_id,
282                                           &pipe_hnd);
283         if (!NT_STATUS_IS_OK(status)) {
284                 DEBUG(0, ("Error connecting to SAM pipe. Error was %s\n",
285                         nt_errstr(status) ));
286                 goto done;
287         }
288
289         b = pipe_hnd->binding_handle;
290
291         CHECK_DCERPC_ERR(dcerpc_samr_Connect2(b, mem_ctx,
292                                               pipe_hnd->desthost,
293                                               SAMR_ACCESS_ENUM_DOMAINS
294                                               | SAMR_ACCESS_LOOKUP_DOMAIN,
295                                               &sam_pol,
296                                               &result),
297                       "could not connect to SAM database");
298
299
300         CHECK_DCERPC_ERR(dcerpc_samr_OpenDomain(b, mem_ctx,
301                                                 &sam_pol,
302                                                 SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
303                                                 | SAMR_DOMAIN_ACCESS_CREATE_USER
304                                                 | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
305                                                 domain_sid,
306                                                 &domain_pol,
307                                                 &result),
308                       "could not open domain");
309
310         /* Create domain user */
311         if ((acct_name = talloc_asprintf(mem_ctx, "%s$", lp_netbios_name())) == NULL) {
312                 status = NT_STATUS_NO_MEMORY;
313                 goto done;
314         }
315         strlower_m(acct_name);
316
317         init_lsa_String(&lsa_acct_name, acct_name);
318
319         acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE |
320                      SEC_STD_WRITE_DAC | SEC_STD_DELETE |
321                      SAMR_USER_ACCESS_SET_PASSWORD |
322                      SAMR_USER_ACCESS_GET_ATTRIBUTES |
323                      SAMR_USER_ACCESS_SET_ATTRIBUTES;
324
325         DEBUG(10, ("Creating account with flags: %d\n",acct_flags));
326
327         status = dcerpc_samr_CreateUser2(b, mem_ctx,
328                                          &domain_pol,
329                                          &lsa_acct_name,
330                                          acb_info,
331                                          acct_flags,
332                                          &user_pol,
333                                          &access_granted,
334                                          &user_rid,
335                                          &result);
336         if (!NT_STATUS_IS_OK(status)) {
337                 goto done;
338         }
339         if (!NT_STATUS_IS_OK(result) &&
340             !NT_STATUS_EQUAL(result, NT_STATUS_USER_EXISTS)) {
341                 status = result;
342                 d_fprintf(stderr,_("Creation of workstation account failed\n"));
343
344                 /* If NT_STATUS_ACCESS_DENIED then we have a valid
345                    username/password combo but the user does not have
346                    administrator access. */
347
348                 if (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED))
349                         d_fprintf(stderr, _("User specified does not have "
350                                             "administrator privileges\n"));
351
352                 goto done;
353         }
354
355         /* We *must* do this.... don't ask... */
356
357         if (NT_STATUS_IS_OK(result)) {
358                 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
359         }
360
361         CHECK_DCERPC_ERR_DEBUG(dcerpc_samr_LookupNames(b, mem_ctx,
362                                                        &domain_pol,
363                                                        1,
364                                                        &lsa_acct_name,
365                                                        &user_rids,
366                                                        &name_types,
367                                                        &result),
368                             ("error looking up rid for user %s: %s/%s\n",
369                              acct_name, nt_errstr(status), nt_errstr(result)));
370
371         if (name_types.ids[0] != SID_NAME_USER) {
372                 DEBUG(0, ("%s is not a user account (type=%d)\n", acct_name, name_types.ids[0]));
373                 goto done;
374         }
375
376         user_rid = user_rids.ids[0];
377
378         /* Open handle on user */
379
380         CHECK_DCERPC_ERR_DEBUG(
381                 dcerpc_samr_OpenUser(b, mem_ctx,
382                                      &domain_pol,
383                                      SEC_FLAG_MAXIMUM_ALLOWED,
384                                      user_rid,
385                                      &user_pol,
386                                      &result),
387                 ("could not re-open existing user %s: %s/%s\n",
388                  acct_name, nt_errstr(status), nt_errstr(result)));
389         
390         /* Create a random machine account password */
391
392         clear_trust_password = generate_random_str(talloc_tos(), DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
393         E_md4hash(clear_trust_password, md4_trust_password);
394
395         /* Set password on machine account */
396
397         init_samr_CryptPassword(clear_trust_password,
398                                 &cli->user_session_key,
399                                 &crypt_pwd);
400
401         set_info.info24.password = crypt_pwd;
402         set_info.info24.password_expired = PASS_DONT_CHANGE_AT_NEXT_LOGON;
403
404         CHECK_DCERPC_ERR(dcerpc_samr_SetUserInfo2(b, mem_ctx,
405                                                   &user_pol,
406                                                   24,
407                                                   &set_info,
408                                                   &result),
409                       "error setting trust account password");
410
411         /* Why do we have to try to (re-)set the ACB to be the same as what
412            we passed in the samr_create_dom_user() call?  When a NT
413            workstation is joined to a domain by an administrator the
414            acb_info is set to 0x80.  For a normal user with "Add
415            workstations to the domain" rights the acb_info is 0x84.  I'm
416            not sure whether it is supposed to make a difference or not.  NT
417            seems to cope with either value so don't bomb out if the set
418            userinfo2 level 0x10 fails.  -tpot */
419
420         set_info.info16.acct_flags = acb_info;
421
422         /* Ignoring the return value is necessary for joining a domain
423            as a normal user with "Add workstation to domain" privilege. */
424
425         status = dcerpc_samr_SetUserInfo(b, mem_ctx,
426                                          &user_pol,
427                                          16,
428                                          &set_info,
429                                          &result);
430
431         dcerpc_samr_Close(b, mem_ctx, &user_pol, &result);
432         TALLOC_FREE(pipe_hnd); /* Done with this pipe */
433
434         /* Now check the whole process from top-to-bottom */
435
436         status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
437                                           &pipe_hnd);
438         if (!NT_STATUS_IS_OK(status)) {
439                 DEBUG(0,("Error connecting to NETLOGON pipe. Error was %s\n",
440                         nt_errstr(status) ));
441                 goto done;
442         }
443
444         status = rpccli_netlogon_setup_creds(pipe_hnd,
445                                         pipe_hnd->desthost, /* server name */
446                                         domain,        /* domain */
447                                         lp_netbios_name(), /* client name */
448                                         lp_netbios_name(), /* machine account name */
449                                         md4_trust_password,
450                                         sec_channel_type,
451                                         &neg_flags);
452
453         if (!NT_STATUS_IS_OK(status)) {
454                 DEBUG(0, ("Error in domain join verification (credential setup failed): %s\n\n",
455                           nt_errstr(status)));
456
457                 if ( NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
458                      (sec_channel_type == SEC_CHAN_BDC) ) {
459                         d_fprintf(stderr, _("Please make sure that no computer "
460                                             "account\nnamed like this machine "
461                                             "(%s) exists in the domain\n"),
462                                  lp_netbios_name());
463                 }
464
465                 goto done;
466         }
467
468         /* We can only check the schannel connection if the client is allowed
469            to do this and the server supports it. If not, just assume success
470            (after all the rpccli_netlogon_setup_creds() succeeded, and we'll
471            do the same again (setup creds) in net_rpc_join_ok(). JRA. */
472
473         if (lp_client_schannel() && (neg_flags & NETLOGON_NEG_SCHANNEL)) {
474                 struct rpc_pipe_client *netlogon_schannel_pipe;
475
476                 status = cli_rpc_pipe_open_schannel_with_key(
477                         cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
478                         DCERPC_AUTH_LEVEL_PRIVACY, domain, &pipe_hnd->dc,
479                         &netlogon_schannel_pipe);
480
481                 if (!NT_STATUS_IS_OK(status)) {
482                         DEBUG(0, ("Error in domain join verification (schannel setup failed): %s\n\n",
483                                   nt_errstr(status)));
484
485                         if ( NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
486                              (sec_channel_type == SEC_CHAN_BDC) ) {
487                                 d_fprintf(stderr, _("Please make sure that no "
488                                                     "computer account\nnamed "
489                                                     "like this machine (%s) "
490                                                     "exists in the domain\n"),
491                                          lp_netbios_name());
492                         }
493
494                         goto done;
495                 }
496                 TALLOC_FREE(netlogon_schannel_pipe);
497         }
498
499         TALLOC_FREE(pipe_hnd);
500
501         /* Now store the secret in the secrets database */
502
503         strupper_m(discard_const_p(char, domain));
504
505         if (!secrets_store_domain_sid(domain, domain_sid)) {
506                 DEBUG(0, ("error storing domain sid for %s\n", domain));
507                 goto done;
508         }
509
510         if (!secrets_store_machine_password(clear_trust_password, domain, sec_channel_type)) {
511                 DEBUG(0, ("error storing plaintext domain secrets for %s\n", domain));
512         }
513
514         /* double-check, connection from scratch */
515         status = net_rpc_join_ok(c, domain, cli_state_remote_name(cli),
516                                  cli_state_remote_sockaddr(cli));
517         retval = NT_STATUS_IS_OK(status) ? 0 : -1;
518
519 done:
520
521         /* Display success or failure */
522
523         if (domain) {
524                 if (retval != 0) {
525                         fprintf(stderr,_("Unable to join domain %s.\n"),domain);
526                 } else {
527                         printf(_("Joined domain %s.\n"),domain);
528                 }
529         }
530
531         cli_shutdown(cli);
532
533         TALLOC_FREE(clear_trust_password);
534
535         return retval;
536 }
537
538 /**
539  * check that a join is OK
540  *
541  * @return A shell status integer (0 for success)
542  *
543  **/
544 int net_rpc_testjoin(struct net_context *c, int argc, const char **argv)
545 {
546         NTSTATUS nt_status;
547
548         if (c->display_usage) {
549                 d_printf(_("Usage\n"
550                            "net rpc testjoin\n"
551                            "    Test if a join is OK\n"));
552                 return 0;
553         }
554
555         /* Display success or failure */
556         nt_status = net_rpc_join_ok(c, c->opt_target_workgroup, NULL, NULL);
557         if (!NT_STATUS_IS_OK(nt_status)) {
558                 fprintf(stderr, _("Join to domain '%s' is not valid: %s\n"),
559                         c->opt_target_workgroup, nt_errstr(nt_status));
560                 return -1;
561         }
562
563         printf(_("Join to '%s' is OK\n"), c->opt_target_workgroup);
564         return 0;
565 }