s3:smbd: Fix code spelling
[samba.git] / source3 / smbd / smb1_sesssetup.c
1 /*
2    Unix SMB/CIFS implementation.
3    handle SMBsessionsetup
4    Copyright (C) Andrew Tridgell 1998-2001
5    Copyright (C) Andrew Bartlett      2001
6    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
7    Copyright (C) Luke Howard          2003
8    Copyright (C) Volker Lendecke      2007
9    Copyright (C) Jeremy Allison       2007
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26 #include "../lib/tsocket/tsocket.h"
27 #include "lib/util/server_id.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "auth.h"
31 #include "messages.h"
32 #include "smbprofile.h"
33 #include "../libcli/security/security.h"
34 #include "auth/gensec/gensec.h"
35 #include "../libcli/smb/smb_signing.h"
36 #include "lib/util/string_wrappers.h"
37 #include "source3/lib/substitute.h"
38
39 /****************************************************************************
40  Add the standard 'Samba' signature to the end of the session setup.
41 ****************************************************************************/
42
43 static int push_signature(uint8_t **outbuf)
44 {
45         char *lanman;
46         int result, tmp;
47         fstring native_os;
48
49         result = 0;
50
51         fstr_sprintf(native_os, "Windows %d.%d", SAMBA_MAJOR_NBT_ANNOUNCE_VERSION,
52                 SAMBA_MINOR_NBT_ANNOUNCE_VERSION);
53
54         tmp = message_push_string(outbuf, native_os, STR_TERMINATE);
55
56         if (tmp == -1) return -1;
57         result += tmp;
58
59         if (asprintf(&lanman, "Samba %s", samba_version_string()) != -1) {
60                 tmp = message_push_string(outbuf, lanman, STR_TERMINATE);
61                 SAFE_FREE(lanman);
62         }
63         else {
64                 tmp = message_push_string(outbuf, "Samba", STR_TERMINATE);
65         }
66
67         if (tmp == -1) return -1;
68         result += tmp;
69
70         tmp = message_push_string(outbuf, lp_workgroup(), STR_TERMINATE);
71
72         if (tmp == -1) return -1;
73         result += tmp;
74
75         return result;
76 }
77
78 /****************************************************************************
79  Reply to a session setup command.
80  conn POINTER CAN BE NULL HERE !
81 ****************************************************************************/
82
83 static void reply_sesssetup_and_X_spnego(struct smb_request *req)
84 {
85         const uint8_t *p;
86         DATA_BLOB in_blob;
87         DATA_BLOB out_blob = data_blob_null;
88         size_t bufrem;
89         char *tmp = NULL;
90         const char *native_os;
91         const char *native_lanman;
92         const char *primary_domain;
93         uint16_t data_blob_len = SVAL(req->vwv+7, 0);
94         enum remote_arch_types ra_type = get_remote_arch();
95         uint64_t vuid = req->vuid;
96         NTSTATUS status = NT_STATUS_OK;
97         struct smbXsrv_connection *xconn = req->xconn;
98         struct smbd_server_connection *sconn = req->sconn;
99         uint16_t action = 0;
100         bool is_authenticated = false;
101         NTTIME now = timeval_to_nttime(&req->request_time);
102         struct smbXsrv_session *session = NULL;
103         uint16_t smb_bufsize = SVAL(req->vwv+2, 0);
104         uint32_t client_caps = IVAL(req->vwv+10, 0);
105         struct smbXsrv_session_auth0 *auth;
106
107         DEBUG(3,("Doing spnego session setup\n"));
108
109         if (!xconn->smb1.sessions.done_sesssetup) {
110                 global_client_caps = client_caps;
111
112                 if (!(global_client_caps & CAP_STATUS32)) {
113                         remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
114                 }
115         }
116
117         p = req->buf;
118
119         if (data_blob_len == 0) {
120                 /* an invalid request */
121                 reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE));
122                 return;
123         }
124
125         bufrem = smbreq_bufrem(req, p);
126         /* pull the spnego blob */
127         in_blob = data_blob_const(p, MIN(bufrem, data_blob_len));
128
129 #if 0
130         file_save("negotiate.dat", in_blob.data, in_blob.length);
131 #endif
132
133         p = req->buf + in_blob.length;
134
135         p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
136                                      STR_TERMINATE);
137         native_os = tmp ? tmp : "";
138
139         p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
140                                      STR_TERMINATE);
141         native_lanman = tmp ? tmp : "";
142
143         p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
144                                      STR_TERMINATE);
145         primary_domain = tmp ? tmp : "";
146
147         DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
148                 native_os, native_lanman, primary_domain));
149
150         if ( ra_type == RA_WIN2K ) {
151                 /* Vista sets neither the OS or lanman strings */
152
153                 if ( !strlen(native_os) && !strlen(native_lanman) )
154                         set_remote_arch(RA_VISTA);
155
156                 /* Windows 2003 doesn't set the native lanman string,
157                    but does set primary domain which is a bug I think */
158
159                 if ( !strlen(native_lanman) ) {
160                         ra_lanman_string( primary_domain );
161                 } else {
162                         ra_lanman_string( native_lanman );
163                 }
164         } else if ( ra_type == RA_VISTA ) {
165                 if ( strncmp(native_os, "Mac OS X", 8) == 0 ) {
166                         set_remote_arch(RA_OSX);
167                 }
168         }
169
170         if (vuid != 0) {
171                 status = smb1srv_session_lookup(xconn,
172                                                 vuid, now,
173                                                 &session);
174                 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
175                         reply_force_doserror(req, ERRSRV, ERRbaduid);
176                         return;
177                 }
178                 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
179                         status = NT_STATUS_OK;
180                 }
181                 if (NT_STATUS_IS_OK(status)) {
182                         session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
183                         status = NT_STATUS_MORE_PROCESSING_REQUIRED;
184                         TALLOC_FREE(session->pending_auth);
185                 }
186                 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
187                         reply_nterror(req, nt_status_squash(status));
188                         return;
189                 }
190         }
191
192         if (session == NULL) {
193                 /* create a new session */
194                 status = smbXsrv_session_create(xconn,
195                                                 now, &session);
196                 if (!NT_STATUS_IS_OK(status)) {
197                         reply_nterror(req, nt_status_squash(status));
198                         return;
199                 }
200         }
201
202         status = smbXsrv_session_find_auth(session, xconn, now, &auth);
203         if (!NT_STATUS_IS_OK(status)) {
204                 status = smbXsrv_session_create_auth(session, xconn, now,
205                                                      0, /* flags */
206                                                      0, /* security */
207                                                      &auth);
208                 if (!NT_STATUS_IS_OK(status)) {
209                         reply_nterror(req, nt_status_squash(status));
210                         return;
211                 }
212         }
213
214         if (auth->gensec == NULL) {
215                 status = auth_generic_prepare(session,
216                                               xconn->remote_address,
217                                               xconn->local_address,
218                                               "SMB",
219                                               &auth->gensec);
220                 if (!NT_STATUS_IS_OK(status)) {
221                         TALLOC_FREE(session);
222                         reply_nterror(req, nt_status_squash(status));
223                         return;
224                 }
225
226                 gensec_want_feature(auth->gensec, GENSEC_FEATURE_SESSION_KEY);
227                 gensec_want_feature(auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
228                 gensec_want_feature(auth->gensec, GENSEC_FEATURE_SMB_TRANSPORT);
229
230                 status = gensec_start_mech_by_oid(auth->gensec,
231                                                   GENSEC_OID_SPNEGO);
232                 if (!NT_STATUS_IS_OK(status)) {
233                         DEBUG(0, ("Failed to start SPNEGO handler!\n"));
234                         TALLOC_FREE(session);;
235                         reply_nterror(req, nt_status_squash(status));
236                         return;
237                 }
238         }
239
240         become_root();
241         status = gensec_update(auth->gensec,
242                                talloc_tos(),
243                                in_blob, &out_blob);
244         unbecome_root();
245         if (!NT_STATUS_IS_OK(status) &&
246             !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
247                 TALLOC_FREE(session);
248                 reply_nterror(req, nt_status_squash(status));
249                 return;
250         }
251
252         if (NT_STATUS_IS_OK(status) && session->global->auth_session_info == NULL) {
253                 struct auth_session_info *session_info = NULL;
254
255                 status = gensec_session_info(auth->gensec,
256                                              session,
257                                              &session_info);
258                 if (!NT_STATUS_IS_OK(status)) {
259                         DEBUG(1,("Failed to generate session_info "
260                                  "(user and group token) for session setup: %s\n",
261                                  nt_errstr(status)));
262                         data_blob_free(&out_blob);
263                         TALLOC_FREE(session);
264                         reply_nterror(req, nt_status_squash(status));
265                         return;
266                 }
267
268                 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
269                         action |= SMB_SETUP_GUEST;
270                 }
271
272                 session->global->signing_algo = SMB2_SIGNING_MD5_SMB1;
273                 session->global->encryption_cipher = 0;
274                 session->global->channels[0].signing_algo =
275                                 session->global->signing_algo;
276                 session->global->channels[0].encryption_cipher =
277                                 session->global->encryption_cipher;
278
279                 if (session_info->session_key.length > 0) {
280                         struct smbXsrv_session *x = session;
281
282                         status = smb2_signing_key_sign_create(x->global,
283                                                 x->global->signing_algo,
284                                                 &session_info->session_key,
285                                                 NULL, /* no derivation */
286                                                 &x->global->signing_key);
287                         if (!NT_STATUS_IS_OK(status)) {
288                                 data_blob_free(&out_blob);
289                                 TALLOC_FREE(session);
290                                 reply_nterror(req, status);
291                                 return;
292                         }
293                         x->global->signing_key_blob = x->global->signing_key->blob;
294
295                         /*
296                          * clear the session key
297                          * the first tcon will add setup the application key
298                          */
299                         data_blob_clear_free(&session_info->session_key);
300                 }
301
302                 sconn->num_users++;
303
304                 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
305                         is_authenticated = true;
306                         session->homes_snum =
307                                 register_homes_share(session_info->unix_info->unix_name);
308                 }
309
310                 if (smb1_srv_is_signing_negotiated(xconn) &&
311                     is_authenticated &&
312                     smb2_signing_key_valid(session->global->signing_key))
313                 {
314                         /*
315                          * Try and turn on server signing on the first non-guest
316                          * sessionsetup.
317                          */
318                         smb1_srv_set_signing(xconn,
319                                 session->global->signing_key->blob,
320                                 data_blob_null);
321                 }
322
323                 set_current_user_info(session_info->unix_info->sanitized_username,
324                                       session_info->unix_info->unix_name,
325                                       session_info->info->domain_name);
326
327                 session->status = NT_STATUS_OK;
328                 session->global->auth_session_info = talloc_move(session->global,
329                                                                  &session_info);
330                 session->global->auth_session_info_seqnum += 1;
331                 session->global->channels[0].auth_session_info_seqnum =
332                         session->global->auth_session_info_seqnum;
333                 session->global->auth_time = now;
334                 if (client_caps & CAP_DYNAMIC_REAUTH) {
335                         session->global->expiration_time =
336                                 gensec_expire_time(auth->gensec);
337                 } else {
338                         session->global->expiration_time =
339                                 GENSEC_EXPIRE_TIME_INFINITY;
340                 }
341
342                 if (!session_claim(session)) {
343                         DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
344                                   (unsigned long long)session->global->session_wire_id));
345                         data_blob_free(&out_blob);
346                         TALLOC_FREE(session);
347                         reply_nterror(req, NT_STATUS_LOGON_FAILURE);
348                         return;
349                 }
350
351                 status = smbXsrv_session_update(session);
352                 if (!NT_STATUS_IS_OK(status)) {
353                         DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
354                                   (unsigned long long)session->global->session_wire_id,
355                                   nt_errstr(status)));
356                         data_blob_free(&out_blob);
357                         TALLOC_FREE(session);
358                         reply_nterror(req, NT_STATUS_LOGON_FAILURE);
359                         return;
360                 }
361
362                 if (!xconn->smb1.sessions.done_sesssetup) {
363                         if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
364                                 reply_force_doserror(req, ERRSRV, ERRerror);
365                                 return;
366                         }
367                         xconn->smb1.sessions.max_send = smb_bufsize;
368                         xconn->smb1.sessions.done_sesssetup = true;
369                 }
370
371                 /* current_user_info is changed on new vuid */
372                 reload_services(sconn, conn_snum_used, true);
373         } else if (NT_STATUS_IS_OK(status)) {
374                 struct auth_session_info *session_info = NULL;
375
376                 status = gensec_session_info(auth->gensec,
377                                              session,
378                                              &session_info);
379                 if (!NT_STATUS_IS_OK(status)) {
380                         DEBUG(1,("Failed to generate session_info "
381                                  "(user and group token) for session setup: %s\n",
382                                  nt_errstr(status)));
383                         data_blob_free(&out_blob);
384                         TALLOC_FREE(session);
385                         reply_nterror(req, nt_status_squash(status));
386                         return;
387                 }
388
389                 if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
390                         action |= SMB_SETUP_GUEST;
391                 }
392
393                 /*
394                  * Keep the application key
395                  */
396                 data_blob_clear_free(&session_info->session_key);
397                 session_info->session_key =
398                         session->global->auth_session_info->session_key;
399                 talloc_steal(session_info, session_info->session_key.data);
400                 TALLOC_FREE(session->global->auth_session_info);
401
402                 if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
403                         session->homes_snum =
404                                 register_homes_share(session_info->unix_info->unix_name);
405                 }
406
407                 set_current_user_info(session_info->unix_info->sanitized_username,
408                                       session_info->unix_info->unix_name,
409                                       session_info->info->domain_name);
410
411                 session->status = NT_STATUS_OK;
412                 session->global->auth_session_info = talloc_move(session->global,
413                                                                  &session_info);
414                 session->global->auth_session_info_seqnum += 1;
415                 session->global->channels[0].auth_session_info_seqnum =
416                         session->global->auth_session_info_seqnum;
417                 session->global->auth_time = now;
418                 if (client_caps & CAP_DYNAMIC_REAUTH) {
419                         session->global->expiration_time =
420                                 gensec_expire_time(auth->gensec);
421                 } else {
422                         session->global->expiration_time =
423                                 GENSEC_EXPIRE_TIME_INFINITY;
424                 }
425
426                 status = smbXsrv_session_update(session);
427                 if (!NT_STATUS_IS_OK(status)) {
428                         DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
429                                   (unsigned long long)session->global->session_wire_id,
430                                   nt_errstr(status)));
431                         data_blob_free(&out_blob);
432                         TALLOC_FREE(session);
433                         reply_nterror(req, NT_STATUS_LOGON_FAILURE);
434                         return;
435                 }
436
437                 conn_clear_vuid_caches(sconn, session->global->session_wire_id);
438
439                 /* current_user_info is changed on new vuid */
440                 reload_services(sconn, conn_snum_used, true);
441         }
442
443         vuid = session->global->session_wire_id;
444
445         reply_smb1_outbuf(req, 4, 0);
446
447         SSVAL(req->outbuf, smb_uid, vuid);
448         SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(status));
449         SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */
450         SSVAL(req->outbuf, smb_vwv2, action);
451         SSVAL(req->outbuf, smb_vwv3, out_blob.length);
452
453         if (message_push_blob(&req->outbuf, out_blob) == -1) {
454                 data_blob_free(&out_blob);
455                 TALLOC_FREE(session);
456                 reply_nterror(req, NT_STATUS_NO_MEMORY);
457                 return;
458         }
459         data_blob_free(&out_blob);
460
461         if (push_signature(&req->outbuf) == -1) {
462                 TALLOC_FREE(session);
463                 reply_nterror(req, NT_STATUS_NO_MEMORY);
464                 return;
465         }
466 }
467
468 /****************************************************************************
469  On new VC == 0, shutdown *all* old connections and users.
470  It seems that only NT4.x does this. At W2K and above (XP etc.).
471  a new session setup with VC==0 is ignored.
472 ****************************************************************************/
473
474 struct shutdown_state {
475         const char *ip;
476         size_t ip_length;
477         struct messaging_context *msg_ctx;
478 };
479
480 static int shutdown_other_smbds(struct smbXsrv_session_global0 *session,
481                                 void *private_data)
482 {
483         struct shutdown_state *state = (struct shutdown_state *)private_data;
484         struct server_id self_pid = messaging_server_id(state->msg_ctx);
485         struct server_id pid = session->channels[0].server_id;
486         const char *addr = session->channels[0].remote_address;
487         const char *port_colon;
488         size_t addr_len;
489         struct server_id_buf tmp;
490
491         DEBUG(10, ("shutdown_other_smbds: %s, %s\n",
492                    server_id_str_buf(pid, &tmp), addr));
493
494         if (!process_exists(pid)) {
495                 DEBUG(10, ("process does not exist\n"));
496                 return 0;
497         }
498
499         if (server_id_equal(&pid, &self_pid)) {
500                 DEBUG(10, ("It's me\n"));
501                 return 0;
502         }
503
504         port_colon = strrchr(addr, ':');
505         if (port_colon == NULL) {
506                 DBG_DEBUG("addr %s in contains no port\n", addr);
507                 return 0;
508         }
509         addr_len = port_colon - addr;
510
511         if ((addr_len != state->ip_length) ||
512             (strncmp(addr, state->ip, state->ip_length) != 0)) {
513                 DEBUG(10, ("%s (%zu) does not match %s (%zu)\n",
514                            state->ip, state->ip_length, addr, addr_len));
515                 return 0;
516         }
517
518         DEBUG(1, ("shutdown_other_smbds: shutting down pid %u "
519                   "(IP %s)\n", (unsigned int)procid_to_pid(&pid),
520                   state->ip));
521
522         messaging_send(state->msg_ctx, pid, MSG_SHUTDOWN,
523                        &data_blob_null);
524         return 0;
525 }
526
527 static void setup_new_vc_session(struct smbd_server_connection *sconn)
528 {
529         DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x "
530                 "compatible we would close all old resources.\n"));
531
532         if (lp_reset_on_zero_vc()) {
533                 char *addr;
534                 const char *port_colon;
535                 struct shutdown_state state;
536
537                 addr = tsocket_address_string(
538                         sconn->remote_address, talloc_tos());
539                 if (addr == NULL) {
540                         return;
541                 }
542                 state.ip = addr;
543
544                 port_colon = strrchr(addr, ':');
545                 if (port_colon == NULL) {
546                         return;
547                 }
548                 state.ip_length = port_colon - addr;
549                 state.msg_ctx = sconn->msg_ctx;
550                 smbXsrv_session_global_traverse(shutdown_other_smbds, &state);
551                 TALLOC_FREE(addr);
552         }
553 }
554
555 /****************************************************************************
556  Reply to a session setup command.
557 ****************************************************************************/
558
559 struct reply_sesssetup_and_X_state {
560         struct smb_request *req;
561         struct auth4_context *auth_context;
562         struct auth_usersupplied_info *user_info;
563         const char *user;
564         const char *domain;
565         DATA_BLOB lm_resp;
566         DATA_BLOB nt_resp;
567         DATA_BLOB plaintext_password;
568 };
569
570 static int reply_sesssetup_and_X_state_destructor(
571                 struct reply_sesssetup_and_X_state *state)
572 {
573         data_blob_clear_free(&state->nt_resp);
574         data_blob_clear_free(&state->lm_resp);
575         data_blob_clear_free(&state->plaintext_password);
576         return 0;
577 }
578
579 void reply_sesssetup_and_X(struct smb_request *req)
580 {
581         struct reply_sesssetup_and_X_state *state = NULL;
582         uint64_t sess_vuid;
583         uint16_t smb_bufsize;
584         char *tmp = NULL;
585         fstring sub_user; /* Sanitised username for substitution */
586         const char *native_os;
587         const char *native_lanman;
588         const char *primary_domain;
589         struct auth_session_info *session_info = NULL;
590         uint16_t smb_flag2 = req->flags2;
591         uint16_t action = 0;
592         bool is_authenticated = false;
593         NTTIME now = timeval_to_nttime(&req->request_time);
594         struct smbXsrv_session *session = NULL;
595         NTSTATUS nt_status;
596         struct smbXsrv_connection *xconn = req->xconn;
597         struct smbd_server_connection *sconn = req->sconn;
598         bool doencrypt = xconn->smb1.negprot.encrypted_passwords;
599         bool signing_allowed = false;
600         bool signing_mandatory = smb1_signing_is_mandatory(
601                 xconn->smb1.signing_state);
602
603         START_PROFILE(SMBsesssetupX);
604
605         DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2));
606
607         state = talloc_zero(req, struct reply_sesssetup_and_X_state);
608         if (state == NULL) {
609                 reply_nterror(req, NT_STATUS_NO_MEMORY);
610                 END_PROFILE(SMBsesssetupX);
611                 return;
612         }
613         state->req = req;
614         talloc_set_destructor(state, reply_sesssetup_and_X_state_destructor);
615
616         if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES) {
617                 signing_allowed = true;
618         }
619         if (req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) {
620                 signing_mandatory = true;
621         }
622
623         /*
624          * We can call smb1_srv_set_signing_negotiated() each time.
625          * It finds out when it needs to turn into a noop
626          * itself.
627          */
628         smb1_srv_set_signing_negotiated(xconn,
629                                    signing_allowed,
630                                    signing_mandatory);
631
632         /* a SPNEGO session setup has 12 command words, whereas a normal
633            NT1 session setup has 13. See the cifs spec. */
634         if (req->wct == 12 &&
635             (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
636
637                 if (!xconn->smb1.negprot.spnego) {
638                         DEBUG(0,("reply_sesssetup_and_X:  Rejecting attempt "
639                                  "at SPNEGO session setup when it was not "
640                                  "negotiated.\n"));
641                         reply_nterror(req, nt_status_squash(
642                                               NT_STATUS_LOGON_FAILURE));
643                         END_PROFILE(SMBsesssetupX);
644                         return;
645                 }
646
647                 if (SVAL(req->vwv+4, 0) == 0) {
648                         setup_new_vc_session(req->sconn);
649                 }
650
651                 reply_sesssetup_and_X_spnego(req);
652                 END_PROFILE(SMBsesssetupX);
653                 return;
654         }
655
656         smb_bufsize = SVAL(req->vwv+2, 0);
657
658         if (xconn->protocol < PROTOCOL_NT1) {
659                 uint16_t passlen1 = SVAL(req->vwv+7, 0);
660
661                 /* Never do NT status codes with protocols before NT1 as we
662                  * don't get client caps. */
663                 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
664
665                 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
666                         reply_nterror(req, nt_status_squash(
667                                               NT_STATUS_INVALID_PARAMETER));
668                         END_PROFILE(SMBsesssetupX);
669                         return;
670                 }
671
672                 if (doencrypt) {
673                         state->lm_resp = data_blob_talloc(state,
674                                                           req->buf,
675                                                           passlen1);
676                 } else {
677                         state->plaintext_password = data_blob_talloc(state,
678                                                                 req->buf,
679                                                                 passlen1+1);
680                         /* Ensure null termination */
681                         state->plaintext_password.data[passlen1] = 0;
682                 }
683
684                 srvstr_pull_req_talloc(state, req, &tmp,
685                                        req->buf + passlen1, STR_TERMINATE);
686                 state->user = tmp ? tmp : "";
687
688                 state->domain = "";
689
690         } else {
691                 uint16_t passlen1 = SVAL(req->vwv+7, 0);
692                 uint16_t passlen2 = SVAL(req->vwv+8, 0);
693                 enum remote_arch_types ra_type = get_remote_arch();
694                 const uint8_t *p = req->buf;
695                 const uint8_t *save_p = req->buf;
696                 uint16_t byte_count;
697
698                 if (!xconn->smb1.sessions.done_sesssetup) {
699                         global_client_caps = IVAL(req->vwv+11, 0);
700
701                         if (!(global_client_caps & CAP_STATUS32)) {
702                                 remove_from_common_flags2(
703                                                 FLAGS2_32_BIT_ERROR_CODES);
704                         }
705
706                         /* client_caps is used as final determination if
707                          * client is NT or Win95. This is needed to return
708                          * the correct error codes in some circumstances.
709                         */
710
711                         if(ra_type == RA_WINNT || ra_type == RA_WIN2K ||
712                                         ra_type == RA_WIN95) {
713                                 if(!(global_client_caps & (CAP_NT_SMBS|
714                                                         CAP_STATUS32))) {
715                                         set_remote_arch( RA_WIN95);
716                                 }
717                         }
718                 }
719
720                 if (!doencrypt) {
721                         /* both Win95 and WinNT stuff up the password
722                          * lengths for non-encrypting systems. Uggh.
723
724                            if passlen1==24 its a win95 system, and its setting
725                            the password length incorrectly. Luckily it still
726                            works with the default code because Win95 will null
727                            terminate the password anyway
728
729                            if passlen1>0 and passlen2>0 then maybe its a NT box
730                            and its setting passlen2 to some random value which
731                            really stuffs things up. we need to fix that one.  */
732
733                         if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
734                                         passlen2 != 1) {
735                                 passlen2 = 0;
736                         }
737                 }
738
739                 /* check for nasty tricks */
740                 if (passlen1 > MAX_PASS_LEN
741                     || passlen1 > smbreq_bufrem(req, p)) {
742                         reply_nterror(req, nt_status_squash(
743                                               NT_STATUS_INVALID_PARAMETER));
744                         END_PROFILE(SMBsesssetupX);
745                         return;
746                 }
747
748                 if (passlen2 > MAX_PASS_LEN
749                     || passlen2 > smbreq_bufrem(req, p+passlen1)) {
750                         reply_nterror(req, nt_status_squash(
751                                               NT_STATUS_INVALID_PARAMETER));
752                         END_PROFILE(SMBsesssetupX);
753                         return;
754                 }
755
756                 /* Save the lanman2 password and the NT md4 password. */
757
758                 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
759                         doencrypt = False;
760                 }
761
762                 if (doencrypt) {
763                         state->lm_resp = data_blob_talloc(state, p, passlen1);
764                         state->nt_resp = data_blob_talloc(state, p+passlen1, passlen2);
765                 } else {
766                         char *pass = NULL;
767                         bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
768
769                         if (unic && (passlen2 == 0) && passlen1) {
770                                 /* Only a ascii plaintext password was sent. */
771                                 (void)srvstr_pull_talloc(state,
772                                                         req->inbuf,
773                                                         req->flags2,
774                                                         &pass,
775                                                         req->buf,
776                                                         passlen1,
777                                                         STR_TERMINATE|STR_ASCII);
778                         } else {
779                                 (void)srvstr_pull_talloc(state,
780                                                         req->inbuf,
781                                                         req->flags2,
782                                                         &pass,
783                                                         req->buf,
784                                                         unic ? passlen2 : passlen1,
785                                                         STR_TERMINATE);
786                         }
787                         if (!pass) {
788                                 reply_nterror(req, nt_status_squash(
789                                               NT_STATUS_INVALID_PARAMETER));
790                                 END_PROFILE(SMBsesssetupX);
791                                 return;
792                         }
793                         state->plaintext_password = data_blob_talloc(state,
794                                                                 pass,
795                                                                 strlen(pass)+1);
796                 }
797
798                 p += passlen1 + passlen2;
799
800                 p += srvstr_pull_req_talloc(state, req, &tmp, p,
801                                             STR_TERMINATE);
802                 state->user = tmp ? tmp : "";
803
804                 p += srvstr_pull_req_talloc(state, req, &tmp, p,
805                                             STR_TERMINATE);
806                 state->domain = tmp ? tmp : "";
807
808                 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
809                                             STR_TERMINATE);
810                 native_os = tmp ? tmp : "";
811
812                 p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
813                                             STR_TERMINATE);
814                 native_lanman = tmp ? tmp : "";
815
816                 /* not documented or decoded by Ethereal but there is one more
817                  * string in the extra bytes which is the same as the
818                  * PrimaryDomain when using extended security.  Windows NT 4
819                  * and 2003 use this string to store the native lanman string.
820                  * Windows 9x does not include a string here at all so we have
821                  * to check if we have any extra bytes left */
822
823                 byte_count = SVAL(req->vwv+13, 0);
824                 if ( PTR_DIFF(p, save_p) < byte_count) {
825                         p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
826                                                     STR_TERMINATE);
827                         primary_domain = tmp ? tmp : "";
828                 } else {
829                         primary_domain = talloc_strdup(talloc_tos(), "null");
830                 }
831
832                 DEBUG(3,("Domain=[%s]  NativeOS=[%s] NativeLanMan=[%s] "
833                         "PrimaryDomain=[%s]\n",
834                         state->domain, native_os, native_lanman, primary_domain));
835
836                 if ( ra_type == RA_WIN2K ) {
837                         if ( strlen(native_lanman) == 0 )
838                                 ra_lanman_string( primary_domain );
839                         else
840                                 ra_lanman_string( native_lanman );
841                 }
842
843         }
844
845         if (SVAL(req->vwv+4, 0) == 0) {
846                 setup_new_vc_session(req->sconn);
847         }
848
849         DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",
850                  state->domain, state->user, get_remote_machine_name()));
851
852         if (*state->user) {
853                 if (xconn->smb1.negprot.spnego) {
854
855                         /* This has to be here, because this is a perfectly
856                          * valid behaviour for guest logons :-( */
857
858                         DEBUG(0,("reply_sesssetup_and_X:  Rejecting attempt "
859                                 "at 'normal' session setup after "
860                                 "negotiating spnego.\n"));
861                         reply_nterror(req, nt_status_squash(
862                                               NT_STATUS_LOGON_FAILURE));
863                         END_PROFILE(SMBsesssetupX);
864                         return;
865                 }
866                 fstrcpy(sub_user, state->user);
867         } else {
868                 fstrcpy(sub_user, "");
869         }
870
871         if (!*state->user) {
872                 DEBUG(3,("Got anonymous request\n"));
873
874                 nt_status = make_auth4_context(state, &state->auth_context);
875                 if (NT_STATUS_IS_OK(nt_status)) {
876                         uint8_t chal[8];
877
878                         state->auth_context->get_ntlm_challenge(
879                                         state->auth_context, chal);
880
881                         if (!make_user_info_guest(state,
882                                                   sconn->remote_address,
883                                                   sconn->local_address,
884                                                   "SMB", &state->user_info)) {
885                                 nt_status =  NT_STATUS_NO_MEMORY;
886                         }
887
888                         if (NT_STATUS_IS_OK(nt_status)) {
889                                 state->user_info->auth_description = "guest";
890                         }
891                 }
892         } else if (doencrypt) {
893                 state->auth_context = xconn->smb1.negprot.auth_context;
894                 if (state->auth_context == NULL) {
895                         DEBUG(0, ("reply_sesssetup_and_X:  Attempted encrypted "
896                                 "session setup without negprot denied!\n"));
897                         reply_nterror(req, nt_status_squash(
898                                               NT_STATUS_LOGON_FAILURE));
899                         END_PROFILE(SMBsesssetupX);
900                         return;
901                 }
902                 nt_status = make_user_info_for_reply_enc(state,
903                                                          &state->user_info,
904                                                          state->user,
905                                                          state->domain,
906                                                          sconn->remote_address,
907                                                          sconn->local_address,
908                                                          "SMB",
909                                                          state->lm_resp,
910                                                          state->nt_resp);
911
912                 if (NT_STATUS_IS_OK(nt_status)) {
913                         state->user_info->auth_description = "bare-NTLM";
914                 }
915         } else {
916                 nt_status = make_auth4_context(state, &state->auth_context);
917                 if (NT_STATUS_IS_OK(nt_status)) {
918                         uint8_t chal[8];
919
920                         state->auth_context->get_ntlm_challenge(
921                                         state->auth_context, chal);
922
923                         if (!make_user_info_for_reply(state,
924                                                       &state->user_info,
925                                                       state->user,
926                                                       state->domain,
927                                                       sconn->remote_address,
928                                                       sconn->local_address,
929                                                       "SMB",
930                                                       chal,
931                                                       state->plaintext_password)) {
932                                 nt_status = NT_STATUS_NO_MEMORY;
933                         }
934
935                         if (NT_STATUS_IS_OK(nt_status)) {
936                                 state->user_info->auth_description = "plaintext";
937                         }
938                 }
939         }
940
941         if (!NT_STATUS_IS_OK(nt_status)) {
942                 reply_nterror(req, nt_status_squash(nt_status));
943                 END_PROFILE(SMBsesssetupX);
944                 return;
945         }
946
947         nt_status = auth_check_password_session_info(state->auth_context,
948                                                      req, state->user_info,
949                                                      &session_info);
950         TALLOC_FREE(state->user_info);
951         if (!NT_STATUS_IS_OK(nt_status)) {
952                 reply_nterror(req, nt_status_squash(nt_status));
953                 END_PROFILE(SMBsesssetupX);
954                 return;
955         }
956
957         /* it's ok - setup a reply */
958         reply_smb1_outbuf(req, 3, 0);
959         SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
960         SSVAL(req->outbuf, smb_vwv1, 0);    /* no andx offset */
961
962         if (xconn->protocol >= PROTOCOL_NT1) {
963                 push_signature(&req->outbuf);
964                 /* perhaps grab OS version here?? */
965         }
966
967         if (security_session_user_level(session_info, NULL) == SECURITY_GUEST) {
968                 action |= SMB_SETUP_GUEST;
969         }
970
971         /* register the name and uid as being validated, so further connections
972            to a uid can get through without a password, on the same VC */
973
974         nt_status = smbXsrv_session_create(xconn,
975                                            now, &session);
976         if (!NT_STATUS_IS_OK(nt_status)) {
977                 reply_nterror(req, nt_status_squash(nt_status));
978                 END_PROFILE(SMBsesssetupX);
979                 return;
980         }
981
982         session->global->signing_algo = SMB2_SIGNING_MD5_SMB1;
983         session->global->encryption_cipher = 0;
984         session->global->channels[0].signing_algo =
985                         session->global->signing_algo;
986         session->global->channels[0].encryption_cipher =
987                         session->global->encryption_cipher;
988
989         if (session_info->session_key.length > 0) {
990                 struct smbXsrv_session *x = session;
991                 uint8_t session_key[16];
992                 NTSTATUS status;
993
994                 status = smb2_signing_key_sign_create(x->global,
995                                         x->global->signing_algo,
996                                         &session_info->session_key,
997                                         NULL, /* no derivation */
998                                         &x->global->signing_key);
999                 if (!NT_STATUS_IS_OK(status)) {
1000                         TALLOC_FREE(session);
1001                         reply_nterror(req, status);
1002                         END_PROFILE(SMBsesssetupX);
1003                         return;
1004                 }
1005                 x->global->signing_key_blob = x->global->signing_key->blob;
1006
1007                 /*
1008                  * The application key is truncated/padded to 16 bytes
1009                  */
1010                 ZERO_STRUCT(session_key);
1011                 memcpy(session_key, session->global->signing_key_blob.data,
1012                        MIN(session->global->signing_key_blob.length,
1013                            sizeof(session_key)));
1014                 session->global->application_key_blob =
1015                         data_blob_talloc(session->global,
1016                                          session_key,
1017                                          sizeof(session_key));
1018                 ZERO_STRUCT(session_key);
1019                 if (session->global->application_key_blob.data == NULL) {
1020                         TALLOC_FREE(session);
1021                         reply_nterror(req, NT_STATUS_NO_MEMORY);
1022                         END_PROFILE(SMBsesssetupX);
1023                         return;
1024                 }
1025                 talloc_keep_secret(session->global->application_key_blob.data);
1026
1027                 /*
1028                  * Place the application key into the session_info
1029                  */
1030                 data_blob_clear_free(&session_info->session_key);
1031                 session_info->session_key = data_blob_dup_talloc(session_info,
1032                                                 session->global->application_key_blob);
1033                 if (session_info->session_key.data == NULL) {
1034                         TALLOC_FREE(session);
1035                         reply_nterror(req, NT_STATUS_NO_MEMORY);
1036                         END_PROFILE(SMBsesssetupX);
1037                         return;
1038                 }
1039                 talloc_keep_secret(session_info->session_key.data);
1040         }
1041
1042         sconn->num_users++;
1043
1044         if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
1045                 is_authenticated = true;
1046                 session->homes_snum =
1047                         register_homes_share(session_info->unix_info->unix_name);
1048         }
1049
1050         if (smb1_srv_is_signing_negotiated(xconn) &&
1051             is_authenticated &&
1052             smb2_signing_key_valid(session->global->signing_key))
1053         {
1054                 /*
1055                  * Try and turn on server signing on the first non-guest
1056                  * sessionsetup.
1057                  */
1058                 smb1_srv_set_signing(xconn,
1059                         session->global->signing_key->blob,
1060                         state->nt_resp.data ? state->nt_resp : state->lm_resp);
1061         }
1062
1063         set_current_user_info(session_info->unix_info->sanitized_username,
1064                               session_info->unix_info->unix_name,
1065                               session_info->info->domain_name);
1066
1067         session->status = NT_STATUS_OK;
1068         session->global->auth_session_info = talloc_move(session->global,
1069                                                          &session_info);
1070         session->global->auth_session_info_seqnum += 1;
1071         session->global->channels[0].auth_session_info_seqnum =
1072                 session->global->auth_session_info_seqnum;
1073         session->global->auth_time = now;
1074         session->global->expiration_time = GENSEC_EXPIRE_TIME_INFINITY;
1075
1076         nt_status = smbXsrv_session_update(session);
1077         if (!NT_STATUS_IS_OK(nt_status)) {
1078                 DEBUG(0, ("smb1: Failed to update session for vuid=%llu - %s\n",
1079                           (unsigned long long)session->global->session_wire_id,
1080                           nt_errstr(nt_status)));
1081                 TALLOC_FREE(session);
1082                 reply_nterror(req, nt_status_squash(nt_status));
1083                 END_PROFILE(SMBsesssetupX);
1084                 return;
1085         }
1086
1087         if (!session_claim(session)) {
1088                 DEBUG(1, ("smb1: Failed to claim session for vuid=%llu\n",
1089                           (unsigned long long)session->global->session_wire_id));
1090                 TALLOC_FREE(session);
1091                 reply_nterror(req, NT_STATUS_LOGON_FAILURE);
1092                 END_PROFILE(SMBsesssetupX);
1093                 return;
1094         }
1095
1096         /* current_user_info is changed on new vuid */
1097         reload_services(sconn, conn_snum_used, true);
1098
1099         sess_vuid = session->global->session_wire_id;
1100
1101         SSVAL(req->outbuf,smb_vwv2,action);
1102         SSVAL(req->outbuf,smb_uid,sess_vuid);
1103         SSVAL(discard_const_p(char, req->inbuf),smb_uid,sess_vuid);
1104         req->vuid = sess_vuid;
1105
1106         if (!xconn->smb1.sessions.done_sesssetup) {
1107                 if (smb_bufsize < SMB_BUFFER_SIZE_MIN) {
1108                         reply_force_doserror(req, ERRSRV, ERRerror);
1109                         END_PROFILE(SMBsesssetupX);
1110                         return;
1111                 }
1112                 xconn->smb1.sessions.max_send = smb_bufsize;
1113                 xconn->smb1.sessions.done_sesssetup = true;
1114         }
1115
1116         TALLOC_FREE(state);
1117         END_PROFILE(SMBsesssetupX);
1118 }