s3: libsmb: Change cli_setfileinfo_ext() and async version to take a uint32_t attr.
[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         status = make_session_info_krb5(mem_ctx,
163                                         ntuser, ntdomain, username, pw,
164                                         info3_copy, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */,
165                                         session_info);
166         if (!NT_STATUS_IS_OK(status)) {
167                 DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n",
168                           nt_errstr(status)));
169                 status = NT_STATUS_ACCESS_DENIED;
170                 goto done;
171         }
172
173         /* setup the string used by %U */
174         set_current_user_info((*session_info)->unix_info->sanitized_username,
175                               (*session_info)->unix_info->unix_name,
176                               (*session_info)->info->domain_name);
177
178         /* reload services so that the new %U is taken into account */
179         lp_load_with_shares(get_dyn_CONFIGFILE());
180
181         DEBUG(5, (__location__ "OK: user: %s domain: %s client: %s\n",
182                   ntuser, ntdomain, rhost));
183
184         status = NT_STATUS_OK;
185
186 done:
187         TALLOC_FREE(tmp_ctx);
188         return status;
189 }
190
191 static struct auth4_context *make_auth4_context_s3(TALLOC_CTX *mem_ctx, struct auth_context *auth_context)
192 {
193         struct auth4_context *auth4_context = talloc_zero(mem_ctx, struct auth4_context);
194         if (auth4_context == NULL) {
195                 DEBUG(10, ("failed to allocate auth4_context failed\n"));
196                 return NULL;
197         }
198         auth4_context->generate_session_info_pac = auth3_generate_session_info_pac;
199         auth4_context->generate_session_info = auth3_generate_session_info;
200         auth4_context->get_ntlm_challenge = auth3_get_challenge;
201         auth4_context->set_ntlm_challenge = auth3_set_challenge;
202         auth4_context->check_ntlm_password_send = auth3_check_password_send;
203         auth4_context->check_ntlm_password_recv = auth3_check_password_recv;
204         auth4_context->private_data = talloc_steal(auth4_context, auth_context);
205         return auth4_context;
206 }
207
208 NTSTATUS make_auth4_context(TALLOC_CTX *mem_ctx, struct auth4_context **auth4_context_out)
209 {
210         struct auth_context *auth_context;
211         NTSTATUS nt_status;
212
213         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
214         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
215
216         nt_status = make_auth3_context_for_ntlm(tmp_ctx, &auth_context);
217         if (!NT_STATUS_IS_OK(nt_status)) {
218                 TALLOC_FREE(tmp_ctx);
219                 return nt_status;
220         }
221
222         if (auth_context->make_auth4_context) {
223                 nt_status = auth_context->make_auth4_context(auth_context, mem_ctx, auth4_context_out);
224                 TALLOC_FREE(tmp_ctx);
225                 return nt_status;
226
227         } else {
228                 struct auth4_context *auth4_context = make_auth4_context_s3(tmp_ctx, auth_context);
229                 if (auth4_context == NULL) {
230                         TALLOC_FREE(tmp_ctx);
231                         return NT_STATUS_NO_MEMORY;
232                 }
233                 *auth4_context_out = talloc_steal(mem_ctx, auth4_context);
234                 TALLOC_FREE(tmp_ctx);
235                 return NT_STATUS_OK;
236         }
237 }
238
239 NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
240                               const struct tsocket_address *remote_address,
241                               const struct tsocket_address *local_address,
242                               const char *service_description,
243                               struct gensec_security **gensec_security_out)
244 {
245         struct gensec_security *gensec_security;
246         struct auth_context *auth_context;
247         NTSTATUS nt_status;
248
249         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
250         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
251
252         nt_status = make_auth3_context_for_ntlm(tmp_ctx, &auth_context);
253         if (!NT_STATUS_IS_OK(nt_status)) {
254                 TALLOC_FREE(tmp_ctx);
255                 return nt_status;
256         }
257
258         if (auth_context->prepare_gensec) {
259                 nt_status = auth_context->prepare_gensec(auth_context, tmp_ctx,
260                                                          &gensec_security);
261                 if (!NT_STATUS_IS_OK(nt_status)) {
262                         TALLOC_FREE(tmp_ctx);
263                         return nt_status;
264                 }
265         } else {
266                 const struct gensec_security_ops **backends = NULL;
267                 struct gensec_settings *gensec_settings;
268                 struct loadparm_context *lp_ctx;
269                 size_t idx = 0;
270                 struct cli_credentials *server_credentials;
271                 const char *dns_name;
272                 const char *dns_domain;
273                 struct auth4_context *auth4_context = make_auth4_context_s3(tmp_ctx, auth_context);
274                 if (auth4_context == NULL) {
275                         TALLOC_FREE(tmp_ctx);
276                         return NT_STATUS_NO_MEMORY;
277                 }
278
279                 lp_ctx = loadparm_init_s3(tmp_ctx, loadparm_s3_helpers());
280                 if (lp_ctx == NULL) {
281                         DEBUG(10, ("loadparm_init_s3 failed\n"));
282                         TALLOC_FREE(tmp_ctx);
283                         return NT_STATUS_INVALID_SERVER_STATE;
284                 }
285
286                 gensec_settings = lpcfg_gensec_settings(tmp_ctx, lp_ctx);
287                 if (lp_ctx == NULL) {
288                         DEBUG(10, ("lpcfg_gensec_settings failed\n"));
289                         TALLOC_FREE(tmp_ctx);
290                         return NT_STATUS_NO_MEMORY;
291                 }
292
293                 /*
294                  * This should be a 'netbios domain -> DNS domain'
295                  * mapping, and can currently validly return NULL on
296                  * poorly configured systems.
297                  *
298                  * This is used for the NTLMSSP server
299                  *
300                  */
301                 dns_name = get_mydnsfullname();
302                 if (dns_name == NULL) {
303                         dns_name = "";
304                 }
305
306                 dns_domain = get_mydnsdomname(tmp_ctx);
307                 if (dns_domain == NULL) {
308                         dns_domain = "";
309                 }
310
311                 gensec_settings->server_dns_name = strlower_talloc(gensec_settings, dns_name);
312                 if (gensec_settings->server_dns_name == NULL) {
313                         TALLOC_FREE(tmp_ctx);
314                         return NT_STATUS_NO_MEMORY;
315                 }
316
317                 gensec_settings->server_dns_domain = strlower_talloc(gensec_settings, dns_domain);
318                 if (gensec_settings->server_dns_domain == NULL) {
319                         TALLOC_FREE(tmp_ctx);
320                         return NT_STATUS_NO_MEMORY;
321                 }
322
323                 backends = talloc_zero_array(gensec_settings,
324                                              const struct gensec_security_ops *, 6);
325                 if (backends == NULL) {
326                         TALLOC_FREE(tmp_ctx);
327                         return NT_STATUS_NO_MEMORY;
328                 }
329                 gensec_settings->backends = backends;
330
331                 gensec_init();
332
333                 /* These need to be in priority order, krb5 before NTLMSSP */
334 #if defined(HAVE_KRB5)
335                 backends[idx++] = &gensec_gse_krb5_security_ops;
336 #endif
337
338                 backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_NTLMSSP);
339
340                 backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_SPNEGO);
341
342                 backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_SCHANNEL);
343
344                 backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM);
345
346                 /*
347                  * This is anonymous for now, because we just use it
348                  * to set the kerberos state at the moment
349                  */
350                 server_credentials = cli_credentials_init_anon(tmp_ctx);
351                 if (!server_credentials) {
352                         DEBUG(0, ("auth_generic_prepare: Failed to init server credentials\n"));
353                         return NT_STATUS_NO_MEMORY;
354                 }
355
356                 cli_credentials_set_conf(server_credentials, lp_ctx);
357
358                 if (lp_security() == SEC_ADS || USE_KERBEROS_KEYTAB) {
359                         cli_credentials_set_kerberos_state(server_credentials, CRED_AUTO_USE_KERBEROS);
360                 } else {
361                         cli_credentials_set_kerberos_state(server_credentials, CRED_DONT_USE_KERBEROS);
362                 }
363
364                 nt_status = gensec_server_start(tmp_ctx, gensec_settings,
365                                                 auth4_context, &gensec_security);
366
367                 if (!NT_STATUS_IS_OK(nt_status)) {
368                         TALLOC_FREE(tmp_ctx);
369                         return nt_status;
370                 }
371
372                 gensec_set_credentials(gensec_security, server_credentials);
373
374                 talloc_unlink(tmp_ctx, lp_ctx);
375                 talloc_unlink(tmp_ctx, server_credentials);
376                 talloc_unlink(tmp_ctx, gensec_settings);
377                 talloc_unlink(tmp_ctx, auth4_context);
378         }
379
380         nt_status = gensec_set_remote_address(gensec_security,
381                                               remote_address);
382         if (!NT_STATUS_IS_OK(nt_status)) {
383                 TALLOC_FREE(tmp_ctx);
384                 return nt_status;
385         }
386
387         nt_status = gensec_set_local_address(gensec_security,
388                                              local_address);
389         if (!NT_STATUS_IS_OK(nt_status)) {
390                 TALLOC_FREE(tmp_ctx);
391                 return nt_status;
392         }
393
394         nt_status = gensec_set_target_service_description(gensec_security,
395                                                           service_description);
396
397         if (!NT_STATUS_IS_OK(nt_status)) {
398                 TALLOC_FREE(tmp_ctx);
399                 return nt_status;
400         }
401
402         *gensec_security_out = talloc_steal(mem_ctx, gensec_security);
403         TALLOC_FREE(tmp_ctx);
404         return NT_STATUS_OK;
405 }
406
407 /*
408  * Check a username and password, and return the final session_info.
409  * We also log the authorization of the session here, just as
410  * gensec_session_info() does.
411  */
412 NTSTATUS auth_check_password_session_info(struct auth4_context *auth_context,
413                                           TALLOC_CTX *mem_ctx,
414                                           struct auth_usersupplied_info *user_info,
415                                           struct auth_session_info **session_info)
416 {
417         NTSTATUS nt_status;
418         void *server_info;
419         uint8_t authoritative = 0;
420         struct tevent_context *ev = NULL;
421         struct tevent_req *subreq = NULL;
422         bool ok;
423
424         ev = samba_tevent_context_init(talloc_tos());
425         if (ev == NULL) {
426                 return NT_STATUS_NO_MEMORY;
427         }
428
429         subreq = auth_context->check_ntlm_password_send(ev, ev,
430                                                         auth_context,
431                                                         user_info);
432         if (subreq == NULL) {
433                 TALLOC_FREE(ev);
434                 return NT_STATUS_NO_MEMORY;
435         }
436         ok = tevent_req_poll_ntstatus(subreq, ev, &nt_status);
437         if (!ok) {
438                 TALLOC_FREE(ev);
439                 return nt_status;
440         }
441         nt_status = auth_context->check_ntlm_password_recv(subreq,
442                                                            talloc_tos(),
443                                                            &authoritative,
444                                                            &server_info,
445                                                            NULL, NULL);
446         TALLOC_FREE(ev);
447         if (!NT_STATUS_IS_OK(nt_status)) {
448                 return nt_status;
449         }
450
451         nt_status = auth_context->generate_session_info(auth_context,
452                                                         mem_ctx,
453                                                         server_info,
454                                                         user_info->client.account_name,
455                                                         AUTH_SESSION_INFO_UNIX_TOKEN |
456                                                         AUTH_SESSION_INFO_DEFAULT_GROUPS |
457                                                         AUTH_SESSION_INFO_NTLM,
458                                                         session_info);
459         TALLOC_FREE(server_info);
460
461         if (!NT_STATUS_IS_OK(nt_status)) {
462                 return nt_status;
463         }
464
465         /*
466          * This is rather redundant (the authentication has just been
467          * logged, with much the same details), but because we want to
468          * log all authorizations consistently (be they NLTM, NTLMSSP
469          * or krb5) we log this info again as an authorization.
470          */
471         log_successful_authz_event(auth_context->msg_ctx,
472                                    auth_context->lp_ctx,
473                                    user_info->remote_host,
474                                    user_info->local_host,
475                                    user_info->service_description,
476                                    user_info->auth_description,
477                                    AUTHZ_TRANSPORT_PROTECTION_SMB,
478                                    *session_info);
479
480         return nt_status;
481 }