| Start/ | End/ | |||
| True | False | - | Line | Source |
| 1 | /* | |||
| 2 | * fs/cifs/cifssmb.c | |||
| 3 | * | |||
| 4 | * Copyright (C) International Business Machines Corp., 2002,2005 | |||
| 5 | * Author(s): Steve French (sfrench@us.ibm.com) | |||
| 6 | * | |||
| 7 | * Contains the routines for constructing the SMB PDUs themselves | |||
| 8 | * | |||
| 9 | * This library is free software; you can redistribute it and/or modify | |||
| 10 | * it under the terms of the GNU Lesser General Public License as published | |||
| 11 | * by the Free Software Foundation; either version 2.1 of the License, or | |||
| 12 | * (at your option) any later version. | |||
| 13 | * | |||
| 14 | * This library is distributed in the hope that it will be useful, | |||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | |||
| 17 | * the GNU Lesser General Public License for more details. | |||
| 18 | * | |||
| 19 | * You should have received a copy of the GNU Lesser General Public License | |||
| 20 | * along with this library; if not, write to the Free Software | |||
| 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
| 22 | */ | |||
| 23 | ||||
| 24 | /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */ | |||
| 25 | /* These are mostly routines that operate on a pathname, or on a tree id */ | |||
| 26 | /* (mounted volume), but there are eight handle based routines which must be */ | |||
| 27 | /* treated slightly different for reconnection purposes since we never want */ | |||
| 28 | /* to reuse a stale file handle and the caller knows the file handle */ | |||
| 29 | ||||
| 30 | #include <linux/fs.h> | |||
| 31 | #include <linux/kernel.h> | |||
| 32 | #include <linux/vfs.h> | |||
| 33 | #include <linux/posix_acl_xattr.h> | |||
| 34 | #include <asm/uaccess.h> | |||
| 35 | #include "cifspdu.h" | |||
| 36 | #include "cifsglob.h" | |||
| 37 | #include "cifsproto.h" | |||
| 38 | #include "cifs_unicode.h" | |||
| 39 | #include "cifs_debug.h" | |||
| 40 | #include "cifsacl.h" | |||
| 41 | ||||
| 42 | #ifdef CONFIG_CIFS_POSIX | |||
| 43 | static struct { | |||
| 44 | int index; | |||
| 45 | char *name; | |||
| 46 | } protocols[] = { | |||
| 47 | {CIFS_PROT, "\2NT LM 0.12"}, | |||
| 48 | {CIFS_PROT, "\2POSIX 2"}, | |||
| 49 | {BAD_PROT, "\2"} | |||
| 50 | }; | |||
| 51 | #else | |||
| 52 | static struct { | |||
| 53 | int index; | |||
| 54 | char *name; | |||
| 55 | } protocols[] = { | |||
| 56 | {CIFS_PROT, "\2NT LM 0.12"}, | |||
| 57 | {BAD_PROT, "\2"} | |||
| 58 | }; | |||
| 59 | #endif | |||
| 60 | ||||
| 61 | ||||
| 62 | /* Mark as invalid, all open files on tree connections since they | |||
| 63 | were closed when session to server was lost */ | |||
| 0 | 0 | - | 64 | static void mark_open_files_invalid(struct cifsTconInfo * pTcon) |
| 65 | { | |||
| 66 | struct cifsFileInfo *open_file = NULL; | |||
| 67 | struct list_head * tmp; | |||
| 68 | struct list_head * tmp1; | |||
| 69 | ||||
| 70 | /* list all files open on tree connection and mark them invalid */ | |||
| 71 | write_lock(&GlobalSMBSeslock); | |||
| 71 | do | |||
| 0 | 0 | - | 71 | do-while (0) |
| 0 | 0 | - | 71 | do-while (0) |
| 0 | 0 | - | 72 | list_for_each_safe(tmp, tmp1, &pTcon->openFileList) { |
| 73 | open_file = list_entry(tmp,struct cifsFileInfo, tlist); | |||
| 0 | 0 | - | 74 | if(open_file) { |
| 75 | open_file->invalidHandle = TRUE; | |||
| 76 | } | |||
| 77 | } | |||
| 78 | write_unlock(&GlobalSMBSeslock); | |||
| 78 | do | |||
| 0 | 0 | - | 78 | do-while (0) |
| 0 | 0 | - | 78 | do-while (0) |
| 79 | /* BB Add call to invalidate_inodes(sb) for all superblocks mounted | |||
| 80 | to this tcon */ | |||
| 81 | } | |||
| 82 | ||||
| 83 | /* If the return code is zero, this function must fill in request_buf pointer */ | |||
| 84 | static int | |||
| 0 | 0 | - | 85 | small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, |
| 86 | void **request_buf /* returned */) | |||
| 87 | { | |||
| 88 | int rc = 0; | |||
| 89 | ||||
| 90 | /* SMBs NegProt, SessSetup, uLogoff do not have tcon yet so | |||
| 91 | check for tcp and smb session status done differently | |||
| 92 | for those three - in the calling routine */ | |||
| 0 | 0 | - | 93 | if(tcon) { |
| 0 | 0 | - | 94 | if(tcon->tidStatus == CifsExiting) { |
| 95 | /* only tree disconnect, open, and write, | |||
| 96 | (and ulogoff which does not have tcon) | |||
| 97 | are allowed as we start force umount */ | |||
| 98 | if((smb_command != SMB_COM_WRITE_ANDX) && | |||
| 99 | (smb_command != SMB_COM_OPEN_ANDX) && | |||
| 0 | 0 | - | 100 | (smb_command != SMB_COM_TREE_DISCONNECT)) { |
| 0 | - | 100 | (T) && (T) && (T) | |
| 0 | - | 100 | (T) && (T) && (F) | |
| 0 | - | 100 | (T) && (F) && (_) | |
| 0 | - | 100 | (F) && (_) && (_) | |
| 0 | 0 | - | 101 | cFYI(1,("can not send cmd %d while umounting", |
| 0 | 0 | - | 101 | if (cifsFYI & 0x01) |
| 102 | smb_command)); | |||
| 0 | - | 103 | return -ENODEV; | |
| 104 | } | |||
| 105 | } | |||
| 106 | if((tcon->ses) && (tcon->ses->status != CifsExiting) && | |||
| 0 | 0 | - | 107 | (tcon->ses->server)){ |
| 0 | - | 107 | (T) && (T) && (T) | |
| 0 | - | 107 | (T) && (T) && (F) | |
| 0 | - | 107 | (T) && (F) && (_) | |
| 0 | - | 107 | (F) && (_) && (_) | |
| 108 | struct nls_table *nls_codepage; | |||
| 109 | /* Give Demultiplex thread up to 10 seconds to | |||
| 110 | reconnect, should be greater than cifs socket | |||
| 111 | timeout which is 7 seconds */ | |||
| 0 | 0 | - | 112 | while(tcon->ses->server->tcpStatus == CifsNeedReconnect) { |
| 113 | wait_event_interruptible_timeout(tcon->ses->server->response_q, | |||
| 114 | (tcon->ses->server->tcpStatus == CifsGood), 10 * HZ); | |||
| 0 | 0 | - | 115 | if(tcon->ses->server->tcpStatus == CifsNeedReconnect) { |
| 116 | /* on "soft" mounts we wait once */ | |||
| 117 | if((tcon->retry == FALSE) || | |||
| 0 | 0 | - | 118 | (tcon->ses->status == CifsExiting)) { |
| 0 | - | 118 | (T) || (_) | |
| 0 | - | 118 | (F) || (T) | |
| 0 | - | 118 | (F) || (F) | |
| 0 | 0 | - | 119 | cFYI(1,("gave up waiting on reconnect in smb_init")); |
| 0 | 0 | - | 119 | if (cifsFYI & 0x01) |
| 0 | - | 120 | return -EHOSTDOWN; | |
| 121 | } /* else "hard" mount - keep retrying | |||
| 122 | until process is killed or server | |||
| 123 | comes back on-line */ | |||
| 124 | } else /* TCP session is reestablished now */ | |||
| 0 | - | 125 | break; | |
| 126 | ||||
| 127 | } | |||
| 128 | ||||
| 129 | nls_codepage = load_nls_default(); | |||
| 130 | /* need to prevent multiple threads trying to | |||
| 131 | simultaneously reconnect the same SMB session */ | |||
| 132 | down(&tcon->ses->sesSem); | |||
| 0 | 0 | - | 133 | if(tcon->ses->status == CifsNeedReconnect) |
| 134 | rc = cifs_setup_session(0, tcon->ses, | |||
| 135 | nls_codepage); | |||
| 0 | 0 | - | 136 | if(!rc && (tcon->tidStatus == CifsNeedReconnect)) { |
| 0 | - | 136 | T && (T) | |
| 0 | - | 136 | T && (F) | |
| 0 | - | 136 | F && (_) | |
| 137 | mark_open_files_invalid(tcon); | |||
| 138 | rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon | |||
| 139 | , nls_codepage); | |||
| 140 | up(&tcon->ses->sesSem); | |||
| 141 | /* BB FIXME add code to check if wsize needs | |||
| 142 | update due to negotiated smb buffer size | |||
| 143 | shrinking */ | |||
| 0 | 0 | - | 144 | if(rc == 0) |
| 145 | atomic_inc(&tconInfoReconnectCount); | |||
| 146 | ||||
| 0 | 0 | - | 147 | cFYI(1, ("reconnect tcon rc = %d", rc)); |
| 0 | 0 | - | 147 | if (cifsFYI & 0x01) |
| 148 | /* Removed call to reopen open files here - | |||
| 149 | it is safer (and faster) to reopen files | |||
| 150 | one at a time as needed in read and write */ | |||
| 151 | ||||
| 152 | /* Check if handle based operation so we | |||
| 153 | know whether we can continue or not without | |||
| 154 | returning to caller to reset file handle */ | |||
| 155 | switch(smb_command) { | |||
| 0 | - | 156 | case SMB_COM_READ_ANDX: | |
| 0 | - | 157 | case SMB_COM_WRITE_ANDX: | |
| 0 | - | 158 | case SMB_COM_CLOSE: | |
| 0 | - | 159 | case SMB_COM_FIND_CLOSE2: | |
| 0 | - | 160 | case SMB_COM_LOCKING_ANDX: { | |
| 161 | unload_nls(nls_codepage); | |||
| 0 | - | 162 | return -EAGAIN; | |
| 163 | } | |||
| 164 | } | |||
| 165 | } else { | |||
| 166 | up(&tcon->ses->sesSem); | |||
| 167 | } | |||
| 168 | unload_nls(nls_codepage); | |||
| 169 | ||||
| 170 | } else { | |||
| 0 | - | 171 | return -EIO; | |
| 172 | } | |||
| 173 | } | |||
| 0 | 0 | - | 174 | if(rc) |
| 0 | - | 175 | return rc; | |
| 176 | ||||
| 177 | *request_buf = cifs_small_buf_get(); | |||
| 0 | 0 | - | 178 | if (*request_buf == NULL) { |
| 179 | /* BB should we add a retry in here if not a writepage? */ | |||
| 0 | - | 180 | return -ENOMEM; | |
| 181 | } | |||
| 182 | ||||
| 183 | header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,wct); | |||
| 184 | ||||
| 0 | 0 | - | 185 | if(tcon != NULL) |
| 186 | cifs_stats_inc(&tcon->num_smbs_sent); | |||
| 0 | 0 | - | 186 | do-while (0) |
| 187 | ||||
| 0 | - | 188 | return rc; | |
| 189 | } | |||
| 190 | ||||
| 191 | /* If the return code is zero, this function must fill in request_buf pointer */ | |||
| 192 | static int | |||
| 0 | 0 | - | 193 | smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, |
| 194 | void **request_buf /* returned */ , | |||
| 195 | void **response_buf /* returned */ ) | |||
| 196 | { | |||
| 197 | int rc = 0; | |||
| 198 | ||||
| 199 | /* SMBs NegProt, SessSetup, uLogoff do not have tcon yet so | |||
| 200 | check for tcp and smb session status done differently | |||
| 201 | for those three - in the calling routine */ | |||
| 0 | 0 | - | 202 | if(tcon) { |
| 0 | 0 | - | 203 | if(tcon->tidStatus == CifsExiting) { |
| 204 | /* only tree disconnect, open, and write, | |||
| 205 | (and ulogoff which does not have tcon) | |||
| 206 | are allowed as we start force umount */ | |||
| 207 | if((smb_command != SMB_COM_WRITE_ANDX) && | |||
| 208 | (smb_command != SMB_COM_OPEN_ANDX) && | |||
| 0 | 0 | - | 209 | (smb_command != SMB_COM_TREE_DISCONNECT)) { |
| 0 | - | 209 | (T) && (T) && (T) | |
| 0 | - | 209 | (T) && (T) && (F) | |
| 0 | - | 209 | (T) && (F) && (_) | |
| 0 | - | 209 | (F) && (_) && (_) | |
| 0 | 0 | - | 210 | cFYI(1,("can not send cmd %d while umounting", |
| 0 | 0 | - | 210 | if (cifsFYI & 0x01) |
| 211 | smb_command)); | |||
| 0 | - | 212 | return -ENODEV; | |
| 213 | } | |||
| 214 | } | |||
| 215 | ||||
| 216 | if((tcon->ses) && (tcon->ses->status != CifsExiting) && | |||
| 0 | 0 | - | 217 | (tcon->ses->server)){ |
| 0 | - | 217 | (T) && (T) && (T) | |
| 0 | - | 217 | (T) && (T) && (F) | |
| 0 | - | 217 | (T) && (F) && (_) | |
| 0 | - | 217 | (F) && (_) && (_) | |
| 218 | struct nls_table *nls_codepage; | |||
| 219 | /* Give Demultiplex thread up to 10 seconds to | |||
| 220 | reconnect, should be greater than cifs socket | |||
| 221 | timeout which is 7 seconds */ | |||
| 0 | 0 | - | 222 | while(tcon->ses->server->tcpStatus == CifsNeedReconnect) { |
| 223 | wait_event_interruptible_timeout(tcon->ses->server->response_q, | |||
| 224 | (tcon->ses->server->tcpStatus == CifsGood), 10 * HZ); | |||
| 225 | if(tcon->ses->server->tcpStatus == | |||
| 0 | 0 | - | 226 | CifsNeedReconnect) { |
| 227 | /* on "soft" mounts we wait once */ | |||
| 228 | if((tcon->retry == FALSE) || | |||
| 0 | 0 | - | 229 | (tcon->ses->status == CifsExiting)) { |
| 0 | - | 229 | (T) || (_) | |
| 0 | - | 229 | (F) || (T) | |
| 0 | - | 229 | (F) || (F) | |
| 0 | 0 | - | 230 | cFYI(1,("gave up waiting on reconnect in smb_init")); |
| 0 | 0 | - | 230 | if (cifsFYI & 0x01) |
| 0 | - | 231 | return -EHOSTDOWN; | |
| 232 | } /* else "hard" mount - keep retrying | |||
| 233 | until process is killed or server | |||
| 234 | comes on-line */ | |||
| 235 | } else /* TCP session is reestablished now */ | |||
| 0 | - | 236 | break; | |
| 237 | ||||
| 238 | } | |||
| 239 | ||||
| 240 | nls_codepage = load_nls_default(); | |||
| 241 | /* need to prevent multiple threads trying to | |||
| 242 | simultaneously reconnect the same SMB session */ | |||
| 243 | down(&tcon->ses->sesSem); | |||
| 0 | 0 | - | 244 | if(tcon->ses->status == CifsNeedReconnect) |
| 245 | rc = cifs_setup_session(0, tcon->ses, | |||
| 246 | nls_codepage); | |||
| 0 | 0 | - | 247 | if(!rc && (tcon->tidStatus == CifsNeedReconnect)) { |
| 0 | - | 247 | T && (T) | |
| 0 | - | 247 | T && (F) | |
| 0 | - | 247 | F && (_) | |
| 248 | mark_open_files_invalid(tcon); | |||
| 249 | rc = CIFSTCon(0, tcon->ses, tcon->treeName, | |||
| 250 | tcon, nls_codepage); | |||
| 251 | up(&tcon->ses->sesSem); | |||
| 252 | /* BB FIXME add code to check if wsize needs | |||
| 253 | update due to negotiated smb buffer size | |||
| 254 | shrinking */ | |||
| 0 | 0 | - | 255 | if(rc == 0) |
| 256 | atomic_inc(&tconInfoReconnectCount); | |||
| 257 | ||||
| 0 | 0 | - | 258 | cFYI(1, ("reconnect tcon rc = %d", rc)); |
| 0 | 0 | - | 258 | if (cifsFYI & 0x01) |
| 259 | /* Removed call to reopen open files here - | |||
| 260 | it is safer (and faster) to reopen files | |||
| 261 | one at a time as needed in read and write */ | |||
| 262 | ||||
| 263 | /* Check if handle based operation so we | |||
| 264 | know whether we can continue or not without | |||
| 265 | returning to caller to reset file handle */ | |||
| 266 | switch(smb_command) { | |||
| 0 | - | 267 | case SMB_COM_READ_ANDX: | |
| 0 | - | 268 | case SMB_COM_WRITE_ANDX: | |
| 0 | - | 269 | case SMB_COM_CLOSE: | |
| 0 | - | 270 | case SMB_COM_FIND_CLOSE2: | |
| 0 | - | 271 | case SMB_COM_LOCKING_ANDX: { | |
| 272 | unload_nls(nls_codepage); | |||
| 0 | - | 273 | return -EAGAIN; | |
| 274 | } | |||
| 275 | } | |||
| 276 | } else { | |||
| 277 | up(&tcon->ses->sesSem); | |||
| 278 | } | |||
| 279 | unload_nls(nls_codepage); | |||
| 280 | ||||
| 281 | } else { | |||
| 0 | - | 282 | return -EIO; | |
| 283 | } | |||
| 284 | } | |||
| 0 | 0 | - | 285 | if(rc) |
| 0 | - | 286 | return rc; | |
| 287 | ||||
| 288 | *request_buf = cifs_buf_get(); | |||
| 0 | 0 | - | 289 | if (*request_buf == NULL) { |
| 290 | /* BB should we add a retry in here if not a writepage? */ | |||
| 0 | - | 291 | return -ENOMEM; | |
| 292 | } | |||
| 293 | /* Although the original thought was we needed the response buf for */ | |||
| 294 | /* potential retries of smb operations it turns out we can determine */ | |||
| 295 | /* from the mid flags when the request buffer can be resent without */ | |||
| 296 | /* having to use a second distinct buffer for the response */ | |||
| 297 | *response_buf = *request_buf; | |||
| 298 | ||||
| 299 | header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon, | |||
| 300 | wct /*wct */ ); | |||
| 301 | ||||
| 0 | 0 | - | 302 | if(tcon != NULL) |
| 303 | cifs_stats_inc(&tcon->num_smbs_sent); | |||
| 0 | 0 | - | 303 | do-while (0) |
| 304 | ||||
| 0 | - | 305 | return rc; | |
| 306 | } | |||
| 307 | ||||
| 0 | 0 | - | 308 | static int validate_t2(struct smb_t2_rsp * pSMB) |
| 309 | { | |||
| 310 | int rc = -EINVAL; | |||
| 311 | int total_size; | |||
| 312 | char * pBCC; | |||
| 313 | ||||
| 314 | /* check for plausible wct, bcc and t2 data and parm sizes */ | |||
| 315 | /* check for parm and data offset going beyond end of smb */ | |||
| 0 | 0 | - | 316 | if(pSMB->hdr.WordCount >= 10) { |
| 317 | if((le16_to_cpu(pSMB->t2_rsp.ParameterOffset) <= 1024) && | |||
| 0 | 0 | - | 318 | (le16_to_cpu(pSMB->t2_rsp.DataOffset) <= 1024)) { |
| 0 | - | 318 | (T) && (T) | |
| 0 | - | 318 | (T) && (F) | |
| 0 | - | 318 | (F) && (_) | |
| 319 | /* check that bcc is at least as big as parms + data */ | |||
| 320 | /* check that bcc is less than negotiated smb buffer */ | |||
| 321 | total_size = le16_to_cpu(pSMB->t2_rsp.ParameterCount); | |||
| 0 | 0 | - | 322 | if(total_size < 512) { |
| 323 | total_size+=le16_to_cpu(pSMB->t2_rsp.DataCount); | |||
| 324 | /* BCC le converted in SendReceive */ | |||
| 325 | pBCC = (pSMB->hdr.WordCount * 2) + | |||
| 326 | sizeof(struct smb_hdr) + | |||
| 327 | (char *)pSMB; | |||
| 328 | if((total_size <= (*(u16 *)pBCC)) && | |||
| 329 | (total_size < | |||
| 0 | 0 | - | 330 | CIFSMaxBufSize+MAX_CIFS_HDR_SIZE)) { |
| 0 | - | 330 | (T) && (T) | |
| 0 | - | 330 | (T) && (F) | |
| 0 | - | 330 | (F) && (_) | |
| 0 | - | 331 | return 0; | |
| 332 | } | |||
| 333 | ||||
| 334 | } | |||
| 335 | } | |||
| 336 | } | |||
| 337 | cifs_dump_mem("Invalid transact2 SMB: ",(char *)pSMB, | |||
| 338 | sizeof(struct smb_t2_rsp) + 16); | |||
| 0 | - | 339 | return rc; | |
| 340 | } | |||
| 341 | int | |||
| 0 | 0 | - | 342 | CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) |
| 343 | { | |||
| 344 | NEGOTIATE_REQ *pSMB; | |||
| 345 | NEGOTIATE_RSP *pSMBr; | |||
| 346 | int rc = 0; | |||
| 347 | int bytes_returned; | |||
| 348 | struct TCP_Server_Info * server; | |||
| 349 | u16 count; | |||
| 350 | ||||
| 0 | 0 | - | 351 | if(ses->server) |
| 352 | server = ses->server; | |||
| 353 | else { | |||
| 354 | rc = -EIO; | |||
| 0 | - | 355 | return rc; | |
| 356 | } | |||
| 357 | rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ , | |||
| 358 | (void **) &pSMB, (void **) &pSMBr); | |||
| 0 | 0 | - | 359 | if (rc) |
| 0 | - | 360 | return rc; | |
| 361 | pSMB->hdr.Mid = GetNextMid(server); | |||
| 362 | pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; | |||
| 0 | 0 | - | 363 | if (extended_security) |
| 364 | pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; | |||
| 365 | ||||
| 366 | count = strlen(protocols[0].name) + 1; | |||
| 367 | strncpy(pSMB->DialectsArray, protocols[0].name, 30); | |||
| 368 | /* null guaranteed to be at end of source and target buffers anyway */ | |||
| 369 | ||||
| 370 | pSMB->hdr.smb_buf_length += count; | |||
| 371 | pSMB->ByteCount = cpu_to_le16(count); | |||
| 372 | ||||
| 373 | rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, | |||
| 374 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | |||
| 0 | 0 | - | 375 | if (rc == 0) { |
| 376 | server->secMode = pSMBr->SecurityMode; | |||
| 0 | 0 | - | 377 | if((server->secMode & SECMODE_USER) == 0) |
| 0 | 0 | - | 378 | cFYI(1,("share mode security")); |
| 0 | 0 | - | 378 | if (cifsFYI & 0x01) |
| 379 | server->secType = NTLM; /* BB override default for | |||
| 380 | NTLMv2 or kerberos v5 */ | |||
| 381 | /* one byte - no need to convert this or EncryptionKeyLen | |||
| 382 | from little endian */ | |||
| 383 | server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount); | |||
| 384 | /* probably no need to store and check maxvcs */ | |||
| 385 | server->maxBuf = | |||
| 386 | min(le32_to_cpu(pSMBr->MaxBufferSize), | |||
| 387 | (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); | |||
| 388 | server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); | |||
| 0 | 0 | - | 389 | cFYI(0, ("Max buf = %d", ses->server->maxBuf)); |
| 0 | 0 | - | 389 | if (cifsFYI & 0x01) |
| 390 | GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); | |||
| 391 | server->capabilities = le32_to_cpu(pSMBr->Capabilities); | |||
| 392 | server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone); | |||
| 393 | /* BB with UTC do we ever need to be using srvr timezone? */ | |||
| 0 | 0 | - | 394 | if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { |
| 395 | memcpy(server->cryptKey, pSMBr->u.EncryptionKey, | |||
| 396 | CIFS_CRYPTO_KEY_SIZE); | |||
| 397 | } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) | |||
| 0 | 0 | - | 398 | && (pSMBr->EncryptionKeyLength == 0)) { |
| 0 | - | 398 | (T) && (T) | |
| 0 | - | 398 | (T) && (F) | |
| 0 | - | 398 | (F) && (_) | |
| 399 | /* decode security blob */ | |||
| 400 | } else | |||
| 401 | rc = -EIO; | |||
| 402 | ||||
| 403 | /* BB might be helpful to save off the domain of server here */ | |||
| 404 | ||||
| 405 | if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) && | |||
| 0 | 0 | - | 406 | (server->capabilities & CAP_EXTENDED_SECURITY)) { |
| 0 | - | 406 | (T) && (T) | |
| 0 | - | |||