^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * fs/cifs/sess.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * SMB/CIFS session setup handling routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) International Business Machines Corp., 2006, 2009
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author(s): Steve French (sfrench@us.ibm.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This library is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * it under the terms of the GNU Lesser General Public License as published
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * by the Free Software Foundation; either version 2.1 of the License, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * (at your option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * This library is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * the GNU Lesser General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * You should have received a copy of the GNU Lesser General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * along with this library; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "cifspdu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "cifsglob.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "cifsproto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "cifs_unicode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "cifs_debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "ntlmssp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "nterr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/utsname.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "cifs_spnego.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "smb2proto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) is_server_using_iface(struct TCP_Server_Info *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct cifs_server_iface *iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct sockaddr_in *i4 = (struct sockaddr_in *)&iface->sockaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct sockaddr_in6 *i6 = (struct sockaddr_in6 *)&iface->sockaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct sockaddr_in *s4 = (struct sockaddr_in *)&server->dstaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)&server->dstaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (server->dstaddr.ss_family != iface->sockaddr.ss_family)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (server->dstaddr.ss_family == AF_INET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (s4->sin_addr.s_addr != i4->sin_addr.s_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) } else if (server->dstaddr.ss_family == AF_INET6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (memcmp(&s6->sin6_addr, &i6->sin6_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) sizeof(i6->sin6_addr)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* unknown family.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) bool is_ses_using_iface(struct cifs_ses *ses, struct cifs_server_iface *iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) for (i = 0; i < ses->chan_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (is_server_using_iface(ses->chans[i].server, iface))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* returns number of channels added */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) int cifs_try_adding_channels(struct cifs_ses *ses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int old_chan_count = ses->chan_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) int left = ses->chan_max - ses->chan_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int tries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct cifs_server_iface *ifaces = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) size_t iface_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (left <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) cifs_dbg(FYI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) "ses already at max_channels (%zu), nothing to open\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ses->chan_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (ses->server->dialect < SMB30_PROT_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) cifs_dbg(VFS, "multichannel is not supported on this protocol version, use 3.0 or above\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (!(ses->server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) cifs_dbg(VFS, "server %s does not support multichannel\n", ses->server->hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ses->chan_max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * Make a copy of the iface list at the time and use that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * instead so as to not hold the iface spinlock for opening
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) spin_lock(&ses->iface_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) iface_count = ses->iface_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (iface_count <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) spin_unlock(&ses->iface_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) cifs_dbg(VFS, "no iface list available to open channels\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ifaces = kmemdup(ses->iface_list, iface_count*sizeof(*ifaces),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (!ifaces) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) spin_unlock(&ses->iface_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) spin_unlock(&ses->iface_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * Keep connecting to same, fastest, iface for all channels as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * long as its RSS. Try next fastest one if not RSS or channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * creation fails.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) while (left > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct cifs_server_iface *iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) tries++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (tries > 3*ses->chan_max) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) cifs_dbg(FYI, "too many channel open attempts (%d channels left to open)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) iface = &ifaces[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (is_ses_using_iface(ses, iface) && !iface->rss_capable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) i = (i+1) % iface_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) rc = cifs_ses_add_channel(ses, iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) cifs_dbg(FYI, "failed to open extra channel on iface#%d rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) i, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) i = (i+1) % iface_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) cifs_dbg(FYI, "successfully opened new channel on iface#%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) left--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) kfree(ifaces);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return ses->chan_count - old_chan_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * If server is a channel of ses, return the corresponding enclosing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * cifs_chan otherwise return NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct cifs_chan *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) for (i = 0; i < ses->chan_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (ses->chans[i].server == server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return &ses->chans[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct cifs_chan *chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct smb_vol vol = {NULL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static const char unc_fmt[] = "\\%s\\foo";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) char unc[sizeof(unc_fmt)+SERVER_NAME_LEN_WITH_NULL] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct sockaddr_in *ipv4 = (struct sockaddr_in *)&iface->sockaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&iface->sockaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) unsigned int xid = get_xid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (iface->sockaddr.ss_family == AF_INET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) cifs_dbg(FYI, "adding channel to ses %p (speed:%zu bps rdma:%s ip:%pI4)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ses, iface->speed, iface->rdma_capable ? "yes" : "no",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) &ipv4->sin_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) cifs_dbg(FYI, "adding channel to ses %p (speed:%zu bps rdma:%s ip:%pI4)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ses, iface->speed, iface->rdma_capable ? "yes" : "no",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) &ipv6->sin6_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * Setup a smb_vol with mostly the same info as the existing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * session and overwrite it with the requested iface data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * We need to setup at least the fields used for negprot and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * sesssetup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * We only need the volume here, so we can reuse memory from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * the session and server without caring about memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * management.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) /* Always make new connection for now (TODO?) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) vol.nosharesock = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* Auth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) vol.domainauto = ses->domainAuto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) vol.domainname = ses->domainName;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) vol.username = ses->user_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) vol.password = ses->password;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) vol.sectype = ses->sectype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) vol.sign = ses->sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* UNC and paths */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* XXX: Use ses->server->hostname? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) sprintf(unc, unc_fmt, ses->serverName);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) vol.UNC = unc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) vol.prepath = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* Reuse same version as master connection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) vol.vals = ses->server->vals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) vol.ops = ses->server->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) vol.noblocksnd = ses->server->noblocksnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) vol.noautotune = ses->server->noautotune;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) vol.sockopt_tcp_nodelay = ses->server->tcp_nodelay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) vol.echo_interval = ses->server->echo_interval / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) vol.max_credits = ses->server->max_credits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * This will be used for encoding/decoding user/domain/pw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * during sess setup auth.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * XXX: We use the default for simplicity but the proper way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * would be to use the one that ses used, which is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * stored. This might break when dealing with non-ascii
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * strings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) vol.local_nls = load_nls_default();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /* Use RDMA if possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) vol.rdma = iface->rdma_capable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) memcpy(&vol.dstaddr, &iface->sockaddr, sizeof(struct sockaddr_storage));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* reuse master con client guid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) memcpy(&vol.client_guid, ses->server->client_guid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) SMB2_CLIENT_GUID_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) vol.use_client_guid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) mutex_lock(&ses->session_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) chan = ses->binding_chan = &ses->chans[ses->chan_count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) chan->server = cifs_get_tcp_session(&vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (IS_ERR(chan->server)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) rc = PTR_ERR(chan->server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) chan->server = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) spin_lock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) chan->server->is_channel = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) spin_unlock(&cifs_tcp_ses_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * We need to allocate the server crypto now as we will need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * to sign packets before we generate the channel signing key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * (we sign with the session key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) rc = smb311_crypto_shash_allocate(chan->server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ses->binding = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) rc = cifs_negotiate_protocol(xid, ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) rc = cifs_setup_session(xid, ses, vol.local_nls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /* success, put it on the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * XXX: sharing ses between 2 tcp servers is not possible, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * way "internal" linked lists works in linux makes element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * only able to belong to one list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * the binding session is already established so the rest of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * the code should be able to look it up, no need to add the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * ses to the new server.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) ses->chan_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) atomic_set(&ses->chan_seq, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) ses->binding = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ses->binding_chan = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) mutex_unlock(&ses->session_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (rc && chan->server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) cifs_put_tcp_session(chan->server, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) unload_nls(vol.local_nls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) __u32 capabilities = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /* init fields common to all four types of SessSetup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* Note that offsets for first seven fields in req struct are same */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /* in CIFS Specs so does not matter which of 3 forms of struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* that we use in next few lines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /* Note that header is initialized to zero in header_assemble */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) pSMB->req.AndXCommand = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) pSMB->req.MaxBufferSize = cpu_to_le16(min_t(u32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) USHRT_MAX));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) pSMB->req.VcNumber = cpu_to_le16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /* BB verify whether signing required on neg or just on auth frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) (and NTLM case) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (ses->server->sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (ses->capabilities & CAP_UNICODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) capabilities |= CAP_UNICODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (ses->capabilities & CAP_STATUS32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) capabilities |= CAP_STATUS32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (ses->capabilities & CAP_DFS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) capabilities |= CAP_DFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (ses->capabilities & CAP_UNIX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) capabilities |= CAP_UNIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return capabilities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) char *bcc_ptr = *pbcc_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) int bytes_ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /* Copy OS version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) bytes_ret = cifs_strtoUTF16((__le16 *)bcc_ptr, "Linux version ", 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) bcc_ptr += 2 * bytes_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, init_utsname()->release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 32, nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) bcc_ptr += 2 * bytes_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) bcc_ptr += 2; /* trailing null */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 32, nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) bcc_ptr += 2 * bytes_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) bcc_ptr += 2; /* trailing null */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) *pbcc_area = bcc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) const struct nls_table *nls_cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) char *bcc_ptr = *pbcc_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) int bytes_ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /* copy domain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (ses->domainName == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* Sending null domain better than using a bogus domain name (as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) we did briefly in 2.6.18) since server will use its default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) *bcc_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) *(bcc_ptr+1) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) bytes_ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->domainName,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) CIFS_MAX_DOMAINNAME_LEN, nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) bcc_ptr += 2 * bytes_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) bcc_ptr += 2; /* account for null terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) *pbcc_area = bcc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) const struct nls_table *nls_cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) char *bcc_ptr = *pbcc_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int bytes_ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /* BB FIXME add check that strings total less
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) than 335 or will need to send them as arrays */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* unicode strings, must be word aligned before the call */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /* if ((long) bcc_ptr % 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) *bcc_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) bcc_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) } */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /* copy user */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (ses->user_name == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* null user mount */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) *bcc_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) *(bcc_ptr+1) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->user_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) CIFS_MAX_USERNAME_LEN, nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) bcc_ptr += 2 * bytes_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) bcc_ptr += 2; /* account for null termination */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) unicode_domain_string(&bcc_ptr, ses, nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) unicode_oslm_strings(&bcc_ptr, nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) *pbcc_area = bcc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) const struct nls_table *nls_cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) char *bcc_ptr = *pbcc_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /* copy user */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /* BB what about null user mounts - check that we do this BB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) /* copy user */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (ses->user_name != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) len = strscpy(bcc_ptr, ses->user_name, CIFS_MAX_USERNAME_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (WARN_ON_ONCE(len < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) len = CIFS_MAX_USERNAME_LEN - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) bcc_ptr += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /* else null user mount */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) *bcc_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) bcc_ptr++; /* account for null termination */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /* copy domain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (ses->domainName != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) len = strscpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (WARN_ON_ONCE(len < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) len = CIFS_MAX_DOMAINNAME_LEN - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) bcc_ptr += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) } /* else we will send a null domain name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) so the server will default to its own domain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) *bcc_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) bcc_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) /* BB check for overflow here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) strcpy(bcc_ptr, "Linux version ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) bcc_ptr += strlen("Linux version ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) strcpy(bcc_ptr, init_utsname()->release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) bcc_ptr += strlen(init_utsname()->release) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) *pbcc_area = bcc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifs_ses *ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) const struct nls_table *nls_cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) char *data = *pbcc_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) cifs_dbg(FYI, "bleft %d\n", bleft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) kfree(ses->serverOS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ses->serverOS = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) cifs_dbg(FYI, "serverOS=%s\n", ses->serverOS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) data += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) bleft -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (bleft <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) kfree(ses->serverNOS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ses->serverNOS = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) cifs_dbg(FYI, "serverNOS=%s\n", ses->serverNOS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) data += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) bleft -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (bleft <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) kfree(ses->serverDomain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) ses->serverDomain = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) cifs_dbg(FYI, "serverDomain=%s\n", ses->serverDomain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static void decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct cifs_ses *ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) const struct nls_table *nls_cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) char *bcc_ptr = *pbcc_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) cifs_dbg(FYI, "decode sessetup ascii. bleft %d\n", bleft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) len = strnlen(bcc_ptr, bleft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (len >= bleft)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) kfree(ses->serverOS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) ses->serverOS = kmalloc(len + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (ses->serverOS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) memcpy(ses->serverOS, bcc_ptr, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) ses->serverOS[len] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (strncmp(ses->serverOS, "OS/2", 4) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) cifs_dbg(FYI, "OS/2 server\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) bcc_ptr += len + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) bleft -= len + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) len = strnlen(bcc_ptr, bleft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (len >= bleft)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) kfree(ses->serverNOS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) ses->serverNOS = kmalloc(len + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (ses->serverNOS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) memcpy(ses->serverNOS, bcc_ptr, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) ses->serverNOS[len] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) bcc_ptr += len + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) bleft -= len + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) len = strnlen(bcc_ptr, bleft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (len > bleft)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) /* No domain field in LANMAN case. Domain is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) returned by old servers in the SMB negprot response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /* BB For newer servers which do not support Unicode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) but thus do return domain here we could add parsing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) for it later, but it is not very important */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) cifs_dbg(FYI, "ascii: bytes left %d\n", bleft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct cifs_ses *ses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) unsigned int tioffset; /* challenge message target info area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) unsigned int tilen; /* challenge message target info area length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) cifs_dbg(VFS, "challenge blob len %d too small\n", blob_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (memcmp(pblob->Signature, "NTLMSSP", 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) cifs_dbg(VFS, "blob signature incorrect %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) pblob->Signature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (pblob->MessageType != NtLmChallenge) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) cifs_dbg(VFS, "Incorrect message type %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) pblob->MessageType);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) memcpy(ses->ntlmssp->cryptkey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) /* BB we could decode pblob->NegotiateFlags; some may be useful */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) /* In particular we can examine sign flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /* BB spec says that if AvId field of MsvAvTimestamp is populated then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) we must set the MIC field of the AUTHENTICATE_MESSAGE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) ses->ntlmssp->server_flags = le32_to_cpu(pblob->NegotiateFlags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) tioffset = le32_to_cpu(pblob->TargetInfoArray.BufferOffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) tilen = le16_to_cpu(pblob->TargetInfoArray.Length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (tioffset > blob_len || tioffset + tilen > blob_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) cifs_dbg(VFS, "tioffset + tilen too high %u + %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) tioffset, tilen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (tilen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) ses->auth_key.response = kmemdup(bcc_ptr + tioffset, tilen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (!ses->auth_key.response) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) cifs_dbg(VFS, "Challenge target info alloc failure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ses->auth_key.len = tilen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) /* BB Move to ntlmssp.c eventually */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /* We do not malloc the blob, it is passed in pbuffer, because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) it is fixed size, and small, making this approach cleaner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) struct cifs_ses *ses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct TCP_Server_Info *server = cifs_ses_server(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) __u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) memset(pbuffer, 0, sizeof(NEGOTIATE_MESSAGE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) sec_blob->MessageType = NtLmNegotiate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) /* BB is NTLMV2 session security format easier to use here? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) NTLMSSP_NEGOTIATE_SEAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (server->sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) flags |= NTLMSSP_NEGOTIATE_SIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (!server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) sec_blob->NegotiateFlags = cpu_to_le32(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) sec_blob->WorkstationName.BufferOffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) sec_blob->WorkstationName.Length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) sec_blob->WorkstationName.MaximumLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /* Domain name is sent on the Challenge not Negotiate NTLMSSP request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) sec_blob->DomainName.BufferOffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) sec_blob->DomainName.Length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) sec_blob->DomainName.MaximumLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static int size_of_ntlmssp_blob(struct cifs_ses *ses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) int sz = sizeof(AUTHENTICATE_MESSAGE) + ses->auth_key.len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) - CIFS_SESS_KEY_SIZE + CIFS_CPHTXT_SIZE + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (ses->domainName)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) sz += 2 * strnlen(ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) sz += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (ses->user_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) sz += 2 * strnlen(ses->user_name, CIFS_MAX_USERNAME_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) sz += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) return sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) int build_ntlmssp_auth_blob(unsigned char **pbuffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) u16 *buflen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct cifs_ses *ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) const struct nls_table *nls_cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) AUTHENTICATE_MESSAGE *sec_blob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) __u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) unsigned char *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) rc = setup_ntlmv2_rsp(ses, nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) cifs_dbg(VFS, "Error %d during NTLMSSP authentication\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) *buflen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) goto setup_ntlmv2_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) *pbuffer = kmalloc(size_of_ntlmssp_blob(ses), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (!*pbuffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) cifs_dbg(VFS, "Error %d during NTLMSSP allocation\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) *buflen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) goto setup_ntlmv2_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) sec_blob = (AUTHENTICATE_MESSAGE *)*pbuffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) sec_blob->MessageType = NtLmAuthenticate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) flags = NTLMSSP_NEGOTIATE_56 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) NTLMSSP_NEGOTIATE_SEAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (ses->server->sign)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) flags |= NTLMSSP_NEGOTIATE_SIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) sec_blob->NegotiateFlags = cpu_to_le32(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) sec_blob->LmChallengeResponse.BufferOffset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) sec_blob->LmChallengeResponse.Length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) sec_blob->LmChallengeResponse.MaximumLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) sec_blob->NtChallengeResponse.BufferOffset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) cpu_to_le32(tmp - *pbuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (ses->user_name != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) ses->auth_key.len - CIFS_SESS_KEY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) sec_blob->NtChallengeResponse.Length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) sec_blob->NtChallengeResponse.MaximumLength =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) * don't send an NT Response for anonymous access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) sec_blob->NtChallengeResponse.Length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) sec_blob->NtChallengeResponse.MaximumLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (ses->domainName == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) sec_blob->DomainName.Length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) sec_blob->DomainName.MaximumLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) tmp += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) len = cifs_strtoUTF16((__le16 *)tmp, ses->domainName,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) CIFS_MAX_DOMAINNAME_LEN, nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) len *= 2; /* unicode is 2 bytes each */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) sec_blob->DomainName.Length = cpu_to_le16(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) tmp += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (ses->user_name == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) sec_blob->UserName.Length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) sec_blob->UserName.MaximumLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) tmp += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) len = cifs_strtoUTF16((__le16 *)tmp, ses->user_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) CIFS_MAX_USERNAME_LEN, nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) len *= 2; /* unicode is 2 bytes each */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) sec_blob->UserName.Length = cpu_to_le16(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) sec_blob->UserName.MaximumLength = cpu_to_le16(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) tmp += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) sec_blob->WorkstationName.Length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) sec_blob->WorkstationName.MaximumLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) tmp += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) (ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) && !calc_seckey(ses)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) sec_blob->SessionKey.MaximumLength =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) cpu_to_le16(CIFS_CPHTXT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) tmp += CIFS_CPHTXT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) sec_blob->SessionKey.Length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) sec_blob->SessionKey.MaximumLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) *buflen = tmp - *pbuffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) setup_ntlmv2_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) enum securityEnum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) cifs_select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) switch (server->negflavor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) case CIFS_NEGFLAVOR_EXTENDED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) switch (requested) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) case Kerberos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) case RawNTLMSSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) return requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) case Unspecified:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (server->sec_ntlmssp &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) (global_secflags & CIFSSEC_MAY_NTLMSSP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) return RawNTLMSSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if ((server->sec_kerberos || server->sec_mskerberos) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) (global_secflags & CIFSSEC_MAY_KRB5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return Kerberos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return Unspecified;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) case CIFS_NEGFLAVOR_UNENCAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) switch (requested) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) case NTLM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) case NTLMv2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) return requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) case Unspecified:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (global_secflags & CIFSSEC_MAY_NTLMV2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return NTLMv2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (global_secflags & CIFSSEC_MAY_NTLM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return NTLM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) fallthrough; /* to attempt LANMAN authentication next */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) case CIFS_NEGFLAVOR_LANMAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) switch (requested) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) case LANMAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) case Unspecified:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (global_secflags & CIFSSEC_MAY_LANMAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return LANMAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) return Unspecified;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) return Unspecified;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) struct sess_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) unsigned int xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) struct cifs_ses *ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) struct nls_table *nls_cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) void (*func)(struct sess_data *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) /* we will send the SMB in three pieces:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * a fixed length beginning part, an optional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) * SPNEGO blob (which can be zero length), and a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) * last part which will include the strings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) * and rest of bcc area. This allows us to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) * a large buffer 17K allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) int buf0_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct kvec iov[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) sess_alloc_buffer(struct sess_data *sess_data, int wct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) struct cifs_ses *ses = sess_data->ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) struct smb_hdr *smb_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) (void **)&smb_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) sess_data->iov[0].iov_base = (char *)smb_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) sess_data->iov[0].iov_len = be32_to_cpu(smb_buf->smb_buf_length) + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) * This variable will be used to clear the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) * allocated above in case of any error in the calling function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) sess_data->buf0_type = CIFS_SMALL_BUFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) /* 2000 big enough to fit max user, domain, NOS name etc. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) sess_data->iov[2].iov_base = kmalloc(2000, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (!sess_data->iov[2].iov_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) goto out_free_smb_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) out_free_smb_buf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) cifs_small_buf_release(smb_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) sess_data->iov[0].iov_base = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) sess_data->iov[0].iov_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) sess_data->buf0_type = CIFS_NO_BUFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) sess_free_buffer(struct sess_data *sess_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) free_rsp_buf(sess_data->buf0_type, sess_data->iov[0].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) sess_data->buf0_type = CIFS_NO_BUFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) kfree(sess_data->iov[2].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) sess_establish_session(struct sess_data *sess_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) struct cifs_ses *ses = sess_data->ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) mutex_lock(&ses->server->srv_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (!ses->server->session_estab) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (ses->server->sign) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) ses->server->session_key.response =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) kmemdup(ses->auth_key.response,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) ses->auth_key.len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (!ses->server->session_key.response) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) mutex_unlock(&ses->server->srv_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) ses->server->session_key.len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) ses->auth_key.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) ses->server->sequence_number = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) ses->server->session_estab = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) mutex_unlock(&ses->server->srv_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) cifs_dbg(FYI, "CIFS session established successfully\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) spin_lock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) ses->status = CifsGood;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) ses->need_reconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) spin_unlock(&GlobalMid_Lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) sess_sendreceive(struct sess_data *sess_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) struct smb_hdr *smb_buf = (struct smb_hdr *) sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) __u16 count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) struct kvec rsp_iov = { NULL, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) count = sess_data->iov[1].iov_len + sess_data->iov[2].iov_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) be32_add_cpu(&smb_buf->smb_buf_length, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) put_bcc(count, smb_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) rc = SendReceive2(sess_data->xid, sess_data->ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) sess_data->iov, 3 /* num_iovecs */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) &sess_data->buf0_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) CIFS_LOG_ERROR, &rsp_iov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) cifs_small_buf_release(sess_data->iov[0].iov_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) memcpy(&sess_data->iov[0], &rsp_iov, sizeof(struct kvec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * LANMAN and plaintext are less secure and off by default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * So we make this explicitly be turned on in kconfig (in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * build) and turned on at runtime (changed from the default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) * in proc/fs/cifs or via mount parm. Unfortunately this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) * needed for old Win (e.g. Win95), some obscure NAS and OS/2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) #ifdef CONFIG_CIFS_WEAK_PW_HASH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) sess_auth_lanman(struct sess_data *sess_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) struct smb_hdr *smb_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) SESSION_SETUP_ANDX *pSMB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) char *bcc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) struct cifs_ses *ses = sess_data->ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) char lnm_session_key[CIFS_AUTH_RESP_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) __u16 bytes_remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) /* lanman 2 style sessionsetup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) /* wct = 10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) rc = sess_alloc_buffer(sess_data, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) bcc_ptr = sess_data->iov[2].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) (void)cifs_ssetup_hdr(ses, pSMB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) pSMB->req.hdr.Flags2 &= ~SMBFLG2_UNICODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (ses->user_name != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) /* no capabilities flags in old lanman negotiation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) /* Calculate hash with password and copy into bcc_ptr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) * Encryption Key (stored as in cryptkey) gets used if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) * security mode bit in Negotiate Protocol response states
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * to use challenge/response method (i.e. Password bit is 1).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) true : false, lnm_session_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) bcc_ptr += CIFS_AUTH_RESP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) pSMB->old_req.PasswordLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) * can not sign if LANMAN negotiated so no need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) * to calculate signing key? but what if server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) * changed to do higher than lanman dialect and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) * we reconnected would we ever calc signing_key?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) cifs_dbg(FYI, "Negotiating LANMAN setting up strings\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) /* Unicode not allowed for LANMAN dialects */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) sess_data->iov[2].iov_len = (long) bcc_ptr -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) (long) sess_data->iov[2].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) rc = sess_sendreceive(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) /* lanman response has a word count of 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (smb_buf->WordCount != 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) bytes_remaining = get_bcc(smb_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) bcc_ptr = pByteArea(smb_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) /* BB check if Unicode and decode strings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) if (bytes_remaining == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) /* no string area to decode, do nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) /* unicode string area must be word-aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) ++bcc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) --bytes_remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) rc = sess_establish_session(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) sess_data->result = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) sess_data->func = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) sess_free_buffer(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) sess_auth_ntlm(struct sess_data *sess_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) struct smb_hdr *smb_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) SESSION_SETUP_ANDX *pSMB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) char *bcc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) struct cifs_ses *ses = sess_data->ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) __u32 capabilities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) __u16 bytes_remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) /* old style NTLM sessionsetup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) /* wct = 13 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) rc = sess_alloc_buffer(sess_data, 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) bcc_ptr = sess_data->iov[2].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) capabilities = cifs_ssetup_hdr(ses, pSMB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if (ses->user_name != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) pSMB->req_no_secext.CaseInsensitivePasswordLength =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) cpu_to_le16(CIFS_AUTH_RESP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) pSMB->req_no_secext.CaseSensitivePasswordLength =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) cpu_to_le16(CIFS_AUTH_RESP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) /* calculate ntlm response and session key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) rc = setup_ntlm_response(ses, sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) cifs_dbg(VFS, "Error %d during NTLM authentication\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) /* copy ntlm response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) CIFS_AUTH_RESP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) bcc_ptr += CIFS_AUTH_RESP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) CIFS_AUTH_RESP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) bcc_ptr += CIFS_AUTH_RESP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) pSMB->req_no_secext.CaseSensitivePasswordLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (ses->capabilities & CAP_UNICODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) /* unicode strings must be word aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (sess_data->iov[0].iov_len % 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) *bcc_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) bcc_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) unicode_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) sess_data->iov[2].iov_len = (long) bcc_ptr -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) (long) sess_data->iov[2].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) rc = sess_sendreceive(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) if (smb_buf->WordCount != 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) bytes_remaining = get_bcc(smb_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) bcc_ptr = pByteArea(smb_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) /* BB check if Unicode and decode strings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if (bytes_remaining == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) /* no string area to decode, do nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) /* unicode string area must be word-aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) ++bcc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) --bytes_remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) rc = sess_establish_session(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) sess_data->result = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) sess_data->func = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) sess_free_buffer(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) kfree(ses->auth_key.response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) ses->auth_key.response = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) sess_auth_ntlmv2(struct sess_data *sess_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) struct smb_hdr *smb_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) SESSION_SETUP_ANDX *pSMB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) char *bcc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) struct cifs_ses *ses = sess_data->ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) __u32 capabilities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) __u16 bytes_remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) /* old style NTLM sessionsetup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) /* wct = 13 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) rc = sess_alloc_buffer(sess_data, 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) bcc_ptr = sess_data->iov[2].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) capabilities = cifs_ssetup_hdr(ses, pSMB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) /* LM2 password would be here if we supported it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) if (ses->user_name != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) /* calculate nlmv2 response and session key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) rc = setup_ntlmv2_rsp(ses, sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) cifs_dbg(VFS, "Error %d during NTLMv2 authentication\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) ses->auth_key.len - CIFS_SESS_KEY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) /* set case sensitive password length after tilen may get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) * assigned, tilen is 0 otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) pSMB->req_no_secext.CaseSensitivePasswordLength =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) pSMB->req_no_secext.CaseSensitivePasswordLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) if (ses->capabilities & CAP_UNICODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) if (sess_data->iov[0].iov_len % 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) *bcc_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) bcc_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) unicode_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) sess_data->iov[2].iov_len = (long) bcc_ptr -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) (long) sess_data->iov[2].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) rc = sess_sendreceive(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (smb_buf->WordCount != 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) bytes_remaining = get_bcc(smb_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) bcc_ptr = pByteArea(smb_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) /* BB check if Unicode and decode strings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) if (bytes_remaining == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) /* no string area to decode, do nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) /* unicode string area must be word-aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) ++bcc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) --bytes_remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) rc = sess_establish_session(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) sess_data->result = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) sess_data->func = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) sess_free_buffer(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) kfree(ses->auth_key.response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) ses->auth_key.response = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) #ifdef CONFIG_CIFS_UPCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) sess_auth_kerberos(struct sess_data *sess_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) struct smb_hdr *smb_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) SESSION_SETUP_ANDX *pSMB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) char *bcc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) struct cifs_ses *ses = sess_data->ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) __u32 capabilities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) __u16 bytes_remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) struct key *spnego_key = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) struct cifs_spnego_msg *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) u16 blob_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) /* extended security */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) /* wct = 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) rc = sess_alloc_buffer(sess_data, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) bcc_ptr = sess_data->iov[2].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) capabilities = cifs_ssetup_hdr(ses, pSMB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) spnego_key = cifs_get_spnego_key(ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (IS_ERR(spnego_key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) rc = PTR_ERR(spnego_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) spnego_key = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) msg = spnego_key->payload.data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) * check version field to make sure that cifs.upcall is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) * sending us a response in an expected form
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) cifs_dbg(VFS, "incorrect version of cifs.upcall (expected %d but got %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) CIFS_SPNEGO_UPCALL_VERSION, msg->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) rc = -EKEYREJECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) goto out_put_spnego_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) if (!ses->auth_key.response) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) cifs_dbg(VFS, "Kerberos can't allocate (%u bytes) memory\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) msg->sesskey_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) goto out_put_spnego_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) ses->auth_key.len = msg->sesskey_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) capabilities |= CAP_EXTENDED_SECURITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) pSMB->req.Capabilities = cpu_to_le32(capabilities);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) sess_data->iov[1].iov_base = msg->data + msg->sesskey_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) sess_data->iov[1].iov_len = msg->secblob_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) pSMB->req.SecurityBlobLength = cpu_to_le16(sess_data->iov[1].iov_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) if (ses->capabilities & CAP_UNICODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) /* unicode strings must be word aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) if ((sess_data->iov[0].iov_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) + sess_data->iov[1].iov_len) % 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) *bcc_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) bcc_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) unicode_domain_string(&bcc_ptr, ses, sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) /* BB: is this right? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) sess_data->iov[2].iov_len = (long) bcc_ptr -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) (long) sess_data->iov[2].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) rc = sess_sendreceive(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) goto out_put_spnego_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) if (smb_buf->WordCount != 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) goto out_put_spnego_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) bytes_remaining = get_bcc(smb_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) bcc_ptr = pByteArea(smb_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) if (blob_len > bytes_remaining) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) cifs_dbg(VFS, "bad security blob length %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) blob_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) goto out_put_spnego_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) bcc_ptr += blob_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) bytes_remaining -= blob_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) /* BB check if Unicode and decode strings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) if (bytes_remaining == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) /* no string area to decode, do nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) /* unicode string area must be word-aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) ++bcc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) --bytes_remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) rc = sess_establish_session(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) out_put_spnego_key:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) key_invalidate(spnego_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) key_put(spnego_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) sess_data->result = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) sess_data->func = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) sess_free_buffer(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) kfree(ses->auth_key.response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) ses->auth_key.response = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) #endif /* ! CONFIG_CIFS_UPCALL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) * The required kvec buffers have to be allocated before calling this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) * function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) _sess_auth_rawntlmssp_assemble_req(struct sess_data *sess_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) SESSION_SETUP_ANDX *pSMB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) struct cifs_ses *ses = sess_data->ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) __u32 capabilities;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) char *bcc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) capabilities = cifs_ssetup_hdr(ses, pSMB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) cifs_dbg(VFS, "NTLMSSP requires Unicode support\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) capabilities |= CAP_EXTENDED_SECURITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) pSMB->req.Capabilities |= cpu_to_le32(capabilities);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) bcc_ptr = sess_data->iov[2].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) /* unicode strings must be word aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if ((sess_data->iov[0].iov_len + sess_data->iov[1].iov_len) % 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) *bcc_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) bcc_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) sess_data->iov[2].iov_len = (long) bcc_ptr -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) (long) sess_data->iov[2].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) sess_auth_rawntlmssp_negotiate(struct sess_data *sess_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) struct smb_hdr *smb_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) SESSION_SETUP_ANDX *pSMB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) struct cifs_ses *ses = sess_data->ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) __u16 bytes_remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) char *bcc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) u16 blob_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) cifs_dbg(FYI, "rawntlmssp session setup negotiate phase\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) * if memory allocation is successful, caller of this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) * frees it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) ses->ntlmssp = kmalloc(sizeof(struct ntlmssp_auth), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) if (!ses->ntlmssp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) ses->ntlmssp->sesskey_per_smbsess = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) /* wct = 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) rc = sess_alloc_buffer(sess_data, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) /* Build security blob before we assemble the request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) build_ntlmssp_negotiate_blob(pSMB->req.SecurityBlob, ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) sess_data->iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) sess_data->iov[1].iov_base = pSMB->req.SecurityBlob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) pSMB->req.SecurityBlobLength = cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) rc = _sess_auth_rawntlmssp_assemble_req(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) rc = sess_sendreceive(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) /* If true, rc here is expected and not an error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) if (sess_data->buf0_type != CIFS_NO_BUFFER &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) smb_buf->Status.CifsError ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) cifs_dbg(FYI, "rawntlmssp session setup challenge phase\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) if (smb_buf->WordCount != 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) bytes_remaining = get_bcc(smb_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) bcc_ptr = pByteArea(smb_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) if (blob_len > bytes_remaining) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) cifs_dbg(VFS, "bad security blob length %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) blob_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) sess_free_buffer(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) sess_data->func = sess_auth_rawntlmssp_authenticate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) /* Else error. Cleanup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) kfree(ses->auth_key.response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) ses->auth_key.response = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) kfree(ses->ntlmssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) ses->ntlmssp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) sess_data->func = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) sess_data->result = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) struct smb_hdr *smb_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) SESSION_SETUP_ANDX *pSMB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) struct cifs_ses *ses = sess_data->ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) __u16 bytes_remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) char *bcc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) unsigned char *ntlmsspblob = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) u16 blob_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) cifs_dbg(FYI, "rawntlmssp session setup authenticate phase\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) /* wct = 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) rc = sess_alloc_buffer(sess_data, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) /* Build security blob before we assemble the request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) smb_buf = (struct smb_hdr *)pSMB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) rc = build_ntlmssp_auth_blob(&ntlmsspblob,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) &blob_len, ses, sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) goto out_free_ntlmsspblob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) sess_data->iov[1].iov_len = blob_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) sess_data->iov[1].iov_base = ntlmsspblob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) pSMB->req.SecurityBlobLength = cpu_to_le16(blob_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) * Make sure that we tell the server that we are using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) * the uid that it just gave us back on the response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) * (challenge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) smb_buf->Uid = ses->Suid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) rc = _sess_auth_rawntlmssp_assemble_req(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) goto out_free_ntlmsspblob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) rc = sess_sendreceive(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) goto out_free_ntlmsspblob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) if (smb_buf->WordCount != 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) goto out_free_ntlmsspblob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) if (ses->Suid != smb_buf->Uid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) ses->Suid = smb_buf->Uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) cifs_dbg(FYI, "UID changed! new UID = %llu\n", ses->Suid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) bytes_remaining = get_bcc(smb_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) bcc_ptr = pByteArea(smb_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) if (blob_len > bytes_remaining) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) cifs_dbg(VFS, "bad security blob length %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) blob_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) goto out_free_ntlmsspblob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) bcc_ptr += blob_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) bytes_remaining -= blob_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) /* BB check if Unicode and decode strings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (bytes_remaining == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) /* no string area to decode, do nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) /* unicode string area must be word-aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) ++bcc_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) --bytes_remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) sess_data->nls_cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) out_free_ntlmsspblob:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) kfree(ntlmsspblob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) sess_free_buffer(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) rc = sess_establish_session(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) /* Cleanup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) kfree(ses->auth_key.response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) ses->auth_key.response = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) kfree(ses->ntlmssp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) ses->ntlmssp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) sess_data->func = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) sess_data->result = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) static int select_sec(struct cifs_ses *ses, struct sess_data *sess_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) type = cifs_select_sectype(ses->server, ses->sectype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) cifs_dbg(FYI, "sess setup type %d\n", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) if (type == Unspecified) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) cifs_dbg(VFS, "Unable to select appropriate authentication method!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) case LANMAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) /* LANMAN and plaintext are less secure and off by default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) * So we make this explicitly be turned on in kconfig (in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) * build) and turned on at runtime (changed from the default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) * in proc/fs/cifs or via mount parm. Unfortunately this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) * needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) #ifdef CONFIG_CIFS_WEAK_PW_HASH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) sess_data->func = sess_auth_lanman;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) case NTLM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) sess_data->func = sess_auth_ntlm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) case NTLMv2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) sess_data->func = sess_auth_ntlmv2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) case Kerberos:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) #ifdef CONFIG_CIFS_UPCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) sess_data->func = sess_auth_kerberos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) cifs_dbg(VFS, "Kerberos negotiated but upcall support disabled!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) #endif /* CONFIG_CIFS_UPCALL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) case RawNTLMSSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) sess_data->func = sess_auth_rawntlmssp_negotiate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) cifs_dbg(VFS, "secType %d not supported!\n", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) const struct nls_table *nls_cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) struct sess_data *sess_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) if (ses == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) WARN(1, "%s: ses == NULL!", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) sess_data = kzalloc(sizeof(struct sess_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) if (!sess_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) rc = select_sec(ses, sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) sess_data->xid = xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) sess_data->ses = ses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) sess_data->buf0_type = CIFS_NO_BUFFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) sess_data->nls_cp = (struct nls_table *) nls_cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) while (sess_data->func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) sess_data->func(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) /* Store result before we free sess_data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) rc = sess_data->result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) kfree(sess_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) }