auth: Remove the "typedef auth_methods"
[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 "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
40 static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx,
41                                                 TALLOC_CTX *mem_ctx,
42                                                 struct smb_krb5_context *smb_krb5_context,
43                                                 DATA_BLOB *pac_blob,
44                                                 const char *princ_name,
45                                                 const struct tsocket_address *remote_address,
46                                                 uint32_t session_info_flags,
47                                                 struct auth_session_info **session_info)
48 {
49         TALLOC_CTX *tmp_ctx;
50         struct PAC_LOGON_INFO *logon_info = NULL;
51         struct netr_SamInfo3 *info3_copy = NULL;
52         bool is_mapped;
53         bool is_guest;
54         char *ntuser;
55         char *ntdomain;
56         char *username;
57         char *rhost;
58         struct passwd *pw;
59         NTSTATUS status;
60         int rc;
61
62         tmp_ctx = talloc_new(mem_ctx);
63         if (!tmp_ctx) {
64                 return NT_STATUS_NO_MEMORY;
65         }
66
67         if (pac_blob) {
68 #ifdef HAVE_KRB5
69                 struct wbcAuthUserParams params = {};
70                 struct wbcAuthUserInfo *info = NULL;
71                 struct wbcAuthErrorInfo *err = NULL;
72                 wbcErr wbc_err;
73
74                 /*
75                  * Let winbind decode the PAC.
76                  * This will also store the user
77                  * data in the netsamlogon cache.
78                  *
79                  * We need to do this *before* we
80                  * call get_user_from_kerberos_info()
81                  * as that does a user lookup that
82                  * expects info in the netsamlogon cache.
83                  *
84                  * See BUG: https://bugzilla.samba.org/show_bug.cgi?id=11259
85                  */
86                 params.level = WBC_AUTH_USER_LEVEL_PAC;
87                 params.password.pac.data = pac_blob->data;
88                 params.password.pac.length = pac_blob->length;
89
90                 become_root();
91                 wbc_err = wbcAuthenticateUserEx(&params, &info, &err);
92                 unbecome_root();
93
94                 /*
95                  * As this is merely a cache prime
96                  * WBC_ERR_WINBIND_NOT_AVAILABLE
97                  * is not a fatal error, treat it
98                  * as success.
99                  */
100
101                 switch (wbc_err) {
102                         case WBC_ERR_WINBIND_NOT_AVAILABLE:
103                         case WBC_ERR_SUCCESS:
104                                 break;
105                         case WBC_ERR_AUTH_ERROR:
106                                 status = NT_STATUS(err->nt_status);
107                                 wbcFreeMemory(err);
108                                 goto done;
109                         default:
110                                 status = NT_STATUS_LOGON_FAILURE;
111                                 goto done;
112                 }
113
114                 status = kerberos_pac_logon_info(tmp_ctx, *pac_blob, NULL, NULL,
115                                                  NULL, NULL, 0, &logon_info);
116 #else
117                 status = NT_STATUS_ACCESS_DENIED;
118 #endif
119                 if (!NT_STATUS_IS_OK(status)) {
120                         goto done;
121                 }
122         }
123
124         rc = get_remote_hostname(remote_address,
125                                  &rhost,
126                                  tmp_ctx);
127         if (rc < 0) {
128                 status = NT_STATUS_NO_MEMORY;
129                 goto done;
130         }
131         if (strequal(rhost, "UNKNOWN")) {
132                 rhost = tsocket_address_inet_addr_string(remote_address,
133                                                          tmp_ctx);
134                 if (rhost == NULL) {
135                         status = NT_STATUS_NO_MEMORY;
136                         goto done;
137                 }
138         }
139
140         status = get_user_from_kerberos_info(tmp_ctx, rhost,
141                                              princ_name, logon_info,
142                                              &is_mapped, &is_guest,
143                                              &ntuser, &ntdomain,
144                                              &username, &pw);
145         if (!NT_STATUS_IS_OK(status)) {
146                 DBG_NOTICE("Failed to map kerberos principal to system user "
147                           "(%s)\n", nt_errstr(status));
148                 status = NT_STATUS_ACCESS_DENIED;
149                 goto done;
150         }
151
152         /* Get the info3 from the PAC data if we have it */
153         if (logon_info) {
154                 status = create_info3_from_pac_logon_info(tmp_ctx,
155                                         logon_info,
156                                         &info3_copy);
157                 if (!NT_STATUS_IS_OK(status)) {
158                         goto done;
159                 }
160         }
161
162         /* setup the string used by %U */
163         sub_set_smb_name(username);
164
165         /* reload services so that the new %U is taken into account */
166         lp_load_with_shares(get_dyn_CONFIGFILE());
167
168         status = make_session_info_krb5(mem_ctx,
169                                         ntuser, ntdomain, username, pw,
170                                         info3_copy, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */,
171                                         session_info);
172         if (!NT_STATUS_IS_OK(status)) {
173                 DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n",
174                           nt_errstr(status)));
175                 status = NT_STATUS_ACCESS_DENIED;
176                 goto done;
177         }
178
179         DEBUG(5, (__location__ "OK: user: %s domain: %s client: %s\n",
180                   ntuser, ntdomain, rhost));
181
182         status = NT_STATUS_OK;
183
184 done:
185         TALLOC_FREE(tmp_ctx);
186         return status;
187 }
188
189 static struct auth4_context *make_auth4_context_s3(TALLOC_CTX *mem_ctx, struct auth_context *auth_context)
190 {
191         struct auth4_context *auth4_context = talloc_zero(mem_ctx, struct auth4_context);
192         if (auth4_context == NULL) {
193                 DEBUG(10, ("failed to allocate auth4_context failed\n"));
194                 return NULL;
195         }
196         auth4_context->generate_session_info_pac = auth3_generate_session_info_pac;
197         auth4_context->generate_session_info = auth3_generate_session_info;
198         auth4_context->get_ntlm_challenge = auth3_get_challenge;
199         auth4_context->set_ntlm_challenge = auth3_set_challenge;
200         auth4_context->check_ntlm_password = auth3_check_password;
201         auth4_context->private_data = talloc_steal(auth4_context, auth_context);
202         return auth4_context;
203 }
204
205 NTSTATUS make_auth4_context(TALLOC_CTX *mem_ctx, struct auth4_context **auth4_context_out)
206 {
207         struct auth_context *auth_context;
208         NTSTATUS nt_status;
209
210         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
211         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
212
213         nt_status = make_auth3_context_for_ntlm(tmp_ctx, &auth_context);
214         if (!NT_STATUS_IS_OK(nt_status)) {
215                 TALLOC_FREE(tmp_ctx);
216                 return nt_status;
217         }
218
219         if (auth_context->make_auth4_context) {
220                 nt_status = auth_context->make_auth4_context(auth_context, mem_ctx, auth4_context_out);
221                 TALLOC_FREE(tmp_ctx);
222                 return nt_status;
223
224         } else {
225                 struct auth4_context *auth4_context = make_auth4_context_s3(tmp_ctx, auth_context);
226                 if (auth4_context == NULL) {
227                         TALLOC_FREE(tmp_ctx);
228                         return NT_STATUS_NO_MEMORY;
229                 }
230                 *auth4_context_out = talloc_steal(mem_ctx, auth4_context);
231                 TALLOC_FREE(tmp_ctx);
232                 return NT_STATUS_OK;
233         }
234 }
235
236 NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
237                               const struct tsocket_address *remote_address,
238                               const struct tsocket_address *local_address,
239                               const char *service_description,
240                               struct gensec_security **gensec_security_out)
241 {
242         struct gensec_security *gensec_security;
243         struct auth_context *auth_context;
244         NTSTATUS nt_status;
245
246         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
247         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
248
249         nt_status = make_auth3_context_for_ntlm(tmp_ctx, &auth_context);
250         if (!NT_STATUS_IS_OK(nt_status)) {
251                 TALLOC_FREE(tmp_ctx);
252                 return nt_status;
253         }
254
255         if (auth_context->prepare_gensec) {
256                 nt_status = auth_context->prepare_gensec(auth_context, tmp_ctx,
257                                                          &gensec_security);
258                 if (!NT_STATUS_IS_OK(nt_status)) {
259                         TALLOC_FREE(tmp_ctx);
260                         return nt_status;
261                 }
262         } else {
263                 const struct gensec_security_ops **backends = NULL;
264                 struct gensec_settings *gensec_settings;
265                 struct loadparm_context *lp_ctx;
266                 size_t idx = 0;
267                 struct cli_credentials *server_credentials;
268                 const char *dns_name;
269                 const char *dns_domain;
270                 struct auth4_context *auth4_context = make_auth4_context_s3(tmp_ctx, auth_context);
271                 if (auth4_context == NULL) {
272                         TALLOC_FREE(tmp_ctx);
273                         return NT_STATUS_NO_MEMORY;
274                 }
275
276                 lp_ctx = loadparm_init_s3(tmp_ctx, loadparm_s3_helpers());
277                 if (lp_ctx == NULL) {
278                         DEBUG(10, ("loadparm_init_s3 failed\n"));
279                         TALLOC_FREE(tmp_ctx);
280                         return NT_STATUS_INVALID_SERVER_STATE;
281                 }
282
283                 gensec_settings = lpcfg_gensec_settings(tmp_ctx, lp_ctx);
284                 if (lp_ctx == NULL) {
285                         DEBUG(10, ("lpcfg_gensec_settings failed\n"));
286                         TALLOC_FREE(tmp_ctx);
287                         return NT_STATUS_NO_MEMORY;
288                 }
289
290                 /*
291                  * This should be a 'netbios domain -> DNS domain'
292                  * mapping, and can currently validly return NULL on
293                  * poorly configured systems.
294                  *
295                  * This is used for the NTLMSSP server
296                  *
297                  */
298                 dns_name = get_mydnsfullname();
299                 if (dns_name == NULL) {
300                         dns_name = "";
301                 }
302
303                 dns_domain = get_mydnsdomname(tmp_ctx);
304                 if (dns_domain == NULL) {
305                         dns_domain = "";
306                 }
307
308                 gensec_settings->server_dns_name = strlower_talloc(gensec_settings, dns_name);
309                 if (gensec_settings->server_dns_name == NULL) {
310                         TALLOC_FREE(tmp_ctx);
311                         return NT_STATUS_NO_MEMORY;
312                 }
313
314                 gensec_settings->server_dns_domain = strlower_talloc(gensec_settings, dns_domain);
315                 if (gensec_settings->server_dns_domain == NULL) {
316                         TALLOC_FREE(tmp_ctx);
317                         return NT_STATUS_NO_MEMORY;
318                 }
319
320                 backends = talloc_zero_array(gensec_settings,
321                                              const struct gensec_security_ops *, 6);
322                 if (backends == NULL) {
323                         TALLOC_FREE(tmp_ctx);
324                         return NT_STATUS_NO_MEMORY;
325                 }
326                 gensec_settings->backends = backends;
327
328                 gensec_init();
329
330                 /* These need to be in priority order, krb5 before NTLMSSP */
331 #if defined(HAVE_KRB5)
332                 backends[idx++] = &gensec_gse_krb5_security_ops;
333 #endif
334
335                 backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_NTLMSSP);
336
337                 backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_SPNEGO);
338
339                 backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_SCHANNEL);
340
341                 backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM);
342
343                 /*
344                  * This is anonymous for now, because we just use it
345                  * to set the kerberos state at the moment
346                  */
347                 server_credentials = cli_credentials_init_anon(tmp_ctx);
348                 if (!server_credentials) {
349                         DEBUG(0, ("auth_generic_prepare: Failed to init server credentials\n"));
350                         return NT_STATUS_NO_MEMORY;
351                 }
352
353                 cli_credentials_set_conf(server_credentials, lp_ctx);
354
355                 if (lp_security() == SEC_ADS || USE_KERBEROS_KEYTAB) {
356                         cli_credentials_set_kerberos_state(server_credentials, CRED_AUTO_USE_KERBEROS);
357                 } else {
358                         cli_credentials_set_kerberos_state(server_credentials, CRED_DONT_USE_KERBEROS);
359                 }
360
361                 nt_status = gensec_server_start(tmp_ctx, gensec_settings,
362                                                 auth4_context, &gensec_security);
363
364                 if (!NT_STATUS_IS_OK(nt_status)) {
365                         TALLOC_FREE(tmp_ctx);
366                         return nt_status;
367                 }
368
369                 gensec_set_credentials(gensec_security, server_credentials);
370
371                 talloc_unlink(tmp_ctx, lp_ctx);
372                 talloc_unlink(tmp_ctx, server_credentials);
373                 talloc_unlink(tmp_ctx, gensec_settings);
374                 talloc_unlink(tmp_ctx, auth4_context);
375         }
376
377         nt_status = gensec_set_remote_address(gensec_security,
378                                               remote_address);
379         if (!NT_STATUS_IS_OK(nt_status)) {
380                 TALLOC_FREE(tmp_ctx);
381                 return nt_status;
382         }
383
384         nt_status = gensec_set_local_address(gensec_security,
385                                              local_address);
386         if (!NT_STATUS_IS_OK(nt_status)) {
387                 TALLOC_FREE(tmp_ctx);
388                 return nt_status;
389         }
390
391         nt_status = gensec_set_target_service_description(gensec_security,
392                                                           service_description);
393
394         if (!NT_STATUS_IS_OK(nt_status)) {
395                 TALLOC_FREE(tmp_ctx);
396                 return nt_status;
397         }
398
399         *gensec_security_out = talloc_steal(mem_ctx, gensec_security);
400         TALLOC_FREE(tmp_ctx);
401         return NT_STATUS_OK;
402 }
403
404 /*
405  * Check a username and password, and return the final session_info.
406  * We also log the authorization of the session here, just as
407  * gensec_session_info() does.
408  */
409 NTSTATUS auth_check_password_session_info(struct auth4_context *auth_context,
410                                           TALLOC_CTX *mem_ctx,
411                                           struct auth_usersupplied_info *user_info,
412                                           struct auth_session_info **session_info)
413 {
414         NTSTATUS nt_status;
415         void *server_info;
416         uint8_t authoritative = 0;
417
418         if (auth_context->check_ntlm_password_send != NULL) {
419                 struct tevent_context *ev = NULL;
420                 struct tevent_req *subreq = NULL;
421                 bool ok;
422
423                 ev = samba_tevent_context_init(talloc_tos());
424                 if (ev == NULL) {
425                         return NT_STATUS_NO_MEMORY;
426                 }
427
428                 subreq = auth_context->check_ntlm_password_send(ev, ev,
429                                                                 auth_context,
430                                                                 user_info);
431                 if (subreq == NULL) {
432                         TALLOC_FREE(ev);
433                         return NT_STATUS_NO_MEMORY;
434                 }
435                 ok = tevent_req_poll_ntstatus(subreq, ev, &nt_status);
436                 if (!ok) {
437                         TALLOC_FREE(ev);
438                         return nt_status;
439                 }
440                 nt_status = auth_context->check_ntlm_password_recv(subreq,
441                                                                    talloc_tos(),
442                                                                    &authoritative,
443                                                                    &server_info,
444                                                                    NULL, NULL);
445                 TALLOC_FREE(ev);
446                 if (!NT_STATUS_IS_OK(nt_status)) {
447                         return nt_status;
448                 }
449         } else {
450                 nt_status = auth_context->check_ntlm_password(auth_context,
451                                                               talloc_tos(),
452                                                               user_info,
453                                                               &authoritative,
454                                                               &server_info,
455                                                               NULL, NULL);
456                 if (!NT_STATUS_IS_OK(nt_status)) {
457                         return nt_status;
458                 }
459         }
460
461         nt_status = auth_context->generate_session_info(auth_context,
462                                                         mem_ctx,
463                                                         server_info,
464                                                         user_info->client.account_name,
465                                                         AUTH_SESSION_INFO_UNIX_TOKEN |
466                                                         AUTH_SESSION_INFO_DEFAULT_GROUPS |
467                                                         AUTH_SESSION_INFO_NTLM,
468                                                         session_info);
469         TALLOC_FREE(server_info);
470
471         if (!NT_STATUS_IS_OK(nt_status)) {
472                 return nt_status;
473         }
474
475         /*
476          * This is rather redundant (the authentication has just been
477          * logged, with much the same details), but because we want to
478          * log all authorizations consistently (be they NLTM, NTLMSSP
479          * or krb5) we log this info again as an authorization.
480          */
481         log_successful_authz_event(auth_context->msg_ctx,
482                                    auth_context->lp_ctx,
483                                    user_info->remote_host,
484                                    user_info->local_host,
485                                    user_info->service_description,
486                                    user_info->auth_description,
487                                    AUTHZ_TRANSPORT_PROTECTION_SMB,
488                                    *session_info);
489
490         return nt_status;
491 }