source3: move lib/substitute.c functions out of proto.h
[gd/samba-autobuild/.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 "auth/kerberos/pac_utils.h"
33 #include "nsswitch/libwbclient/wbclient.h"
34 #endif
35 #include "librpc/crypto/gse.h"
36 #include "auth/credentials/credentials.h"
37 #include "lib/param/loadparm.h"
38 #include "librpc/gen_ndr/dcerpc.h"
39 #include "source3/lib/substitute.h"
40
41 static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
42                                                 TALLOC_CTX *mem_ctx,
43                                                 struct smb_krb5_context *smb_krb5_context,
44                                                 DATA_BLOB *pac_blob,
45                                                 const char *princ_name,
46                                                 const struct tsocket_address *remote_address,
47                                                 uint32_t session_info_flags,
48                                                 struct auth_session_info **session_info)
49 {
50         enum server_role server_role = lp_server_role();
51         TALLOC_CTX *tmp_ctx;
52         bool is_mapped;
53         bool is_guest;
54         char *ntuser;
55         char *ntdomain;
56         char *username;
57         const char *rhost;
58         struct passwd *pw;
59         NTSTATUS status;
60
61         tmp_ctx = talloc_new(mem_ctx);
62         if (!tmp_ctx) {
63                 return NT_STATUS_NO_MEMORY;
64         }
65
66         if (tsocket_address_is_inet(remote_address, "ip")) {
67                 rhost = tsocket_address_inet_addr_string(
68                         remote_address, tmp_ctx);
69                 if (rhost == NULL) {
70                         status = NT_STATUS_NO_MEMORY;
71                         goto done;
72                 }
73         } else {
74                 rhost = "127.0.0.1";
75         }
76
77         if (server_role != ROLE_STANDALONE) {
78                 struct wbcAuthUserParams params = { 0 };
79                 struct wbcAuthUserInfo *info = NULL;
80                 struct wbcAuthErrorInfo *err = NULL;
81                 struct auth_serversupplied_info *server_info = NULL;
82                 char *original_user_name = NULL;
83                 char *p = NULL;
84                 wbcErr wbc_err;
85
86                 if (pac_blob == NULL) {
87                         /*
88                          * This should already be catched at the main
89                          * gensec layer, but better check twice
90                          */
91                         status = NT_STATUS_INTERNAL_ERROR;
92                         goto done;
93                 }
94
95                 /*
96                  * Let winbind decode the PAC.
97                  * This will also store the user
98                  * data in the netsamlogon cache.
99                  *
100                  * This used to be a cache prime
101                  * optimization, but now we delegate
102                  * all logic to winbindd, as we require
103                  * winbindd as domain member anyway.
104                  */
105                 params.level = WBC_AUTH_USER_LEVEL_PAC;
106                 params.password.pac.data = pac_blob->data;
107                 params.password.pac.length = pac_blob->length;
108
109                 /* we are contacting the privileged pipe */
110                 become_root();
111                 wbc_err = wbcAuthenticateUserEx(&params, &info, &err);
112                 unbecome_root();
113
114                 /*
115                  * As this is merely a cache prime
116                  * WBC_ERR_WINBIND_NOT_AVAILABLE
117                  * is not a fatal error, treat it
118                  * as success.
119                  */
120
121                 switch (wbc_err) {
122                         case WBC_ERR_SUCCESS:
123                                 break;
124                         case WBC_ERR_WINBIND_NOT_AVAILABLE:
125                                 status = NT_STATUS_NO_LOGON_SERVERS;
126                                 DBG_ERR("winbindd not running - "
127                                         "but required as domain member: %s\n",
128                                         nt_errstr(status));
129                                 goto done;
130                         case WBC_ERR_AUTH_ERROR:
131                                 status = NT_STATUS(err->nt_status);
132                                 wbcFreeMemory(err);
133                                 goto done;
134                         case WBC_ERR_NO_MEMORY:
135                                 status = NT_STATUS_NO_MEMORY;
136                                 goto done;
137                         default:
138                                 status = NT_STATUS_LOGON_FAILURE;
139                                 goto done;
140                 }
141
142                 status = make_server_info_wbcAuthUserInfo(tmp_ctx,
143                                                           info->account_name,
144                                                           info->domain_name,
145                                                           info, &server_info);
146                 if (!NT_STATUS_IS_OK(status)) {
147                         DEBUG(10, ("make_server_info_wbcAuthUserInfo failed: %s\n",
148                                    nt_errstr(status)));
149                         goto done;
150                 }
151
152                 /* We skip doing this step if the caller asked us not to */
153                 if (!(server_info->guest)) {
154                         const char *unix_username = server_info->unix_name;
155
156                         /* We might not be root if we are an RPC call */
157                         become_root();
158                         status = smb_pam_accountcheck(unix_username, rhost);
159                         unbecome_root();
160
161                         if (!NT_STATUS_IS_OK(status)) {
162                                 DEBUG(3, ("check_ntlm_password:  PAM Account for user [%s] "
163                                           "FAILED with error %s\n",
164                                           unix_username, nt_errstr(status)));
165                                 goto done;
166                         }
167
168                         DEBUG(5, ("check_ntlm_password:  PAM Account for user [%s] "
169                                   "succeeded\n", unix_username));
170                 }
171
172                 DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name));
173
174                 p = strchr_m(princ_name, '@');
175                 if (!p) {
176                         DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
177                                   princ_name));
178                         status = NT_STATUS_LOGON_FAILURE;
179                         goto done;
180                 }
181
182                 original_user_name = talloc_strndup(tmp_ctx, princ_name, p - princ_name);
183                 if (original_user_name == NULL) {
184                         status = NT_STATUS_NO_MEMORY;
185                         goto done;
186                 }
187
188                 status = create_local_token(mem_ctx,
189                                             server_info,
190                                             NULL,
191                                             original_user_name,
192                                             session_info);
193                 if (!NT_STATUS_IS_OK(status)) {
194                         DEBUG(10, ("create_local_token failed: %s\n",
195                                    nt_errstr(status)));
196                         goto done;
197                 }
198
199                 goto session_info_ready;
200         }
201
202         /* This is the standalone legacy code path */
203
204         if (pac_blob != NULL) {
205                 /*
206                  * In standalone mode we don't expect a PAC!
207                  * we only support MIT realms
208                  */
209                 status = NT_STATUS_BAD_TOKEN_TYPE;
210                 DBG_WARNING("Unexpected PAC for [%s] in standalone mode - %s\n",
211                             princ_name, nt_errstr(status));
212                 if (!NT_STATUS_IS_OK(status)) {
213                         goto done;
214                 }
215         }
216
217         status = get_user_from_kerberos_info(tmp_ctx, rhost,
218                                              princ_name,
219                                              &is_mapped, &is_guest,
220                                              &ntuser, &ntdomain,
221                                              &username, &pw);
222         if (!NT_STATUS_IS_OK(status)) {
223                 DBG_NOTICE("Failed to map kerberos principal to system user "
224                           "(%s)\n", nt_errstr(status));
225                 status = NT_STATUS_ACCESS_DENIED;
226                 goto done;
227         }
228
229         status = make_session_info_krb5(mem_ctx,
230                                         ntuser, ntdomain, username, pw,
231                                         is_guest, is_mapped,
232                                         session_info);
233         if (!NT_STATUS_IS_OK(status)) {
234                 DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n",
235                           nt_errstr(status)));
236                 status = nt_status_squash(status);
237                 goto done;
238         }
239
240 session_info_ready:
241
242         /* setup the string used by %U */
243         set_current_user_info((*session_info)->unix_info->sanitized_username,
244                               (*session_info)->unix_info->unix_name,
245                               (*session_info)->info->domain_name);
246
247         /* reload services so that the new %U is taken into account */
248         lp_load_with_shares(get_dyn_CONFIGFILE());
249
250         DEBUG(5, (__location__ "OK: user: %s domain: %s client: %s\n",
251                   (*session_info)->info->account_name,
252                   (*session_info)->info->domain_name,
253                   rhost));
254
255         status = NT_STATUS_OK;
256
257 done:
258         TALLOC_FREE(tmp_ctx);
259         return status;
260 }
261
262 static struct auth4_context *make_auth4_context_s3(TALLOC_CTX *mem_ctx, struct auth_context *auth_context)
263 {
264         struct auth4_context *auth4_context = talloc_zero(mem_ctx, struct auth4_context);
265         if (auth4_context == NULL) {
266                 DEBUG(10, ("failed to allocate auth4_context failed\n"));
267                 return NULL;
268         }
269         auth4_context->generate_session_info_pac = auth3_generate_session_info_pac;
270         auth4_context->generate_session_info = auth3_generate_session_info;
271         auth4_context->get_ntlm_challenge = auth3_get_challenge;
272         auth4_context->set_ntlm_challenge = auth3_set_challenge;
273         auth4_context->check_ntlm_password_send = auth3_check_password_send;
274         auth4_context->check_ntlm_password_recv = auth3_check_password_recv;
275         auth4_context->private_data = talloc_steal(auth4_context, auth_context);
276         return auth4_context;
277 }
278
279 NTSTATUS make_auth4_context(TALLOC_CTX *mem_ctx, struct auth4_context **auth4_context_out)
280 {
281         struct auth_context *auth_context;
282         NTSTATUS nt_status;
283
284         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
285         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
286
287         nt_status = make_auth3_context_for_ntlm(tmp_ctx, &auth_context);
288         if (!NT_STATUS_IS_OK(nt_status)) {
289                 TALLOC_FREE(tmp_ctx);
290                 return nt_status;
291         }
292
293         if (auth_context->make_auth4_context) {
294                 nt_status = auth_context->make_auth4_context(auth_context, mem_ctx, auth4_context_out);
295                 TALLOC_FREE(tmp_ctx);
296                 return nt_status;
297
298         } else {
299                 struct auth4_context *auth4_context = make_auth4_context_s3(tmp_ctx, auth_context);
300                 if (auth4_context == NULL) {
301                         TALLOC_FREE(tmp_ctx);
302                         return NT_STATUS_NO_MEMORY;
303                 }
304                 *auth4_context_out = talloc_steal(mem_ctx, auth4_context);
305                 TALLOC_FREE(tmp_ctx);
306                 return NT_STATUS_OK;
307         }
308 }
309
310 NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
311                               const struct tsocket_address *remote_address,
312                               const struct tsocket_address *local_address,
313                               const char *service_description,
314                               struct gensec_security **gensec_security_out)
315 {
316         struct gensec_security *gensec_security;
317         struct auth_context *auth_context = NULL;
318         NTSTATUS nt_status;
319
320         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
321         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
322
323         nt_status = make_auth3_context_for_ntlm(tmp_ctx, &auth_context);
324         if (!NT_STATUS_IS_OK(nt_status)) {
325                 goto done;
326         }
327
328         if (auth_context->prepare_gensec) {
329                 nt_status = auth_context->prepare_gensec(auth_context, tmp_ctx,
330                                                          &gensec_security);
331                 if (!NT_STATUS_IS_OK(nt_status)) {
332                         goto done;
333                 }
334         } else {
335                 const struct gensec_security_ops **backends = NULL;
336                 struct gensec_settings *gensec_settings;
337                 struct loadparm_context *lp_ctx;
338                 size_t idx = 0;
339                 struct cli_credentials *server_credentials;
340                 const char *dns_name;
341                 const char *dns_domain;
342                 bool ok;
343                 struct auth4_context *auth4_context = make_auth4_context_s3(tmp_ctx, auth_context);
344                 if (auth4_context == NULL) {
345                         goto nomem;
346                 }
347
348                 lp_ctx = loadparm_init_s3(tmp_ctx, loadparm_s3_helpers());
349                 if (lp_ctx == NULL) {
350                         DEBUG(10, ("loadparm_init_s3 failed\n"));
351                         nt_status = NT_STATUS_INVALID_SERVER_STATE;
352                         goto done;
353                 }
354
355                 gensec_settings = lpcfg_gensec_settings(tmp_ctx, lp_ctx);
356                 if (lp_ctx == NULL) {
357                         DEBUG(10, ("lpcfg_gensec_settings failed\n"));
358                         goto nomem;
359                 }
360
361                 /*
362                  * This should be a 'netbios domain -> DNS domain'
363                  * mapping, and can currently validly return NULL on
364                  * poorly configured systems.
365                  *
366                  * This is used for the NTLMSSP server
367                  *
368                  */
369                 dns_name = get_mydnsfullname();
370                 if (dns_name == NULL) {
371                         dns_name = "";
372                 }
373
374                 dns_domain = get_mydnsdomname(tmp_ctx);
375                 if (dns_domain == NULL) {
376                         dns_domain = "";
377                 }
378
379                 gensec_settings->server_dns_name = strlower_talloc(gensec_settings, dns_name);
380                 if (gensec_settings->server_dns_name == NULL) {
381                         goto nomem;
382                 }
383
384                 gensec_settings->server_dns_domain = strlower_talloc(gensec_settings, dns_domain);
385                 if (gensec_settings->server_dns_domain == NULL) {
386                         goto nomem;
387                 }
388
389                 backends = talloc_zero_array(gensec_settings,
390                                              const struct gensec_security_ops *, 6);
391                 if (backends == NULL) {
392                         goto nomem;
393                 }
394                 gensec_settings->backends = backends;
395
396                 gensec_init();
397
398                 /* These need to be in priority order, krb5 before NTLMSSP */
399 #if defined(HAVE_KRB5)
400                 backends[idx++] = &gensec_gse_krb5_security_ops;
401 #endif
402
403                 backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_NTLMSSP);
404
405                 backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_SPNEGO);
406
407                 backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_SCHANNEL);
408
409                 backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM);
410
411                 /*
412                  * This is anonymous for now, because we just use it
413                  * to set the kerberos state at the moment
414                  */
415                 server_credentials = cli_credentials_init_anon(tmp_ctx);
416                 if (!server_credentials) {
417                         DEBUG(0, ("auth_generic_prepare: Failed to init server credentials\n"));
418                         goto nomem;
419                 }
420
421                 ok = cli_credentials_set_conf(server_credentials, lp_ctx);
422                 if (!ok) {
423                         DBG_ERR("Failed to set server credentials defaults "
424                                 "from smb.conf.\n");
425                         goto nomem;
426                 }
427
428                 if (lp_security() == SEC_ADS || USE_KERBEROS_KEYTAB) {
429                         cli_credentials_set_kerberos_state(server_credentials,
430                                                            CRED_USE_KERBEROS_DESIRED,
431                                                            CRED_SPECIFIED);
432                 } else {
433                         cli_credentials_set_kerberos_state(server_credentials,
434                                                            CRED_USE_KERBEROS_DISABLED,
435                                                            CRED_SPECIFIED);
436                 }
437
438                 nt_status = gensec_server_start(tmp_ctx, gensec_settings,
439                                                 auth4_context, &gensec_security);
440
441                 if (!NT_STATUS_IS_OK(nt_status)) {
442                         goto done;
443                 }
444
445                 nt_status = gensec_set_credentials(
446                         gensec_security, server_credentials);
447                 if (!NT_STATUS_IS_OK(nt_status)) {
448                         goto done;
449                 }
450         }
451
452         nt_status = gensec_set_remote_address(gensec_security,
453                                               remote_address);
454         if (!NT_STATUS_IS_OK(nt_status)) {
455                 goto done;
456         }
457
458         nt_status = gensec_set_local_address(gensec_security,
459                                              local_address);
460         if (!NT_STATUS_IS_OK(nt_status)) {
461                 goto done;
462         }
463
464         nt_status = gensec_set_target_service_description(gensec_security,
465                                                           service_description);
466         if (!NT_STATUS_IS_OK(nt_status)) {
467                 goto done;
468         }
469
470         *gensec_security_out = talloc_move(mem_ctx, &gensec_security);
471         nt_status = NT_STATUS_OK;
472         goto done;
473 nomem:
474         nt_status = NT_STATUS_NO_MEMORY;
475 done:
476         TALLOC_FREE(tmp_ctx);
477         return nt_status;
478 }
479
480 /*
481  * Check a username and password, and return the final session_info.
482  * We also log the authorization of the session here, just as
483  * gensec_session_info() does.
484  */
485 NTSTATUS auth_check_password_session_info(struct auth4_context *auth_context,
486                                           TALLOC_CTX *mem_ctx,
487                                           struct auth_usersupplied_info *user_info,
488                                           struct auth_session_info **session_info)
489 {
490         NTSTATUS nt_status;
491         void *server_info;
492         uint8_t authoritative = 1;
493         struct tevent_context *ev = NULL;
494         struct tevent_req *subreq = NULL;
495         bool ok;
496
497         ev = samba_tevent_context_init(talloc_tos());
498         if (ev == NULL) {
499                 return NT_STATUS_NO_MEMORY;
500         }
501
502         subreq = auth_context->check_ntlm_password_send(ev, ev,
503                                                         auth_context,
504                                                         user_info);
505         if (subreq == NULL) {
506                 TALLOC_FREE(ev);
507                 return NT_STATUS_NO_MEMORY;
508         }
509         ok = tevent_req_poll_ntstatus(subreq, ev, &nt_status);
510         if (!ok) {
511                 TALLOC_FREE(ev);
512                 return nt_status;
513         }
514         nt_status = auth_context->check_ntlm_password_recv(subreq,
515                                                            talloc_tos(),
516                                                            &authoritative,
517                                                            &server_info,
518                                                            NULL, NULL);
519         TALLOC_FREE(ev);
520         if (!NT_STATUS_IS_OK(nt_status)) {
521                 return nt_status;
522         }
523
524         nt_status = auth_context->generate_session_info(auth_context,
525                                                         mem_ctx,
526                                                         server_info,
527                                                         user_info->client.account_name,
528                                                         AUTH_SESSION_INFO_UNIX_TOKEN |
529                                                         AUTH_SESSION_INFO_DEFAULT_GROUPS |
530                                                         AUTH_SESSION_INFO_NTLM,
531                                                         session_info);
532         TALLOC_FREE(server_info);
533
534         if (!NT_STATUS_IS_OK(nt_status)) {
535                 return nt_status;
536         }
537
538         /*
539          * This is rather redundant (the authentication has just been
540          * logged, with much the same details), but because we want to
541          * log all authorizations consistently (be they NLTM, NTLMSSP
542          * or krb5) we log this info again as an authorization.
543          */
544         log_successful_authz_event(auth_context->msg_ctx,
545                                    auth_context->lp_ctx,
546                                    user_info->remote_host,
547                                    user_info->local_host,
548                                    user_info->service_description,
549                                    user_info->auth_description,
550                                    AUTHZ_TRANSPORT_PROTECTION_SMB,
551                                    *session_info);
552
553         return nt_status;
554 }