Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: LGPL-2.1
0002 /*
0003  *
0004  *   SMB/CIFS session setup handling routines
0005  *
0006  *   Copyright (c) International Business Machines  Corp., 2006, 2009
0007  *   Author(s): Steve French (sfrench@us.ibm.com)
0008  *
0009  */
0010 
0011 #include "cifspdu.h"
0012 #include "cifsglob.h"
0013 #include "cifsproto.h"
0014 #include "cifs_unicode.h"
0015 #include "cifs_debug.h"
0016 #include "ntlmssp.h"
0017 #include "nterr.h"
0018 #include <linux/utsname.h>
0019 #include <linux/slab.h>
0020 #include <linux/version.h>
0021 #include "cifsfs.h"
0022 #include "cifs_spnego.h"
0023 #include "smb2proto.h"
0024 #include "fs_context.h"
0025 
0026 static int
0027 cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
0028              struct cifs_server_iface *iface);
0029 
0030 bool
0031 is_server_using_iface(struct TCP_Server_Info *server,
0032               struct cifs_server_iface *iface)
0033 {
0034     struct sockaddr_in *i4 = (struct sockaddr_in *)&iface->sockaddr;
0035     struct sockaddr_in6 *i6 = (struct sockaddr_in6 *)&iface->sockaddr;
0036     struct sockaddr_in *s4 = (struct sockaddr_in *)&server->dstaddr;
0037     struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)&server->dstaddr;
0038 
0039     if (server->dstaddr.ss_family != iface->sockaddr.ss_family)
0040         return false;
0041     if (server->dstaddr.ss_family == AF_INET) {
0042         if (s4->sin_addr.s_addr != i4->sin_addr.s_addr)
0043             return false;
0044     } else if (server->dstaddr.ss_family == AF_INET6) {
0045         if (memcmp(&s6->sin6_addr, &i6->sin6_addr,
0046                sizeof(i6->sin6_addr)) != 0)
0047             return false;
0048     } else {
0049         /* unknown family.. */
0050         return false;
0051     }
0052     return true;
0053 }
0054 
0055 bool is_ses_using_iface(struct cifs_ses *ses, struct cifs_server_iface *iface)
0056 {
0057     int i;
0058 
0059     spin_lock(&ses->chan_lock);
0060     for (i = 0; i < ses->chan_count; i++) {
0061         if (ses->chans[i].iface == iface) {
0062             spin_unlock(&ses->chan_lock);
0063             return true;
0064         }
0065     }
0066     spin_unlock(&ses->chan_lock);
0067     return false;
0068 }
0069 
0070 /* channel helper functions. assumed that chan_lock is held by caller. */
0071 
0072 unsigned int
0073 cifs_ses_get_chan_index(struct cifs_ses *ses,
0074             struct TCP_Server_Info *server)
0075 {
0076     unsigned int i;
0077 
0078     for (i = 0; i < ses->chan_count; i++) {
0079         if (ses->chans[i].server == server)
0080             return i;
0081     }
0082 
0083     /* If we didn't find the channel, it is likely a bug */
0084     if (server)
0085         cifs_dbg(VFS, "unable to get chan index for server: 0x%llx",
0086              server->conn_id);
0087     WARN_ON(1);
0088     return 0;
0089 }
0090 
0091 void
0092 cifs_chan_set_in_reconnect(struct cifs_ses *ses,
0093                  struct TCP_Server_Info *server)
0094 {
0095     unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
0096 
0097     ses->chans[chan_index].in_reconnect = true;
0098 }
0099 
0100 void
0101 cifs_chan_clear_in_reconnect(struct cifs_ses *ses,
0102                  struct TCP_Server_Info *server)
0103 {
0104     unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
0105 
0106     ses->chans[chan_index].in_reconnect = false;
0107 }
0108 
0109 bool
0110 cifs_chan_in_reconnect(struct cifs_ses *ses,
0111               struct TCP_Server_Info *server)
0112 {
0113     unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
0114 
0115     return CIFS_CHAN_IN_RECONNECT(ses, chan_index);
0116 }
0117 
0118 void
0119 cifs_chan_set_need_reconnect(struct cifs_ses *ses,
0120                  struct TCP_Server_Info *server)
0121 {
0122     unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
0123 
0124     set_bit(chan_index, &ses->chans_need_reconnect);
0125     cifs_dbg(FYI, "Set reconnect bitmask for chan %u; now 0x%lx\n",
0126          chan_index, ses->chans_need_reconnect);
0127 }
0128 
0129 void
0130 cifs_chan_clear_need_reconnect(struct cifs_ses *ses,
0131                    struct TCP_Server_Info *server)
0132 {
0133     unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
0134 
0135     clear_bit(chan_index, &ses->chans_need_reconnect);
0136     cifs_dbg(FYI, "Cleared reconnect bitmask for chan %u; now 0x%lx\n",
0137          chan_index, ses->chans_need_reconnect);
0138 }
0139 
0140 bool
0141 cifs_chan_needs_reconnect(struct cifs_ses *ses,
0142               struct TCP_Server_Info *server)
0143 {
0144     unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
0145 
0146     return CIFS_CHAN_NEEDS_RECONNECT(ses, chan_index);
0147 }
0148 
0149 bool
0150 cifs_chan_is_iface_active(struct cifs_ses *ses,
0151               struct TCP_Server_Info *server)
0152 {
0153     unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
0154 
0155     return ses->chans[chan_index].iface &&
0156         ses->chans[chan_index].iface->is_active;
0157 }
0158 
0159 /* returns number of channels added */
0160 int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses)
0161 {
0162     int old_chan_count, new_chan_count;
0163     int left;
0164     int rc = 0;
0165     int tries = 0;
0166     struct cifs_server_iface *iface = NULL, *niface = NULL;
0167 
0168     spin_lock(&ses->chan_lock);
0169 
0170     new_chan_count = old_chan_count = ses->chan_count;
0171     left = ses->chan_max - ses->chan_count;
0172 
0173     if (left <= 0) {
0174         spin_unlock(&ses->chan_lock);
0175         cifs_dbg(FYI,
0176              "ses already at max_channels (%zu), nothing to open\n",
0177              ses->chan_max);
0178         return 0;
0179     }
0180 
0181     if (ses->server->dialect < SMB30_PROT_ID) {
0182         spin_unlock(&ses->chan_lock);
0183         cifs_dbg(VFS, "multichannel is not supported on this protocol version, use 3.0 or above\n");
0184         return 0;
0185     }
0186 
0187     if (!(ses->server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
0188         ses->chan_max = 1;
0189         spin_unlock(&ses->chan_lock);
0190         cifs_dbg(VFS, "server %s does not support multichannel\n", ses->server->hostname);
0191         return 0;
0192     }
0193     spin_unlock(&ses->chan_lock);
0194 
0195     /*
0196      * Keep connecting to same, fastest, iface for all channels as
0197      * long as its RSS. Try next fastest one if not RSS or channel
0198      * creation fails.
0199      */
0200     spin_lock(&ses->iface_lock);
0201     iface = list_first_entry(&ses->iface_list, struct cifs_server_iface,
0202                  iface_head);
0203     spin_unlock(&ses->iface_lock);
0204 
0205     while (left > 0) {
0206 
0207         tries++;
0208         if (tries > 3*ses->chan_max) {
0209             cifs_dbg(FYI, "too many channel open attempts (%d channels left to open)\n",
0210                  left);
0211             break;
0212         }
0213 
0214         spin_lock(&ses->iface_lock);
0215         if (!ses->iface_count) {
0216             spin_unlock(&ses->iface_lock);
0217             break;
0218         }
0219 
0220         list_for_each_entry_safe_from(iface, niface, &ses->iface_list,
0221                     iface_head) {
0222             /* skip ifaces that are unusable */
0223             if (!iface->is_active ||
0224                 (is_ses_using_iface(ses, iface) &&
0225                  !iface->rss_capable)) {
0226                 continue;
0227             }
0228 
0229             /* take ref before unlock */
0230             kref_get(&iface->refcount);
0231 
0232             spin_unlock(&ses->iface_lock);
0233             rc = cifs_ses_add_channel(cifs_sb, ses, iface);
0234             spin_lock(&ses->iface_lock);
0235 
0236             if (rc) {
0237                 cifs_dbg(VFS, "failed to open extra channel on iface:%pIS rc=%d\n",
0238                      &iface->sockaddr,
0239                      rc);
0240                 kref_put(&iface->refcount, release_iface);
0241                 continue;
0242             }
0243 
0244             cifs_dbg(FYI, "successfully opened new channel on iface:%pIS\n",
0245                  &iface->sockaddr);
0246             break;
0247         }
0248         spin_unlock(&ses->iface_lock);
0249 
0250         left--;
0251         new_chan_count++;
0252     }
0253 
0254     return new_chan_count - old_chan_count;
0255 }
0256 
0257 /*
0258  * update the iface for the channel if necessary.
0259  * will return 0 when iface is updated, 1 if removed, 2 otherwise
0260  * Must be called with chan_lock held.
0261  */
0262 int
0263 cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
0264 {
0265     unsigned int chan_index;
0266     struct cifs_server_iface *iface = NULL;
0267     struct cifs_server_iface *old_iface = NULL;
0268     int rc = 0;
0269 
0270     spin_lock(&ses->chan_lock);
0271     chan_index = cifs_ses_get_chan_index(ses, server);
0272     if (!chan_index) {
0273         spin_unlock(&ses->chan_lock);
0274         return 0;
0275     }
0276 
0277     if (ses->chans[chan_index].iface) {
0278         old_iface = ses->chans[chan_index].iface;
0279         if (old_iface->is_active) {
0280             spin_unlock(&ses->chan_lock);
0281             return 1;
0282         }
0283     }
0284     spin_unlock(&ses->chan_lock);
0285 
0286     spin_lock(&ses->iface_lock);
0287     /* then look for a new one */
0288     list_for_each_entry(iface, &ses->iface_list, iface_head) {
0289         if (!iface->is_active ||
0290             (is_ses_using_iface(ses, iface) &&
0291              !iface->rss_capable)) {
0292             continue;
0293         }
0294         kref_get(&iface->refcount);
0295     }
0296 
0297     if (!list_entry_is_head(iface, &ses->iface_list, iface_head)) {
0298         rc = 1;
0299         iface = NULL;
0300         cifs_dbg(FYI, "unable to find a suitable iface\n");
0301     }
0302 
0303     /* now drop the ref to the current iface */
0304     if (old_iface && iface) {
0305         kref_put(&old_iface->refcount, release_iface);
0306         cifs_dbg(FYI, "replacing iface: %pIS with %pIS\n",
0307              &old_iface->sockaddr,
0308              &iface->sockaddr);
0309     } else if (old_iface) {
0310         kref_put(&old_iface->refcount, release_iface);
0311         cifs_dbg(FYI, "releasing ref to iface: %pIS\n",
0312              &old_iface->sockaddr);
0313     } else {
0314         WARN_ON(!iface);
0315         cifs_dbg(FYI, "adding new iface: %pIS\n", &iface->sockaddr);
0316     }
0317     spin_unlock(&ses->iface_lock);
0318 
0319     spin_lock(&ses->chan_lock);
0320     chan_index = cifs_ses_get_chan_index(ses, server);
0321     ses->chans[chan_index].iface = iface;
0322 
0323     /* No iface is found. if secondary chan, drop connection */
0324     if (!iface && CIFS_SERVER_IS_CHAN(server))
0325         ses->chans[chan_index].server = NULL;
0326 
0327     spin_unlock(&ses->chan_lock);
0328 
0329     if (!iface && CIFS_SERVER_IS_CHAN(server))
0330         cifs_put_tcp_session(server, false);
0331 
0332     return rc;
0333 }
0334 
0335 /*
0336  * If server is a channel of ses, return the corresponding enclosing
0337  * cifs_chan otherwise return NULL.
0338  */
0339 struct cifs_chan *
0340 cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server)
0341 {
0342     int i;
0343 
0344     spin_lock(&ses->chan_lock);
0345     for (i = 0; i < ses->chan_count; i++) {
0346         if (ses->chans[i].server == server) {
0347             spin_unlock(&ses->chan_lock);
0348             return &ses->chans[i];
0349         }
0350     }
0351     spin_unlock(&ses->chan_lock);
0352     return NULL;
0353 }
0354 
0355 static int
0356 cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
0357              struct cifs_server_iface *iface)
0358 {
0359     struct TCP_Server_Info *chan_server;
0360     struct cifs_chan *chan;
0361     struct smb3_fs_context ctx = {NULL};
0362     static const char unc_fmt[] = "\\%s\\foo";
0363     char unc[sizeof(unc_fmt)+SERVER_NAME_LEN_WITH_NULL] = {0};
0364     struct sockaddr_in *ipv4 = (struct sockaddr_in *)&iface->sockaddr;
0365     struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&iface->sockaddr;
0366     int rc;
0367     unsigned int xid = get_xid();
0368 
0369     if (iface->sockaddr.ss_family == AF_INET)
0370         cifs_dbg(FYI, "adding channel to ses %p (speed:%zu bps rdma:%s ip:%pI4)\n",
0371              ses, iface->speed, iface->rdma_capable ? "yes" : "no",
0372              &ipv4->sin_addr);
0373     else
0374         cifs_dbg(FYI, "adding channel to ses %p (speed:%zu bps rdma:%s ip:%pI6)\n",
0375              ses, iface->speed, iface->rdma_capable ? "yes" : "no",
0376              &ipv6->sin6_addr);
0377 
0378     /*
0379      * Setup a ctx with mostly the same info as the existing
0380      * session and overwrite it with the requested iface data.
0381      *
0382      * We need to setup at least the fields used for negprot and
0383      * sesssetup.
0384      *
0385      * We only need the ctx here, so we can reuse memory from
0386      * the session and server without caring about memory
0387      * management.
0388      */
0389 
0390     /* Always make new connection for now (TODO?) */
0391     ctx.nosharesock = true;
0392 
0393     /* Auth */
0394     ctx.domainauto = ses->domainAuto;
0395     ctx.domainname = ses->domainName;
0396 
0397     /* no hostname for extra channels */
0398     ctx.server_hostname = "";
0399 
0400     ctx.username = ses->user_name;
0401     ctx.password = ses->password;
0402     ctx.sectype = ses->sectype;
0403     ctx.sign = ses->sign;
0404 
0405     /* UNC and paths */
0406     /* XXX: Use ses->server->hostname? */
0407     sprintf(unc, unc_fmt, ses->ip_addr);
0408     ctx.UNC = unc;
0409     ctx.prepath = "";
0410 
0411     /* Reuse same version as master connection */
0412     ctx.vals = ses->server->vals;
0413     ctx.ops = ses->server->ops;
0414 
0415     ctx.noblocksnd = ses->server->noblocksnd;
0416     ctx.noautotune = ses->server->noautotune;
0417     ctx.sockopt_tcp_nodelay = ses->server->tcp_nodelay;
0418     ctx.echo_interval = ses->server->echo_interval / HZ;
0419     ctx.max_credits = ses->server->max_credits;
0420 
0421     /*
0422      * This will be used for encoding/decoding user/domain/pw
0423      * during sess setup auth.
0424      */
0425     ctx.local_nls = cifs_sb->local_nls;
0426 
0427     /* Use RDMA if possible */
0428     ctx.rdma = iface->rdma_capable;
0429     memcpy(&ctx.dstaddr, &iface->sockaddr, sizeof(struct sockaddr_storage));
0430 
0431     /* reuse master con client guid */
0432     memcpy(&ctx.client_guid, ses->server->client_guid,
0433            SMB2_CLIENT_GUID_SIZE);
0434     ctx.use_client_guid = true;
0435 
0436     chan_server = cifs_get_tcp_session(&ctx, ses->server);
0437 
0438     spin_lock(&ses->chan_lock);
0439     chan = &ses->chans[ses->chan_count];
0440     chan->server = chan_server;
0441     if (IS_ERR(chan->server)) {
0442         rc = PTR_ERR(chan->server);
0443         chan->server = NULL;
0444         spin_unlock(&ses->chan_lock);
0445         goto out;
0446     }
0447     chan->iface = iface;
0448     ses->chan_count++;
0449     atomic_set(&ses->chan_seq, 0);
0450 
0451     /* Mark this channel as needing connect/setup */
0452     cifs_chan_set_need_reconnect(ses, chan->server);
0453 
0454     spin_unlock(&ses->chan_lock);
0455 
0456     mutex_lock(&ses->session_mutex);
0457     /*
0458      * We need to allocate the server crypto now as we will need
0459      * to sign packets before we generate the channel signing key
0460      * (we sign with the session key)
0461      */
0462     rc = smb311_crypto_shash_allocate(chan->server);
0463     if (rc) {
0464         cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
0465         mutex_unlock(&ses->session_mutex);
0466         goto out;
0467     }
0468 
0469     rc = cifs_negotiate_protocol(xid, ses, chan->server);
0470     if (!rc)
0471         rc = cifs_setup_session(xid, ses, chan->server, cifs_sb->local_nls);
0472 
0473     mutex_unlock(&ses->session_mutex);
0474 
0475 out:
0476     if (rc && chan->server) {
0477         /*
0478          * we should avoid race with these delayed works before we
0479          * remove this channel
0480          */
0481         cancel_delayed_work_sync(&chan->server->echo);
0482         cancel_delayed_work_sync(&chan->server->resolve);
0483         cancel_delayed_work_sync(&chan->server->reconnect);
0484 
0485         spin_lock(&ses->chan_lock);
0486         /* we rely on all bits beyond chan_count to be clear */
0487         cifs_chan_clear_need_reconnect(ses, chan->server);
0488         ses->chan_count--;
0489         /*
0490          * chan_count should never reach 0 as at least the primary
0491          * channel is always allocated
0492          */
0493         WARN_ON(ses->chan_count < 1);
0494         spin_unlock(&ses->chan_lock);
0495 
0496         cifs_put_tcp_session(chan->server, 0);
0497     }
0498 
0499     return rc;
0500 }
0501 
0502 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
0503 static __u32 cifs_ssetup_hdr(struct cifs_ses *ses,
0504                  struct TCP_Server_Info *server,
0505                  SESSION_SETUP_ANDX *pSMB)
0506 {
0507     __u32 capabilities = 0;
0508 
0509     /* init fields common to all four types of SessSetup */
0510     /* Note that offsets for first seven fields in req struct are same  */
0511     /*  in CIFS Specs so does not matter which of 3 forms of struct */
0512     /*  that we use in next few lines                               */
0513     /* Note that header is initialized to zero in header_assemble */
0514     pSMB->req.AndXCommand = 0xFF;
0515     pSMB->req.MaxBufferSize = cpu_to_le16(min_t(u32,
0516                     CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4,
0517                     USHRT_MAX));
0518     pSMB->req.MaxMpxCount = cpu_to_le16(server->maxReq);
0519     pSMB->req.VcNumber = cpu_to_le16(1);
0520 
0521     /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
0522 
0523     /* BB verify whether signing required on neg or just on auth frame
0524        (and NTLM case) */
0525 
0526     capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
0527             CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
0528 
0529     if (server->sign)
0530         pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
0531 
0532     if (ses->capabilities & CAP_UNICODE) {
0533         pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
0534         capabilities |= CAP_UNICODE;
0535     }
0536     if (ses->capabilities & CAP_STATUS32) {
0537         pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
0538         capabilities |= CAP_STATUS32;
0539     }
0540     if (ses->capabilities & CAP_DFS) {
0541         pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
0542         capabilities |= CAP_DFS;
0543     }
0544     if (ses->capabilities & CAP_UNIX)
0545         capabilities |= CAP_UNIX;
0546 
0547     return capabilities;
0548 }
0549 
0550 static void
0551 unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
0552 {
0553     char *bcc_ptr = *pbcc_area;
0554     int bytes_ret = 0;
0555 
0556     /* Copy OS version */
0557     bytes_ret = cifs_strtoUTF16((__le16 *)bcc_ptr, "Linux version ", 32,
0558                     nls_cp);
0559     bcc_ptr += 2 * bytes_ret;
0560     bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, init_utsname()->release,
0561                     32, nls_cp);
0562     bcc_ptr += 2 * bytes_ret;
0563     bcc_ptr += 2; /* trailing null */
0564 
0565     bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
0566                     32, nls_cp);
0567     bcc_ptr += 2 * bytes_ret;
0568     bcc_ptr += 2; /* trailing null */
0569 
0570     *pbcc_area = bcc_ptr;
0571 }
0572 
0573 static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
0574                    const struct nls_table *nls_cp)
0575 {
0576     char *bcc_ptr = *pbcc_area;
0577     int bytes_ret = 0;
0578 
0579     /* copy domain */
0580     if (ses->domainName == NULL) {
0581         /* Sending null domain better than using a bogus domain name (as
0582         we did briefly in 2.6.18) since server will use its default */
0583         *bcc_ptr = 0;
0584         *(bcc_ptr+1) = 0;
0585         bytes_ret = 0;
0586     } else
0587         bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->domainName,
0588                         CIFS_MAX_DOMAINNAME_LEN, nls_cp);
0589     bcc_ptr += 2 * bytes_ret;
0590     bcc_ptr += 2;  /* account for null terminator */
0591 
0592     *pbcc_area = bcc_ptr;
0593 }
0594 
0595 static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
0596                    const struct nls_table *nls_cp)
0597 {
0598     char *bcc_ptr = *pbcc_area;
0599     int bytes_ret = 0;
0600 
0601     /* BB FIXME add check that strings total less
0602     than 335 or will need to send them as arrays */
0603 
0604     /* unicode strings, must be word aligned before the call */
0605 /*  if ((long) bcc_ptr % 2) {
0606         *bcc_ptr = 0;
0607         bcc_ptr++;
0608     } */
0609     /* copy user */
0610     if (ses->user_name == NULL) {
0611         /* null user mount */
0612         *bcc_ptr = 0;
0613         *(bcc_ptr+1) = 0;
0614     } else {
0615         bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->user_name,
0616                         CIFS_MAX_USERNAME_LEN, nls_cp);
0617     }
0618     bcc_ptr += 2 * bytes_ret;
0619     bcc_ptr += 2; /* account for null termination */
0620 
0621     unicode_domain_string(&bcc_ptr, ses, nls_cp);
0622     unicode_oslm_strings(&bcc_ptr, nls_cp);
0623 
0624     *pbcc_area = bcc_ptr;
0625 }
0626 
0627 static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
0628                  const struct nls_table *nls_cp)
0629 {
0630     char *bcc_ptr = *pbcc_area;
0631     int len;
0632 
0633     /* copy user */
0634     /* BB what about null user mounts - check that we do this BB */
0635     /* copy user */
0636     if (ses->user_name != NULL) {
0637         len = strscpy(bcc_ptr, ses->user_name, CIFS_MAX_USERNAME_LEN);
0638         if (WARN_ON_ONCE(len < 0))
0639             len = CIFS_MAX_USERNAME_LEN - 1;
0640         bcc_ptr += len;
0641     }
0642     /* else null user mount */
0643     *bcc_ptr = 0;
0644     bcc_ptr++; /* account for null termination */
0645 
0646     /* copy domain */
0647     if (ses->domainName != NULL) {
0648         len = strscpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
0649         if (WARN_ON_ONCE(len < 0))
0650             len = CIFS_MAX_DOMAINNAME_LEN - 1;
0651         bcc_ptr += len;
0652     } /* else we will send a null domain name
0653          so the server will default to its own domain */
0654     *bcc_ptr = 0;
0655     bcc_ptr++;
0656 
0657     /* BB check for overflow here */
0658 
0659     strcpy(bcc_ptr, "Linux version ");
0660     bcc_ptr += strlen("Linux version ");
0661     strcpy(bcc_ptr, init_utsname()->release);
0662     bcc_ptr += strlen(init_utsname()->release) + 1;
0663 
0664     strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
0665     bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
0666 
0667     *pbcc_area = bcc_ptr;
0668 }
0669 
0670 static void
0671 decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifs_ses *ses,
0672               const struct nls_table *nls_cp)
0673 {
0674     int len;
0675     char *data = *pbcc_area;
0676 
0677     cifs_dbg(FYI, "bleft %d\n", bleft);
0678 
0679     kfree(ses->serverOS);
0680     ses->serverOS = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
0681     cifs_dbg(FYI, "serverOS=%s\n", ses->serverOS);
0682     len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
0683     data += len;
0684     bleft -= len;
0685     if (bleft <= 0)
0686         return;
0687 
0688     kfree(ses->serverNOS);
0689     ses->serverNOS = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
0690     cifs_dbg(FYI, "serverNOS=%s\n", ses->serverNOS);
0691     len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
0692     data += len;
0693     bleft -= len;
0694     if (bleft <= 0)
0695         return;
0696 
0697     kfree(ses->serverDomain);
0698     ses->serverDomain = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
0699     cifs_dbg(FYI, "serverDomain=%s\n", ses->serverDomain);
0700 
0701     return;
0702 }
0703 
0704 static void decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
0705                 struct cifs_ses *ses,
0706                 const struct nls_table *nls_cp)
0707 {
0708     int len;
0709     char *bcc_ptr = *pbcc_area;
0710 
0711     cifs_dbg(FYI, "decode sessetup ascii. bleft %d\n", bleft);
0712 
0713     len = strnlen(bcc_ptr, bleft);
0714     if (len >= bleft)
0715         return;
0716 
0717     kfree(ses->serverOS);
0718 
0719     ses->serverOS = kmalloc(len + 1, GFP_KERNEL);
0720     if (ses->serverOS) {
0721         memcpy(ses->serverOS, bcc_ptr, len);
0722         ses->serverOS[len] = 0;
0723         if (strncmp(ses->serverOS, "OS/2", 4) == 0)
0724             cifs_dbg(FYI, "OS/2 server\n");
0725     }
0726 
0727     bcc_ptr += len + 1;
0728     bleft -= len + 1;
0729 
0730     len = strnlen(bcc_ptr, bleft);
0731     if (len >= bleft)
0732         return;
0733 
0734     kfree(ses->serverNOS);
0735 
0736     ses->serverNOS = kmalloc(len + 1, GFP_KERNEL);
0737     if (ses->serverNOS) {
0738         memcpy(ses->serverNOS, bcc_ptr, len);
0739         ses->serverNOS[len] = 0;
0740     }
0741 
0742     bcc_ptr += len + 1;
0743     bleft -= len + 1;
0744 
0745     len = strnlen(bcc_ptr, bleft);
0746     if (len > bleft)
0747         return;
0748 
0749     /* No domain field in LANMAN case. Domain is
0750        returned by old servers in the SMB negprot response */
0751     /* BB For newer servers which do not support Unicode,
0752        but thus do return domain here we could add parsing
0753        for it later, but it is not very important */
0754     cifs_dbg(FYI, "ascii: bytes left %d\n", bleft);
0755 }
0756 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
0757 
0758 int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
0759                     struct cifs_ses *ses)
0760 {
0761     unsigned int tioffset; /* challenge message target info area */
0762     unsigned int tilen; /* challenge message target info area length  */
0763     CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
0764     __u32 server_flags;
0765 
0766     if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
0767         cifs_dbg(VFS, "challenge blob len %d too small\n", blob_len);
0768         return -EINVAL;
0769     }
0770 
0771     if (memcmp(pblob->Signature, "NTLMSSP", 8)) {
0772         cifs_dbg(VFS, "blob signature incorrect %s\n",
0773              pblob->Signature);
0774         return -EINVAL;
0775     }
0776     if (pblob->MessageType != NtLmChallenge) {
0777         cifs_dbg(VFS, "Incorrect message type %d\n",
0778              pblob->MessageType);
0779         return -EINVAL;
0780     }
0781 
0782     server_flags = le32_to_cpu(pblob->NegotiateFlags);
0783     cifs_dbg(FYI, "%s: negotiate=0x%08x challenge=0x%08x\n", __func__,
0784          ses->ntlmssp->client_flags, server_flags);
0785 
0786     if ((ses->ntlmssp->client_flags & (NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN)) &&
0787         (!(server_flags & NTLMSSP_NEGOTIATE_56) && !(server_flags & NTLMSSP_NEGOTIATE_128))) {
0788         cifs_dbg(VFS, "%s: requested signing/encryption but server did not return either 56-bit or 128-bit session key size\n",
0789              __func__);
0790         return -EINVAL;
0791     }
0792     if (!(server_flags & NTLMSSP_NEGOTIATE_NTLM) && !(server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC)) {
0793         cifs_dbg(VFS, "%s: server does not seem to support either NTLMv1 or NTLMv2\n", __func__);
0794         return -EINVAL;
0795     }
0796     if (ses->server->sign && !(server_flags & NTLMSSP_NEGOTIATE_SIGN)) {
0797         cifs_dbg(VFS, "%s: forced packet signing but server does not seem to support it\n",
0798              __func__);
0799         return -EOPNOTSUPP;
0800     }
0801     if ((ses->ntlmssp->client_flags & NTLMSSP_NEGOTIATE_KEY_XCH) &&
0802         !(server_flags & NTLMSSP_NEGOTIATE_KEY_XCH))
0803         pr_warn_once("%s: authentication has been weakened as server does not support key exchange\n",
0804                  __func__);
0805 
0806     ses->ntlmssp->server_flags = server_flags;
0807 
0808     memcpy(ses->ntlmssp->cryptkey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE);
0809     /* In particular we can examine sign flags */
0810     /* BB spec says that if AvId field of MsvAvTimestamp is populated then
0811         we must set the MIC field of the AUTHENTICATE_MESSAGE */
0812 
0813     tioffset = le32_to_cpu(pblob->TargetInfoArray.BufferOffset);
0814     tilen = le16_to_cpu(pblob->TargetInfoArray.Length);
0815     if (tioffset > blob_len || tioffset + tilen > blob_len) {
0816         cifs_dbg(VFS, "tioffset + tilen too high %u + %u\n",
0817              tioffset, tilen);
0818         return -EINVAL;
0819     }
0820     if (tilen) {
0821         ses->auth_key.response = kmemdup(bcc_ptr + tioffset, tilen,
0822                          GFP_KERNEL);
0823         if (!ses->auth_key.response) {
0824             cifs_dbg(VFS, "Challenge target info alloc failure\n");
0825             return -ENOMEM;
0826         }
0827         ses->auth_key.len = tilen;
0828     }
0829 
0830     return 0;
0831 }
0832 
0833 static int size_of_ntlmssp_blob(struct cifs_ses *ses, int base_size)
0834 {
0835     int sz = base_size + ses->auth_key.len
0836         - CIFS_SESS_KEY_SIZE + CIFS_CPHTXT_SIZE + 2;
0837 
0838     if (ses->domainName)
0839         sz += sizeof(__le16) * strnlen(ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
0840     else
0841         sz += sizeof(__le16);
0842 
0843     if (ses->user_name)
0844         sz += sizeof(__le16) * strnlen(ses->user_name, CIFS_MAX_USERNAME_LEN);
0845     else
0846         sz += sizeof(__le16);
0847 
0848     if (ses->workstation_name[0])
0849         sz += sizeof(__le16) * strnlen(ses->workstation_name,
0850                            ntlmssp_workstation_name_size(ses));
0851     else
0852         sz += sizeof(__le16);
0853 
0854     return sz;
0855 }
0856 
0857 static inline void cifs_security_buffer_from_str(SECURITY_BUFFER *pbuf,
0858                          char *str_value,
0859                          int str_length,
0860                          unsigned char *pstart,
0861                          unsigned char **pcur,
0862                          const struct nls_table *nls_cp)
0863 {
0864     unsigned char *tmp = pstart;
0865     int len;
0866 
0867     if (!pbuf)
0868         return;
0869 
0870     if (!pcur)
0871         pcur = &tmp;
0872 
0873     if (!str_value) {
0874         pbuf->BufferOffset = cpu_to_le32(*pcur - pstart);
0875         pbuf->Length = 0;
0876         pbuf->MaximumLength = 0;
0877         *pcur += sizeof(__le16);
0878     } else {
0879         len = cifs_strtoUTF16((__le16 *)*pcur,
0880                       str_value,
0881                       str_length,
0882                       nls_cp);
0883         len *= sizeof(__le16);
0884         pbuf->BufferOffset = cpu_to_le32(*pcur - pstart);
0885         pbuf->Length = cpu_to_le16(len);
0886         pbuf->MaximumLength = cpu_to_le16(len);
0887         *pcur += len;
0888     }
0889 }
0890 
0891 /* BB Move to ntlmssp.c eventually */
0892 
0893 int build_ntlmssp_negotiate_blob(unsigned char **pbuffer,
0894                  u16 *buflen,
0895                  struct cifs_ses *ses,
0896                  struct TCP_Server_Info *server,
0897                  const struct nls_table *nls_cp)
0898 {
0899     int rc = 0;
0900     NEGOTIATE_MESSAGE *sec_blob;
0901     __u32 flags;
0902     unsigned char *tmp;
0903     int len;
0904 
0905     len = size_of_ntlmssp_blob(ses, sizeof(NEGOTIATE_MESSAGE));
0906     *pbuffer = kmalloc(len, GFP_KERNEL);
0907     if (!*pbuffer) {
0908         rc = -ENOMEM;
0909         cifs_dbg(VFS, "Error %d during NTLMSSP allocation\n", rc);
0910         *buflen = 0;
0911         goto setup_ntlm_neg_ret;
0912     }
0913     sec_blob = (NEGOTIATE_MESSAGE *)*pbuffer;
0914 
0915     memset(*pbuffer, 0, sizeof(NEGOTIATE_MESSAGE));
0916     memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
0917     sec_blob->MessageType = NtLmNegotiate;
0918 
0919     /* BB is NTLMV2 session security format easier to use here? */
0920     flags = NTLMSSP_NEGOTIATE_56 |  NTLMSSP_REQUEST_TARGET |
0921         NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
0922         NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
0923         NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_SEAL |
0924         NTLMSSP_NEGOTIATE_SIGN;
0925     if (!server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
0926         flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
0927 
0928     tmp = *pbuffer + sizeof(NEGOTIATE_MESSAGE);
0929     ses->ntlmssp->client_flags = flags;
0930     sec_blob->NegotiateFlags = cpu_to_le32(flags);
0931 
0932     /* these fields should be null in negotiate phase MS-NLMP 3.1.5.1.1 */
0933     cifs_security_buffer_from_str(&sec_blob->DomainName,
0934                       NULL,
0935                       CIFS_MAX_DOMAINNAME_LEN,
0936                       *pbuffer, &tmp,
0937                       nls_cp);
0938 
0939     cifs_security_buffer_from_str(&sec_blob->WorkstationName,
0940                       NULL,
0941                       CIFS_MAX_WORKSTATION_LEN,
0942                       *pbuffer, &tmp,
0943                       nls_cp);
0944 
0945     *buflen = tmp - *pbuffer;
0946 setup_ntlm_neg_ret:
0947     return rc;
0948 }
0949 
0950 /*
0951  * Build ntlmssp blob with additional fields, such as version,
0952  * supported by modern servers. For safety limit to SMB3 or later
0953  * See notes in MS-NLMP Section 2.2.2.1 e.g.
0954  */
0955 int build_ntlmssp_smb3_negotiate_blob(unsigned char **pbuffer,
0956                  u16 *buflen,
0957                  struct cifs_ses *ses,
0958                  struct TCP_Server_Info *server,
0959                  const struct nls_table *nls_cp)
0960 {
0961     int rc = 0;
0962     struct negotiate_message *sec_blob;
0963     __u32 flags;
0964     unsigned char *tmp;
0965     int len;
0966 
0967     len = size_of_ntlmssp_blob(ses, sizeof(struct negotiate_message));
0968     *pbuffer = kmalloc(len, GFP_KERNEL);
0969     if (!*pbuffer) {
0970         rc = -ENOMEM;
0971         cifs_dbg(VFS, "Error %d during NTLMSSP allocation\n", rc);
0972         *buflen = 0;
0973         goto setup_ntlm_smb3_neg_ret;
0974     }
0975     sec_blob = (struct negotiate_message *)*pbuffer;
0976 
0977     memset(*pbuffer, 0, sizeof(struct negotiate_message));
0978     memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
0979     sec_blob->MessageType = NtLmNegotiate;
0980 
0981     /* BB is NTLMV2 session security format easier to use here? */
0982     flags = NTLMSSP_NEGOTIATE_56 |  NTLMSSP_REQUEST_TARGET |
0983         NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
0984         NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
0985         NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_SEAL |
0986         NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_VERSION;
0987     if (!server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
0988         flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
0989 
0990     sec_blob->Version.ProductMajorVersion = LINUX_VERSION_MAJOR;
0991     sec_blob->Version.ProductMinorVersion = LINUX_VERSION_PATCHLEVEL;
0992     sec_blob->Version.ProductBuild = cpu_to_le16(SMB3_PRODUCT_BUILD);
0993     sec_blob->Version.NTLMRevisionCurrent = NTLMSSP_REVISION_W2K3;
0994 
0995     tmp = *pbuffer + sizeof(struct negotiate_message);
0996     ses->ntlmssp->client_flags = flags;
0997     sec_blob->NegotiateFlags = cpu_to_le32(flags);
0998 
0999     /* these fields should be null in negotiate phase MS-NLMP 3.1.5.1.1 */
1000     cifs_security_buffer_from_str(&sec_blob->DomainName,
1001                       NULL,
1002                       CIFS_MAX_DOMAINNAME_LEN,
1003                       *pbuffer, &tmp,
1004                       nls_cp);
1005 
1006     cifs_security_buffer_from_str(&sec_blob->WorkstationName,
1007                       NULL,
1008                       CIFS_MAX_WORKSTATION_LEN,
1009                       *pbuffer, &tmp,
1010                       nls_cp);
1011 
1012     *buflen = tmp - *pbuffer;
1013 setup_ntlm_smb3_neg_ret:
1014     return rc;
1015 }
1016 
1017 
1018 int build_ntlmssp_auth_blob(unsigned char **pbuffer,
1019                     u16 *buflen,
1020                    struct cifs_ses *ses,
1021                    struct TCP_Server_Info *server,
1022                    const struct nls_table *nls_cp)
1023 {
1024     int rc;
1025     AUTHENTICATE_MESSAGE *sec_blob;
1026     __u32 flags;
1027     unsigned char *tmp;
1028     int len;
1029 
1030     rc = setup_ntlmv2_rsp(ses, nls_cp);
1031     if (rc) {
1032         cifs_dbg(VFS, "Error %d during NTLMSSP authentication\n", rc);
1033         *buflen = 0;
1034         goto setup_ntlmv2_ret;
1035     }
1036 
1037     len = size_of_ntlmssp_blob(ses, sizeof(AUTHENTICATE_MESSAGE));
1038     *pbuffer = kmalloc(len, GFP_KERNEL);
1039     if (!*pbuffer) {
1040         rc = -ENOMEM;
1041         cifs_dbg(VFS, "Error %d during NTLMSSP allocation\n", rc);
1042         *buflen = 0;
1043         goto setup_ntlmv2_ret;
1044     }
1045     sec_blob = (AUTHENTICATE_MESSAGE *)*pbuffer;
1046 
1047     memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
1048     sec_blob->MessageType = NtLmAuthenticate;
1049 
1050     flags = ses->ntlmssp->server_flags | NTLMSSP_REQUEST_TARGET |
1051         NTLMSSP_NEGOTIATE_TARGET_INFO | NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED;
1052 
1053     tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE);
1054     sec_blob->NegotiateFlags = cpu_to_le32(flags);
1055 
1056     sec_blob->LmChallengeResponse.BufferOffset =
1057                 cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE));
1058     sec_blob->LmChallengeResponse.Length = 0;
1059     sec_blob->LmChallengeResponse.MaximumLength = 0;
1060 
1061     sec_blob->NtChallengeResponse.BufferOffset =
1062                 cpu_to_le32(tmp - *pbuffer);
1063     if (ses->user_name != NULL) {
1064         memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
1065                 ses->auth_key.len - CIFS_SESS_KEY_SIZE);
1066         tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
1067 
1068         sec_blob->NtChallengeResponse.Length =
1069                 cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
1070         sec_blob->NtChallengeResponse.MaximumLength =
1071                 cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
1072     } else {
1073         /*
1074          * don't send an NT Response for anonymous access
1075          */
1076         sec_blob->NtChallengeResponse.Length = 0;
1077         sec_blob->NtChallengeResponse.MaximumLength = 0;
1078     }
1079 
1080     cifs_security_buffer_from_str(&sec_blob->DomainName,
1081                       ses->domainName,
1082                       CIFS_MAX_DOMAINNAME_LEN,
1083                       *pbuffer, &tmp,
1084                       nls_cp);
1085 
1086     cifs_security_buffer_from_str(&sec_blob->UserName,
1087                       ses->user_name,
1088                       CIFS_MAX_USERNAME_LEN,
1089                       *pbuffer, &tmp,
1090                       nls_cp);
1091 
1092     cifs_security_buffer_from_str(&sec_blob->WorkstationName,
1093                       ses->workstation_name,
1094                       ntlmssp_workstation_name_size(ses),
1095                       *pbuffer, &tmp,
1096                       nls_cp);
1097 
1098     if ((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) &&
1099         (!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess) &&
1100         !calc_seckey(ses)) {
1101         memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
1102         sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
1103         sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
1104         sec_blob->SessionKey.MaximumLength =
1105                 cpu_to_le16(CIFS_CPHTXT_SIZE);
1106         tmp += CIFS_CPHTXT_SIZE;
1107     } else {
1108         sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
1109         sec_blob->SessionKey.Length = 0;
1110         sec_blob->SessionKey.MaximumLength = 0;
1111     }
1112 
1113     *buflen = tmp - *pbuffer;
1114 setup_ntlmv2_ret:
1115     return rc;
1116 }
1117 
1118 enum securityEnum
1119 cifs_select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
1120 {
1121     switch (server->negflavor) {
1122     case CIFS_NEGFLAVOR_EXTENDED:
1123         switch (requested) {
1124         case Kerberos:
1125         case RawNTLMSSP:
1126             return requested;
1127         case Unspecified:
1128             if (server->sec_ntlmssp &&
1129                 (global_secflags & CIFSSEC_MAY_NTLMSSP))
1130                 return RawNTLMSSP;
1131             if ((server->sec_kerberos || server->sec_mskerberos) &&
1132                 (global_secflags & CIFSSEC_MAY_KRB5))
1133                 return Kerberos;
1134             fallthrough;
1135         default:
1136             return Unspecified;
1137         }
1138     case CIFS_NEGFLAVOR_UNENCAP:
1139         switch (requested) {
1140         case NTLMv2:
1141             return requested;
1142         case Unspecified:
1143             if (global_secflags & CIFSSEC_MAY_NTLMV2)
1144                 return NTLMv2;
1145             break;
1146         default:
1147             break;
1148         }
1149         fallthrough;
1150     default:
1151         return Unspecified;
1152     }
1153 }
1154 
1155 struct sess_data {
1156     unsigned int xid;
1157     struct cifs_ses *ses;
1158     struct TCP_Server_Info *server;
1159     struct nls_table *nls_cp;
1160     void (*func)(struct sess_data *);
1161     int result;
1162 
1163     /* we will send the SMB in three pieces:
1164      * a fixed length beginning part, an optional
1165      * SPNEGO blob (which can be zero length), and a
1166      * last part which will include the strings
1167      * and rest of bcc area. This allows us to avoid
1168      * a large buffer 17K allocation
1169      */
1170     int buf0_type;
1171     struct kvec iov[3];
1172 };
1173 
1174 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
1175 static int
1176 sess_alloc_buffer(struct sess_data *sess_data, int wct)
1177 {
1178     int rc;
1179     struct cifs_ses *ses = sess_data->ses;
1180     struct smb_hdr *smb_buf;
1181 
1182     rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
1183                   (void **)&smb_buf);
1184 
1185     if (rc)
1186         return rc;
1187 
1188     sess_data->iov[0].iov_base = (char *)smb_buf;
1189     sess_data->iov[0].iov_len = be32_to_cpu(smb_buf->smb_buf_length) + 4;
1190     /*
1191      * This variable will be used to clear the buffer
1192      * allocated above in case of any error in the calling function.
1193      */
1194     sess_data->buf0_type = CIFS_SMALL_BUFFER;
1195 
1196     /* 2000 big enough to fit max user, domain, NOS name etc. */
1197     sess_data->iov[2].iov_base = kmalloc(2000, GFP_KERNEL);
1198     if (!sess_data->iov[2].iov_base) {
1199         rc = -ENOMEM;
1200         goto out_free_smb_buf;
1201     }
1202 
1203     return 0;
1204 
1205 out_free_smb_buf:
1206     cifs_small_buf_release(smb_buf);
1207     sess_data->iov[0].iov_base = NULL;
1208     sess_data->iov[0].iov_len = 0;
1209     sess_data->buf0_type = CIFS_NO_BUFFER;
1210     return rc;
1211 }
1212 
1213 static void
1214 sess_free_buffer(struct sess_data *sess_data)
1215 {
1216 
1217     free_rsp_buf(sess_data->buf0_type, sess_data->iov[0].iov_base);
1218     sess_data->buf0_type = CIFS_NO_BUFFER;
1219     kfree(sess_data->iov[2].iov_base);
1220 }
1221 
1222 static int
1223 sess_establish_session(struct sess_data *sess_data)
1224 {
1225     struct cifs_ses *ses = sess_data->ses;
1226     struct TCP_Server_Info *server = sess_data->server;
1227 
1228     cifs_server_lock(server);
1229     if (!server->session_estab) {
1230         if (server->sign) {
1231             server->session_key.response =
1232                 kmemdup(ses->auth_key.response,
1233                 ses->auth_key.len, GFP_KERNEL);
1234             if (!server->session_key.response) {
1235                 cifs_server_unlock(server);
1236                 return -ENOMEM;
1237             }
1238             server->session_key.len =
1239                         ses->auth_key.len;
1240         }
1241         server->sequence_number = 0x2;
1242         server->session_estab = true;
1243     }
1244     cifs_server_unlock(server);
1245 
1246     cifs_dbg(FYI, "CIFS session established successfully\n");
1247     return 0;
1248 }
1249 
1250 static int
1251 sess_sendreceive(struct sess_data *sess_data)
1252 {
1253     int rc;
1254     struct smb_hdr *smb_buf = (struct smb_hdr *) sess_data->iov[0].iov_base;
1255     __u16 count;
1256     struct kvec rsp_iov = { NULL, 0 };
1257 
1258     count = sess_data->iov[1].iov_len + sess_data->iov[2].iov_len;
1259     be32_add_cpu(&smb_buf->smb_buf_length, count);
1260     put_bcc(count, smb_buf);
1261 
1262     rc = SendReceive2(sess_data->xid, sess_data->ses,
1263               sess_data->iov, 3 /* num_iovecs */,
1264               &sess_data->buf0_type,
1265               CIFS_LOG_ERROR, &rsp_iov);
1266     cifs_small_buf_release(sess_data->iov[0].iov_base);
1267     memcpy(&sess_data->iov[0], &rsp_iov, sizeof(struct kvec));
1268 
1269     return rc;
1270 }
1271 
1272 static void
1273 sess_auth_ntlmv2(struct sess_data *sess_data)
1274 {
1275     int rc = 0;
1276     struct smb_hdr *smb_buf;
1277     SESSION_SETUP_ANDX *pSMB;
1278     char *bcc_ptr;
1279     struct cifs_ses *ses = sess_data->ses;
1280     struct TCP_Server_Info *server = sess_data->server;
1281     __u32 capabilities;
1282     __u16 bytes_remaining;
1283 
1284     /* old style NTLM sessionsetup */
1285     /* wct = 13 */
1286     rc = sess_alloc_buffer(sess_data, 13);
1287     if (rc)
1288         goto out;
1289 
1290     pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1291     bcc_ptr = sess_data->iov[2].iov_base;
1292     capabilities = cifs_ssetup_hdr(ses, server, pSMB);
1293 
1294     pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
1295 
1296     /* LM2 password would be here if we supported it */
1297     pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
1298 
1299     if (ses->user_name != NULL) {
1300         /* calculate nlmv2 response and session key */
1301         rc = setup_ntlmv2_rsp(ses, sess_data->nls_cp);
1302         if (rc) {
1303             cifs_dbg(VFS, "Error %d during NTLMv2 authentication\n", rc);
1304             goto out;
1305         }
1306 
1307         memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
1308                 ses->auth_key.len - CIFS_SESS_KEY_SIZE);
1309         bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
1310 
1311         /* set case sensitive password length after tilen may get
1312          * assigned, tilen is 0 otherwise.
1313          */
1314         pSMB->req_no_secext.CaseSensitivePasswordLength =
1315             cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
1316     } else {
1317         pSMB->req_no_secext.CaseSensitivePasswordLength = 0;
1318     }
1319 
1320     if (ses->capabilities & CAP_UNICODE) {
1321         if (sess_data->iov[0].iov_len % 2) {
1322             *bcc_ptr = 0;
1323             bcc_ptr++;
1324         }
1325         unicode_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
1326     } else {
1327         ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
1328     }
1329 
1330 
1331     sess_data->iov[2].iov_len = (long) bcc_ptr -
1332             (long) sess_data->iov[2].iov_base;
1333 
1334     rc = sess_sendreceive(sess_data);
1335     if (rc)
1336         goto out;
1337 
1338     pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1339     smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
1340 
1341     if (smb_buf->WordCount != 3) {
1342         rc = -EIO;
1343         cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
1344         goto out;
1345     }
1346 
1347     if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
1348         cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
1349 
1350     ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
1351     cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
1352 
1353     bytes_remaining = get_bcc(smb_buf);
1354     bcc_ptr = pByteArea(smb_buf);
1355 
1356     /* BB check if Unicode and decode strings */
1357     if (bytes_remaining == 0) {
1358         /* no string area to decode, do nothing */
1359     } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
1360         /* unicode string area must be word-aligned */
1361         if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
1362             ++bcc_ptr;
1363             --bytes_remaining;
1364         }
1365         decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
1366                       sess_data->nls_cp);
1367     } else {
1368         decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
1369                     sess_data->nls_cp);
1370     }
1371 
1372     rc = sess_establish_session(sess_data);
1373 out:
1374     sess_data->result = rc;
1375     sess_data->func = NULL;
1376     sess_free_buffer(sess_data);
1377     kfree(ses->auth_key.response);
1378     ses->auth_key.response = NULL;
1379 }
1380 
1381 #ifdef CONFIG_CIFS_UPCALL
1382 static void
1383 sess_auth_kerberos(struct sess_data *sess_data)
1384 {
1385     int rc = 0;
1386     struct smb_hdr *smb_buf;
1387     SESSION_SETUP_ANDX *pSMB;
1388     char *bcc_ptr;
1389     struct cifs_ses *ses = sess_data->ses;
1390     struct TCP_Server_Info *server = sess_data->server;
1391     __u32 capabilities;
1392     __u16 bytes_remaining;
1393     struct key *spnego_key = NULL;
1394     struct cifs_spnego_msg *msg;
1395     u16 blob_len;
1396 
1397     /* extended security */
1398     /* wct = 12 */
1399     rc = sess_alloc_buffer(sess_data, 12);
1400     if (rc)
1401         goto out;
1402 
1403     pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1404     bcc_ptr = sess_data->iov[2].iov_base;
1405     capabilities = cifs_ssetup_hdr(ses, server, pSMB);
1406 
1407     spnego_key = cifs_get_spnego_key(ses, server);
1408     if (IS_ERR(spnego_key)) {
1409         rc = PTR_ERR(spnego_key);
1410         spnego_key = NULL;
1411         goto out;
1412     }
1413 
1414     msg = spnego_key->payload.data[0];
1415     /*
1416      * check version field to make sure that cifs.upcall is
1417      * sending us a response in an expected form
1418      */
1419     if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
1420         cifs_dbg(VFS, "incorrect version of cifs.upcall (expected %d but got %d)\n",
1421              CIFS_SPNEGO_UPCALL_VERSION, msg->version);
1422         rc = -EKEYREJECTED;
1423         goto out_put_spnego_key;
1424     }
1425 
1426     ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
1427                      GFP_KERNEL);
1428     if (!ses->auth_key.response) {
1429         cifs_dbg(VFS, "Kerberos can't allocate (%u bytes) memory\n",
1430              msg->sesskey_len);
1431         rc = -ENOMEM;
1432         goto out_put_spnego_key;
1433     }
1434     ses->auth_key.len = msg->sesskey_len;
1435 
1436     pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
1437     capabilities |= CAP_EXTENDED_SECURITY;
1438     pSMB->req.Capabilities = cpu_to_le32(capabilities);
1439     sess_data->iov[1].iov_base = msg->data + msg->sesskey_len;
1440     sess_data->iov[1].iov_len = msg->secblob_len;
1441     pSMB->req.SecurityBlobLength = cpu_to_le16(sess_data->iov[1].iov_len);
1442 
1443     if (ses->capabilities & CAP_UNICODE) {
1444         /* unicode strings must be word aligned */
1445         if ((sess_data->iov[0].iov_len
1446             + sess_data->iov[1].iov_len) % 2) {
1447             *bcc_ptr = 0;
1448             bcc_ptr++;
1449         }
1450         unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp);
1451         unicode_domain_string(&bcc_ptr, ses, sess_data->nls_cp);
1452     } else {
1453         /* BB: is this right? */
1454         ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
1455     }
1456 
1457     sess_data->iov[2].iov_len = (long) bcc_ptr -
1458             (long) sess_data->iov[2].iov_base;
1459 
1460     rc = sess_sendreceive(sess_data);
1461     if (rc)
1462         goto out_put_spnego_key;
1463 
1464     pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1465     smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
1466 
1467     if (smb_buf->WordCount != 4) {
1468         rc = -EIO;
1469         cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
1470         goto out_put_spnego_key;
1471     }
1472 
1473     if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
1474         cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
1475 
1476     ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
1477     cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
1478 
1479     bytes_remaining = get_bcc(smb_buf);
1480     bcc_ptr = pByteArea(smb_buf);
1481 
1482     blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
1483     if (blob_len > bytes_remaining) {
1484         cifs_dbg(VFS, "bad security blob length %d\n",
1485                 blob_len);
1486         rc = -EINVAL;
1487         goto out_put_spnego_key;
1488     }
1489     bcc_ptr += blob_len;
1490     bytes_remaining -= blob_len;
1491 
1492     /* BB check if Unicode and decode strings */
1493     if (bytes_remaining == 0) {
1494         /* no string area to decode, do nothing */
1495     } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
1496         /* unicode string area must be word-aligned */
1497         if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
1498             ++bcc_ptr;
1499             --bytes_remaining;
1500         }
1501         decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
1502                       sess_data->nls_cp);
1503     } else {
1504         decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
1505                     sess_data->nls_cp);
1506     }
1507 
1508     rc = sess_establish_session(sess_data);
1509 out_put_spnego_key:
1510     key_invalidate(spnego_key);
1511     key_put(spnego_key);
1512 out:
1513     sess_data->result = rc;
1514     sess_data->func = NULL;
1515     sess_free_buffer(sess_data);
1516     kfree(ses->auth_key.response);
1517     ses->auth_key.response = NULL;
1518 }
1519 
1520 #endif /* ! CONFIG_CIFS_UPCALL */
1521 
1522 /*
1523  * The required kvec buffers have to be allocated before calling this
1524  * function.
1525  */
1526 static int
1527 _sess_auth_rawntlmssp_assemble_req(struct sess_data *sess_data)
1528 {
1529     SESSION_SETUP_ANDX *pSMB;
1530     struct cifs_ses *ses = sess_data->ses;
1531     struct TCP_Server_Info *server = sess_data->server;
1532     __u32 capabilities;
1533     char *bcc_ptr;
1534 
1535     pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1536 
1537     capabilities = cifs_ssetup_hdr(ses, server, pSMB);
1538     if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
1539         cifs_dbg(VFS, "NTLMSSP requires Unicode support\n");
1540         return -ENOSYS;
1541     }
1542 
1543     pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
1544     capabilities |= CAP_EXTENDED_SECURITY;
1545     pSMB->req.Capabilities |= cpu_to_le32(capabilities);
1546 
1547     bcc_ptr = sess_data->iov[2].iov_base;
1548     /* unicode strings must be word aligned */
1549     if ((sess_data->iov[0].iov_len + sess_data->iov[1].iov_len) % 2) {
1550         *bcc_ptr = 0;
1551         bcc_ptr++;
1552     }
1553     unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp);
1554 
1555     sess_data->iov[2].iov_len = (long) bcc_ptr -
1556                     (long) sess_data->iov[2].iov_base;
1557 
1558     return 0;
1559 }
1560 
1561 static void
1562 sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data);
1563 
1564 static void
1565 sess_auth_rawntlmssp_negotiate(struct sess_data *sess_data)
1566 {
1567     int rc;
1568     struct smb_hdr *smb_buf;
1569     SESSION_SETUP_ANDX *pSMB;
1570     struct cifs_ses *ses = sess_data->ses;
1571     struct TCP_Server_Info *server = sess_data->server;
1572     __u16 bytes_remaining;
1573     char *bcc_ptr;
1574     unsigned char *ntlmsspblob = NULL;
1575     u16 blob_len;
1576 
1577     cifs_dbg(FYI, "rawntlmssp session setup negotiate phase\n");
1578 
1579     /*
1580      * if memory allocation is successful, caller of this function
1581      * frees it.
1582      */
1583     ses->ntlmssp = kmalloc(sizeof(struct ntlmssp_auth), GFP_KERNEL);
1584     if (!ses->ntlmssp) {
1585         rc = -ENOMEM;
1586         goto out;
1587     }
1588     ses->ntlmssp->sesskey_per_smbsess = false;
1589 
1590     /* wct = 12 */
1591     rc = sess_alloc_buffer(sess_data, 12);
1592     if (rc)
1593         goto out;
1594 
1595     pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1596 
1597     /* Build security blob before we assemble the request */
1598     rc = build_ntlmssp_negotiate_blob(&ntlmsspblob,
1599                      &blob_len, ses, server,
1600                      sess_data->nls_cp);
1601     if (rc)
1602         goto out_free_ntlmsspblob;
1603 
1604     sess_data->iov[1].iov_len = blob_len;
1605     sess_data->iov[1].iov_base = ntlmsspblob;
1606     pSMB->req.SecurityBlobLength = cpu_to_le16(blob_len);
1607 
1608     rc = _sess_auth_rawntlmssp_assemble_req(sess_data);
1609     if (rc)
1610         goto out_free_ntlmsspblob;
1611 
1612     rc = sess_sendreceive(sess_data);
1613 
1614     pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1615     smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
1616 
1617     /* If true, rc here is expected and not an error */
1618     if (sess_data->buf0_type != CIFS_NO_BUFFER &&
1619         smb_buf->Status.CifsError ==
1620             cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
1621         rc = 0;
1622 
1623     if (rc)
1624         goto out_free_ntlmsspblob;
1625 
1626     cifs_dbg(FYI, "rawntlmssp session setup challenge phase\n");
1627 
1628     if (smb_buf->WordCount != 4) {
1629         rc = -EIO;
1630         cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
1631         goto out_free_ntlmsspblob;
1632     }
1633 
1634     ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
1635     cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
1636 
1637     bytes_remaining = get_bcc(smb_buf);
1638     bcc_ptr = pByteArea(smb_buf);
1639 
1640     blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
1641     if (blob_len > bytes_remaining) {
1642         cifs_dbg(VFS, "bad security blob length %d\n",
1643                 blob_len);
1644         rc = -EINVAL;
1645         goto out_free_ntlmsspblob;
1646     }
1647 
1648     rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses);
1649 
1650 out_free_ntlmsspblob:
1651     kfree(ntlmsspblob);
1652 out:
1653     sess_free_buffer(sess_data);
1654 
1655     if (!rc) {
1656         sess_data->func = sess_auth_rawntlmssp_authenticate;
1657         return;
1658     }
1659 
1660     /* Else error. Cleanup */
1661     kfree(ses->auth_key.response);
1662     ses->auth_key.response = NULL;
1663     kfree(ses->ntlmssp);
1664     ses->ntlmssp = NULL;
1665 
1666     sess_data->func = NULL;
1667     sess_data->result = rc;
1668 }
1669 
1670 static void
1671 sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
1672 {
1673     int rc;
1674     struct smb_hdr *smb_buf;
1675     SESSION_SETUP_ANDX *pSMB;
1676     struct cifs_ses *ses = sess_data->ses;
1677     struct TCP_Server_Info *server = sess_data->server;
1678     __u16 bytes_remaining;
1679     char *bcc_ptr;
1680     unsigned char *ntlmsspblob = NULL;
1681     u16 blob_len;
1682 
1683     cifs_dbg(FYI, "rawntlmssp session setup authenticate phase\n");
1684 
1685     /* wct = 12 */
1686     rc = sess_alloc_buffer(sess_data, 12);
1687     if (rc)
1688         goto out;
1689 
1690     /* Build security blob before we assemble the request */
1691     pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1692     smb_buf = (struct smb_hdr *)pSMB;
1693     rc = build_ntlmssp_auth_blob(&ntlmsspblob,
1694                     &blob_len, ses, server,
1695                     sess_data->nls_cp);
1696     if (rc)
1697         goto out_free_ntlmsspblob;
1698     sess_data->iov[1].iov_len = blob_len;
1699     sess_data->iov[1].iov_base = ntlmsspblob;
1700     pSMB->req.SecurityBlobLength = cpu_to_le16(blob_len);
1701     /*
1702      * Make sure that we tell the server that we are using
1703      * the uid that it just gave us back on the response
1704      * (challenge)
1705      */
1706     smb_buf->Uid = ses->Suid;
1707 
1708     rc = _sess_auth_rawntlmssp_assemble_req(sess_data);
1709     if (rc)
1710         goto out_free_ntlmsspblob;
1711 
1712     rc = sess_sendreceive(sess_data);
1713     if (rc)
1714         goto out_free_ntlmsspblob;
1715 
1716     pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1717     smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
1718     if (smb_buf->WordCount != 4) {
1719         rc = -EIO;
1720         cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
1721         goto out_free_ntlmsspblob;
1722     }
1723 
1724     if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
1725         cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
1726 
1727     if (ses->Suid != smb_buf->Uid) {
1728         ses->Suid = smb_buf->Uid;
1729         cifs_dbg(FYI, "UID changed! new UID = %llu\n", ses->Suid);
1730     }
1731 
1732     bytes_remaining = get_bcc(smb_buf);
1733     bcc_ptr = pByteArea(smb_buf);
1734     blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
1735     if (blob_len > bytes_remaining) {
1736         cifs_dbg(VFS, "bad security blob length %d\n",
1737                 blob_len);
1738         rc = -EINVAL;
1739         goto out_free_ntlmsspblob;
1740     }
1741     bcc_ptr += blob_len;
1742     bytes_remaining -= blob_len;
1743 
1744 
1745     /* BB check if Unicode and decode strings */
1746     if (bytes_remaining == 0) {
1747         /* no string area to decode, do nothing */
1748     } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
1749         /* unicode string area must be word-aligned */
1750         if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
1751             ++bcc_ptr;
1752             --bytes_remaining;
1753         }
1754         decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
1755                       sess_data->nls_cp);
1756     } else {
1757         decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
1758                     sess_data->nls_cp);
1759     }
1760 
1761 out_free_ntlmsspblob:
1762     kfree(ntlmsspblob);
1763 out:
1764     sess_free_buffer(sess_data);
1765 
1766     if (!rc)
1767         rc = sess_establish_session(sess_data);
1768 
1769     /* Cleanup */
1770     kfree(ses->auth_key.response);
1771     ses->auth_key.response = NULL;
1772     kfree(ses->ntlmssp);
1773     ses->ntlmssp = NULL;
1774 
1775     sess_data->func = NULL;
1776     sess_data->result = rc;
1777 }
1778 
1779 static int select_sec(struct sess_data *sess_data)
1780 {
1781     int type;
1782     struct cifs_ses *ses = sess_data->ses;
1783     struct TCP_Server_Info *server = sess_data->server;
1784 
1785     type = cifs_select_sectype(server, ses->sectype);
1786     cifs_dbg(FYI, "sess setup type %d\n", type);
1787     if (type == Unspecified) {
1788         cifs_dbg(VFS, "Unable to select appropriate authentication method!\n");
1789         return -EINVAL;
1790     }
1791 
1792     switch (type) {
1793     case NTLMv2:
1794         sess_data->func = sess_auth_ntlmv2;
1795         break;
1796     case Kerberos:
1797 #ifdef CONFIG_CIFS_UPCALL
1798         sess_data->func = sess_auth_kerberos;
1799         break;
1800 #else
1801         cifs_dbg(VFS, "Kerberos negotiated but upcall support disabled!\n");
1802         return -ENOSYS;
1803 #endif /* CONFIG_CIFS_UPCALL */
1804     case RawNTLMSSP:
1805         sess_data->func = sess_auth_rawntlmssp_negotiate;
1806         break;
1807     default:
1808         cifs_dbg(VFS, "secType %d not supported!\n", type);
1809         return -ENOSYS;
1810     }
1811 
1812     return 0;
1813 }
1814 
1815 int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
1816            struct TCP_Server_Info *server,
1817            const struct nls_table *nls_cp)
1818 {
1819     int rc = 0;
1820     struct sess_data *sess_data;
1821 
1822     if (ses == NULL) {
1823         WARN(1, "%s: ses == NULL!", __func__);
1824         return -EINVAL;
1825     }
1826 
1827     sess_data = kzalloc(sizeof(struct sess_data), GFP_KERNEL);
1828     if (!sess_data)
1829         return -ENOMEM;
1830 
1831     sess_data->xid = xid;
1832     sess_data->ses = ses;
1833     sess_data->server = server;
1834     sess_data->buf0_type = CIFS_NO_BUFFER;
1835     sess_data->nls_cp = (struct nls_table *) nls_cp;
1836 
1837     rc = select_sec(sess_data);
1838     if (rc)
1839         goto out;
1840 
1841     while (sess_data->func)
1842         sess_data->func(sess_data);
1843 
1844     /* Store result before we free sess_data */
1845     rc = sess_data->result;
1846 
1847 out:
1848     kfree(sess_data);
1849     return rc;
1850 }
1851 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */