s3:auth: Add support standalone server with MIT Keberos 1.21
[samba.git] / source3 / auth / auth_generic.c
1 /*
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    handle GENSEC authentication, server side
5
6    Copyright (C) Andrew Tridgell      2001
7    Copyright (C) Andrew Bartlett 2001-2003,2011
8    Copyright (C) Simo Sorce 2010.
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include <tevent.h>
26 #include "../lib/util/tevent_ntstatus.h"
27 #include "auth.h"
28 #include "../lib/tsocket/tsocket.h"
29 #include "auth/gensec/gensec.h"
30 #include "lib/param/param.h"
31 #ifdef HAVE_KRB5
32 #include "librpc/gen_ndr/ndr_krb5pac.h"
33 #include "auth/kerberos/pac_utils.h"
34 #include "nsswitch/libwbclient/wbclient.h"
35 #endif
36 #include "librpc/crypto/gse.h"
37 #include "auth/credentials/credentials.h"
38 #include "lib/param/loadparm.h"
39 #include "librpc/gen_ndr/dcerpc.h"
40 #include "source3/lib/substitute.h"
41
42 static NTSTATUS generate_pac_session_info(
43         TALLOC_CTX *mem_ctx,
44         const char *princ_name,
45         const char *rhost,
46         DATA_BLOB *pac_blob,
47         struct auth_session_info **psession_info)
48 {
49         NTSTATUS status;
50         struct wbcAuthUserParams params = {0};
51         struct wbcAuthUserInfo *info = NULL;
52         struct wbcAuthErrorInfo *err = NULL;
53         struct auth_serversupplied_info *server_info = NULL;
54         char *original_user_name = NULL;
55         char *p = NULL;
56         wbcErr wbc_err;
57
58         /*
59          * Let winbind decode the PAC.
60          * This will also store the user
61          * data in the netsamlogon cache.
62          *
63          * This used to be a cache prime
64          * optimization, but now we delegate
65          * all logic to winbindd, as we require
66          * winbindd as domain member anyway.
67          */
68         params.level = WBC_AUTH_USER_LEVEL_PAC;
69         params.password.pac.data = pac_blob->data;
70         params.password.pac.length = pac_blob->length;
71
72         /* we are contacting the privileged pipe */
73         become_root();
74         wbc_err = wbcAuthenticateUserEx(&params, &info, &err);
75         unbecome_root();
76
77         /*
78          * As this is merely a cache prime
79          * WBC_ERR_WINBIND_NOT_AVAILABLE
80          * is not a fatal error, treat it
81          * as success.
82          */
83
84         switch (wbc_err) {
85         case WBC_ERR_SUCCESS:
86                 break;
87         case WBC_ERR_WINBIND_NOT_AVAILABLE:
88                 status = NT_STATUS_NO_LOGON_SERVERS;
89                 DBG_ERR("winbindd not running - "
90                         "but required as domain member: %s\n",
91                         nt_errstr(status));
92                 return status;
93         case WBC_ERR_AUTH_ERROR:
94                 wbcFreeMemory(err);
95                 return NT_STATUS(err->nt_status);
96         case WBC_ERR_NO_MEMORY:
97                 return NT_STATUS_NO_MEMORY;
98         default:
99                 return NT_STATUS_LOGON_FAILURE;
100         }
101
102         status = make_server_info_wbcAuthUserInfo(mem_ctx,
103                                                   info->account_name,
104                                                   info->domain_name,
105                                                   info,
106                                                   &server_info);
107         wbcFreeMemory(info);
108         if (!NT_STATUS_IS_OK(status)) {
109                 DEBUG(10, ("make_server_info_wbcAuthUserInfo failed: %s\n",
110                            nt_errstr(status)));
111                 return status;
112         }
113
114         /* We skip doing this step if the caller asked us not to */
115         if (!(server_info->guest)) {
116                 const char *unix_username = server_info->unix_name;
117
118                 /* We might not be root if we are an RPC call */
119                 become_root();
120                 status = smb_pam_accountcheck(unix_username, rhost);
121                 unbecome_root();
122
123                 if (!NT_STATUS_IS_OK(status)) {
124                         DEBUG(3, ("check_ntlm_password:  PAM Account for user [%s] "
125                                           "FAILED with error %s\n",
126                                           unix_username, nt_errstr(status)));
127                         return status;
128                 }
129
130                 DEBUG(5, ("check_ntlm_password:  PAM Account for user [%s] "
131                           "succeeded\n", unix_username));
132         }
133
134         DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name));
135
136         p = strchr_m(princ_name, '@');
137         if (!p) {
138                 DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
139                                   princ_name));
140                 return NT_STATUS_LOGON_FAILURE;
141         }
142
143         original_user_name = talloc_strndup(mem_ctx,
144                                             princ_name,
145                                             p - princ_name);
146         if (original_user_name == NULL) {
147                 return NT_STATUS_NO_MEMORY;
148         }
149
150         status = create_local_token(
151                 mem_ctx, server_info, NULL, original_user_name, psession_info);
152         if (!NT_STATUS_IS_OK(status)) {
153                 DEBUG(10, ("create_local_token failed: %s\n",
154                                    nt_errstr(status)));
155                 return status;
156         }
157
158         return NT_STATUS_OK;
159 }
160
161 static NTSTATUS generate_krb5_session_info(
162         TALLOC_CTX *mem_ctx,
163         const char *princ_name,
164         const char *rhost,
165         DATA_BLOB *pac_blob,
166         struct auth_session_info **psession_info)
167 {
168         bool is_mapped = false;
169         bool is_guest = false;
170         char *ntuser = NULL;
171         char *ntdomain = NULL;
172         char *username = NULL;
173         struct passwd *pw = NULL;
174         NTSTATUS status;
175
176         if (pac_blob != NULL) {
177                 struct PAC_LOGON_NAME *logon_name = NULL;
178                 struct PAC_LOGON_INFO *logon_info = NULL;
179                 struct PAC_DATA *pac_data = NULL;
180                 enum ndr_err_code ndr_err;
181                 size_t i;
182
183                 pac_data = talloc_zero(mem_ctx, struct PAC_DATA);
184                 if (pac_data == NULL) {
185                         return NT_STATUS_NO_MEMORY;
186                 }
187
188                 ndr_err = ndr_pull_struct_blob(pac_blob,
189                                                pac_data,
190                                                pac_data,
191                                                (ndr_pull_flags_fn_t)
192                                                        ndr_pull_PAC_DATA);
193                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
194                         status = ndr_map_error2ntstatus(ndr_err);
195                         DBG_ERR("Can't parse the PAC: %s\n", nt_errstr(status));
196                         return status;
197                 }
198
199                 if (pac_data->num_buffers < 4) {
200                         DBG_ERR("We expect at least 4 PAC buffers.\n");
201                         return NT_STATUS_INVALID_PARAMETER;
202                 }
203
204                 for (i = 0; i < pac_data->num_buffers; i++) {
205                         struct PAC_BUFFER *data_buf = &pac_data->buffers[i];
206
207                         switch (data_buf->type) {
208                         case PAC_TYPE_LOGON_NAME:
209                                 logon_name = &data_buf->info->logon_name;
210                                 break;
211                         case PAC_TYPE_LOGON_INFO:
212                                 if (!data_buf->info) {
213                                         break;
214                                 }
215                                 logon_info = data_buf->info->logon_info.info;
216                                 break;
217                         default:
218                                 break;
219                         }
220                 }
221
222                 if (logon_name == NULL) {
223                         TALLOC_FREE(pac_data);
224                         DBG_ERR("PAC without logon_name\n");
225                         return NT_STATUS_INVALID_PARAMETER;
226                 }
227
228                 if (logon_info != NULL) {
229                         /*
230                         * In standalone mode we don't expect a MS-PAC!
231                         * we only support MIT realms
232                         */
233                         TALLOC_FREE(pac_data);
234                         status = NT_STATUS_BAD_TOKEN_TYPE;
235                         DBG_WARNING("Unexpected PAC for [%s] in standalone mode - %s\n",
236                                 princ_name, nt_errstr(status));
237                         return status;
238                 }
239
240                 TALLOC_FREE(pac_data);
241         }
242
243         status = get_user_from_kerberos_info(mem_ctx,
244                                              rhost,
245                                              princ_name,
246                                              &is_mapped,
247                                              &is_guest,
248                                              &ntuser,
249                                              &ntdomain,
250                                              &username,
251                                              &pw);
252         if (!NT_STATUS_IS_OK(status)) {
253                 DBG_NOTICE("Failed to map kerberos principal to system user "
254                           "(%s)\n", nt_errstr(status));
255                 return NT_STATUS_ACCESS_DENIED;
256         }
257
258         status = make_session_info_krb5(mem_ctx,
259                                         ntuser,
260                                         ntdomain,
261                                         username,
262                                         pw,
263                                         is_guest,
264                                         is_mapped,
265                                         psession_info);
266         if (!NT_STATUS_IS_OK(status)) {
267                 DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n",
268                           nt_errstr(status)));
269                 status = nt_status_squash(status);
270                 return status;
271         }
272
273         return NT_STATUS_OK;
274 }
275
276 static NTSTATUS auth3_generate_session_info_pac(
277         struct auth4_context *auth_ctx,
278         TALLOC_CTX *mem_ctx,
279         struct smb_krb5_context *smb_krb5_context,
280         DATA_BLOB *pac_blob,
281         const char *princ_name,
282         const struct tsocket_address *remote_address,
283         uint32_t session_info_flags,
284         struct auth_session_info **psession_info)
285 {
286         enum server_role server_role = lp_server_role();
287         struct auth_session_info *session_info = NULL;
288         const char *rhost;
289         NTSTATUS status;
290         TALLOC_CTX *tmp_ctx = NULL;
291
292         tmp_ctx = talloc_new(mem_ctx);
293         if (tmp_ctx == NULL) {
294                 return NT_STATUS_NO_MEMORY;
295         }
296
297         if (tsocket_address_is_inet(remote_address, "ip")) {
298                 rhost = tsocket_address_inet_addr_string(remote_address,
299                                                          tmp_ctx);
300                 if (rhost == NULL) {
301                         status = NT_STATUS_NO_MEMORY;
302                         goto done;
303                 }
304         } else {
305                 rhost = "127.0.0.1";
306         }
307
308         switch (server_role) {
309         case ROLE_DOMAIN_MEMBER:
310         case ROLE_DOMAIN_BDC:
311         case ROLE_DOMAIN_PDC:
312         case ROLE_ACTIVE_DIRECTORY_DC:
313         case ROLE_IPA_DC:
314                 /* This requires a complete MS-PAC including logon_info */
315                 status = generate_pac_session_info(
316                         tmp_ctx, princ_name, rhost, pac_blob, &session_info);
317                 break;
318         case ROLE_STANDALONE:
319                 /* This requires no PAC or a minimal PAC */
320                 status = generate_krb5_session_info(
321                         tmp_ctx, princ_name, rhost, pac_blob, &session_info);
322                 break;
323         default:
324                 status = NT_STATUS_INVALID_PARAMETER;
325                 goto done;
326         }
327
328         if (!NT_STATUS_IS_OK(status)) {
329                 goto done;
330         }
331
332         /* setup the string used by %U */
333         set_current_user_info(session_info->unix_info->sanitized_username,
334                               session_info->unix_info->unix_name,
335                               session_info->info->domain_name);
336
337         /* reload services so that the new %U is taken into account */
338         lp_load_with_shares(get_dyn_CONFIGFILE());
339
340         DEBUG(5, (__location__ "OK: user: %s domain: %s client: %s\n",
341                   session_info->info->account_name,
342                   session_info->info->domain_name,
343                   rhost));
344
345         *psession_info = talloc_move(mem_ctx, &session_info);
346
347         status = NT_STATUS_OK;
348 done:
349         TALLOC_FREE(tmp_ctx);
350         return status;
351 }
352
353 static struct auth4_context *make_auth4_context_s3(TALLOC_CTX *mem_ctx, struct auth_context *auth_context)
354 {
355         struct auth4_context *auth4_context = talloc_zero(mem_ctx, struct auth4_context);
356         if (auth4_context == NULL) {
357                 DEBUG(10, ("failed to allocate auth4_context failed\n"));
358                 return NULL;
359         }
360         auth4_context->generate_session_info_pac = auth3_generate_session_info_pac;
361         auth4_context->generate_session_info = auth3_generate_session_info;
362         auth4_context->get_ntlm_challenge = auth3_get_challenge;
363         auth4_context->set_ntlm_challenge = auth3_set_challenge;
364         auth4_context->check_ntlm_password_send = auth3_check_password_send;
365         auth4_context->check_ntlm_password_recv = auth3_check_password_recv;
366         auth4_context->private_data = talloc_steal(auth4_context, auth_context);
367         return auth4_context;
368 }
369
370 NTSTATUS make_auth4_context(TALLOC_CTX *mem_ctx, struct auth4_context **auth4_context_out)
371 {
372         struct auth_context *auth_context;
373         NTSTATUS nt_status;
374
375         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
376         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
377
378         nt_status = make_auth3_context_for_ntlm(tmp_ctx, &auth_context);
379         if (!NT_STATUS_IS_OK(nt_status)) {
380                 TALLOC_FREE(tmp_ctx);
381                 return nt_status;
382         }
383
384         if (auth_context->make_auth4_context) {
385                 nt_status = auth_context->make_auth4_context(auth_context, mem_ctx, auth4_context_out);
386                 TALLOC_FREE(tmp_ctx);
387                 return nt_status;
388
389         } else {
390                 struct auth4_context *auth4_context = make_auth4_context_s3(tmp_ctx, auth_context);
391                 if (auth4_context == NULL) {
392                         TALLOC_FREE(tmp_ctx);
393                         return NT_STATUS_NO_MEMORY;
394                 }
395                 *auth4_context_out = talloc_steal(mem_ctx, auth4_context);
396                 TALLOC_FREE(tmp_ctx);
397                 return NT_STATUS_OK;
398         }
399 }
400
401 NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
402                               const struct tsocket_address *remote_address,
403                               const struct tsocket_address *local_address,
404                               const char *service_description,
405                               struct gensec_security **gensec_security_out)
406 {
407         struct gensec_security *gensec_security;
408         struct auth_context *auth_context = NULL;
409         NTSTATUS nt_status;
410
411         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
412         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
413
414         nt_status = make_auth3_context_for_ntlm(tmp_ctx, &auth_context);
415         if (!NT_STATUS_IS_OK(nt_status)) {
416                 goto done;
417         }
418
419         if (auth_context->prepare_gensec) {
420                 nt_status = auth_context->prepare_gensec(auth_context, tmp_ctx,
421                                                          &gensec_security);
422                 if (!NT_STATUS_IS_OK(nt_status)) {
423                         goto done;
424                 }
425         } else {
426                 const struct gensec_security_ops **backends = NULL;
427                 struct gensec_settings *gensec_settings;
428                 struct loadparm_context *lp_ctx;
429                 size_t idx = 0;
430                 struct cli_credentials *server_credentials;
431                 const char *dns_name;
432                 const char *dns_domain;
433                 bool ok;
434                 struct auth4_context *auth4_context = make_auth4_context_s3(tmp_ctx, auth_context);
435                 if (auth4_context == NULL) {
436                         goto nomem;
437                 }
438
439                 lp_ctx = loadparm_init_s3(tmp_ctx, loadparm_s3_helpers());
440                 if (lp_ctx == NULL) {
441                         DEBUG(10, ("loadparm_init_s3 failed\n"));
442                         nt_status = NT_STATUS_INVALID_SERVER_STATE;
443                         goto done;
444                 }
445
446                 gensec_settings = lpcfg_gensec_settings(tmp_ctx, lp_ctx);
447                 if (lp_ctx == NULL) {
448                         DEBUG(10, ("lpcfg_gensec_settings failed\n"));
449                         goto nomem;
450                 }
451
452                 /*
453                  * This should be a 'netbios domain -> DNS domain'
454                  * mapping, and can currently validly return NULL on
455                  * poorly configured systems.
456                  *
457                  * This is used for the NTLMSSP server
458                  *
459                  */
460                 dns_name = get_mydnsfullname();
461                 if (dns_name == NULL) {
462                         dns_name = "";
463                 }
464
465                 dns_domain = get_mydnsdomname(tmp_ctx);
466                 if (dns_domain == NULL) {
467                         dns_domain = "";
468                 }
469
470                 gensec_settings->server_dns_name = strlower_talloc(gensec_settings, dns_name);
471                 if (gensec_settings->server_dns_name == NULL) {
472                         goto nomem;
473                 }
474
475                 gensec_settings->server_dns_domain = strlower_talloc(gensec_settings, dns_domain);
476                 if (gensec_settings->server_dns_domain == NULL) {
477                         goto nomem;
478                 }
479
480                 backends = talloc_zero_array(gensec_settings,
481                                              const struct gensec_security_ops *, 6);
482                 if (backends == NULL) {
483                         goto nomem;
484                 }
485                 gensec_settings->backends = backends;
486
487                 gensec_init();
488
489                 /* These need to be in priority order, krb5 before NTLMSSP */
490 #if defined(HAVE_KRB5)
491                 backends[idx++] = &gensec_gse_krb5_security_ops;
492 #endif
493
494                 backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_NTLMSSP);
495
496                 backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_SPNEGO);
497
498                 backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_SCHANNEL);
499
500                 backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM);
501
502                 /*
503                  * This is anonymous for now, because we just use it
504                  * to set the kerberos state at the moment
505                  */
506                 server_credentials = cli_credentials_init_anon(tmp_ctx);
507                 if (!server_credentials) {
508                         DEBUG(0, ("auth_generic_prepare: Failed to init server credentials\n"));
509                         goto nomem;
510                 }
511
512                 ok = cli_credentials_set_conf(server_credentials, lp_ctx);
513                 if (!ok) {
514                         DBG_ERR("Failed to set server credentials defaults "
515                                 "from smb.conf.\n");
516                         goto nomem;
517                 }
518
519                 if (lp_security() == SEC_ADS || USE_KERBEROS_KEYTAB) {
520                         cli_credentials_set_kerberos_state(server_credentials,
521                                                            CRED_USE_KERBEROS_DESIRED,
522                                                            CRED_SPECIFIED);
523                 } else {
524                         cli_credentials_set_kerberos_state(server_credentials,
525                                                            CRED_USE_KERBEROS_DISABLED,
526                                                            CRED_SPECIFIED);
527                 }
528
529                 nt_status = gensec_server_start(tmp_ctx, gensec_settings,
530                                                 auth4_context, &gensec_security);
531
532                 if (!NT_STATUS_IS_OK(nt_status)) {
533                         goto done;
534                 }
535
536                 nt_status = gensec_set_credentials(
537                         gensec_security, server_credentials);
538                 if (!NT_STATUS_IS_OK(nt_status)) {
539                         goto done;
540                 }
541         }
542
543         nt_status = gensec_set_remote_address(gensec_security,
544                                               remote_address);
545         if (!NT_STATUS_IS_OK(nt_status)) {
546                 goto done;
547         }
548
549         nt_status = gensec_set_local_address(gensec_security,
550                                              local_address);
551         if (!NT_STATUS_IS_OK(nt_status)) {
552                 goto done;
553         }
554
555         nt_status = gensec_set_target_service_description(gensec_security,
556                                                           service_description);
557         if (!NT_STATUS_IS_OK(nt_status)) {
558                 goto done;
559         }
560
561         *gensec_security_out = talloc_move(mem_ctx, &gensec_security);
562         nt_status = NT_STATUS_OK;
563         goto done;
564 nomem:
565         nt_status = NT_STATUS_NO_MEMORY;
566 done:
567         TALLOC_FREE(tmp_ctx);
568         return nt_status;
569 }
570
571 /*
572  * Check a username and password, and return the final session_info.
573  * We also log the authorization of the session here, just as
574  * gensec_session_info() does.
575  */
576 NTSTATUS auth_check_password_session_info(struct auth4_context *auth_context,
577                                           TALLOC_CTX *mem_ctx,
578                                           struct auth_usersupplied_info *user_info,
579                                           struct auth_session_info **session_info)
580 {
581         NTSTATUS nt_status;
582         void *server_info;
583         uint8_t authoritative = 1;
584         struct tevent_context *ev = NULL;
585         struct tevent_req *subreq = NULL;
586         bool ok;
587
588         ev = samba_tevent_context_init(talloc_tos());
589         if (ev == NULL) {
590                 return NT_STATUS_NO_MEMORY;
591         }
592
593         subreq = auth_context->check_ntlm_password_send(ev, ev,
594                                                         auth_context,
595                                                         user_info);
596         if (subreq == NULL) {
597                 TALLOC_FREE(ev);
598                 return NT_STATUS_NO_MEMORY;
599         }
600         ok = tevent_req_poll_ntstatus(subreq, ev, &nt_status);
601         if (!ok) {
602                 TALLOC_FREE(ev);
603                 return nt_status;
604         }
605         nt_status = auth_context->check_ntlm_password_recv(subreq,
606                                                            talloc_tos(),
607                                                            &authoritative,
608                                                            &server_info,
609                                                            NULL, NULL);
610         TALLOC_FREE(ev);
611         if (!NT_STATUS_IS_OK(nt_status)) {
612                 return nt_status;
613         }
614
615         nt_status = auth_context->generate_session_info(auth_context,
616                                                         mem_ctx,
617                                                         server_info,
618                                                         user_info->client.account_name,
619                                                         AUTH_SESSION_INFO_UNIX_TOKEN |
620                                                         AUTH_SESSION_INFO_DEFAULT_GROUPS |
621                                                         AUTH_SESSION_INFO_NTLM,
622                                                         session_info);
623         TALLOC_FREE(server_info);
624
625         if (!NT_STATUS_IS_OK(nt_status)) {
626                 return nt_status;
627         }
628
629         /*
630          * This is rather redundant (the authentication has just been
631          * logged, with much the same details), but because we want to
632          * log all authorizations consistently (be they NLTM, NTLMSSP
633          * or krb5) we log this info again as an authorization.
634          */
635         log_successful_authz_event(auth_context->msg_ctx,
636                                    auth_context->lp_ctx,
637                                    user_info->remote_host,
638                                    user_info->local_host,
639                                    user_info->service_description,
640                                    user_info->auth_description,
641                                    AUTHZ_TRANSPORT_PROTECTION_SMB,
642                                    *session_info,
643                                    NULL /* client_audit_info */,
644                                    NULL /* server_audit_info */);
645
646         return nt_status;
647 }