1 /* 2 * fs/cifs/cifssmb.c 3 * 4 * Copyright (C) International Business Machines Corp., 2002,2010 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 differently for reconnection purposes since we never */ 28 /* want to reuse a stale file handle and only the caller knows the file info */ 29 30 #include <linux/fs.h> 31 #include <linux/kernel.h> 32 #include <linux/vfs.h> 33 #include <linux/slab.h> 34 #include <linux/posix_acl_xattr.h> 35 #include <linux/pagemap.h> 36 #include <linux/swap.h> 37 #include <linux/task_io_accounting_ops.h> 38 #include <linux/uaccess.h> 39 #include "cifspdu.h" 40 #include "cifsglob.h" 41 #include "cifsacl.h" 42 #include "cifsproto.h" 43 #include "cifs_unicode.h" 44 #include "cifs_debug.h" 45 #include "fscache.h" 46 #include "smbdirect.h" 47 48 #ifdef CONFIG_CIFS_POSIX 49 static struct { 50 int index; 51 char *name; 52 } protocols[] = { 53 #ifdef CONFIG_CIFS_WEAK_PW_HASH 54 {LANMAN_PROT, "\2LM1.2X002"}, 55 {LANMAN2_PROT, "\2LANMAN2.1"}, 56 #endif /* weak password hashing for legacy clients */ 57 {CIFS_PROT, "\2NT LM 0.12"}, 58 {POSIX_PROT, "\2POSIX 2"}, 59 {BAD_PROT, "\2"} 60 }; 61 #else 62 static struct { 63 int index; 64 char *name; 65 } protocols[] = { 66 #ifdef CONFIG_CIFS_WEAK_PW_HASH 67 {LANMAN_PROT, "\2LM1.2X002"}, 68 {LANMAN2_PROT, "\2LANMAN2.1"}, 69 #endif /* weak password hashing for legacy clients */ 70 {CIFS_PROT, "\2NT LM 0.12"}, 71 {BAD_PROT, "\2"} 72 }; 73 #endif 74 75 /* define the number of elements in the cifs dialect array */ 76 #ifdef CONFIG_CIFS_POSIX 77 #ifdef CONFIG_CIFS_WEAK_PW_HASH 78 #define CIFS_NUM_PROT 4 79 #else 80 #define CIFS_NUM_PROT 2 81 #endif /* CIFS_WEAK_PW_HASH */ 82 #else /* not posix */ 83 #ifdef CONFIG_CIFS_WEAK_PW_HASH 84 #define CIFS_NUM_PROT 3 85 #else 86 #define CIFS_NUM_PROT 1 87 #endif /* CONFIG_CIFS_WEAK_PW_HASH */ 88 #endif /* CIFS_POSIX */ 89 90 /* 91 * Mark as invalid, all open files on tree connections since they 92 * were closed when session to server was lost. 93 */ 94 void 95 cifs_mark_open_files_invalid(struct cifs_tcon *tcon) 96 { 97 struct cifsFileInfo *open_file = NULL; 98 struct list_head *tmp; 99 struct list_head *tmp1; 100 101 /* list all files open on tree connection and mark them invalid */ 102 spin_lock(&tcon->open_file_lock); 103 list_for_each_safe(tmp, tmp1, &tcon->openFileList) { 104 open_file = list_entry(tmp, struct cifsFileInfo, tlist); 105 open_file->invalidHandle = true; 106 open_file->oplock_break_cancelled = true; 107 } 108 spin_unlock(&tcon->open_file_lock); 109 /* 110 * BB Add call to invalidate_inodes(sb) for all superblocks mounted 111 * to this tcon. 112 */ 113 } 114 115 /* reconnect the socket, tcon, and smb session if needed */ 116 static int 117 cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) 118 { 119 int rc; 120 struct cifs_ses *ses; 121 struct TCP_Server_Info *server; 122 struct nls_table *nls_codepage; 123 124 /* 125 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for 126 * tcp and smb session status done differently for those three - in the 127 * calling routine 128 */ 129 if (!tcon) 130 return 0; 131 132 ses = tcon->ses; 133 server = ses->server; 134 135 /* 136 * only tree disconnect, open, and write, (and ulogoff which does not 137 * have tcon) are allowed as we start force umount 138 */ 139 if (tcon->tidStatus == CifsExiting) { 140 if (smb_command != SMB_COM_WRITE_ANDX && 141 smb_command != SMB_COM_OPEN_ANDX && 142 smb_command != SMB_COM_TREE_DISCONNECT) { 143 cifs_dbg(FYI, "can not send cmd %d while umounting\n", 144 smb_command); 145 return -ENODEV; 146 } 147 } 148 149 /* 150 * Give demultiplex thread up to 10 seconds to reconnect, should be 151 * greater than cifs socket timeout which is 7 seconds 152 */ 153 while (server->tcpStatus == CifsNeedReconnect) { 154 rc = wait_event_interruptible_timeout(server->response_q, 155 (server->tcpStatus != CifsNeedReconnect), 156 10 * HZ); 157 if (rc < 0) { 158 cifs_dbg(FYI, "%s: aborting reconnect due to a received" 159 " signal by the process\n", __func__); 160 return -ERESTARTSYS; 161 } 162 163 /* are we still trying to reconnect? */ 164 if (server->tcpStatus != CifsNeedReconnect) 165 break; 166 167 /* 168 * on "soft" mounts we wait once. Hard mounts keep 169 * retrying until process is killed or server comes 170 * back on-line 171 */ 172 if (!tcon->retry) { 173 cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n"); 174 return -EHOSTDOWN; 175 } 176 } 177 178 if (!ses->need_reconnect && !tcon->need_reconnect) 179 return 0; 180 181 nls_codepage = load_nls_default(); 182 183 /* 184 * need to prevent multiple threads trying to simultaneously 185 * reconnect the same SMB session 186 */ 187 mutex_lock(&ses->session_mutex); 188 189 /* 190 * Recheck after acquire mutex. If another thread is negotiating 191 * and the server never sends an answer the socket will be closed 192 * and tcpStatus set to reconnect. 193 */ 194 if (server->tcpStatus == CifsNeedReconnect) { 195 rc = -EHOSTDOWN; 196 mutex_unlock(&ses->session_mutex); 197 goto out; 198 } 199 200 rc = cifs_negotiate_protocol(0, ses); 201 if (rc == 0 && ses->need_reconnect) 202 rc = cifs_setup_session(0, ses, nls_codepage); 203 204 /* do we need to reconnect tcon? */ 205 if (rc || !tcon->need_reconnect) { 206 mutex_unlock(&ses->session_mutex); 207 goto out; 208 } 209 210 cifs_mark_open_files_invalid(tcon); 211 rc = CIFSTCon(0, ses, tcon->treeName, tcon, nls_codepage); 212 mutex_unlock(&ses->session_mutex); 213 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc); 214 215 if (rc) { 216 printk_once(KERN_WARNING "reconnect tcon failed rc = %d\n", rc); 217 goto out; 218 } 219 220 atomic_inc(&tconInfoReconnectCount); 221 222 /* tell server Unix caps we support */ 223 if (ses->capabilities & CAP_UNIX) 224 reset_cifs_unix_caps(0, tcon, NULL, NULL); 225 226 /* 227 * Removed call to reopen open files here. It is safer (and faster) to 228 * reopen files one at a time as needed in read and write. 229 * 230 * FIXME: what about file locks? don't we need to reclaim them ASAP? 231 */ 232 233 out: 234 /* 235 * Check if handle based operation so we know whether we can continue 236 * or not without returning to caller to reset file handle 237 */ 238 switch (smb_command) { 239 case SMB_COM_READ_ANDX: 240 case SMB_COM_WRITE_ANDX: 241 case SMB_COM_CLOSE: 242 case SMB_COM_FIND_CLOSE2: 243 case SMB_COM_LOCKING_ANDX: 244 rc = -EAGAIN; 245 } 246 247 unload_nls(nls_codepage); 248 return rc; 249 } 250 251 /* Allocate and return pointer to an SMB request buffer, and set basic 252 SMB information in the SMB header. If the return code is zero, this 253 function must have filled in request_buf pointer */ 254 static int 255 small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon, 256 void **request_buf) 257 { 258 int rc; 259 260 rc = cifs_reconnect_tcon(tcon, smb_command); 261 if (rc) 262 return rc; 263 264 *request_buf = cifs_small_buf_get(); 265 if (*request_buf == NULL) { 266 /* BB should we add a retry in here if not a writepage? */ 267 return -ENOMEM; 268 } 269 270 header_assemble((struct smb_hdr *) *request_buf, smb_command, 271 tcon, wct); 272 273 if (tcon != NULL) 274 cifs_stats_inc(&tcon->num_smbs_sent); 275 276 return 0; 277 } 278 279 int 280 small_smb_init_no_tc(const int smb_command, const int wct, 281 struct cifs_ses *ses, void **request_buf) 282 { 283 int rc; 284 struct smb_hdr *buffer; 285 286 rc = small_smb_init(smb_command, wct, NULL, request_buf); 287 if (rc) 288 return rc; 289 290 buffer = (struct smb_hdr *)*request_buf; 291 buffer->Mid = get_next_mid(ses->server); 292 if (ses->capabilities & CAP_UNICODE) 293 buffer->Flags2 |= SMBFLG2_UNICODE; 294 if (ses->capabilities & CAP_STATUS32) 295 buffer->Flags2 |= SMBFLG2_ERR_STATUS; 296 297 /* uid, tid can stay at zero as set in header assemble */ 298 299 /* BB add support for turning on the signing when 300 this function is used after 1st of session setup requests */ 301 302 return rc; 303 } 304 305 /* If the return code is zero, this function must fill in request_buf pointer */ 306 static int 307 __smb_init(int smb_command, int wct, struct cifs_tcon *tcon, 308 void **request_buf, void **response_buf) 309 { 310 *request_buf = cifs_buf_get(); 311 if (*request_buf == NULL) { 312 /* BB should we add a retry in here if not a writepage? */ 313 return -ENOMEM; 314 } 315 /* Although the original thought was we needed the response buf for */ 316 /* potential retries of smb operations it turns out we can determine */ 317 /* from the mid flags when the request buffer can be resent without */ 318 /* having to use a second distinct buffer for the response */ 319 if (response_buf) 320 *response_buf = *request_buf; 321 322 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon, 323 wct); 324 325 if (tcon != NULL) 326 cifs_stats_inc(&tcon->num_smbs_sent); 327 328 return 0; 329 } 330 331 /* If the return code is zero, this function must fill in request_buf pointer */ 332 static int 333 smb_init(int smb_command, int wct, struct cifs_tcon *tcon, 334 void **request_buf, void **response_buf) 335 { 336 int rc; 337 338 rc = cifs_reconnect_tcon(tcon, smb_command); 339 if (rc) 340 return rc; 341 342 return __smb_init(smb_command, wct, tcon, request_buf, response_buf); 343 } 344 345 static int 346 smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon, 347 void **request_buf, void **response_buf) 348 { 349 if (tcon->ses->need_reconnect || tcon->need_reconnect) 350 return -EHOSTDOWN; 351 352 return __smb_init(smb_command, wct, tcon, request_buf, response_buf); 353 } 354 355 static int validate_t2(struct smb_t2_rsp *pSMB) 356 { 357 unsigned int total_size; 358 359 /* check for plausible wct */ 360 if (pSMB->hdr.WordCount < 10) 361 goto vt2_err; 362 363 /* check for parm and data offset going beyond end of smb */ 364 if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 || 365 get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024) 366 goto vt2_err; 367 368 total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount); 369 if (total_size >= 512) 370 goto vt2_err; 371 372 /* check that bcc is at least as big as parms + data, and that it is 373 * less than negotiated smb buffer 374 */ 375 total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount); 376 if (total_size > get_bcc(&pSMB->hdr) || 377 total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) 378 goto vt2_err; 379 380 return 0; 381 vt2_err: 382 cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB, 383 sizeof(struct smb_t2_rsp) + 16); 384 return -EINVAL; 385 } 386 387 static int 388 decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr) 389 { 390 int rc = 0; 391 u16 count; 392 char *guid = pSMBr->u.extended_response.GUID; 393 struct TCP_Server_Info *server = ses->server; 394 395 count = get_bcc(&pSMBr->hdr); 396 if (count < SMB1_CLIENT_GUID_SIZE) 397 return -EIO; 398 399 spin_lock(&cifs_tcp_ses_lock); 400 if (server->srv_count > 1) { 401 spin_unlock(&cifs_tcp_ses_lock); 402 if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) { 403 cifs_dbg(FYI, "server UID changed\n"); 404 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE); 405 } 406 } else { 407 spin_unlock(&cifs_tcp_ses_lock); 408 memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE); 409 } 410 411 if (count == SMB1_CLIENT_GUID_SIZE) { 412 server->sec_ntlmssp = true; 413 } else { 414 count -= SMB1_CLIENT_GUID_SIZE; 415 rc = decode_negTokenInit( 416 pSMBr->u.extended_response.SecurityBlob, count, server); 417 if (rc != 1) 418 return -EINVAL; 419 } 420 421 return 0; 422 } 423 424 int 425 cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required) 426 { 427 bool srv_sign_required = server->sec_mode & server->vals->signing_required; 428 bool srv_sign_enabled = server->sec_mode & server->vals->signing_enabled; 429 bool mnt_sign_enabled = global_secflags & CIFSSEC_MAY_SIGN; 430 431 /* 432 * Is signing required by mnt options? If not then check 433 * global_secflags to see if it is there. 434 */ 435 if (!mnt_sign_required) 436 mnt_sign_required = ((global_secflags & CIFSSEC_MUST_SIGN) == 437 CIFSSEC_MUST_SIGN); 438 439 /* 440 * If signing is required then it's automatically enabled too, 441 * otherwise, check to see if the secflags allow it. 442 */ 443 mnt_sign_enabled = mnt_sign_required ? mnt_sign_required : 444 (global_secflags & CIFSSEC_MAY_SIGN); 445 446 /* If server requires signing, does client allow it? */ 447 if (srv_sign_required) { 448 if (!mnt_sign_enabled) { 449 cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!"); 450 return -ENOTSUPP; 451 } 452 server->sign = true; 453 } 454 455 /* If client requires signing, does server allow it? */ 456 if (mnt_sign_required) { 457 if (!srv_sign_enabled) { 458 cifs_dbg(VFS, "Server does not support signing!"); 459 return -ENOTSUPP; 460 } 461 server->sign = true; 462 } 463 464 if (cifs_rdma_enabled(server) && server->sign) 465 cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled"); 466 467 return 0; 468 } 469 470 #ifdef CONFIG_CIFS_WEAK_PW_HASH 471 static int 472 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr) 473 { 474 __s16 tmp; 475 struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr; 476 477 if (server->dialect != LANMAN_PROT && server->dialect != LANMAN2_PROT) 478 return -EOPNOTSUPP; 479 480 server->sec_mode = le16_to_cpu(rsp->SecurityMode); 481 server->maxReq = min_t(unsigned int, 482 le16_to_cpu(rsp->MaxMpxCount), 483 cifs_max_pending); 484 set_credits(server, server->maxReq); 485 server->maxBuf = le16_to_cpu(rsp->MaxBufSize); 486 /* even though we do not use raw we might as well set this 487 accurately, in case we ever find a need for it */ 488 if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) { 489 server->max_rw = 0xFF00; 490 server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE; 491 } else { 492 server->max_rw = 0;/* do not need to use raw anyway */ 493 server->capabilities = CAP_MPX_MODE; 494 } 495 tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone); 496 if (tmp == -1) { 497 /* OS/2 often does not set timezone therefore 498 * we must use server time to calc time zone. 499 * Could deviate slightly from the right zone. 500 * Smallest defined timezone difference is 15 minutes 501 * (i.e. Nepal). Rounding up/down is done to match 502 * this requirement. 503 */ 504 int val, seconds, remain, result; 505 struct timespec ts; 506 unsigned long utc = ktime_get_real_seconds(); 507 ts = cnvrtDosUnixTm(rsp->SrvTime.Date, 508 rsp->SrvTime.Time, 0); 509 cifs_dbg(FYI, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n", 510 (int)ts.tv_sec, (int)utc, 511 (int)(utc - ts.tv_sec)); 512 val = (int)(utc - ts.tv_sec); 513 seconds = abs(val); 514 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ; 515 remain = seconds % MIN_TZ_ADJ; 516 if (remain >= (MIN_TZ_ADJ / 2)) 517 result += MIN_TZ_ADJ; 518 if (val < 0) 519 result = -result; 520 server->timeAdj = result; 521 } else { 522 server->timeAdj = (int)tmp; 523 server->timeAdj *= 60; /* also in seconds */ 524 } 525 cifs_dbg(FYI, "server->timeAdj: %d seconds\n", server->timeAdj); 526 527 528 /* BB get server time for time conversions and add 529 code to use it and timezone since this is not UTC */ 530 531 if (rsp->EncryptionKeyLength == 532 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) { 533 memcpy(server->cryptkey, rsp->EncryptionKey, 534 CIFS_CRYPTO_KEY_SIZE); 535 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) { 536 return -EIO; /* need cryptkey unless plain text */ 537 } 538 539 cifs_dbg(FYI, "LANMAN negotiated\n"); 540 return 0; 541 } 542 #else 543 static inline int 544 decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr) 545 { 546 cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n"); 547 return -EOPNOTSUPP; 548 } 549 #endif 550 551 static bool 552 should_set_ext_sec_flag(enum securityEnum sectype) 553 { 554 switch (sectype) { 555 case RawNTLMSSP: 556 case Kerberos: 557 return true; 558 case Unspecified: 559 if (global_secflags & 560 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP)) 561 return true; 562 /* Fallthrough */ 563 default: 564 return false; 565 } 566 } 567 568 int 569 CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses) 570 { 571 NEGOTIATE_REQ *pSMB; 572 NEGOTIATE_RSP *pSMBr; 573 int rc = 0; 574 int bytes_returned; 575 int i; 576 struct TCP_Server_Info *server = ses->server; 577 u16 count; 578 579 if (!server) { 580 WARN(1, "%s: server is NULL!\n", __func__); 581 return -EIO; 582 } 583 584 rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ , 585 (void **) &pSMB, (void **) &pSMBr); 586 if (rc) 587 return rc; 588 589 pSMB->hdr.Mid = get_next_mid(server); 590 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS); 591 592 if (should_set_ext_sec_flag(ses->sectype)) { 593 cifs_dbg(FYI, "Requesting extended security."); 594 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 595 } 596 597 count = 0; 598 for (i = 0; i < CIFS_NUM_PROT; i++) { 599 strncpy(pSMB->DialectsArray+count, protocols[i].name, 16); 600 count += strlen(protocols[i].name) + 1; 601 /* null at end of source and target buffers anyway */ 602 } 603 inc_rfc1001_len(pSMB, count); 604 pSMB->ByteCount = cpu_to_le16(count); 605 606 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 607 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 608 if (rc != 0) 609 goto neg_err_exit; 610 611 server->dialect = le16_to_cpu(pSMBr->DialectIndex); 612 cifs_dbg(FYI, "Dialect: %d\n", server->dialect); 613 /* Check wct = 1 error case */ 614 if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) { 615 /* core returns wct = 1, but we do not ask for core - otherwise 616 small wct just comes when dialect index is -1 indicating we 617 could not negotiate a common dialect */ 618 rc = -EOPNOTSUPP; 619 goto neg_err_exit; 620 } else if (pSMBr->hdr.WordCount == 13) { 621 server->negflavor = CIFS_NEGFLAVOR_LANMAN; 622 rc = decode_lanman_negprot_rsp(server, pSMBr); 623 goto signing_check; 624 } else if (pSMBr->hdr.WordCount != 17) { 625 /* unknown wct */ 626 rc = -EOPNOTSUPP; 627 goto neg_err_exit; 628 } 629 /* else wct == 17, NTLM or better */ 630 631 server->sec_mode = pSMBr->SecurityMode; 632 if ((server->sec_mode & SECMODE_USER) == 0) 633 cifs_dbg(FYI, "share mode security\n"); 634 635 /* one byte, so no need to convert this or EncryptionKeyLen from 636 little endian */ 637 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount), 638 cifs_max_pending); 639 set_credits(server, server->maxReq); 640 /* probably no need to store and check maxvcs */ 641 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize); 642 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize); 643 cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf); 644 server->capabilities = le32_to_cpu(pSMBr->Capabilities); 645 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone); 646 server->timeAdj *= 60; 647 648 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { 649 server->negflavor = CIFS_NEGFLAVOR_UNENCAP; 650 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey, 651 CIFS_CRYPTO_KEY_SIZE); 652 } else if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC || 653 server->capabilities & CAP_EXTENDED_SECURITY) { 654 server->negflavor = CIFS_NEGFLAVOR_EXTENDED; 655 rc = decode_ext_sec_blob(ses, pSMBr); 656 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) { 657 rc = -EIO; /* no crypt key only if plain text pwd */ 658 } else { 659 server->negflavor = CIFS_NEGFLAVOR_UNENCAP; 660 server->capabilities &= ~CAP_EXTENDED_SECURITY; 661 } 662 663 signing_check: 664 if (!rc) 665 rc = cifs_enable_signing(server, ses->sign); 666 neg_err_exit: 667 cifs_buf_release(pSMB); 668 669 cifs_dbg(FYI, "negprot rc %d\n", rc); 670 return rc; 671 } 672 673 int 674 CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon) 675 { 676 struct smb_hdr *smb_buffer; 677 int rc = 0; 678 679 cifs_dbg(FYI, "In tree disconnect\n"); 680 681 /* BB: do we need to check this? These should never be NULL. */ 682 if ((tcon->ses == NULL) || (tcon->ses->server == NULL)) 683 return -EIO; 684 685 /* 686 * No need to return error on this operation if tid invalidated and 687 * closed on server already e.g. due to tcp session crashing. Also, 688 * the tcon is no longer on the list, so no need to take lock before 689 * checking this. 690 */ 691 if ((tcon->need_reconnect) || (tcon->ses->need_reconnect)) 692 return 0; 693 694 rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, 695 (void **)&smb_buffer); 696 if (rc) 697 return rc; 698 699 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0); 700 cifs_small_buf_release(smb_buffer); 701 if (rc) 702 cifs_dbg(FYI, "Tree disconnect failed %d\n", rc); 703 704 /* No need to return error on this operation if tid invalidated and 705 closed on server already e.g. due to tcp session crashing */ 706 if (rc == -EAGAIN) 707 rc = 0; 708 709 return rc; 710 } 711 712 /* 713 * This is a no-op for now. We're not really interested in the reply, but 714 * rather in the fact that the server sent one and that server->lstrp 715 * gets updated. 716 * 717 * FIXME: maybe we should consider checking that the reply matches request? 718 */ 719 static void 720 cifs_echo_callback(struct mid_q_entry *mid) 721 { 722 struct TCP_Server_Info *server = mid->callback_data; 723 724 DeleteMidQEntry(mid); 725 add_credits(server, 1, CIFS_ECHO_OP); 726 } 727 728 int 729 CIFSSMBEcho(struct TCP_Server_Info *server) 730 { 731 ECHO_REQ *smb; 732 int rc = 0; 733 struct kvec iov[2]; 734 struct smb_rqst rqst = { .rq_iov = iov, 735 .rq_nvec = 2 }; 736 737 cifs_dbg(FYI, "In echo request\n"); 738 739 rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb); 740 if (rc) 741 return rc; 742 743 if (server->capabilities & CAP_UNICODE) 744 smb->hdr.Flags2 |= SMBFLG2_UNICODE; 745 746 /* set up echo request */ 747 smb->hdr.Tid = 0xffff; 748 smb->hdr.WordCount = 1; 749 put_unaligned_le16(1, &smb->EchoCount); 750 put_bcc(1, &smb->hdr); 751 smb->Data[0] = 'a'; 752 inc_rfc1001_len(smb, 3); 753 754 iov[0].iov_len = 4; 755 iov[0].iov_base = smb; 756 iov[1].iov_len = get_rfc1002_length(smb); 757 iov[1].iov_base = (char *)smb + 4; 758 759 rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL, 760 server, CIFS_ASYNC_OP | CIFS_ECHO_OP); 761 if (rc) 762 cifs_dbg(FYI, "Echo request failed: %d\n", rc); 763 764 cifs_small_buf_release(smb); 765 766 return rc; 767 } 768 769 int 770 CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses) 771 { 772 LOGOFF_ANDX_REQ *pSMB; 773 int rc = 0; 774 775 cifs_dbg(FYI, "In SMBLogoff for session disconnect\n"); 776 777 /* 778 * BB: do we need to check validity of ses and server? They should 779 * always be valid since we have an active reference. If not, that 780 * should probably be a BUG() 781 */ 782 if (!ses || !ses->server) 783 return -EIO; 784 785 mutex_lock(&ses->session_mutex); 786 if (ses->need_reconnect) 787 goto session_already_dead; /* no need to send SMBlogoff if uid 788 already closed due to reconnect */ 789 rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB); 790 if (rc) { 791 mutex_unlock(&ses->session_mutex); 792 return rc; 793 } 794 795 pSMB->hdr.Mid = get_next_mid(ses->server); 796 797 if (ses->server->sign) 798 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 799 800 pSMB->hdr.Uid = ses->Suid; 801 802 pSMB->AndXCommand = 0xFF; 803 rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0); 804 cifs_small_buf_release(pSMB); 805 session_already_dead: 806 mutex_unlock(&ses->session_mutex); 807 808 /* if session dead then we do not need to do ulogoff, 809 since server closed smb session, no sense reporting 810 error */ 811 if (rc == -EAGAIN) 812 rc = 0; 813 return rc; 814 } 815 816 int 817 CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon, 818 const char *fileName, __u16 type, 819 const struct nls_table *nls_codepage, int remap) 820 { 821 TRANSACTION2_SPI_REQ *pSMB = NULL; 822 TRANSACTION2_SPI_RSP *pSMBr = NULL; 823 struct unlink_psx_rq *pRqD; 824 int name_len; 825 int rc = 0; 826 int bytes_returned = 0; 827 __u16 params, param_offset, offset, byte_count; 828 829 cifs_dbg(FYI, "In POSIX delete\n"); 830 PsxDelete: 831 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 832 (void **) &pSMBr); 833 if (rc) 834 return rc; 835 836 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 837 name_len = 838 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 839 PATH_MAX, nls_codepage, remap); 840 name_len++; /* trailing null */ 841 name_len *= 2; 842 } else { /* BB add path length overrun check */ 843 name_len = strnlen(fileName, PATH_MAX); 844 name_len++; /* trailing null */ 845 strncpy(pSMB->FileName, fileName, name_len); 846 } 847 848 params = 6 + name_len; 849 pSMB->MaxParameterCount = cpu_to_le16(2); 850 pSMB->MaxDataCount = 0; /* BB double check this with jra */ 851 pSMB->MaxSetupCount = 0; 852 pSMB->Reserved = 0; 853 pSMB->Flags = 0; 854 pSMB->Timeout = 0; 855 pSMB->Reserved2 = 0; 856 param_offset = offsetof(struct smb_com_transaction2_spi_req, 857 InformationLevel) - 4; 858 offset = param_offset + params; 859 860 /* Setup pointer to Request Data (inode type) */ 861 pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset); 862 pRqD->type = cpu_to_le16(type); 863 pSMB->ParameterOffset = cpu_to_le16(param_offset); 864 pSMB->DataOffset = cpu_to_le16(offset); 865 pSMB->SetupCount = 1; 866 pSMB->Reserved3 = 0; 867 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 868 byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq); 869 870 pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq)); 871 pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq)); 872 pSMB->ParameterCount = cpu_to_le16(params); 873 pSMB->TotalParameterCount = pSMB->ParameterCount; 874 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK); 875 pSMB->Reserved4 = 0; 876 inc_rfc1001_len(pSMB, byte_count); 877 pSMB->ByteCount = cpu_to_le16(byte_count); 878 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 879 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 880 if (rc) 881 cifs_dbg(FYI, "Posix delete returned %d\n", rc); 882 cifs_buf_release(pSMB); 883 884 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes); 885 886 if (rc == -EAGAIN) 887 goto PsxDelete; 888 889 return rc; 890 } 891 892 int 893 CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name, 894 struct cifs_sb_info *cifs_sb) 895 { 896 DELETE_FILE_REQ *pSMB = NULL; 897 DELETE_FILE_RSP *pSMBr = NULL; 898 int rc = 0; 899 int bytes_returned; 900 int name_len; 901 int remap = cifs_remap(cifs_sb); 902 903 DelFileRetry: 904 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB, 905 (void **) &pSMBr); 906 if (rc) 907 return rc; 908 909 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 910 name_len = cifsConvertToUTF16((__le16 *) pSMB->fileName, name, 911 PATH_MAX, cifs_sb->local_nls, 912 remap); 913 name_len++; /* trailing null */ 914 name_len *= 2; 915 } else { /* BB improve check for buffer overruns BB */ 916 name_len = strnlen(name, PATH_MAX); 917 name_len++; /* trailing null */ 918 strncpy(pSMB->fileName, name, name_len); 919 } 920 pSMB->SearchAttributes = 921 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM); 922 pSMB->BufferFormat = 0x04; 923 inc_rfc1001_len(pSMB, name_len + 1); 924 pSMB->ByteCount = cpu_to_le16(name_len + 1); 925 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 926 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 927 cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes); 928 if (rc) 929 cifs_dbg(FYI, "Error in RMFile = %d\n", rc); 930 931 cifs_buf_release(pSMB); 932 if (rc == -EAGAIN) 933 goto DelFileRetry; 934 935 return rc; 936 } 937 938 int 939 CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, 940 struct cifs_sb_info *cifs_sb) 941 { 942 DELETE_DIRECTORY_REQ *pSMB = NULL; 943 DELETE_DIRECTORY_RSP *pSMBr = NULL; 944 int rc = 0; 945 int bytes_returned; 946 int name_len; 947 int remap = cifs_remap(cifs_sb); 948 949 cifs_dbg(FYI, "In CIFSSMBRmDir\n"); 950 RmDirRetry: 951 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB, 952 (void **) &pSMBr); 953 if (rc) 954 return rc; 955 956 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 957 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name, 958 PATH_MAX, cifs_sb->local_nls, 959 remap); 960 name_len++; /* trailing null */ 961 name_len *= 2; 962 } else { /* BB improve check for buffer overruns BB */ 963 name_len = strnlen(name, PATH_MAX); 964 name_len++; /* trailing null */ 965 strncpy(pSMB->DirName, name, name_len); 966 } 967 968 pSMB->BufferFormat = 0x04; 969 inc_rfc1001_len(pSMB, name_len + 1); 970 pSMB->ByteCount = cpu_to_le16(name_len + 1); 971 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 972 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 973 cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs); 974 if (rc) 975 cifs_dbg(FYI, "Error in RMDir = %d\n", rc); 976 977 cifs_buf_release(pSMB); 978 if (rc == -EAGAIN) 979 goto RmDirRetry; 980 return rc; 981 } 982 983 int 984 CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, 985 struct cifs_sb_info *cifs_sb) 986 { 987 int rc = 0; 988 CREATE_DIRECTORY_REQ *pSMB = NULL; 989 CREATE_DIRECTORY_RSP *pSMBr = NULL; 990 int bytes_returned; 991 int name_len; 992 int remap = cifs_remap(cifs_sb); 993 994 cifs_dbg(FYI, "In CIFSSMBMkDir\n"); 995 MkDirRetry: 996 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB, 997 (void **) &pSMBr); 998 if (rc) 999 return rc; 1000 1001 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1002 name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name, 1003 PATH_MAX, cifs_sb->local_nls, 1004 remap); 1005 name_len++; /* trailing null */ 1006 name_len *= 2; 1007 } else { /* BB improve check for buffer overruns BB */ 1008 name_len = strnlen(name, PATH_MAX); 1009 name_len++; /* trailing null */ 1010 strncpy(pSMB->DirName, name, name_len); 1011 } 1012 1013 pSMB->BufferFormat = 0x04; 1014 inc_rfc1001_len(pSMB, name_len + 1); 1015 pSMB->ByteCount = cpu_to_le16(name_len + 1); 1016 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1017 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1018 cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs); 1019 if (rc) 1020 cifs_dbg(FYI, "Error in Mkdir = %d\n", rc); 1021 1022 cifs_buf_release(pSMB); 1023 if (rc == -EAGAIN) 1024 goto MkDirRetry; 1025 return rc; 1026 } 1027 1028 int 1029 CIFSPOSIXCreate(const unsigned int xid, struct cifs_tcon *tcon, 1030 __u32 posix_flags, __u64 mode, __u16 *netfid, 1031 FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock, 1032 const char *name, const struct nls_table *nls_codepage, 1033 int remap) 1034 { 1035 TRANSACTION2_SPI_REQ *pSMB = NULL; 1036 TRANSACTION2_SPI_RSP *pSMBr = NULL; 1037 int name_len; 1038 int rc = 0; 1039 int bytes_returned = 0; 1040 __u16 params, param_offset, offset, byte_count, count; 1041 OPEN_PSX_REQ *pdata; 1042 OPEN_PSX_RSP *psx_rsp; 1043 1044 cifs_dbg(FYI, "In POSIX Create\n"); 1045 PsxCreat: 1046 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 1047 (void **) &pSMBr); 1048 if (rc) 1049 return rc; 1050 1051 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1052 name_len = 1053 cifsConvertToUTF16((__le16 *) pSMB->FileName, name, 1054 PATH_MAX, nls_codepage, remap); 1055 name_len++; /* trailing null */ 1056 name_len *= 2; 1057 } else { /* BB improve the check for buffer overruns BB */ 1058 name_len = strnlen(name, PATH_MAX); 1059 name_len++; /* trailing null */ 1060 strncpy(pSMB->FileName, name, name_len); 1061 } 1062 1063 params = 6 + name_len; 1064 count = sizeof(OPEN_PSX_REQ); 1065 pSMB->MaxParameterCount = cpu_to_le16(2); 1066 pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */ 1067 pSMB->MaxSetupCount = 0; 1068 pSMB->Reserved = 0; 1069 pSMB->Flags = 0; 1070 pSMB->Timeout = 0; 1071 pSMB->Reserved2 = 0; 1072 param_offset = offsetof(struct smb_com_transaction2_spi_req, 1073 InformationLevel) - 4; 1074 offset = param_offset + params; 1075 pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset); 1076 pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); 1077 pdata->Permissions = cpu_to_le64(mode); 1078 pdata->PosixOpenFlags = cpu_to_le32(posix_flags); 1079 pdata->OpenFlags = cpu_to_le32(*pOplock); 1080 pSMB->ParameterOffset = cpu_to_le16(param_offset); 1081 pSMB->DataOffset = cpu_to_le16(offset); 1082 pSMB->SetupCount = 1; 1083 pSMB->Reserved3 = 0; 1084 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 1085 byte_count = 3 /* pad */ + params + count; 1086 1087 pSMB->DataCount = cpu_to_le16(count); 1088 pSMB->ParameterCount = cpu_to_le16(params); 1089 pSMB->TotalDataCount = pSMB->DataCount; 1090 pSMB->TotalParameterCount = pSMB->ParameterCount; 1091 pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN); 1092 pSMB->Reserved4 = 0; 1093 inc_rfc1001_len(pSMB, byte_count); 1094 pSMB->ByteCount = cpu_to_le16(byte_count); 1095 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1096 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1097 if (rc) { 1098 cifs_dbg(FYI, "Posix create returned %d\n", rc); 1099 goto psx_create_err; 1100 } 1101 1102 cifs_dbg(FYI, "copying inode info\n"); 1103 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 1104 1105 if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) { 1106 rc = -EIO; /* bad smb */ 1107 goto psx_create_err; 1108 } 1109 1110 /* copy return information to pRetData */ 1111 psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol 1112 + le16_to_cpu(pSMBr->t2.DataOffset)); 1113 1114 *pOplock = le16_to_cpu(psx_rsp->OplockFlags); 1115 if (netfid) 1116 *netfid = psx_rsp->Fid; /* cifs fid stays in le */ 1117 /* Let caller know file was created so we can set the mode. */ 1118 /* Do we care about the CreateAction in any other cases? */ 1119 if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction) 1120 *pOplock |= CIFS_CREATE_ACTION; 1121 /* check to make sure response data is there */ 1122 if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) { 1123 pRetData->Type = cpu_to_le32(-1); /* unknown */ 1124 cifs_dbg(NOISY, "unknown type\n"); 1125 } else { 1126 if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP) 1127 + sizeof(FILE_UNIX_BASIC_INFO)) { 1128 cifs_dbg(VFS, "Open response data too small\n"); 1129 pRetData->Type = cpu_to_le32(-1); 1130 goto psx_create_err; 1131 } 1132 memcpy((char *) pRetData, 1133 (char *)psx_rsp + sizeof(OPEN_PSX_RSP), 1134 sizeof(FILE_UNIX_BASIC_INFO)); 1135 } 1136 1137 psx_create_err: 1138 cifs_buf_release(pSMB); 1139 1140 if (posix_flags & SMB_O_DIRECTORY) 1141 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs); 1142 else 1143 cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens); 1144 1145 if (rc == -EAGAIN) 1146 goto PsxCreat; 1147 1148 return rc; 1149 } 1150 1151 static __u16 convert_disposition(int disposition) 1152 { 1153 __u16 ofun = 0; 1154 1155 switch (disposition) { 1156 case FILE_SUPERSEDE: 1157 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC; 1158 break; 1159 case FILE_OPEN: 1160 ofun = SMBOPEN_OAPPEND; 1161 break; 1162 case FILE_CREATE: 1163 ofun = SMBOPEN_OCREATE; 1164 break; 1165 case FILE_OPEN_IF: 1166 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND; 1167 break; 1168 case FILE_OVERWRITE: 1169 ofun = SMBOPEN_OTRUNC; 1170 break; 1171 case FILE_OVERWRITE_IF: 1172 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC; 1173 break; 1174 default: 1175 cifs_dbg(FYI, "unknown disposition %d\n", disposition); 1176 ofun = SMBOPEN_OAPPEND; /* regular open */ 1177 } 1178 return ofun; 1179 } 1180 1181 static int 1182 access_flags_to_smbopen_mode(const int access_flags) 1183 { 1184 int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE); 1185 1186 if (masked_flags == GENERIC_READ) 1187 return SMBOPEN_READ; 1188 else if (masked_flags == GENERIC_WRITE) 1189 return SMBOPEN_WRITE; 1190 1191 /* just go for read/write */ 1192 return SMBOPEN_READWRITE; 1193 } 1194 1195 int 1196 SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon, 1197 const char *fileName, const int openDisposition, 1198 const int access_flags, const int create_options, __u16 *netfid, 1199 int *pOplock, FILE_ALL_INFO *pfile_info, 1200 const struct nls_table *nls_codepage, int remap) 1201 { 1202 int rc = -EACCES; 1203 OPENX_REQ *pSMB = NULL; 1204 OPENX_RSP *pSMBr = NULL; 1205 int bytes_returned; 1206 int name_len; 1207 __u16 count; 1208 1209 OldOpenRetry: 1210 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB, 1211 (void **) &pSMBr); 1212 if (rc) 1213 return rc; 1214 1215 pSMB->AndXCommand = 0xFF; /* none */ 1216 1217 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 1218 count = 1; /* account for one byte pad to word boundary */ 1219 name_len = 1220 cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1), 1221 fileName, PATH_MAX, nls_codepage, remap); 1222 name_len++; /* trailing null */ 1223 name_len *= 2; 1224 } else { /* BB improve check for buffer overruns BB */ 1225 count = 0; /* no pad */ 1226 name_len = strnlen(fileName, PATH_MAX); 1227 name_len++; /* trailing null */ 1228 strncpy(pSMB->fileName, fileName, name_len); 1229 } 1230 if (*pOplock & REQ_OPLOCK) 1231 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK); 1232 else if (*pOplock & REQ_BATCHOPLOCK) 1233 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK); 1234 1235 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO); 1236 pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags)); 1237 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */ 1238 /* set file as system file if special file such 1239 as fifo and server expecting SFU style and 1240 no Unix extensions */ 1241 1242 if (create_options & CREATE_OPTION_SPECIAL) 1243 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM); 1244 else /* BB FIXME BB */ 1245 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); 1246 1247 if (create_options & CREATE_OPTION_READONLY) 1248 pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY); 1249 1250 /* BB FIXME BB */ 1251 /* pSMB->CreateOptions = cpu_to_le32(create_options & 1252 CREATE_OPTIONS_MASK); */ 1253 /* BB FIXME END BB */ 1254 1255 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY); 1256 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition)); 1257 count += name_len; 1258 inc_rfc1001_len(pSMB, count); 1259 1260 pSMB->ByteCount = cpu_to_le16(count); 1261 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1262 (struct smb_hdr *)pSMBr, &bytes_returned, 0); 1263 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens); 1264 if (rc) { 1265 cifs_dbg(FYI, "Error in Open = %d\n", rc); 1266 } else { 1267 /* BB verify if wct == 15 */ 1268 1269 /* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/ 1270 1271 *netfid = pSMBr->Fid; /* cifs fid stays in le */ 1272 /* Let caller know file was created so we can set the mode. */ 1273 /* Do we care about the CreateAction in any other cases? */ 1274 /* BB FIXME BB */ 1275 /* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction) 1276 *pOplock |= CIFS_CREATE_ACTION; */ 1277 /* BB FIXME END */ 1278 1279 if (pfile_info) { 1280 pfile_info->CreationTime = 0; /* BB convert CreateTime*/ 1281 pfile_info->LastAccessTime = 0; /* BB fixme */ 1282 pfile_info->LastWriteTime = 0; /* BB fixme */ 1283 pfile_info->ChangeTime = 0; /* BB fixme */ 1284 pfile_info->Attributes = 1285 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes)); 1286 /* the file_info buf is endian converted by caller */ 1287 pfile_info->AllocationSize = 1288 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile)); 1289 pfile_info->EndOfFile = pfile_info->AllocationSize; 1290 pfile_info->NumberOfLinks = cpu_to_le32(1); 1291 pfile_info->DeletePending = 0; 1292 } 1293 } 1294 1295 cifs_buf_release(pSMB); 1296 if (rc == -EAGAIN) 1297 goto OldOpenRetry; 1298 return rc; 1299 } 1300 1301 int 1302 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock, 1303 FILE_ALL_INFO *buf) 1304 { 1305 int rc = -EACCES; 1306 OPEN_REQ *req = NULL; 1307 OPEN_RSP *rsp = NULL; 1308 int bytes_returned; 1309 int name_len; 1310 __u16 count; 1311 struct cifs_sb_info *cifs_sb = oparms->cifs_sb; 1312 struct cifs_tcon *tcon = oparms->tcon; 1313 int remap = cifs_remap(cifs_sb); 1314 const struct nls_table *nls = cifs_sb->local_nls; 1315 int create_options = oparms->create_options; 1316 int desired_access = oparms->desired_access; 1317 int disposition = oparms->disposition; 1318 const char *path = oparms->path; 1319 1320 openRetry: 1321 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **)&req, 1322 (void **)&rsp); 1323 if (rc) 1324 return rc; 1325 1326 /* no commands go after this */ 1327 req->AndXCommand = 0xFF; 1328 1329 if (req->hdr.Flags2 & SMBFLG2_UNICODE) { 1330 /* account for one byte pad to word boundary */ 1331 count = 1; 1332 name_len = cifsConvertToUTF16((__le16 *)(req->fileName + 1), 1333 path, PATH_MAX, nls, remap); 1334 /* trailing null */ 1335 name_len++; 1336 name_len *= 2; 1337 req->NameLength = cpu_to_le16(name_len); 1338 } else { 1339 /* BB improve check for buffer overruns BB */ 1340 /* no pad */ 1341 count = 0; 1342 name_len = strnlen(path, PATH_MAX); 1343 /* trailing null */ 1344 name_len++; 1345 req->NameLength = cpu_to_le16(name_len); 1346 strncpy(req->fileName, path, name_len); 1347 } 1348 1349 if (*oplock & REQ_OPLOCK) 1350 req->OpenFlags = cpu_to_le32(REQ_OPLOCK); 1351 else if (*oplock & REQ_BATCHOPLOCK) 1352 req->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK); 1353 1354 req->DesiredAccess = cpu_to_le32(desired_access); 1355 req->AllocationSize = 0; 1356 1357 /* 1358 * Set file as system file if special file such as fifo and server 1359 * expecting SFU style and no Unix extensions. 1360 */ 1361 if (create_options & CREATE_OPTION_SPECIAL) 1362 req->FileAttributes = cpu_to_le32(ATTR_SYSTEM); 1363 else 1364 req->FileAttributes = cpu_to_le32(ATTR_NORMAL); 1365 1366 /* 1367 * XP does not handle ATTR_POSIX_SEMANTICS but it helps speed up case 1368 * sensitive checks for other servers such as Samba. 1369 */ 1370 if (tcon->ses->capabilities & CAP_UNIX) 1371 req->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS); 1372 1373 if (create_options & CREATE_OPTION_READONLY) 1374 req->FileAttributes |= cpu_to_le32(ATTR_READONLY); 1375 1376 req->ShareAccess = cpu_to_le32(FILE_SHARE_ALL); 1377 req->CreateDisposition = cpu_to_le32(disposition); 1378 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); 1379 1380 /* BB Expirement with various impersonation levels and verify */ 1381 req->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION); 1382 req->SecurityFlags = SECURITY_CONTEXT_TRACKING|SECURITY_EFFECTIVE_ONLY; 1383 1384 count += name_len; 1385 inc_rfc1001_len(req, count); 1386 1387 req->ByteCount = cpu_to_le16(count); 1388 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)req, 1389 (struct smb_hdr *)rsp, &bytes_returned, 0); 1390 cifs_stats_inc(&tcon->stats.cifs_stats.num_opens); 1391 if (rc) { 1392 cifs_dbg(FYI, "Error in Open = %d\n", rc); 1393 cifs_buf_release(req); 1394 if (rc == -EAGAIN) 1395 goto openRetry; 1396 return rc; 1397 } 1398 1399 /* 1 byte no need to le_to_cpu */ 1400 *oplock = rsp->OplockLevel; 1401 /* cifs fid stays in le */ 1402 oparms->fid->netfid = rsp->Fid; 1403 1404 /* Let caller know file was created so we can set the mode. */ 1405 /* Do we care about the CreateAction in any other cases? */ 1406 if (cpu_to_le32(FILE_CREATE) == rsp->CreateAction) 1407 *oplock |= CIFS_CREATE_ACTION; 1408 1409 if (buf) { 1410 /* copy from CreationTime to Attributes */ 1411 memcpy((char *)buf, (char *)&rsp->CreationTime, 36); 1412 /* the file_info buf is endian converted by caller */ 1413 buf->AllocationSize = rsp->AllocationSize; 1414 buf->EndOfFile = rsp->EndOfFile; 1415 buf->NumberOfLinks = cpu_to_le32(1); 1416 buf->DeletePending = 0; 1417 } 1418 1419 cifs_buf_release(req); 1420 return rc; 1421 } 1422 1423 /* 1424 * Discard any remaining data in the current SMB. To do this, we borrow the 1425 * current bigbuf. 1426 */ 1427 int 1428 cifs_discard_remaining_data(struct TCP_Server_Info *server) 1429 { 1430 unsigned int rfclen = server->pdu_size; 1431 int remaining = rfclen + server->vals->header_preamble_size - 1432 server->total_read; 1433 1434 while (remaining > 0) { 1435 int length; 1436 1437 length = cifs_read_from_socket(server, server->bigbuf, 1438 min_t(unsigned int, remaining, 1439 CIFSMaxBufSize + MAX_HEADER_SIZE(server))); 1440 if (length < 0) 1441 return length; 1442 server->total_read += length; 1443 remaining -= length; 1444 } 1445 1446 return 0; 1447 } 1448 1449 static int 1450 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) 1451 { 1452 int length; 1453 struct cifs_readdata *rdata = mid->callback_data; 1454 1455 length = cifs_discard_remaining_data(server); 1456 dequeue_mid(mid, rdata->result); 1457 mid->resp_buf = server->smallbuf; 1458 server->smallbuf = NULL; 1459 return length; 1460 } 1461 1462 int 1463 cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) 1464 { 1465 int length, len; 1466 unsigned int data_offset, data_len; 1467 struct cifs_readdata *rdata = mid->callback_data; 1468 char *buf = server->smallbuf; 1469 unsigned int buflen = server->pdu_size + 1470 server->vals->header_preamble_size; 1471 bool use_rdma_mr = false; 1472 1473 cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n", 1474 __func__, mid->mid, rdata->offset, rdata->bytes); 1475 1476 /* 1477 * read the rest of READ_RSP header (sans Data array), or whatever we 1478 * can if there's not enough data. At this point, we've read down to 1479 * the Mid. 1480 */ 1481 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) - 1482 HEADER_SIZE(server) + 1; 1483 1484 length = cifs_read_from_socket(server, 1485 buf + HEADER_SIZE(server) - 1, len); 1486 if (length < 0) 1487 return length; 1488 server->total_read += length; 1489 1490 if (server->ops->is_session_expired && 1491 server->ops->is_session_expired(buf)) { 1492 cifs_reconnect(server); 1493 wake_up(&server->response_q); 1494 return -1; 1495 } 1496 1497 if (server->ops->is_status_pending && 1498 server->ops->is_status_pending(buf, server, 0)) { 1499 cifs_discard_remaining_data(server); 1500 return -1; 1501 } 1502 1503 /* Was the SMB read successful? */ 1504 rdata->result = server->ops->map_error(buf, false); 1505 if (rdata->result != 0) { 1506 cifs_dbg(FYI, "%s: server returned error %d\n", 1507 __func__, rdata->result); 1508 return cifs_readv_discard(server, mid); 1509 } 1510 1511 /* Is there enough to get to the rest of the READ_RSP header? */ 1512 if (server->total_read < server->vals->read_rsp_size) { 1513 cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n", 1514 __func__, server->total_read, 1515 server->vals->read_rsp_size); 1516 rdata->result = -EIO; 1517 return cifs_readv_discard(server, mid); 1518 } 1519 1520 data_offset = server->ops->read_data_offset(buf) + 1521 server->vals->header_preamble_size; 1522 if (data_offset < server->total_read) { 1523 /* 1524 * win2k8 sometimes sends an offset of 0 when the read 1525 * is beyond the EOF. Treat it as if the data starts just after 1526 * the header. 1527 */ 1528 cifs_dbg(FYI, "%s: data offset (%u) inside read response header\n", 1529 __func__, data_offset); 1530 data_offset = server->total_read; 1531 } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) { 1532 /* data_offset is beyond the end of smallbuf */ 1533 cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n", 1534 __func__, data_offset); 1535 rdata->result = -EIO; 1536 return cifs_readv_discard(server, mid); 1537 } 1538 1539 cifs_dbg(FYI, "%s: total_read=%u data_offset=%u\n", 1540 __func__, server->total_read, data_offset); 1541 1542 len = data_offset - server->total_read; 1543 if (len > 0) { 1544 /* read any junk before data into the rest of smallbuf */ 1545 length = cifs_read_from_socket(server, 1546 buf + server->total_read, len); 1547 if (length < 0) 1548 return length; 1549 server->total_read += length; 1550 } 1551 1552 /* set up first iov for signature check */ 1553 rdata->iov[0].iov_base = buf; 1554 rdata->iov[0].iov_len = 4; 1555 rdata->iov[1].iov_base = buf + 4; 1556 rdata->iov[1].iov_len = server->total_read - 4; 1557 cifs_dbg(FYI, "0: iov_base=%p iov_len=%u\n", 1558 rdata->iov[0].iov_base, server->total_read); 1559 1560 /* how much data is in the response? */ 1561 #ifdef CONFIG_CIFS_SMB_DIRECT 1562 use_rdma_mr = rdata->mr; 1563 #endif 1564 data_len = server->ops->read_data_length(buf, use_rdma_mr); 1565 if (!use_rdma_mr && (data_offset + data_len > buflen)) { 1566 /* data_len is corrupt -- discard frame */ 1567 rdata->result = -EIO; 1568 return cifs_readv_discard(server, mid); 1569 } 1570 1571 length = rdata->read_into_pages(server, rdata, data_len); 1572 if (length < 0) 1573 return length; 1574 1575 server->total_read += length; 1576 1577 cifs_dbg(FYI, "total_read=%u buflen=%u remaining=%u\n", 1578 server->total_read, buflen, data_len); 1579 1580 /* discard anything left over */ 1581 if (server->total_read < buflen) 1582 return cifs_readv_discard(server, mid); 1583 1584 dequeue_mid(mid, false); 1585 mid->resp_buf = server->smallbuf; 1586 server->smallbuf = NULL; 1587 return length; 1588 } 1589 1590 static void 1591 cifs_readv_callback(struct mid_q_entry *mid) 1592 { 1593 struct cifs_readdata *rdata = mid->callback_data; 1594 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink); 1595 struct TCP_Server_Info *server = tcon->ses->server; 1596 struct smb_rqst rqst = { .rq_iov = rdata->iov, 1597 .rq_nvec = 2, 1598 .rq_pages = rdata->pages, 1599 .rq_npages = rdata->nr_pages, 1600 .rq_pagesz = rdata->pagesz, 1601 .rq_tailsz = rdata->tailsz }; 1602 1603 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n", 1604 __func__, mid->mid, mid->mid_state, rdata->result, 1605 rdata->bytes); 1606 1607 switch (mid->mid_state) { 1608 case MID_RESPONSE_RECEIVED: 1609 /* result already set, check signature */ 1610 if (server->sign) { 1611 int rc = 0; 1612 1613 rc = cifs_verify_signature(&rqst, server, 1614 mid->sequence_number); 1615 if (rc) 1616 cifs_dbg(VFS, "SMB signature verification returned error = %d\n", 1617 rc); 1618 } 1619 /* FIXME: should this be counted toward the initiating task? */ 1620 task_io_account_read(rdata->got_bytes); 1621 cifs_stats_bytes_read(tcon, rdata->got_bytes); 1622 break; 1623 case MID_REQUEST_SUBMITTED: 1624 case MID_RETRY_NEEDED: 1625 rdata->result = -EAGAIN; 1626 if (server->sign && rdata->got_bytes) 1627 /* reset bytes number since we can not check a sign */ 1628 rdata->got_bytes = 0; 1629 /* FIXME: should this be counted toward the initiating task? */ 1630 task_io_account_read(rdata->got_bytes); 1631 cifs_stats_bytes_read(tcon, rdata->got_bytes); 1632 break; 1633 default: 1634 rdata->result = -EIO; 1635 } 1636 1637 queue_work(cifsiod_wq, &rdata->work); 1638 DeleteMidQEntry(mid); 1639 add_credits(server, 1, 0); 1640 } 1641 1642 /* cifs_async_readv - send an async write, and set up mid to handle result */ 1643 int 1644 cifs_async_readv(struct cifs_readdata *rdata) 1645 { 1646 int rc; 1647 READ_REQ *smb = NULL; 1648 int wct; 1649 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink); 1650 struct smb_rqst rqst = { .rq_iov = rdata->iov, 1651 .rq_nvec = 2 }; 1652 1653 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n", 1654 __func__, rdata->offset, rdata->bytes); 1655 1656 if (tcon->ses->capabilities & CAP_LARGE_FILES) 1657 wct = 12; 1658 else { 1659 wct = 10; /* old style read */ 1660 if ((rdata->offset >> 32) > 0) { 1661 /* can not handle this big offset for old */ 1662 return -EIO; 1663 } 1664 } 1665 1666 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb); 1667 if (rc) 1668 return rc; 1669 1670 smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid); 1671 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16)); 1672 1673 smb->AndXCommand = 0xFF; /* none */ 1674 smb->Fid = rdata->cfile->fid.netfid; 1675 smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF); 1676 if (wct == 12) 1677 smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32); 1678 smb->Remaining = 0; 1679 smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF); 1680 smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16); 1681 if (wct == 12) 1682 smb->ByteCount = 0; 1683 else { 1684 /* old style read */ 1685 struct smb_com_readx_req *smbr = 1686 (struct smb_com_readx_req *)smb; 1687 smbr->ByteCount = 0; 1688 } 1689 1690 /* 4 for RFC1001 length + 1 for BCC */ 1691 rdata->iov[0].iov_base = smb; 1692 rdata->iov[0].iov_len = 4; 1693 rdata->iov[1].iov_base = (char *)smb + 4; 1694 rdata->iov[1].iov_len = get_rfc1002_length(smb); 1695 1696 kref_get(&rdata->refcount); 1697 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive, 1698 cifs_readv_callback, NULL, rdata, 0); 1699 1700 if (rc == 0) 1701 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads); 1702 else 1703 kref_put(&rdata->refcount, cifs_readdata_release); 1704 1705 cifs_small_buf_release(smb); 1706 return rc; 1707 } 1708 1709 int 1710 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms, 1711 unsigned int *nbytes, char **buf, int *pbuf_type) 1712 { 1713 int rc = -EACCES; 1714 READ_REQ *pSMB = NULL; 1715 READ_RSP *pSMBr = NULL; 1716 char *pReadData = NULL; 1717 int wct; 1718 int resp_buf_type = 0; 1719 struct kvec iov[1]; 1720 struct kvec rsp_iov; 1721 __u32 pid = io_parms->pid; 1722 __u16 netfid = io_parms->netfid; 1723 __u64 offset = io_parms->offset; 1724 struct cifs_tcon *tcon = io_parms->tcon; 1725 unsigned int count = io_parms->length; 1726 1727 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid); 1728 if (tcon->ses->capabilities & CAP_LARGE_FILES) 1729 wct = 12; 1730 else { 1731 wct = 10; /* old style read */ 1732 if ((offset >> 32) > 0) { 1733 /* can not handle this big offset for old */ 1734 return -EIO; 1735 } 1736 } 1737 1738 *nbytes = 0; 1739 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB); 1740 if (rc) 1741 return rc; 1742 1743 pSMB->hdr.Pid = cpu_to_le16((__u16)pid); 1744 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16)); 1745 1746 /* tcon and ses pointer are checked in smb_init */ 1747 if (tcon->ses->server == NULL) 1748 return -ECONNABORTED; 1749 1750 pSMB->AndXCommand = 0xFF; /* none */ 1751 pSMB->Fid = netfid; 1752 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1753 if (wct == 12) 1754 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1755 1756 pSMB->Remaining = 0; 1757 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); 1758 pSMB->MaxCountHigh = cpu_to_le32(count >> 16); 1759 if (wct == 12) 1760 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */ 1761 else { 1762 /* old style read */ 1763 struct smb_com_readx_req *pSMBW = 1764 (struct smb_com_readx_req *)pSMB; 1765 pSMBW->ByteCount = 0; 1766 } 1767 1768 iov[0].iov_base = (char *)pSMB; 1769 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4; 1770 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type, 1771 CIFS_LOG_ERROR, &rsp_iov); 1772 cifs_small_buf_release(pSMB); 1773 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads); 1774 pSMBr = (READ_RSP *)rsp_iov.iov_base; 1775 if (rc) { 1776 cifs_dbg(VFS, "Send error in read = %d\n", rc); 1777 } else { 1778 int data_length = le16_to_cpu(pSMBr->DataLengthHigh); 1779 data_length = data_length << 16; 1780 data_length += le16_to_cpu(pSMBr->DataLength); 1781 *nbytes = data_length; 1782 1783 /*check that DataLength would not go beyond end of SMB */ 1784 if ((data_length > CIFSMaxBufSize) 1785 || (data_length > count)) { 1786 cifs_dbg(FYI, "bad length %d for count %d\n", 1787 data_length, count); 1788 rc = -EIO; 1789 *nbytes = 0; 1790 } else { 1791 pReadData = (char *) (&pSMBr->hdr.Protocol) + 1792 le16_to_cpu(pSMBr->DataOffset); 1793 /* if (rc = copy_to_user(buf, pReadData, data_length)) { 1794 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc); 1795 rc = -EFAULT; 1796 }*/ /* can not use copy_to_user when using page cache*/ 1797 if (*buf) 1798 memcpy(*buf, pReadData, data_length); 1799 } 1800 } 1801 1802 if (*buf) { 1803 free_rsp_buf(resp_buf_type, rsp_iov.iov_base); 1804 } else if (resp_buf_type != CIFS_NO_BUFFER) { 1805 /* return buffer to caller to free */ 1806 *buf = rsp_iov.iov_base; 1807 if (resp_buf_type == CIFS_SMALL_BUFFER) 1808 *pbuf_type = CIFS_SMALL_BUFFER; 1809 else if (resp_buf_type == CIFS_LARGE_BUFFER) 1810 *pbuf_type = CIFS_LARGE_BUFFER; 1811 } /* else no valid buffer on return - leave as null */ 1812 1813 /* Note: On -EAGAIN error only caller can retry on handle based calls 1814 since file handle passed in no longer valid */ 1815 return rc; 1816 } 1817 1818 1819 int 1820 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms, 1821 unsigned int *nbytes, const char *buf) 1822 { 1823 int rc = -EACCES; 1824 WRITE_REQ *pSMB = NULL; 1825 WRITE_RSP *pSMBr = NULL; 1826 int bytes_returned, wct; 1827 __u32 bytes_sent; 1828 __u16 byte_count; 1829 __u32 pid = io_parms->pid; 1830 __u16 netfid = io_parms->netfid; 1831 __u64 offset = io_parms->offset; 1832 struct cifs_tcon *tcon = io_parms->tcon; 1833 unsigned int count = io_parms->length; 1834 1835 *nbytes = 0; 1836 1837 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/ 1838 if (tcon->ses == NULL) 1839 return -ECONNABORTED; 1840 1841 if (tcon->ses->capabilities & CAP_LARGE_FILES) 1842 wct = 14; 1843 else { 1844 wct = 12; 1845 if ((offset >> 32) > 0) { 1846 /* can not handle big offset for old srv */ 1847 return -EIO; 1848 } 1849 } 1850 1851 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB, 1852 (void **) &pSMBr); 1853 if (rc) 1854 return rc; 1855 1856 pSMB->hdr.Pid = cpu_to_le16((__u16)pid); 1857 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16)); 1858 1859 /* tcon and ses pointer are checked in smb_init */ 1860 if (tcon->ses->server == NULL) 1861 return -ECONNABORTED; 1862 1863 pSMB->AndXCommand = 0xFF; /* none */ 1864 pSMB->Fid = netfid; 1865 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1866 if (wct == 14) 1867 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1868 1869 pSMB->Reserved = 0xFFFFFFFF; 1870 pSMB->WriteMode = 0; 1871 pSMB->Remaining = 0; 1872 1873 /* Can increase buffer size if buffer is big enough in some cases ie we 1874 can send more if LARGE_WRITE_X capability returned by the server and if 1875 our buffer is big enough or if we convert to iovecs on socket writes 1876 and eliminate the copy to the CIFS buffer */ 1877 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) { 1878 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count); 1879 } else { 1880 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) 1881 & ~0xFF; 1882 } 1883 1884 if (bytes_sent > count) 1885 bytes_sent = count; 1886 pSMB->DataOffset = 1887 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4); 1888 if (buf) 1889 memcpy(pSMB->Data, buf, bytes_sent); 1890 else if (count != 0) { 1891 /* No buffer */ 1892 cifs_buf_release(pSMB); 1893 return -EINVAL; 1894 } /* else setting file size with write of zero bytes */ 1895 if (wct == 14) 1896 byte_count = bytes_sent + 1; /* pad */ 1897 else /* wct == 12 */ 1898 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */ 1899 1900 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF); 1901 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); 1902 inc_rfc1001_len(pSMB, byte_count); 1903 1904 if (wct == 14) 1905 pSMB->ByteCount = cpu_to_le16(byte_count); 1906 else { /* old style write has byte count 4 bytes earlier 1907 so 4 bytes pad */ 1908 struct smb_com_writex_req *pSMBW = 1909 (struct smb_com_writex_req *)pSMB; 1910 pSMBW->ByteCount = cpu_to_le16(byte_count); 1911 } 1912 1913 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1914 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1915 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); 1916 if (rc) { 1917 cifs_dbg(FYI, "Send error in write = %d\n", rc); 1918 } else { 1919 *nbytes = le16_to_cpu(pSMBr->CountHigh); 1920 *nbytes = (*nbytes) << 16; 1921 *nbytes += le16_to_cpu(pSMBr->Count); 1922 1923 /* 1924 * Mask off high 16 bits when bytes written as returned by the 1925 * server is greater than bytes requested by the client. Some 1926 * OS/2 servers are known to set incorrect CountHigh values. 1927 */ 1928 if (*nbytes > count) 1929 *nbytes &= 0xFFFF; 1930 } 1931 1932 cifs_buf_release(pSMB); 1933 1934 /* Note: On -EAGAIN error only caller can retry on handle based calls 1935 since file handle passed in no longer valid */ 1936 1937 return rc; 1938 } 1939 1940 void 1941 cifs_writedata_release(struct kref *refcount) 1942 { 1943 struct cifs_writedata *wdata = container_of(refcount, 1944 struct cifs_writedata, refcount); 1945 #ifdef CONFIG_CIFS_SMB_DIRECT 1946 if (wdata->mr) { 1947 smbd_deregister_mr(wdata->mr); 1948 wdata->mr = NULL; 1949 } 1950 #endif 1951 1952 if (wdata->cfile) 1953 cifsFileInfo_put(wdata->cfile); 1954 1955 kfree(wdata); 1956 } 1957 1958 /* 1959 * Write failed with a retryable error. Resend the write request. It's also 1960 * possible that the page was redirtied so re-clean the page. 1961 */ 1962 static void 1963 cifs_writev_requeue(struct cifs_writedata *wdata) 1964 { 1965 int i, rc = 0; 1966 struct inode *inode = d_inode(wdata->cfile->dentry); 1967 struct TCP_Server_Info *server; 1968 unsigned int rest_len; 1969 1970 server = tlink_tcon(wdata->cfile->tlink)->ses->server; 1971 i = 0; 1972 rest_len = wdata->bytes; 1973 do { 1974 struct cifs_writedata *wdata2; 1975 unsigned int j, nr_pages, wsize, tailsz, cur_len; 1976 1977 wsize = server->ops->wp_retry_size(inode); 1978 if (wsize < rest_len) { 1979 nr_pages = wsize / PAGE_SIZE; 1980 if (!nr_pages) { 1981 rc = -ENOTSUPP; 1982 break; 1983 } 1984 cur_len = nr_pages * PAGE_SIZE; 1985 tailsz = PAGE_SIZE; 1986 } else { 1987 nr_pages = DIV_ROUND_UP(rest_len, PAGE_SIZE); 1988 cur_len = rest_len; 1989 tailsz = rest_len - (nr_pages - 1) * PAGE_SIZE; 1990 } 1991 1992 wdata2 = cifs_writedata_alloc(nr_pages, cifs_writev_complete); 1993 if (!wdata2) { 1994 rc = -ENOMEM; 1995 break; 1996 } 1997 1998 for (j = 0; j < nr_pages; j++) { 1999 wdata2->pages[j] = wdata->pages[i + j]; 2000 lock_page(wdata2->pages[j]); 2001 clear_page_dirty_for_io(wdata2->pages[j]); 2002 } 2003 2004 wdata2->sync_mode = wdata->sync_mode; 2005 wdata2->nr_pages = nr_pages; 2006 wdata2->offset = page_offset(wdata2->pages[0]); 2007 wdata2->pagesz = PAGE_SIZE; 2008 wdata2->tailsz = tailsz; 2009 wdata2->bytes = cur_len; 2010 2011 wdata2->cfile = find_writable_file(CIFS_I(inode), false); 2012 if (!wdata2->cfile) { 2013 cifs_dbg(VFS, "No writable handles for inode\n"); 2014 rc = -EBADF; 2015 break; 2016 } 2017 wdata2->pid = wdata2->cfile->pid; 2018 rc = server->ops->async_writev(wdata2, cifs_writedata_release); 2019 2020 for (j = 0; j < nr_pages; j++) { 2021 unlock_page(wdata2->pages[j]); 2022 if (rc != 0 && rc != -EAGAIN) { 2023 SetPageError(wdata2->pages[j]); 2024 end_page_writeback(wdata2->pages[j]); 2025 put_page(wdata2->pages[j]); 2026 } 2027 } 2028 2029 if (rc) { 2030 kref_put(&wdata2->refcount, cifs_writedata_release); 2031 if (rc == -EAGAIN) 2032 continue; 2033 break; 2034 } 2035 2036 rest_len -= cur_len; 2037 i += nr_pages; 2038 } while (i < wdata->nr_pages); 2039 2040 mapping_set_error(inode->i_mapping, rc); 2041 kref_put(&wdata->refcount, cifs_writedata_release); 2042 } 2043 2044 void 2045 cifs_writev_complete(struct work_struct *work) 2046 { 2047 struct cifs_writedata *wdata = container_of(work, 2048 struct cifs_writedata, work); 2049 struct inode *inode = d_inode(wdata->cfile->dentry); 2050 int i = 0; 2051 2052 if (wdata->result == 0) { 2053 spin_lock(&inode->i_lock); 2054 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes); 2055 spin_unlock(&inode->i_lock); 2056 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink), 2057 wdata->bytes); 2058 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN) 2059 return cifs_writev_requeue(wdata); 2060 2061 for (i = 0; i < wdata->nr_pages; i++) { 2062 struct page *page = wdata->pages[i]; 2063 if (wdata->result == -EAGAIN) 2064 __set_page_dirty_nobuffers(page); 2065 else if (wdata->result < 0) 2066 SetPageError(page); 2067 end_page_writeback(page); 2068 put_page(page); 2069 } 2070 if (wdata->result != -EAGAIN) 2071 mapping_set_error(inode->i_mapping, wdata->result); 2072 kref_put(&wdata->refcount, cifs_writedata_release); 2073 } 2074 2075 struct cifs_writedata * 2076 cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete) 2077 { 2078 struct cifs_writedata *wdata; 2079 2080 /* writedata + number of page pointers */ 2081 wdata = kzalloc(sizeof(*wdata) + 2082 sizeof(struct page *) * nr_pages, GFP_NOFS); 2083 if (wdata != NULL) { 2084 kref_init(&wdata->refcount); 2085 INIT_LIST_HEAD(&wdata->list); 2086 init_completion(&wdata->done); 2087 INIT_WORK(&wdata->work, complete); 2088 } 2089 return wdata; 2090 } 2091 2092 /* 2093 * Check the mid_state and signature on received buffer (if any), and queue the 2094 * workqueue completion task. 2095 */ 2096 static void 2097 cifs_writev_callback(struct mid_q_entry *mid) 2098 { 2099 struct cifs_writedata *wdata = mid->callback_data; 2100 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink); 2101 unsigned int written; 2102 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf; 2103 2104 switch (mid->mid_state) { 2105 case MID_RESPONSE_RECEIVED: 2106 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0); 2107 if (wdata->result != 0) 2108 break; 2109 2110 written = le16_to_cpu(smb->CountHigh); 2111 written <<= 16; 2112 written += le16_to_cpu(smb->Count); 2113 /* 2114 * Mask off high 16 bits when bytes written as returned 2115 * by the server is greater than bytes requested by the 2116 * client. OS/2 servers are known to set incorrect 2117 * CountHigh values. 2118 */ 2119 if (written > wdata->bytes) 2120 written &= 0xFFFF; 2121 2122 if (written < wdata->bytes) 2123 wdata->result = -ENOSPC; 2124 else 2125 wdata->bytes = written; 2126 break; 2127 case MID_REQUEST_SUBMITTED: 2128 case MID_RETRY_NEEDED: 2129 wdata->result = -EAGAIN; 2130 break; 2131 default: 2132 wdata->result = -EIO; 2133 break; 2134 } 2135 2136 queue_work(cifsiod_wq, &wdata->work); 2137 DeleteMidQEntry(mid); 2138 add_credits(tcon->ses->server, 1, 0); 2139 } 2140 2141 /* cifs_async_writev - send an async write, and set up mid to handle result */ 2142 int 2143 cifs_async_writev(struct cifs_writedata *wdata, 2144 void (*release)(struct kref *kref)) 2145 { 2146 int rc = -EACCES; 2147 WRITE_REQ *smb = NULL; 2148 int wct; 2149 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink); 2150 struct kvec iov[2]; 2151 struct smb_rqst rqst = { }; 2152 2153 if (tcon->ses->capabilities & CAP_LARGE_FILES) { 2154 wct = 14; 2155 } else { 2156 wct = 12; 2157 if (wdata->offset >> 32 > 0) { 2158 /* can not handle big offset for old srv */ 2159 return -EIO; 2160 } 2161 } 2162 2163 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb); 2164 if (rc) 2165 goto async_writev_out; 2166 2167 smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid); 2168 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16)); 2169 2170 smb->AndXCommand = 0xFF; /* none */ 2171 smb->Fid = wdata->cfile->fid.netfid; 2172 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF); 2173 if (wct == 14) 2174 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32); 2175 smb->Reserved = 0xFFFFFFFF; 2176 smb->WriteMode = 0; 2177 smb->Remaining = 0; 2178 2179 smb->DataOffset = 2180 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4); 2181 2182 /* 4 for RFC1001 length + 1 for BCC */ 2183 iov[0].iov_len = 4; 2184 iov[0].iov_base = smb; 2185 iov[1].iov_len = get_rfc1002_length(smb) + 1; 2186 iov[1].iov_base = (char *)smb + 4; 2187 2188 rqst.rq_iov = iov; 2189 rqst.rq_nvec = 2; 2190 rqst.rq_pages = wdata->pages; 2191 rqst.rq_npages = wdata->nr_pages; 2192 rqst.rq_pagesz = wdata->pagesz; 2193 rqst.rq_tailsz = wdata->tailsz; 2194 2195 cifs_dbg(FYI, "async write at %llu %u bytes\n", 2196 wdata->offset, wdata->bytes); 2197 2198 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF); 2199 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16); 2200 2201 if (wct == 14) { 2202 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1); 2203 put_bcc(wdata->bytes + 1, &smb->hdr); 2204 } else { 2205 /* wct == 12 */ 2206 struct smb_com_writex_req *smbw = 2207 (struct smb_com_writex_req *)smb; 2208 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5); 2209 put_bcc(wdata->bytes + 5, &smbw->hdr); 2210 iov[1].iov_len += 4; /* pad bigger by four bytes */ 2211 } 2212 2213 kref_get(&wdata->refcount); 2214 rc = cifs_call_async(tcon->ses->server, &rqst, NULL, 2215 cifs_writev_callback, NULL, wdata, 0); 2216 2217 if (rc == 0) 2218 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); 2219 else 2220 kref_put(&wdata->refcount, release); 2221 2222 async_writev_out: 2223 cifs_small_buf_release(smb); 2224 return rc; 2225 } 2226 2227 int 2228 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms, 2229 unsigned int *nbytes, struct kvec *iov, int n_vec) 2230 { 2231 int rc = -EACCES; 2232 WRITE_REQ *pSMB = NULL; 2233 int wct; 2234 int smb_hdr_len; 2235 int resp_buf_type = 0; 2236 __u32 pid = io_parms->pid; 2237 __u16 netfid = io_parms->netfid; 2238 __u64 offset = io_parms->offset; 2239 struct cifs_tcon *tcon = io_parms->tcon; 2240 unsigned int count = io_parms->length; 2241 struct kvec rsp_iov; 2242 2243 *nbytes = 0; 2244 2245 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count); 2246 2247 if (tcon->ses->capabilities & CAP_LARGE_FILES) { 2248 wct = 14; 2249 } else { 2250 wct = 12; 2251 if ((offset >> 32) > 0) { 2252 /* can not handle big offset for old srv */ 2253 return -EIO; 2254 } 2255 } 2256 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB); 2257 if (rc) 2258 return rc; 2259 2260 pSMB->hdr.Pid = cpu_to_le16((__u16)pid); 2261 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16)); 2262 2263 /* tcon and ses pointer are checked in smb_init */ 2264 if (tcon->ses->server == NULL) 2265 return -ECONNABORTED; 2266 2267 pSMB->AndXCommand = 0xFF; /* none */ 2268 pSMB->Fid = netfid; 2269 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 2270 if (wct == 14) 2271 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 2272 pSMB->Reserved = 0xFFFFFFFF; 2273 pSMB->WriteMode = 0; 2274 pSMB->Remaining = 0; 2275 2276 pSMB->DataOffset = 2277 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4); 2278 2279 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF); 2280 pSMB->DataLengthHigh = cpu_to_le16(count >> 16); 2281 /* header + 1 byte pad */ 2282 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1; 2283 if (wct == 14) 2284 inc_rfc1001_len(pSMB, count + 1); 2285 else /* wct == 12 */ 2286 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */ 2287 if (wct == 14) 2288 pSMB->ByteCount = cpu_to_le16(count + 1); 2289 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ { 2290 struct smb_com_writex_req *pSMBW = 2291 (struct smb_com_writex_req *)pSMB; 2292 pSMBW->ByteCount = cpu_to_le16(count + 5); 2293 } 2294 iov[0].iov_base = pSMB; 2295 if (wct == 14) 2296 iov[0].iov_len = smb_hdr_len + 4; 2297 else /* wct == 12 pad bigger by four bytes */ 2298 iov[0].iov_len = smb_hdr_len + 8; 2299 2300 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0, 2301 &rsp_iov); 2302 cifs_small_buf_release(pSMB); 2303 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); 2304 if (rc) { 2305 cifs_dbg(FYI, "Send error Write2 = %d\n", rc); 2306 } else if (resp_buf_type == 0) { 2307 /* presumably this can not happen, but best to be safe */ 2308 rc = -EIO; 2309 } else { 2310 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base; 2311 *nbytes = le16_to_cpu(pSMBr->CountHigh); 2312 *nbytes = (*nbytes) << 16; 2313 *nbytes += le16_to_cpu(pSMBr->Count); 2314 2315 /* 2316 * Mask off high 16 bits when bytes written as returned by the 2317 * server is greater than bytes requested by the client. OS/2 2318 * servers are known to set incorrect CountHigh values. 2319 */ 2320 if (*nbytes > count) 2321 *nbytes &= 0xFFFF; 2322 } 2323 2324 free_rsp_buf(resp_buf_type, rsp_iov.iov_base); 2325 2326 /* Note: On -EAGAIN error only caller can retry on handle based calls 2327 since file handle passed in no longer valid */ 2328 2329 return rc; 2330 } 2331 2332 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon, 2333 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock, 2334 const __u32 num_lock, LOCKING_ANDX_RANGE *buf) 2335 { 2336 int rc = 0; 2337 LOCK_REQ *pSMB = NULL; 2338 struct kvec iov[2]; 2339 struct kvec rsp_iov; 2340 int resp_buf_type; 2341 __u16 count; 2342 2343 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n", 2344 num_lock, num_unlock); 2345 2346 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); 2347 if (rc) 2348 return rc; 2349 2350 pSMB->Timeout = 0; 2351 pSMB->NumberOfLocks = cpu_to_le16(num_lock); 2352 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock); 2353 pSMB->LockType = lock_type; 2354 pSMB->AndXCommand = 0xFF; /* none */ 2355 pSMB->Fid = netfid; /* netfid stays le */ 2356 2357 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE); 2358 inc_rfc1001_len(pSMB, count); 2359 pSMB->ByteCount = cpu_to_le16(count); 2360 2361 iov[0].iov_base = (char *)pSMB; 2362 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 - 2363 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE); 2364 iov[1].iov_base = (char *)buf; 2365 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE); 2366 2367 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks); 2368 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP, 2369 &rsp_iov); 2370 cifs_small_buf_release(pSMB); 2371 if (rc) 2372 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc); 2373 2374 return rc; 2375 } 2376 2377 int 2378 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon, 2379 const __u16 smb_file_id, const __u32 netpid, const __u64 len, 2380 const __u64 offset, const __u32 numUnlock, 2381 const __u32 numLock, const __u8 lockType, 2382 const bool waitFlag, const __u8 oplock_level) 2383 { 2384 int rc = 0; 2385 LOCK_REQ *pSMB = NULL; 2386 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */ 2387 int bytes_returned; 2388 int flags = 0; 2389 __u16 count; 2390 2391 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n", 2392 (int)waitFlag, numLock); 2393 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); 2394 2395 if (rc) 2396 return rc; 2397 2398 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) { 2399 /* no response expected */ 2400 flags = CIFS_ASYNC_OP | CIFS_OBREAK_OP; 2401 pSMB->Timeout = 0; 2402 } else if (waitFlag) { 2403 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */ 2404 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */ 2405 } else { 2406 pSMB->Timeout = 0; 2407 } 2408 2409 pSMB->NumberOfLocks = cpu_to_le16(numLock); 2410 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock); 2411 pSMB->LockType = lockType; 2412 pSMB->OplockLevel = oplock_level; 2413 pSMB->AndXCommand = 0xFF; /* none */ 2414 pSMB->Fid = smb_file_id; /* netfid stays le */ 2415 2416 if ((numLock != 0) || (numUnlock != 0)) { 2417 pSMB->Locks[0].Pid = cpu_to_le16(netpid); 2418 /* BB where to store pid high? */ 2419 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len); 2420 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32)); 2421 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset); 2422 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32)); 2423 count = sizeof(LOCKING_ANDX_RANGE); 2424 } else { 2425 /* oplock break */ 2426 count = 0; 2427 } 2428 inc_rfc1001_len(pSMB, count); 2429 pSMB->ByteCount = cpu_to_le16(count); 2430 2431 if (waitFlag) 2432 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, 2433 (struct smb_hdr *) pSMB, &bytes_returned); 2434 else 2435 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags); 2436 cifs_small_buf_release(pSMB); 2437 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks); 2438 if (rc) 2439 cifs_dbg(FYI, "Send error in Lock = %d\n", rc); 2440 2441 /* Note: On -EAGAIN error only caller can retry on handle based calls 2442 since file handle passed in no longer valid */ 2443 return rc; 2444 } 2445 2446 int 2447 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon, 2448 const __u16 smb_file_id, const __u32 netpid, 2449 const loff_t start_offset, const __u64 len, 2450 struct file_lock *pLockData, const __u16 lock_type, 2451 const bool waitFlag) 2452 { 2453 struct smb_com_transaction2_sfi_req *pSMB = NULL; 2454 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 2455 struct cifs_posix_lock *parm_data; 2456 int rc = 0; 2457 int timeout = 0; 2458 int bytes_returned = 0; 2459 int resp_buf_type = 0; 2460 __u16 params, param_offset, offset, byte_count, count; 2461 struct kvec iov[1]; 2462 struct kvec rsp_iov; 2463 2464 cifs_dbg(FYI, "Posix Lock\n"); 2465 2466 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 2467 2468 if (rc) 2469 return rc; 2470 2471 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB; 2472 2473 params = 6; 2474 pSMB->MaxSetupCount = 0; 2475 pSMB->Reserved = 0; 2476 pSMB->Flags = 0; 2477 pSMB->Reserved2 = 0; 2478 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 2479 offset = param_offset + params; 2480 2481 count = sizeof(struct cifs_posix_lock); 2482 pSMB->MaxParameterCount = cpu_to_le16(2); 2483 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */ 2484 pSMB->SetupCount = 1; 2485 pSMB->Reserved3 = 0; 2486 if (pLockData) 2487 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 2488 else 2489 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 2490 byte_count = 3 /* pad */ + params + count; 2491 pSMB->DataCount = cpu_to_le16(count); 2492 pSMB->ParameterCount = cpu_to_le16(params); 2493 pSMB->TotalDataCount = pSMB->DataCount; 2494 pSMB->TotalParameterCount = pSMB->ParameterCount; 2495 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2496 parm_data = (struct cifs_posix_lock *) 2497 (((char *) &pSMB->hdr.Protocol) + offset); 2498 2499 parm_data->lock_type = cpu_to_le16(lock_type); 2500 if (waitFlag) { 2501 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */ 2502 parm_data->lock_flags = cpu_to_le16(1); 2503 pSMB->Timeout = cpu_to_le32(-1); 2504 } else 2505 pSMB->Timeout = 0; 2506 2507 parm_data->pid = cpu_to_le32(netpid); 2508 parm_data->start = cpu_to_le64(start_offset); 2509 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */ 2510 2511 pSMB->DataOffset = cpu_to_le16(offset); 2512 pSMB->Fid = smb_file_id; 2513 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK); 2514 pSMB->Reserved4 = 0; 2515 inc_rfc1001_len(pSMB, byte_count); 2516 pSMB->ByteCount = cpu_to_le16(byte_count); 2517 if (waitFlag) { 2518 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, 2519 (struct smb_hdr *) pSMBr, &bytes_returned); 2520 } else { 2521 iov[0].iov_base = (char *)pSMB; 2522 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4; 2523 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, 2524 &resp_buf_type, timeout, &rsp_iov); 2525 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base; 2526 } 2527 cifs_small_buf_release(pSMB); 2528 2529 if (rc) { 2530 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc); 2531 } else if (pLockData) { 2532 /* lock structure can be returned on get */ 2533 __u16 data_offset; 2534 __u16 data_count; 2535 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2536 2537 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) { 2538 rc = -EIO; /* bad smb */ 2539 goto plk_err_exit; 2540 } 2541 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 2542 data_count = le16_to_cpu(pSMBr->t2.DataCount); 2543 if (data_count < sizeof(struct cifs_posix_lock)) { 2544 rc = -EIO; 2545 goto plk_err_exit; 2546 } 2547 parm_data = (struct cifs_posix_lock *) 2548 ((char *)&pSMBr->hdr.Protocol + data_offset); 2549 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK)) 2550 pLockData->fl_type = F_UNLCK; 2551 else { 2552 if (parm_data->lock_type == 2553 cpu_to_le16(CIFS_RDLCK)) 2554 pLockData->fl_type = F_RDLCK; 2555 else if (parm_data->lock_type == 2556 cpu_to_le16(CIFS_WRLCK)) 2557 pLockData->fl_type = F_WRLCK; 2558 2559 pLockData->fl_start = le64_to_cpu(parm_data->start); 2560 pLockData->fl_end = pLockData->fl_start + 2561 le64_to_cpu(parm_data->length) - 1; 2562 pLockData->fl_pid = -le32_to_cpu(parm_data->pid); 2563 } 2564 } 2565 2566 plk_err_exit: 2567 free_rsp_buf(resp_buf_type, rsp_iov.iov_base); 2568 2569 /* Note: On -EAGAIN error only caller can retry on handle based calls 2570 since file handle passed in no longer valid */ 2571 2572 return rc; 2573 } 2574 2575 2576 int 2577 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id) 2578 { 2579 int rc = 0; 2580 CLOSE_REQ *pSMB = NULL; 2581 cifs_dbg(FYI, "In CIFSSMBClose\n"); 2582 2583 /* do not retry on dead session on close */ 2584 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB); 2585 if (rc == -EAGAIN) 2586 return 0; 2587 if (rc) 2588 return rc; 2589 2590 pSMB->FileID = (__u16) smb_file_id; 2591 pSMB->LastWriteTime = 0xFFFFFFFF; 2592 pSMB->ByteCount = 0; 2593 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 2594 cifs_small_buf_release(pSMB); 2595 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes); 2596 if (rc) { 2597 if (rc != -EINTR) { 2598 /* EINTR is expected when user ctl-c to kill app */ 2599 cifs_dbg(VFS, "Send error in Close = %d\n", rc); 2600 } 2601 } 2602 2603 /* Since session is dead, file will be closed on server already */ 2604 if (rc == -EAGAIN) 2605 rc = 0; 2606 2607 return rc; 2608 } 2609 2610 int 2611 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id) 2612 { 2613 int rc = 0; 2614 FLUSH_REQ *pSMB = NULL; 2615 cifs_dbg(FYI, "In CIFSSMBFlush\n"); 2616 2617 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB); 2618 if (rc) 2619 return rc; 2620 2621 pSMB->FileID = (__u16) smb_file_id; 2622 pSMB->ByteCount = 0; 2623 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 2624 cifs_small_buf_release(pSMB); 2625 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes); 2626 if (rc) 2627 cifs_dbg(VFS, "Send error in Flush = %d\n", rc); 2628 2629 return rc; 2630 } 2631 2632 int 2633 CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon, 2634 const char *from_name, const char *to_name, 2635 struct cifs_sb_info *cifs_sb) 2636 { 2637 int rc = 0; 2638 RENAME_REQ *pSMB = NULL; 2639 RENAME_RSP *pSMBr = NULL; 2640 int bytes_returned; 2641 int name_len, name_len2; 2642 __u16 count; 2643 int remap = cifs_remap(cifs_sb); 2644 2645 cifs_dbg(FYI, "In CIFSSMBRename\n"); 2646 renameRetry: 2647 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB, 2648 (void **) &pSMBr); 2649 if (rc) 2650 return rc; 2651 2652 pSMB->BufferFormat = 0x04; 2653 pSMB->SearchAttributes = 2654 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 2655 ATTR_DIRECTORY); 2656 2657 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2658 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName, 2659 from_name, PATH_MAX, 2660 cifs_sb->local_nls, remap); 2661 name_len++; /* trailing null */ 2662 name_len *= 2; 2663 pSMB->OldFileName[name_len] = 0x04; /* pad */ 2664 /* protocol requires ASCII signature byte on Unicode string */ 2665 pSMB->OldFileName[name_len + 1] = 0x00; 2666 name_len2 = 2667 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2], 2668 to_name, PATH_MAX, cifs_sb->local_nls, 2669 remap); 2670 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 2671 name_len2 *= 2; /* convert to bytes */ 2672 } else { /* BB improve the check for buffer overruns BB */ 2673 name_len = strnlen(from_name, PATH_MAX); 2674 name_len++; /* trailing null */ 2675 strncpy(pSMB->OldFileName, from_name, name_len); 2676 name_len2 = strnlen(to_name, PATH_MAX); 2677 name_len2++; /* trailing null */ 2678 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ 2679 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2); 2680 name_len2++; /* trailing null */ 2681 name_len2++; /* signature byte */ 2682 } 2683 2684 count = 1 /* 1st signature byte */ + name_len + name_len2; 2685 inc_rfc1001_len(pSMB, count); 2686 pSMB->ByteCount = cpu_to_le16(count); 2687 2688 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2689 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2690 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames); 2691 if (rc) 2692 cifs_dbg(FYI, "Send error in rename = %d\n", rc); 2693 2694 cifs_buf_release(pSMB); 2695 2696 if (rc == -EAGAIN) 2697 goto renameRetry; 2698 2699 return rc; 2700 } 2701 2702 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon, 2703 int netfid, const char *target_name, 2704 const struct nls_table *nls_codepage, int remap) 2705 { 2706 struct smb_com_transaction2_sfi_req *pSMB = NULL; 2707 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 2708 struct set_file_rename *rename_info; 2709 char *data_offset; 2710 char dummy_string[30]; 2711 int rc = 0; 2712 int bytes_returned = 0; 2713 int len_of_str; 2714 __u16 params, param_offset, offset, count, byte_count; 2715 2716 cifs_dbg(FYI, "Rename to File by handle\n"); 2717 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB, 2718 (void **) &pSMBr); 2719 if (rc) 2720 return rc; 2721 2722 params = 6; 2723 pSMB->MaxSetupCount = 0; 2724 pSMB->Reserved = 0; 2725 pSMB->Flags = 0; 2726 pSMB->Timeout = 0; 2727 pSMB->Reserved2 = 0; 2728 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 2729 offset = param_offset + params; 2730 2731 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 2732 rename_info = (struct set_file_rename *) data_offset; 2733 pSMB->MaxParameterCount = cpu_to_le16(2); 2734 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */ 2735 pSMB->SetupCount = 1; 2736 pSMB->Reserved3 = 0; 2737 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 2738 byte_count = 3 /* pad */ + params; 2739 pSMB->ParameterCount = cpu_to_le16(params); 2740 pSMB->TotalParameterCount = pSMB->ParameterCount; 2741 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2742 pSMB->DataOffset = cpu_to_le16(offset); 2743 /* construct random name ".cifs_tmp<inodenum><mid>" */ 2744 rename_info->overwrite = cpu_to_le32(1); 2745 rename_info->root_fid = 0; 2746 /* unicode only call */ 2747 if (target_name == NULL) { 2748 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid); 2749 len_of_str = 2750 cifsConvertToUTF16((__le16 *)rename_info->target_name, 2751 dummy_string, 24, nls_codepage, remap); 2752 } else { 2753 len_of_str = 2754 cifsConvertToUTF16((__le16 *)rename_info->target_name, 2755 target_name, PATH_MAX, nls_codepage, 2756 remap); 2757 } 2758 rename_info->target_name_len = cpu_to_le32(2 * len_of_str); 2759 count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str); 2760 byte_count += count; 2761 pSMB->DataCount = cpu_to_le16(count); 2762 pSMB->TotalDataCount = pSMB->DataCount; 2763 pSMB->Fid = netfid; 2764 pSMB->InformationLevel = 2765 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION); 2766 pSMB->Reserved4 = 0; 2767 inc_rfc1001_len(pSMB, byte_count); 2768 pSMB->ByteCount = cpu_to_le16(byte_count); 2769 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, 2770 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2771 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames); 2772 if (rc) 2773 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n", 2774 rc); 2775 2776 cifs_buf_release(pSMB); 2777 2778 /* Note: On -EAGAIN error only caller can retry on handle based calls 2779 since file handle passed in no longer valid */ 2780 2781 return rc; 2782 } 2783 2784 int 2785 CIFSSMBCopy(const unsigned int xid, struct cifs_tcon *tcon, 2786 const char *fromName, const __u16 target_tid, const char *toName, 2787 const int flags, const struct nls_table *nls_codepage, int remap) 2788 { 2789 int rc = 0; 2790 COPY_REQ *pSMB = NULL; 2791 COPY_RSP *pSMBr = NULL; 2792 int bytes_returned; 2793 int name_len, name_len2; 2794 __u16 count; 2795 2796 cifs_dbg(FYI, "In CIFSSMBCopy\n"); 2797 copyRetry: 2798 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB, 2799 (void **) &pSMBr); 2800 if (rc) 2801 return rc; 2802 2803 pSMB->BufferFormat = 0x04; 2804 pSMB->Tid2 = target_tid; 2805 2806 pSMB->Flags = cpu_to_le16(flags & COPY_TREE); 2807 2808 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2809 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName, 2810 fromName, PATH_MAX, nls_codepage, 2811 remap); 2812 name_len++; /* trailing null */ 2813 name_len *= 2; 2814 pSMB->OldFileName[name_len] = 0x04; /* pad */ 2815 /* protocol requires ASCII signature byte on Unicode string */ 2816 pSMB->OldFileName[name_len + 1] = 0x00; 2817 name_len2 = 2818 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2], 2819 toName, PATH_MAX, nls_codepage, remap); 2820 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 2821 name_len2 *= 2; /* convert to bytes */ 2822 } else { /* BB improve the check for buffer overruns BB */ 2823 name_len = strnlen(fromName, PATH_MAX); 2824 name_len++; /* trailing null */ 2825 strncpy(pSMB->OldFileName, fromName, name_len); 2826 name_len2 = strnlen(toName, PATH_MAX); 2827 name_len2++; /* trailing null */ 2828 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ 2829 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2); 2830 name_len2++; /* trailing null */ 2831 name_len2++; /* signature byte */ 2832 } 2833 2834 count = 1 /* 1st signature byte */ + name_len + name_len2; 2835 inc_rfc1001_len(pSMB, count); 2836 pSMB->ByteCount = cpu_to_le16(count); 2837 2838 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2839 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2840 if (rc) { 2841 cifs_dbg(FYI, "Send error in copy = %d with %d files copied\n", 2842 rc, le16_to_cpu(pSMBr->CopyCount)); 2843 } 2844 cifs_buf_release(pSMB); 2845 2846 if (rc == -EAGAIN) 2847 goto copyRetry; 2848 2849 return rc; 2850 } 2851 2852 int 2853 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon, 2854 const char *fromName, const char *toName, 2855 const struct nls_table *nls_codepage, int remap) 2856 { 2857 TRANSACTION2_SPI_REQ *pSMB = NULL; 2858 TRANSACTION2_SPI_RSP *pSMBr = NULL; 2859 char *data_offset; 2860 int name_len; 2861 int name_len_target; 2862 int rc = 0; 2863 int bytes_returned = 0; 2864 __u16 params, param_offset, offset, byte_count; 2865 2866 cifs_dbg(FYI, "In Symlink Unix style\n"); 2867 createSymLinkRetry: 2868 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 2869 (void **) &pSMBr); 2870 if (rc) 2871 return rc; 2872 2873 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2874 name_len = 2875 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName, 2876 /* find define for this maxpathcomponent */ 2877 PATH_MAX, nls_codepage, remap); 2878 name_len++; /* trailing null */ 2879 name_len *= 2; 2880 2881 } else { /* BB improve the check for buffer overruns BB */ 2882 name_len = strnlen(fromName, PATH_MAX); 2883 name_len++; /* trailing null */ 2884 strncpy(pSMB->FileName, fromName, name_len); 2885 } 2886 params = 6 + name_len; 2887 pSMB->MaxSetupCount = 0; 2888 pSMB->Reserved = 0; 2889 pSMB->Flags = 0; 2890 pSMB->Timeout = 0; 2891 pSMB->Reserved2 = 0; 2892 param_offset = offsetof(struct smb_com_transaction2_spi_req, 2893 InformationLevel) - 4; 2894 offset = param_offset + params; 2895 2896 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 2897 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2898 name_len_target = 2899 cifsConvertToUTF16((__le16 *) data_offset, toName, 2900 /* find define for this maxpathcomponent */ 2901 PATH_MAX, nls_codepage, remap); 2902 name_len_target++; /* trailing null */ 2903 name_len_target *= 2; 2904 } else { /* BB improve the check for buffer overruns BB */ 2905 name_len_target = strnlen(toName, PATH_MAX); 2906 name_len_target++; /* trailing null */ 2907 strncpy(data_offset, toName, name_len_target); 2908 } 2909 2910 pSMB->MaxParameterCount = cpu_to_le16(2); 2911 /* BB find exact max on data count below from sess */ 2912 pSMB->MaxDataCount = cpu_to_le16(1000); 2913 pSMB->SetupCount = 1; 2914 pSMB->Reserved3 = 0; 2915 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 2916 byte_count = 3 /* pad */ + params + name_len_target; 2917 pSMB->DataCount = cpu_to_le16(name_len_target); 2918 pSMB->ParameterCount = cpu_to_le16(params); 2919 pSMB->TotalDataCount = pSMB->DataCount; 2920 pSMB->TotalParameterCount = pSMB->ParameterCount; 2921 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2922 pSMB->DataOffset = cpu_to_le16(offset); 2923 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK); 2924 pSMB->Reserved4 = 0; 2925 inc_rfc1001_len(pSMB, byte_count); 2926 pSMB->ByteCount = cpu_to_le16(byte_count); 2927 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2928 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2929 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks); 2930 if (rc) 2931 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n", 2932 rc); 2933 2934 cifs_buf_release(pSMB); 2935 2936 if (rc == -EAGAIN) 2937 goto createSymLinkRetry; 2938 2939 return rc; 2940 } 2941 2942 int 2943 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, 2944 const char *fromName, const char *toName, 2945 const struct nls_table *nls_codepage, int remap) 2946 { 2947 TRANSACTION2_SPI_REQ *pSMB = NULL; 2948 TRANSACTION2_SPI_RSP *pSMBr = NULL; 2949 char *data_offset; 2950 int name_len; 2951 int name_len_target; 2952 int rc = 0; 2953 int bytes_returned = 0; 2954 __u16 params, param_offset, offset, byte_count; 2955 2956 cifs_dbg(FYI, "In Create Hard link Unix style\n"); 2957 createHardLinkRetry: 2958 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 2959 (void **) &pSMBr); 2960 if (rc) 2961 return rc; 2962 2963 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2964 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName, 2965 PATH_MAX, nls_codepage, remap); 2966 name_len++; /* trailing null */ 2967 name_len *= 2; 2968 2969 } else { /* BB improve the check for buffer overruns BB */ 2970 name_len = strnlen(toName, PATH_MAX); 2971 name_len++; /* trailing null */ 2972 strncpy(pSMB->FileName, toName, name_len); 2973 } 2974 params = 6 + name_len; 2975 pSMB->MaxSetupCount = 0; 2976 pSMB->Reserved = 0; 2977 pSMB->Flags = 0; 2978 pSMB->Timeout = 0; 2979 pSMB->Reserved2 = 0; 2980 param_offset = offsetof(struct smb_com_transaction2_spi_req, 2981 InformationLevel) - 4; 2982 offset = param_offset + params; 2983 2984 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 2985 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2986 name_len_target = 2987 cifsConvertToUTF16((__le16 *) data_offset, fromName, 2988 PATH_MAX, nls_codepage, remap); 2989 name_len_target++; /* trailing null */ 2990 name_len_target *= 2; 2991 } else { /* BB improve the check for buffer overruns BB */ 2992 name_len_target = strnlen(fromName, PATH_MAX); 2993 name_len_target++; /* trailing null */ 2994 strncpy(data_offset, fromName, name_len_target); 2995 } 2996 2997 pSMB->MaxParameterCount = cpu_to_le16(2); 2998 /* BB find exact max on data count below from sess*/ 2999 pSMB->MaxDataCount = cpu_to_le16(1000); 3000 pSMB->SetupCount = 1; 3001 pSMB->Reserved3 = 0; 3002 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 3003 byte_count = 3 /* pad */ + params + name_len_target; 3004 pSMB->ParameterCount = cpu_to_le16(params); 3005 pSMB->TotalParameterCount = pSMB->ParameterCount; 3006 pSMB->DataCount = cpu_to_le16(name_len_target); 3007 pSMB->TotalDataCount = pSMB->DataCount; 3008 pSMB->ParameterOffset = cpu_to_le16(param_offset); 3009 pSMB->DataOffset = cpu_to_le16(offset); 3010 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK); 3011 pSMB->Reserved4 = 0; 3012 inc_rfc1001_len(pSMB, byte_count); 3013 pSMB->ByteCount = cpu_to_le16(byte_count); 3014 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3015 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3016 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks); 3017 if (rc) 3018 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n", 3019 rc); 3020 3021 cifs_buf_release(pSMB); 3022 if (rc == -EAGAIN) 3023 goto createHardLinkRetry; 3024 3025 return rc; 3026 } 3027 3028 int 3029 CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, 3030 const char *from_name, const char *to_name, 3031 struct cifs_sb_info *cifs_sb) 3032 { 3033 int rc = 0; 3034 NT_RENAME_REQ *pSMB = NULL; 3035 RENAME_RSP *pSMBr = NULL; 3036 int bytes_returned; 3037 int name_len, name_len2; 3038 __u16 count; 3039 int remap = cifs_remap(cifs_sb); 3040 3041 cifs_dbg(FYI, "In CIFSCreateHardLink\n"); 3042 winCreateHardLinkRetry: 3043 3044 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB, 3045 (void **) &pSMBr); 3046 if (rc) 3047 return rc; 3048 3049 pSMB->SearchAttributes = 3050 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 3051 ATTR_DIRECTORY); 3052 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK); 3053 pSMB->ClusterCount = 0; 3054 3055 pSMB->BufferFormat = 0x04; 3056 3057 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3058 name_len = 3059 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name, 3060 PATH_MAX, cifs_sb->local_nls, remap); 3061 name_len++; /* trailing null */ 3062 name_len *= 2; 3063 3064 /* protocol specifies ASCII buffer format (0x04) for unicode */ 3065 pSMB->OldFileName[name_len] = 0x04; 3066 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */ 3067 name_len2 = 3068 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2], 3069 to_name, PATH_MAX, cifs_sb->local_nls, 3070 remap); 3071 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 3072 name_len2 *= 2; /* convert to bytes */ 3073 } else { /* BB improve the check for buffer overruns BB */ 3074 name_len = strnlen(from_name, PATH_MAX); 3075 name_len++; /* trailing null */ 3076 strncpy(pSMB->OldFileName, from_name, name_len); 3077 name_len2 = strnlen(to_name, PATH_MAX); 3078 name_len2++; /* trailing null */ 3079 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ 3080 strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2); 3081 name_len2++; /* trailing null */ 3082 name_len2++; /* signature byte */ 3083 } 3084 3085 count = 1 /* string type byte */ + name_len + name_len2; 3086 inc_rfc1001_len(pSMB, count); 3087 pSMB->ByteCount = cpu_to_le16(count); 3088 3089 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3090 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3091 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks); 3092 if (rc) 3093 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc); 3094 3095 cifs_buf_release(pSMB); 3096 if (rc == -EAGAIN) 3097 goto winCreateHardLinkRetry; 3098 3099 return rc; 3100 } 3101 3102 int 3103 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon, 3104 const unsigned char *searchName, char **symlinkinfo, 3105 const struct nls_table *nls_codepage, int remap) 3106 { 3107 /* SMB_QUERY_FILE_UNIX_LINK */ 3108 TRANSACTION2_QPI_REQ *pSMB = NULL; 3109 TRANSACTION2_QPI_RSP *pSMBr = NULL; 3110 int rc = 0; 3111 int bytes_returned; 3112 int name_len; 3113 __u16 params, byte_count; 3114 char *data_start; 3115 3116 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName); 3117 3118 querySymLinkRetry: 3119 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3120 (void **) &pSMBr); 3121 if (rc) 3122 return rc; 3123 3124 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3125 name_len = 3126 cifsConvertToUTF16((__le16 *) pSMB->FileName, 3127 searchName, PATH_MAX, nls_codepage, 3128 remap); 3129 name_len++; /* trailing null */ 3130 name_len *= 2; 3131 } else { /* BB improve the check for buffer overruns BB */ 3132 name_len = strnlen(searchName, PATH_MAX); 3133 name_len++; /* trailing null */ 3134 strncpy(pSMB->FileName, searchName, name_len); 3135 } 3136 3137 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 3138 pSMB->TotalDataCount = 0; 3139 pSMB->MaxParameterCount = cpu_to_le16(2); 3140 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 3141 pSMB->MaxSetupCount = 0; 3142 pSMB->Reserved = 0; 3143 pSMB->Flags = 0; 3144 pSMB->Timeout = 0; 3145 pSMB->Reserved2 = 0; 3146 pSMB->ParameterOffset = cpu_to_le16(offsetof( 3147 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 3148 pSMB->DataCount = 0; 3149 pSMB->DataOffset = 0; 3150 pSMB->SetupCount = 1; 3151 pSMB->Reserved3 = 0; 3152 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 3153 byte_count = params + 1 /* pad */ ; 3154 pSMB->TotalParameterCount = cpu_to_le16(params); 3155 pSMB->ParameterCount = pSMB->TotalParameterCount; 3156 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK); 3157 pSMB->Reserved4 = 0; 3158 inc_rfc1001_len(pSMB, byte_count); 3159 pSMB->ByteCount = cpu_to_le16(byte_count); 3160 3161 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3162 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3163 if (rc) { 3164 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc); 3165 } else { 3166 /* decode response */ 3167 3168 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3169 /* BB also check enough total bytes returned */ 3170 if (rc || get_bcc(&pSMBr->hdr) < 2) 3171 rc = -EIO; 3172 else { 3173 bool is_unicode; 3174 u16 count = le16_to_cpu(pSMBr->t2.DataCount); 3175 3176 data_start = ((char *) &pSMBr->hdr.Protocol) + 3177 le16_to_cpu(pSMBr->t2.DataOffset); 3178 3179 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) 3180 is_unicode = true; 3181 else 3182 is_unicode = false; 3183 3184 /* BB FIXME investigate remapping reserved chars here */ 3185 *symlinkinfo = cifs_strndup_from_utf16(data_start, 3186 count, is_unicode, nls_codepage); 3187 if (!*symlinkinfo) 3188 rc = -ENOMEM; 3189 } 3190 } 3191 cifs_buf_release(pSMB); 3192 if (rc == -EAGAIN) 3193 goto querySymLinkRetry; 3194 return rc; 3195 } 3196 3197 /* 3198 * Recent Windows versions now create symlinks more frequently 3199 * and they use the "reparse point" mechanism below. We can of course 3200 * do symlinks nicely to Samba and other servers which support the 3201 * CIFS Unix Extensions and we can also do SFU symlinks and "client only" 3202 * "MF" symlinks optionally, but for recent Windows we really need to 3203 * reenable the code below and fix the cifs_symlink callers to handle this. 3204 * In the interim this code has been moved to its own config option so 3205 * it is not compiled in by default until callers fixed up and more tested. 3206 */ 3207 int 3208 CIFSSMBQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon, 3209 __u16 fid, char **symlinkinfo, 3210 const struct nls_table *nls_codepage) 3211 { 3212 int rc = 0; 3213 int bytes_returned; 3214 struct smb_com_transaction_ioctl_req *pSMB; 3215 struct smb_com_transaction_ioctl_rsp *pSMBr; 3216 bool is_unicode; 3217 unsigned int sub_len; 3218 char *sub_start; 3219 struct reparse_symlink_data *reparse_buf; 3220 struct reparse_posix_data *posix_buf; 3221 __u32 data_offset, data_count; 3222 char *end_of_smb; 3223 3224 cifs_dbg(FYI, "In Windows reparse style QueryLink for fid %u\n", fid); 3225 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB, 3226 (void **) &pSMBr); 3227 if (rc) 3228 return rc; 3229 3230 pSMB->TotalParameterCount = 0 ; 3231 pSMB->TotalDataCount = 0; 3232 pSMB->MaxParameterCount = cpu_to_le32(2); 3233 /* BB find exact data count max from sess structure BB */ 3234 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00); 3235 pSMB->MaxSetupCount = 4; 3236 pSMB->Reserved = 0; 3237 pSMB->ParameterOffset = 0; 3238 pSMB->DataCount = 0; 3239 pSMB->DataOffset = 0; 3240 pSMB->SetupCount = 4; 3241 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL); 3242 pSMB->ParameterCount = pSMB->TotalParameterCount; 3243 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT); 3244 pSMB->IsFsctl = 1; /* FSCTL */ 3245 pSMB->IsRootFlag = 0; 3246 pSMB->Fid = fid; /* file handle always le */ 3247 pSMB->ByteCount = 0; 3248 3249 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3250 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3251 if (rc) { 3252 cifs_dbg(FYI, "Send error in QueryReparseLinkInfo = %d\n", rc); 3253 goto qreparse_out; 3254 } 3255 3256 data_offset = le32_to_cpu(pSMBr->DataOffset); 3257 data_count = le32_to_cpu(pSMBr->DataCount); 3258 if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) { 3259 /* BB also check enough total bytes returned */ 3260 rc = -EIO; /* bad smb */ 3261 goto qreparse_out; 3262 } 3263 if (!data_count || (data_count > 2048)) { 3264 rc = -EIO; 3265 cifs_dbg(FYI, "Invalid return data count on get reparse info ioctl\n"); 3266 goto qreparse_out; 3267 } 3268 end_of_smb = 2 + get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount; 3269 reparse_buf = (struct reparse_symlink_data *) 3270 ((char *)&pSMBr->hdr.Protocol + data_offset); 3271 if ((char *)reparse_buf >= end_of_smb) { 3272 rc = -EIO; 3273 goto qreparse_out; 3274 } 3275 if (reparse_buf->ReparseTag == cpu_to_le32(IO_REPARSE_TAG_NFS)) { 3276 cifs_dbg(FYI, "NFS style reparse tag\n"); 3277 posix_buf = (struct reparse_posix_data *)reparse_buf; 3278 3279 if (posix_buf->InodeType != cpu_to_le64(NFS_SPECFILE_LNK)) { 3280 cifs_dbg(FYI, "unsupported file type 0x%llx\n", 3281 le64_to_cpu(posix_buf->InodeType)); 3282 rc = -EOPNOTSUPP; 3283 goto qreparse_out; 3284 } 3285 is_unicode = true; 3286 sub_len = le16_to_cpu(reparse_buf->ReparseDataLength); 3287 if (posix_buf->PathBuffer + sub_len > end_of_smb) { 3288 cifs_dbg(FYI, "reparse buf beyond SMB\n"); 3289 rc = -EIO; 3290 goto qreparse_out; 3291 } 3292 *symlinkinfo = cifs_strndup_from_utf16(posix_buf->PathBuffer, 3293 sub_len, is_unicode, nls_codepage); 3294 goto qreparse_out; 3295 } else if (reparse_buf->ReparseTag != 3296 cpu_to_le32(IO_REPARSE_TAG_SYMLINK)) { 3297 rc = -EOPNOTSUPP; 3298 goto qreparse_out; 3299 } 3300 3301 /* Reparse tag is NTFS symlink */ 3302 sub_start = le16_to_cpu(reparse_buf->SubstituteNameOffset) + 3303 reparse_buf->PathBuffer; 3304 sub_len = le16_to_cpu(reparse_buf->SubstituteNameLength); 3305 if (sub_start + sub_len > end_of_smb) { 3306 cifs_dbg(FYI, "reparse buf beyond SMB\n"); 3307 rc = -EIO; 3308 goto qreparse_out; 3309 } 3310 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) 3311 is_unicode = true; 3312 else 3313 is_unicode = false; 3314 3315 /* BB FIXME investigate remapping reserved chars here */ 3316 *symlinkinfo = cifs_strndup_from_utf16(sub_start, sub_len, is_unicode, 3317 nls_codepage); 3318 if (!*symlinkinfo) 3319 rc = -ENOMEM; 3320 qreparse_out: 3321 cifs_buf_release(pSMB); 3322 3323 /* 3324 * Note: On -EAGAIN error only caller can retry on handle based calls 3325 * since file handle passed in no longer valid. 3326 */ 3327 return rc; 3328 } 3329 3330 int 3331 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon, 3332 __u16 fid) 3333 { 3334 int rc = 0; 3335 int bytes_returned; 3336 struct smb_com_transaction_compr_ioctl_req *pSMB; 3337 struct smb_com_transaction_ioctl_rsp *pSMBr; 3338 3339 cifs_dbg(FYI, "Set compression for %u\n", fid); 3340 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB, 3341 (void **) &pSMBr); 3342 if (rc) 3343 return rc; 3344 3345 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT); 3346 3347 pSMB->TotalParameterCount = 0; 3348 pSMB->TotalDataCount = cpu_to_le32(2); 3349 pSMB->MaxParameterCount = 0; 3350 pSMB->MaxDataCount = 0; 3351 pSMB->MaxSetupCount = 4; 3352 pSMB->Reserved = 0; 3353 pSMB->ParameterOffset = 0; 3354 pSMB->DataCount = cpu_to_le32(2); 3355 pSMB->DataOffset = 3356 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req, 3357 compression_state) - 4); /* 84 */ 3358 pSMB->SetupCount = 4; 3359 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL); 3360 pSMB->ParameterCount = 0; 3361 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION); 3362 pSMB->IsFsctl = 1; /* FSCTL */ 3363 pSMB->IsRootFlag = 0; 3364 pSMB->Fid = fid; /* file handle always le */ 3365 /* 3 byte pad, followed by 2 byte compress state */ 3366 pSMB->ByteCount = cpu_to_le16(5); 3367 inc_rfc1001_len(pSMB, 5); 3368 3369 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3370 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3371 if (rc) 3372 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc); 3373 3374 cifs_buf_release(pSMB); 3375 3376 /* 3377 * Note: On -EAGAIN error only caller can retry on handle based calls 3378 * since file handle passed in no longer valid. 3379 */ 3380 return rc; 3381 } 3382 3383 3384 #ifdef CONFIG_CIFS_POSIX 3385 3386 /*Convert an Access Control Entry from wire format to local POSIX xattr format*/ 3387 static void cifs_convert_ace(struct posix_acl_xattr_entry *ace, 3388 struct cifs_posix_ace *cifs_ace) 3389 { 3390 /* u8 cifs fields do not need le conversion */ 3391 ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm); 3392 ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag); 3393 ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid)); 3394 /* 3395 cifs_dbg(FYI, "perm %d tag %d id %d\n", 3396 ace->e_perm, ace->e_tag, ace->e_id); 3397 */ 3398 3399 return; 3400 } 3401 3402 /* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */ 3403 static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen, 3404 const int acl_type, const int size_of_data_area) 3405 { 3406 int size = 0; 3407 int i; 3408 __u16 count; 3409 struct cifs_posix_ace *pACE; 3410 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src; 3411 struct posix_acl_xattr_header *local_acl = (void *)trgt; 3412 3413 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION) 3414 return -EOPNOTSUPP; 3415 3416 if (acl_type == ACL_TYPE_ACCESS) { 3417 count = le16_to_cpu(cifs_acl->access_entry_count); 3418 pACE = &cifs_acl->ace_array[0]; 3419 size = sizeof(struct cifs_posix_acl); 3420 size += sizeof(struct cifs_posix_ace) * count; 3421 /* check if we would go beyond end of SMB */ 3422 if (size_of_data_area < size) { 3423 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n", 3424 size_of_data_area, size); 3425 return -EINVAL; 3426 } 3427 } else if (acl_type == ACL_TYPE_DEFAULT) { 3428 count = le16_to_cpu(cifs_acl->access_entry_count); 3429 size = sizeof(struct cifs_posix_acl); 3430 size += sizeof(struct cifs_posix_ace) * count; 3431 /* skip past access ACEs to get to default ACEs */ 3432 pACE = &cifs_acl->ace_array[count]; 3433 count = le16_to_cpu(cifs_acl->default_entry_count); 3434 size += sizeof(struct cifs_posix_ace) * count; 3435 /* check if we would go beyond end of SMB */ 3436 if (size_of_data_area < size) 3437 return -EINVAL; 3438 } else { 3439 /* illegal type */ 3440 return -EINVAL; 3441 } 3442 3443 size = posix_acl_xattr_size(count); 3444 if ((buflen == 0) || (local_acl == NULL)) { 3445 /* used to query ACL EA size */ 3446 } else if (size > buflen) { 3447 return -ERANGE; 3448 } else /* buffer big enough */ { 3449 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1); 3450 3451 local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION); 3452 for (i = 0; i < count ; i++) { 3453 cifs_convert_ace(&ace[i], pACE); 3454 pACE++; 3455 } 3456 } 3457 return size; 3458 } 3459 3460 static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace, 3461 const struct posix_acl_xattr_entry *local_ace) 3462 { 3463 __u16 rc = 0; /* 0 = ACL converted ok */ 3464 3465 cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm); 3466 cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag); 3467 /* BB is there a better way to handle the large uid? */ 3468 if (local_ace->e_id == cpu_to_le32(-1)) { 3469 /* Probably no need to le convert -1 on any arch but can not hurt */ 3470 cifs_ace->cifs_uid = cpu_to_le64(-1); 3471 } else 3472 cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id)); 3473 /* 3474 cifs_dbg(FYI, "perm %d tag %d id %d\n", 3475 ace->e_perm, ace->e_tag, ace->e_id); 3476 */ 3477 return rc; 3478 } 3479 3480 /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */ 3481 static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL, 3482 const int buflen, const int acl_type) 3483 { 3484 __u16 rc = 0; 3485 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data; 3486 struct posix_acl_xattr_header *local_acl = (void *)pACL; 3487 struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1); 3488 int count; 3489 int i; 3490 3491 if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL)) 3492 return 0; 3493 3494 count = posix_acl_xattr_count((size_t)buflen); 3495 cifs_dbg(FYI, "setting acl with %d entries from buf of length %d and version of %d\n", 3496 count, buflen, le32_to_cpu(local_acl->a_version)); 3497 if (le32_to_cpu(local_acl->a_version) != 2) { 3498 cifs_dbg(FYI, "unknown POSIX ACL version %d\n", 3499 le32_to_cpu(local_acl->a_version)); 3500 return 0; 3501 } 3502 cifs_acl->version = cpu_to_le16(1); 3503 if (acl_type == ACL_TYPE_ACCESS) { 3504 cifs_acl->access_entry_count = cpu_to_le16(count); 3505 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF); 3506 } else if (acl_type == ACL_TYPE_DEFAULT) { 3507 cifs_acl->default_entry_count = cpu_to_le16(count); 3508 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF); 3509 } else { 3510 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type); 3511 return 0; 3512 } 3513 for (i = 0; i < count; i++) { 3514 rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i], &ace[i]); 3515 if (rc != 0) { 3516 /* ACE not converted */ 3517 break; 3518 } 3519 } 3520 if (rc == 0) { 3521 rc = (__u16)(count * sizeof(struct cifs_posix_ace)); 3522 rc += sizeof(struct cifs_posix_acl); 3523 /* BB add check to make sure ACL does not overflow SMB */ 3524 } 3525 return rc; 3526 } 3527 3528 int 3529 CIFSSMBGetPosixACL(const unsigned int xid, struct cifs_tcon *tcon, 3530 const unsigned char *searchName, 3531 char *acl_inf, const int buflen, const int acl_type, 3532 const struct nls_table *nls_codepage, int remap) 3533 { 3534 /* SMB_QUERY_POSIX_ACL */ 3535 TRANSACTION2_QPI_REQ *pSMB = NULL; 3536 TRANSACTION2_QPI_RSP *pSMBr = NULL; 3537 int rc = 0; 3538 int bytes_returned; 3539 int name_len; 3540 __u16 params, byte_count; 3541 3542 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName); 3543 3544 queryAclRetry: 3545 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3546 (void **) &pSMBr); 3547 if (rc) 3548 return rc; 3549 3550 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3551 name_len = 3552 cifsConvertToUTF16((__le16 *) pSMB->FileName, 3553 searchName, PATH_MAX, nls_codepage, 3554 remap); 3555 name_len++; /* trailing null */ 3556 name_len *= 2; 3557 pSMB->FileName[name_len] = 0; 3558 pSMB->FileName[name_len+1] = 0; 3559 } else { /* BB improve the check for buffer overruns BB */ 3560 name_len = strnlen(searchName, PATH_MAX); 3561 name_len++; /* trailing null */ 3562 strncpy(pSMB->FileName, searchName, name_len); 3563 } 3564 3565 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 3566 pSMB->TotalDataCount = 0; 3567 pSMB->MaxParameterCount = cpu_to_le16(2); 3568 /* BB find exact max data count below from sess structure BB */ 3569 pSMB->MaxDataCount = cpu_to_le16(4000); 3570 pSMB->MaxSetupCount = 0; 3571 pSMB->Reserved = 0; 3572 pSMB->Flags = 0; 3573 pSMB->Timeout = 0; 3574 pSMB->Reserved2 = 0; 3575 pSMB->ParameterOffset = cpu_to_le16( 3576 offsetof(struct smb_com_transaction2_qpi_req, 3577 InformationLevel) - 4); 3578 pSMB->DataCount = 0; 3579 pSMB->DataOffset = 0; 3580 pSMB->SetupCount = 1; 3581 pSMB->Reserved3 = 0; 3582 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 3583 byte_count = params + 1 /* pad */ ; 3584 pSMB->TotalParameterCount = cpu_to_le16(params); 3585 pSMB->ParameterCount = pSMB->TotalParameterCount; 3586 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL); 3587 pSMB->Reserved4 = 0; 3588 inc_rfc1001_len(pSMB, byte_count); 3589 pSMB->ByteCount = cpu_to_le16(byte_count); 3590 3591 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3592 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3593 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get); 3594 if (rc) { 3595 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc); 3596 } else { 3597 /* decode response */ 3598 3599 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3600 /* BB also check enough total bytes returned */ 3601 if (rc || get_bcc(&pSMBr->hdr) < 2) 3602 rc = -EIO; /* bad smb */ 3603 else { 3604 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3605 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 3606 rc = cifs_copy_posix_acl(acl_inf, 3607 (char *)&pSMBr->hdr.Protocol+data_offset, 3608 buflen, acl_type, count); 3609 } 3610 } 3611 cifs_buf_release(pSMB); 3612 if (rc == -EAGAIN) 3613 goto queryAclRetry; 3614 return rc; 3615 } 3616 3617 int 3618 CIFSSMBSetPosixACL(const unsigned int xid, struct cifs_tcon *tcon, 3619 const unsigned char *fileName, 3620 const char *local_acl, const int buflen, 3621 const int acl_type, 3622 const struct nls_table *nls_codepage, int remap) 3623 { 3624 struct smb_com_transaction2_spi_req *pSMB = NULL; 3625 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 3626 char *parm_data; 3627 int name_len; 3628 int rc = 0; 3629 int bytes_returned = 0; 3630 __u16 params, byte_count, data_count, param_offset, offset; 3631 3632 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName); 3633 setAclRetry: 3634 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3635 (void **) &pSMBr); 3636 if (rc) 3637 return rc; 3638 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3639 name_len = 3640 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 3641 PATH_MAX, nls_codepage, remap); 3642 name_len++; /* trailing null */ 3643 name_len *= 2; 3644 } else { /* BB improve the check for buffer overruns BB */ 3645 name_len = strnlen(fileName, PATH_MAX); 3646 name_len++; /* trailing null */ 3647 strncpy(pSMB->FileName, fileName, name_len); 3648 } 3649 params = 6 + name_len; 3650 pSMB->MaxParameterCount = cpu_to_le16(2); 3651 /* BB find max SMB size from sess */ 3652 pSMB->MaxDataCount = cpu_to_le16(1000); 3653 pSMB->MaxSetupCount = 0; 3654 pSMB->Reserved = 0; 3655 pSMB->Flags = 0; 3656 pSMB->Timeout = 0; 3657 pSMB->Reserved2 = 0; 3658 param_offset = offsetof(struct smb_com_transaction2_spi_req, 3659 InformationLevel) - 4; 3660 offset = param_offset + params; 3661 parm_data = ((char *) &pSMB->hdr.Protocol) + offset; 3662 pSMB->ParameterOffset = cpu_to_le16(param_offset); 3663 3664 /* convert to on the wire format for POSIX ACL */ 3665 data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type); 3666 3667 if (data_count == 0) { 3668 rc = -EOPNOTSUPP; 3669 goto setACLerrorExit; 3670 } 3671 pSMB->DataOffset = cpu_to_le16(offset); 3672 pSMB->SetupCount = 1; 3673 pSMB->Reserved3 = 0; 3674 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 3675 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL); 3676 byte_count = 3 /* pad */ + params + data_count; 3677 pSMB->DataCount = cpu_to_le16(data_count); 3678 pSMB->TotalDataCount = pSMB->DataCount; 3679 pSMB->ParameterCount = cpu_to_le16(params); 3680 pSMB->TotalParameterCount = pSMB->ParameterCount; 3681 pSMB->Reserved4 = 0; 3682 inc_rfc1001_len(pSMB, byte_count); 3683 pSMB->ByteCount = cpu_to_le16(byte_count); 3684 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3685 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3686 if (rc) 3687 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc); 3688 3689 setACLerrorExit: 3690 cifs_buf_release(pSMB); 3691 if (rc == -EAGAIN) 3692 goto setAclRetry; 3693 return rc; 3694 } 3695 3696 /* BB fix tabs in this function FIXME BB */ 3697 int 3698 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon, 3699 const int netfid, __u64 *pExtAttrBits, __u64 *pMask) 3700 { 3701 int rc = 0; 3702 struct smb_t2_qfi_req *pSMB = NULL; 3703 struct smb_t2_qfi_rsp *pSMBr = NULL; 3704 int bytes_returned; 3705 __u16 params, byte_count; 3706 3707 cifs_dbg(FYI, "In GetExtAttr\n"); 3708 if (tcon == NULL) 3709 return -ENODEV; 3710 3711 GetExtAttrRetry: 3712 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3713 (void **) &pSMBr); 3714 if (rc) 3715 return rc; 3716 3717 params = 2 /* level */ + 2 /* fid */; 3718 pSMB->t2.TotalDataCount = 0; 3719 pSMB->t2.MaxParameterCount = cpu_to_le16(4); 3720 /* BB find exact max data count below from sess structure BB */ 3721 pSMB->t2.MaxDataCount = cpu_to_le16(4000); 3722 pSMB->t2.MaxSetupCount = 0; 3723 pSMB->t2.Reserved = 0; 3724 pSMB->t2.Flags = 0; 3725 pSMB->t2.Timeout = 0; 3726 pSMB->t2.Reserved2 = 0; 3727 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 3728 Fid) - 4); 3729 pSMB->t2.DataCount = 0; 3730 pSMB->t2.DataOffset = 0; 3731 pSMB->t2.SetupCount = 1; 3732 pSMB->t2.Reserved3 = 0; 3733 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 3734 byte_count = params + 1 /* pad */ ; 3735 pSMB->t2.TotalParameterCount = cpu_to_le16(params); 3736 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 3737 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS); 3738 pSMB->Pad = 0; 3739 pSMB->Fid = netfid; 3740 inc_rfc1001_len(pSMB, byte_count); 3741 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 3742 3743 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3744 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3745 if (rc) { 3746 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc); 3747 } else { 3748 /* decode response */ 3749 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3750 /* BB also check enough total bytes returned */ 3751 if (rc || get_bcc(&pSMBr->hdr) < 2) 3752 /* If rc should we check for EOPNOSUPP and 3753 disable the srvino flag? or in caller? */ 3754 rc = -EIO; /* bad smb */ 3755 else { 3756 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3757 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 3758 struct file_chattr_info *pfinfo; 3759 /* BB Do we need a cast or hash here ? */ 3760 if (count != 16) { 3761 cifs_dbg(FYI, "Illegal size ret in GetExtAttr\n"); 3762 rc = -EIO; 3763 goto GetExtAttrOut; 3764 } 3765 pfinfo = (struct file_chattr_info *) 3766 (data_offset + (char *) &pSMBr->hdr.Protocol); 3767 *pExtAttrBits = le64_to_cpu(pfinfo->mode); 3768 *pMask = le64_to_cpu(pfinfo->mask); 3769 } 3770 } 3771 GetExtAttrOut: 3772 cifs_buf_release(pSMB); 3773 if (rc == -EAGAIN) 3774 goto GetExtAttrRetry; 3775 return rc; 3776 } 3777 3778 #endif /* CONFIG_POSIX */ 3779 3780 #ifdef CONFIG_CIFS_ACL 3781 /* 3782 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that 3783 * all NT TRANSACTS that we init here have total parm and data under about 400 3784 * bytes (to fit in small cifs buffer size), which is the case so far, it 3785 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of 3786 * returned setup area) and MaxParameterCount (returned parms size) must be set 3787 * by caller 3788 */ 3789 static int 3790 smb_init_nttransact(const __u16 sub_command, const int setup_count, 3791 const int parm_len, struct cifs_tcon *tcon, 3792 void **ret_buf) 3793 { 3794 int rc; 3795 __u32 temp_offset; 3796 struct smb_com_ntransact_req *pSMB; 3797 3798 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon, 3799 (void **)&pSMB); 3800 if (rc) 3801 return rc; 3802 *ret_buf = (void *)pSMB; 3803 pSMB->Reserved = 0; 3804 pSMB->TotalParameterCount = cpu_to_le32(parm_len); 3805 pSMB->TotalDataCount = 0; 3806 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00); 3807 pSMB->ParameterCount = pSMB->TotalParameterCount; 3808 pSMB->DataCount = pSMB->TotalDataCount; 3809 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) + 3810 (setup_count * 2) - 4 /* for rfc1001 length itself */; 3811 pSMB->ParameterOffset = cpu_to_le32(temp_offset); 3812 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len); 3813 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */ 3814 pSMB->SubCommand = cpu_to_le16(sub_command); 3815 return 0; 3816 } 3817 3818 static int 3819 validate_ntransact(char *buf, char **ppparm, char **ppdata, 3820 __u32 *pparmlen, __u32 *pdatalen) 3821 { 3822 char *end_of_smb; 3823 __u32 data_count, data_offset, parm_count, parm_offset; 3824 struct smb_com_ntransact_rsp *pSMBr; 3825 u16 bcc; 3826 3827 *pdatalen = 0; 3828 *pparmlen = 0; 3829 3830 if (buf == NULL) 3831 return -EINVAL; 3832 3833 pSMBr = (struct smb_com_ntransact_rsp *)buf; 3834 3835 bcc = get_bcc(&pSMBr->hdr); 3836 end_of_smb = 2 /* sizeof byte count */ + bcc + 3837 (char *)&pSMBr->ByteCount; 3838 3839 data_offset = le32_to_cpu(pSMBr->DataOffset); 3840 data_count = le32_to_cpu(pSMBr->DataCount); 3841 parm_offset = le32_to_cpu(pSMBr->ParameterOffset); 3842 parm_count = le32_to_cpu(pSMBr->ParameterCount); 3843 3844 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset; 3845 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset; 3846 3847 /* should we also check that parm and data areas do not overlap? */ 3848 if (*ppparm > end_of_smb) { 3849 cifs_dbg(FYI, "parms start after end of smb\n"); 3850 return -EINVAL; 3851 } else if (parm_count + *ppparm > end_of_smb) { 3852 cifs_dbg(FYI, "parm end after end of smb\n"); 3853 return -EINVAL; 3854 } else if (*ppdata > end_of_smb) { 3855 cifs_dbg(FYI, "data starts after end of smb\n"); 3856 return -EINVAL; 3857 } else if (data_count + *ppdata > end_of_smb) { 3858 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n", 3859 *ppdata, data_count, (data_count + *ppdata), 3860 end_of_smb, pSMBr); 3861 return -EINVAL; 3862 } else if (parm_count + data_count > bcc) { 3863 cifs_dbg(FYI, "parm count and data count larger than SMB\n"); 3864 return -EINVAL; 3865 } 3866 *pdatalen = data_count; 3867 *pparmlen = parm_count; 3868 return 0; 3869 } 3870 3871 /* Get Security Descriptor (by handle) from remote server for a file or dir */ 3872 int 3873 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, 3874 struct cifs_ntsd **acl_inf, __u32 *pbuflen) 3875 { 3876 int rc = 0; 3877 int buf_type = 0; 3878 QUERY_SEC_DESC_REQ *pSMB; 3879 struct kvec iov[1]; 3880 struct kvec rsp_iov; 3881 3882 cifs_dbg(FYI, "GetCifsACL\n"); 3883 3884 *pbuflen = 0; 3885 *acl_inf = NULL; 3886 3887 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0, 3888 8 /* parm len */, tcon, (void **) &pSMB); 3889 if (rc) 3890 return rc; 3891 3892 pSMB->MaxParameterCount = cpu_to_le32(4); 3893 /* BB TEST with big acls that might need to be e.g. larger than 16K */ 3894 pSMB->MaxSetupCount = 0; 3895 pSMB->Fid = fid; /* file handle always le */ 3896 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP | 3897 CIFS_ACL_DACL); 3898 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */ 3899 inc_rfc1001_len(pSMB, 11); 3900 iov[0].iov_base = (char *)pSMB; 3901 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4; 3902 3903 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 3904 0, &rsp_iov); 3905 cifs_small_buf_release(pSMB); 3906 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get); 3907 if (rc) { 3908 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc); 3909 } else { /* decode response */ 3910 __le32 *parm; 3911 __u32 parm_len; 3912 __u32 acl_len; 3913 struct smb_com_ntransact_rsp *pSMBr; 3914 char *pdata; 3915 3916 /* validate_nttransact */ 3917 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm, 3918 &pdata, &parm_len, pbuflen); 3919 if (rc) 3920 goto qsec_out; 3921 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base; 3922 3923 cifs_dbg(FYI, "smb %p parm %p data %p\n", 3924 pSMBr, parm, *acl_inf); 3925 3926 if (le32_to_cpu(pSMBr->ParameterCount) != 4) { 3927 rc = -EIO; /* bad smb */ 3928 *pbuflen = 0; 3929 goto qsec_out; 3930 } 3931 3932 /* BB check that data area is minimum length and as big as acl_len */ 3933 3934 acl_len = le32_to_cpu(*parm); 3935 if (acl_len != *pbuflen) { 3936 cifs_dbg(VFS, "acl length %d does not match %d\n", 3937 acl_len, *pbuflen); 3938 if (*pbuflen > acl_len) 3939 *pbuflen = acl_len; 3940 } 3941 3942 /* check if buffer is big enough for the acl 3943 header followed by the smallest SID */ 3944 if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) || 3945 (*pbuflen >= 64 * 1024)) { 3946 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen); 3947 rc = -EINVAL; 3948 *pbuflen = 0; 3949 } else { 3950 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL); 3951 if (*acl_inf == NULL) { 3952 *pbuflen = 0; 3953 rc = -ENOMEM; 3954 } 3955 } 3956 } 3957 qsec_out: 3958 free_rsp_buf(buf_type, rsp_iov.iov_base); 3959 return rc; 3960 } 3961 3962 int 3963 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, 3964 struct cifs_ntsd *pntsd, __u32 acllen, int aclflag) 3965 { 3966 __u16 byte_count, param_count, data_count, param_offset, data_offset; 3967 int rc = 0; 3968 int bytes_returned = 0; 3969 SET_SEC_DESC_REQ *pSMB = NULL; 3970 void *pSMBr; 3971 3972 setCifsAclRetry: 3973 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr); 3974 if (rc) 3975 return rc; 3976 3977 pSMB->MaxSetupCount = 0; 3978 pSMB->Reserved = 0; 3979 3980 param_count = 8; 3981 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4; 3982 data_count = acllen; 3983 data_offset = param_offset + param_count; 3984 byte_count = 3 /* pad */ + param_count; 3985 3986 pSMB->DataCount = cpu_to_le32(data_count); 3987 pSMB->TotalDataCount = pSMB->DataCount; 3988 pSMB->MaxParameterCount = cpu_to_le32(4); 3989 pSMB->MaxDataCount = cpu_to_le32(16384); 3990 pSMB->ParameterCount = cpu_to_le32(param_count); 3991 pSMB->ParameterOffset = cpu_to_le32(param_offset); 3992 pSMB->TotalParameterCount = pSMB->ParameterCount; 3993 pSMB->DataOffset = cpu_to_le32(data_offset); 3994 pSMB->SetupCount = 0; 3995 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC); 3996 pSMB->ByteCount = cpu_to_le16(byte_count+data_count); 3997 3998 pSMB->Fid = fid; /* file handle always le */ 3999 pSMB->Reserved2 = 0; 4000 pSMB->AclFlags = cpu_to_le32(aclflag); 4001 4002 if (pntsd && acllen) { 4003 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) + 4004 data_offset, pntsd, acllen); 4005 inc_rfc1001_len(pSMB, byte_count + data_count); 4006 } else 4007 inc_rfc1001_len(pSMB, byte_count); 4008 4009 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4010 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4011 4012 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n", 4013 bytes_returned, rc); 4014 if (rc) 4015 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc); 4016 cifs_buf_release(pSMB); 4017 4018 if (rc == -EAGAIN) 4019 goto setCifsAclRetry; 4020 4021 return (rc); 4022 } 4023 4024 #endif /* CONFIG_CIFS_ACL */ 4025 4026 /* Legacy Query Path Information call for lookup to old servers such 4027 as Win9x/WinME */ 4028 int 4029 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon, 4030 const char *search_name, FILE_ALL_INFO *data, 4031 const struct nls_table *nls_codepage, int remap) 4032 { 4033 QUERY_INFORMATION_REQ *pSMB; 4034 QUERY_INFORMATION_RSP *pSMBr; 4035 int rc = 0; 4036 int bytes_returned; 4037 int name_len; 4038 4039 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name); 4040 QInfRetry: 4041 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB, 4042 (void **) &pSMBr); 4043 if (rc) 4044 return rc; 4045 4046 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4047 name_len = 4048 cifsConvertToUTF16((__le16 *) pSMB->FileName, 4049 search_name, PATH_MAX, nls_codepage, 4050 remap); 4051 name_len++; /* trailing null */ 4052 name_len *= 2; 4053 } else { 4054 name_len = strnlen(search_name, PATH_MAX); 4055 name_len++; /* trailing null */ 4056 strncpy(pSMB->FileName, search_name, name_len); 4057 } 4058 pSMB->BufferFormat = 0x04; 4059 name_len++; /* account for buffer type byte */ 4060 inc_rfc1001_len(pSMB, (__u16)name_len); 4061 pSMB->ByteCount = cpu_to_le16(name_len); 4062 4063 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4064 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4065 if (rc) { 4066 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc); 4067 } else if (data) { 4068 struct timespec ts; 4069 __u32 time = le32_to_cpu(pSMBr->last_write_time); 4070 4071 /* decode response */ 4072 /* BB FIXME - add time zone adjustment BB */ 4073 memset(data, 0, sizeof(FILE_ALL_INFO)); 4074 ts.tv_nsec = 0; 4075 ts.tv_sec = time; 4076 /* decode time fields */ 4077 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts)); 4078 data->LastWriteTime = data->ChangeTime; 4079 data->LastAccessTime = 0; 4080 data->AllocationSize = 4081 cpu_to_le64(le32_to_cpu(pSMBr->size)); 4082 data->EndOfFile = data->AllocationSize; 4083 data->Attributes = 4084 cpu_to_le32(le16_to_cpu(pSMBr->attr)); 4085 } else 4086 rc = -EIO; /* bad buffer passed in */ 4087 4088 cifs_buf_release(pSMB); 4089 4090 if (rc == -EAGAIN) 4091 goto QInfRetry; 4092 4093 return rc; 4094 } 4095 4096 int 4097 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 4098 u16 netfid, FILE_ALL_INFO *pFindData) 4099 { 4100 struct smb_t2_qfi_req *pSMB = NULL; 4101 struct smb_t2_qfi_rsp *pSMBr = NULL; 4102 int rc = 0; 4103 int bytes_returned; 4104 __u16 params, byte_count; 4105 4106 QFileInfoRetry: 4107 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4108 (void **) &pSMBr); 4109 if (rc) 4110 return rc; 4111 4112 params = 2 /* level */ + 2 /* fid */; 4113 pSMB->t2.TotalDataCount = 0; 4114 pSMB->t2.MaxParameterCount = cpu_to_le16(4); 4115 /* BB find exact max data count below from sess structure BB */ 4116 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 4117 pSMB->t2.MaxSetupCount = 0; 4118 pSMB->t2.Reserved = 0; 4119 pSMB->t2.Flags = 0; 4120 pSMB->t2.Timeout = 0; 4121 pSMB->t2.Reserved2 = 0; 4122 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 4123 Fid) - 4); 4124 pSMB->t2.DataCount = 0; 4125 pSMB->t2.DataOffset = 0; 4126 pSMB->t2.SetupCount = 1; 4127 pSMB->t2.Reserved3 = 0; 4128 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 4129 byte_count = params + 1 /* pad */ ; 4130 pSMB->t2.TotalParameterCount = cpu_to_le16(params); 4131 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 4132 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 4133 pSMB->Pad = 0; 4134 pSMB->Fid = netfid; 4135 inc_rfc1001_len(pSMB, byte_count); 4136 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 4137 4138 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4139 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4140 if (rc) { 4141 cifs_dbg(FYI, "Send error in QFileInfo = %d", rc); 4142 } else { /* decode response */ 4143 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4144 4145 if (rc) /* BB add auto retry on EOPNOTSUPP? */ 4146 rc = -EIO; 4147 else if (get_bcc(&pSMBr->hdr) < 40) 4148 rc = -EIO; /* bad smb */ 4149 else if (pFindData) { 4150 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4151 memcpy((char *) pFindData, 4152 (char *) &pSMBr->hdr.Protocol + 4153 data_offset, sizeof(FILE_ALL_INFO)); 4154 } else 4155 rc = -ENOMEM; 4156 } 4157 cifs_buf_release(pSMB); 4158 if (rc == -EAGAIN) 4159 goto QFileInfoRetry; 4160 4161 return rc; 4162 } 4163 4164 int 4165 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 4166 const char *search_name, FILE_ALL_INFO *data, 4167 int legacy /* old style infolevel */, 4168 const struct nls_table *nls_codepage, int remap) 4169 { 4170 /* level 263 SMB_QUERY_FILE_ALL_INFO */ 4171 TRANSACTION2_QPI_REQ *pSMB = NULL; 4172 TRANSACTION2_QPI_RSP *pSMBr = NULL; 4173 int rc = 0; 4174 int bytes_returned; 4175 int name_len; 4176 __u16 params, byte_count; 4177 4178 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */ 4179 QPathInfoRetry: 4180 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4181 (void **) &pSMBr); 4182 if (rc) 4183 return rc; 4184 4185 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4186 name_len = 4187 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name, 4188 PATH_MAX, nls_codepage, remap); 4189 name_len++; /* trailing null */ 4190 name_len *= 2; 4191 } else { /* BB improve the check for buffer overruns BB */ 4192 name_len = strnlen(search_name, PATH_MAX); 4193 name_len++; /* trailing null */ 4194 strncpy(pSMB->FileName, search_name, name_len); 4195 } 4196 4197 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; 4198 pSMB->TotalDataCount = 0; 4199 pSMB->MaxParameterCount = cpu_to_le16(2); 4200 /* BB find exact max SMB PDU from sess structure BB */ 4201 pSMB->MaxDataCount = cpu_to_le16(4000); 4202 pSMB->MaxSetupCount = 0; 4203 pSMB->Reserved = 0; 4204 pSMB->Flags = 0; 4205 pSMB->Timeout = 0; 4206 pSMB->Reserved2 = 0; 4207 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4208 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 4209 pSMB->DataCount = 0; 4210 pSMB->DataOffset = 0; 4211 pSMB->SetupCount = 1; 4212 pSMB->Reserved3 = 0; 4213 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 4214 byte_count = params + 1 /* pad */ ; 4215 pSMB->TotalParameterCount = cpu_to_le16(params); 4216 pSMB->ParameterCount = pSMB->TotalParameterCount; 4217 if (legacy) 4218 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD); 4219 else 4220 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 4221 pSMB->Reserved4 = 0; 4222 inc_rfc1001_len(pSMB, byte_count); 4223 pSMB->ByteCount = cpu_to_le16(byte_count); 4224 4225 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4226 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4227 if (rc) { 4228 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc); 4229 } else { /* decode response */ 4230 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4231 4232 if (rc) /* BB add auto retry on EOPNOTSUPP? */ 4233 rc = -EIO; 4234 else if (!legacy && get_bcc(&pSMBr->hdr) < 40) 4235 rc = -EIO; /* bad smb */ 4236 else if (legacy && get_bcc(&pSMBr->hdr) < 24) 4237 rc = -EIO; /* 24 or 26 expected but we do not read 4238 last field */ 4239 else if (data) { 4240 int size; 4241 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4242 4243 /* 4244 * On legacy responses we do not read the last field, 4245 * EAsize, fortunately since it varies by subdialect and 4246 * also note it differs on Set vs Get, ie two bytes or 4 4247 * bytes depending but we don't care here. 4248 */ 4249 if (legacy) 4250 size = sizeof(FILE_INFO_STANDARD); 4251 else 4252 size = sizeof(FILE_ALL_INFO); 4253 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol + 4254 data_offset, size); 4255 } else 4256 rc = -ENOMEM; 4257 } 4258 cifs_buf_release(pSMB); 4259 if (rc == -EAGAIN) 4260 goto QPathInfoRetry; 4261 4262 return rc; 4263 } 4264 4265 int 4266 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 4267 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData) 4268 { 4269 struct smb_t2_qfi_req *pSMB = NULL; 4270 struct smb_t2_qfi_rsp *pSMBr = NULL; 4271 int rc = 0; 4272 int bytes_returned; 4273 __u16 params, byte_count; 4274 4275 UnixQFileInfoRetry: 4276 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4277 (void **) &pSMBr); 4278 if (rc) 4279 return rc; 4280 4281 params = 2 /* level */ + 2 /* fid */; 4282 pSMB->t2.TotalDataCount = 0; 4283 pSMB->t2.MaxParameterCount = cpu_to_le16(4); 4284 /* BB find exact max data count below from sess structure BB */ 4285 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 4286 pSMB->t2.MaxSetupCount = 0; 4287 pSMB->t2.Reserved = 0; 4288 pSMB->t2.Flags = 0; 4289 pSMB->t2.Timeout = 0; 4290 pSMB->t2.Reserved2 = 0; 4291 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 4292 Fid) - 4); 4293 pSMB->t2.DataCount = 0; 4294 pSMB->t2.DataOffset = 0; 4295 pSMB->t2.SetupCount = 1; 4296 pSMB->t2.Reserved3 = 0; 4297 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 4298 byte_count = params + 1 /* pad */ ; 4299 pSMB->t2.TotalParameterCount = cpu_to_le16(params); 4300 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 4301 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); 4302 pSMB->Pad = 0; 4303 pSMB->Fid = netfid; 4304 inc_rfc1001_len(pSMB, byte_count); 4305 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 4306 4307 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4308 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4309 if (rc) { 4310 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d", rc); 4311 } else { /* decode response */ 4312 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4313 4314 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) { 4315 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n"); 4316 rc = -EIO; /* bad smb */ 4317 } else { 4318 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4319 memcpy((char *) pFindData, 4320 (char *) &pSMBr->hdr.Protocol + 4321 data_offset, 4322 sizeof(FILE_UNIX_BASIC_INFO)); 4323 } 4324 } 4325 4326 cifs_buf_release(pSMB); 4327 if (rc == -EAGAIN) 4328 goto UnixQFileInfoRetry; 4329 4330 return rc; 4331 } 4332 4333 int 4334 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 4335 const unsigned char *searchName, 4336 FILE_UNIX_BASIC_INFO *pFindData, 4337 const struct nls_table *nls_codepage, int remap) 4338 { 4339 /* SMB_QUERY_FILE_UNIX_BASIC */ 4340 TRANSACTION2_QPI_REQ *pSMB = NULL; 4341 TRANSACTION2_QPI_RSP *pSMBr = NULL; 4342 int rc = 0; 4343 int bytes_returned = 0; 4344 int name_len; 4345 __u16 params, byte_count; 4346 4347 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName); 4348 UnixQPathInfoRetry: 4349 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4350 (void **) &pSMBr); 4351 if (rc) 4352 return rc; 4353 4354 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4355 name_len = 4356 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, 4357 PATH_MAX, nls_codepage, remap); 4358 name_len++; /* trailing null */ 4359 name_len *= 2; 4360 } else { /* BB improve the check for buffer overruns BB */ 4361 name_len = strnlen(searchName, PATH_MAX); 4362 name_len++; /* trailing null */ 4363 strncpy(pSMB->FileName, searchName, name_len); 4364 } 4365 4366 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; 4367 pSMB->TotalDataCount = 0; 4368 pSMB->MaxParameterCount = cpu_to_le16(2); 4369 /* BB find exact max SMB PDU from sess structure BB */ 4370 pSMB->MaxDataCount = cpu_to_le16(4000); 4371 pSMB->MaxSetupCount = 0; 4372 pSMB->Reserved = 0; 4373 pSMB->Flags = 0; 4374 pSMB->Timeout = 0; 4375 pSMB->Reserved2 = 0; 4376 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4377 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 4378 pSMB->DataCount = 0; 4379 pSMB->DataOffset = 0; 4380 pSMB->SetupCount = 1; 4381 pSMB->Reserved3 = 0; 4382 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 4383 byte_count = params + 1 /* pad */ ; 4384 pSMB->TotalParameterCount = cpu_to_le16(params); 4385 pSMB->ParameterCount = pSMB->TotalParameterCount; 4386 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); 4387 pSMB->Reserved4 = 0; 4388 inc_rfc1001_len(pSMB, byte_count); 4389 pSMB->ByteCount = cpu_to_le16(byte_count); 4390 4391 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4392 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4393 if (rc) { 4394 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d", rc); 4395 } else { /* decode response */ 4396 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4397 4398 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) { 4399 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n"); 4400 rc = -EIO; /* bad smb */ 4401 } else { 4402 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4403 memcpy((char *) pFindData, 4404 (char *) &pSMBr->hdr.Protocol + 4405 data_offset, 4406 sizeof(FILE_UNIX_BASIC_INFO)); 4407 } 4408 } 4409 cifs_buf_release(pSMB); 4410 if (rc == -EAGAIN) 4411 goto UnixQPathInfoRetry; 4412 4413 return rc; 4414 } 4415 4416 /* xid, tcon, searchName and codepage are input parms, rest are returned */ 4417 int 4418 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon, 4419 const char *searchName, struct cifs_sb_info *cifs_sb, 4420 __u16 *pnetfid, __u16 search_flags, 4421 struct cifs_search_info *psrch_inf, bool msearch) 4422 { 4423 /* level 257 SMB_ */ 4424 TRANSACTION2_FFIRST_REQ *pSMB = NULL; 4425 TRANSACTION2_FFIRST_RSP *pSMBr = NULL; 4426 T2_FFIRST_RSP_PARMS *parms; 4427 int rc = 0; 4428 int bytes_returned = 0; 4429 int name_len, remap; 4430 __u16 params, byte_count; 4431 struct nls_table *nls_codepage; 4432 4433 cifs_dbg(FYI, "In FindFirst for %s\n", searchName); 4434 4435 findFirstRetry: 4436 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4437 (void **) &pSMBr); 4438 if (rc) 4439 return rc; 4440 4441 nls_codepage = cifs_sb->local_nls; 4442 remap = cifs_remap(cifs_sb); 4443 4444 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4445 name_len = 4446 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, 4447 PATH_MAX, nls_codepage, remap); 4448 /* We can not add the asterik earlier in case 4449 it got remapped to 0xF03A as if it were part of the 4450 directory name instead of a wildcard */ 4451 name_len *= 2; 4452 if (msearch) { 4453 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb); 4454 pSMB->FileName[name_len+1] = 0; 4455 pSMB->FileName[name_len+2] = '*'; 4456 pSMB->FileName[name_len+3] = 0; 4457 name_len += 4; /* now the trailing null */ 4458 /* null terminate just in case */ 4459 pSMB->FileName[name_len] = 0; 4460 pSMB->FileName[name_len+1] = 0; 4461 name_len += 2; 4462 } 4463 } else { /* BB add check for overrun of SMB buf BB */ 4464 name_len = strnlen(searchName, PATH_MAX); 4465 /* BB fix here and in unicode clause above ie 4466 if (name_len > buffersize-header) 4467 free buffer exit; BB */ 4468 strncpy(pSMB->FileName, searchName, name_len); 4469 if (msearch) { 4470 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb); 4471 pSMB->FileName[name_len+1] = '*'; 4472 pSMB->FileName[name_len+2] = 0; 4473 name_len += 3; 4474 } 4475 } 4476 4477 params = 12 + name_len /* includes null */ ; 4478 pSMB->TotalDataCount = 0; /* no EAs */ 4479 pSMB->MaxParameterCount = cpu_to_le16(10); 4480 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00); 4481 pSMB->MaxSetupCount = 0; 4482 pSMB->Reserved = 0; 4483 pSMB->Flags = 0; 4484 pSMB->Timeout = 0; 4485 pSMB->Reserved2 = 0; 4486 byte_count = params + 1 /* pad */ ; 4487 pSMB->TotalParameterCount = cpu_to_le16(params); 4488 pSMB->ParameterCount = pSMB->TotalParameterCount; 4489 pSMB->ParameterOffset = cpu_to_le16( 4490 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes) 4491 - 4); 4492 pSMB->DataCount = 0; 4493 pSMB->DataOffset = 0; 4494 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */ 4495 pSMB->Reserved3 = 0; 4496 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST); 4497 pSMB->SearchAttributes = 4498 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 4499 ATTR_DIRECTORY); 4500 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO)); 4501 pSMB->SearchFlags = cpu_to_le16(search_flags); 4502 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 4503 4504 /* BB what should we set StorageType to? Does it matter? BB */ 4505 pSMB->SearchStorageType = 0; 4506 inc_rfc1001_len(pSMB, byte_count); 4507 pSMB->ByteCount = cpu_to_le16(byte_count); 4508 4509 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4510 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4511 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst); 4512 4513 if (rc) {/* BB add logic to retry regular search if Unix search 4514 rejected unexpectedly by server */ 4515 /* BB Add code to handle unsupported level rc */ 4516 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc); 4517 4518 cifs_buf_release(pSMB); 4519 4520 /* BB eventually could optimize out free and realloc of buf */ 4521 /* for this case */ 4522 if (rc == -EAGAIN) 4523 goto findFirstRetry; 4524 } else { /* decode response */ 4525 /* BB remember to free buffer if error BB */ 4526 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4527 if (rc == 0) { 4528 unsigned int lnoff; 4529 4530 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) 4531 psrch_inf->unicode = true; 4532 else 4533 psrch_inf->unicode = false; 4534 4535 psrch_inf->ntwrk_buf_start = (char *)pSMBr; 4536 psrch_inf->smallBuf = 0; 4537 psrch_inf->srch_entries_start = 4538 (char *) &pSMBr->hdr.Protocol + 4539 le16_to_cpu(pSMBr->t2.DataOffset); 4540 parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol + 4541 le16_to_cpu(pSMBr->t2.ParameterOffset)); 4542 4543 if (parms->EndofSearch) 4544 psrch_inf->endOfSearch = true; 4545 else 4546 psrch_inf->endOfSearch = false; 4547 4548 psrch_inf->entries_in_buffer = 4549 le16_to_cpu(parms->SearchCount); 4550 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ + 4551 psrch_inf->entries_in_buffer; 4552 lnoff = le16_to_cpu(parms->LastNameOffset); 4553 if (CIFSMaxBufSize < lnoff) { 4554 cifs_dbg(VFS, "ignoring corrupt resume name\n"); 4555 psrch_inf->last_entry = NULL; 4556 return rc; 4557 } 4558 4559 psrch_inf->last_entry = psrch_inf->srch_entries_start + 4560 lnoff; 4561 4562 if (pnetfid) 4563 *pnetfid = parms->SearchHandle; 4564 } else { 4565 cifs_buf_release(pSMB); 4566 } 4567 } 4568 4569 return rc; 4570 } 4571 4572 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon, 4573 __u16 searchHandle, __u16 search_flags, 4574 struct cifs_search_info *psrch_inf) 4575 { 4576 TRANSACTION2_FNEXT_REQ *pSMB = NULL; 4577 TRANSACTION2_FNEXT_RSP *pSMBr = NULL; 4578 T2_FNEXT_RSP_PARMS *parms; 4579 char *response_data; 4580 int rc = 0; 4581 int bytes_returned; 4582 unsigned int name_len; 4583 __u16 params, byte_count; 4584 4585 cifs_dbg(FYI, "In FindNext\n"); 4586 4587 if (psrch_inf->endOfSearch) 4588 return -ENOENT; 4589 4590 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4591 (void **) &pSMBr); 4592 if (rc) 4593 return rc; 4594 4595 params = 14; /* includes 2 bytes of null string, converted to LE below*/ 4596 byte_count = 0; 4597 pSMB->TotalDataCount = 0; /* no EAs */ 4598 pSMB->MaxParameterCount = cpu_to_le16(8); 4599 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00); 4600 pSMB->MaxSetupCount = 0; 4601 pSMB->Reserved = 0; 4602 pSMB->Flags = 0; 4603 pSMB->Timeout = 0; 4604 pSMB->Reserved2 = 0; 4605 pSMB->ParameterOffset = cpu_to_le16( 4606 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4); 4607 pSMB->DataCount = 0; 4608 pSMB->DataOffset = 0; 4609 pSMB->SetupCount = 1; 4610 pSMB->Reserved3 = 0; 4611 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT); 4612 pSMB->SearchHandle = searchHandle; /* always kept as le */ 4613 pSMB->SearchCount = 4614 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO)); 4615 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 4616 pSMB->ResumeKey = psrch_inf->resume_key; 4617 pSMB->SearchFlags = cpu_to_le16(search_flags); 4618 4619 name_len = psrch_inf->resume_name_len; 4620 params += name_len; 4621 if (name_len < PATH_MAX) { 4622 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len); 4623 byte_count += name_len; 4624 /* 14 byte parm len above enough for 2 byte null terminator */ 4625 pSMB->ResumeFileName[name_len] = 0; 4626 pSMB->ResumeFileName[name_len+1] = 0; 4627 } else { 4628 rc = -EINVAL; 4629 goto FNext2_err_exit; 4630 } 4631 byte_count = params + 1 /* pad */ ; 4632 pSMB->TotalParameterCount = cpu_to_le16(params); 4633 pSMB->ParameterCount = pSMB->TotalParameterCount; 4634 inc_rfc1001_len(pSMB, byte_count); 4635 pSMB->ByteCount = cpu_to_le16(byte_count); 4636 4637 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4638 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4639 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext); 4640 if (rc) { 4641 if (rc == -EBADF) { 4642 psrch_inf->endOfSearch = true; 4643 cifs_buf_release(pSMB); 4644 rc = 0; /* search probably was closed at end of search*/ 4645 } else 4646 cifs_dbg(FYI, "FindNext returned = %d\n", rc); 4647 } else { /* decode response */ 4648 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4649 4650 if (rc == 0) { 4651 unsigned int lnoff; 4652 4653 /* BB fixme add lock for file (srch_info) struct here */ 4654 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) 4655 psrch_inf->unicode = true; 4656 else 4657 psrch_inf->unicode = false; 4658 response_data = (char *) &pSMBr->hdr.Protocol + 4659 le16_to_cpu(pSMBr->t2.ParameterOffset); 4660 parms = (T2_FNEXT_RSP_PARMS *)response_data; 4661 response_data = (char *)&pSMBr->hdr.Protocol + 4662 le16_to_cpu(pSMBr->t2.DataOffset); 4663 if (psrch_inf->smallBuf) 4664 cifs_small_buf_release( 4665 psrch_inf->ntwrk_buf_start); 4666 else 4667 cifs_buf_release(psrch_inf->ntwrk_buf_start); 4668 psrch_inf->srch_entries_start = response_data; 4669 psrch_inf->ntwrk_buf_start = (char *)pSMB; 4670 psrch_inf->smallBuf = 0; 4671 if (parms->EndofSearch) 4672 psrch_inf->endOfSearch = true; 4673 else 4674 psrch_inf->endOfSearch = false; 4675 psrch_inf->entries_in_buffer = 4676 le16_to_cpu(parms->SearchCount); 4677 psrch_inf->index_of_last_entry += 4678 psrch_inf->entries_in_buffer; 4679 lnoff = le16_to_cpu(parms->LastNameOffset); 4680 if (CIFSMaxBufSize < lnoff) { 4681 cifs_dbg(VFS, "ignoring corrupt resume name\n"); 4682 psrch_inf->last_entry = NULL; 4683 return rc; 4684 } else 4685 psrch_inf->last_entry = 4686 psrch_inf->srch_entries_start + lnoff; 4687 4688 /* cifs_dbg(FYI, "fnxt2 entries in buf %d index_of_last %d\n", 4689 psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */ 4690 4691 /* BB fixme add unlock here */ 4692 } 4693 4694 } 4695 4696 /* BB On error, should we leave previous search buf (and count and 4697 last entry fields) intact or free the previous one? */ 4698 4699 /* Note: On -EAGAIN error only caller can retry on handle based calls 4700 since file handle passed in no longer valid */ 4701 FNext2_err_exit: 4702 if (rc != 0) 4703 cifs_buf_release(pSMB); 4704 return rc; 4705 } 4706 4707 int 4708 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon, 4709 const __u16 searchHandle) 4710 { 4711 int rc = 0; 4712 FINDCLOSE_REQ *pSMB = NULL; 4713 4714 cifs_dbg(FYI, "In CIFSSMBFindClose\n"); 4715 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB); 4716 4717 /* no sense returning error if session restarted 4718 as file handle has been closed */ 4719 if (rc == -EAGAIN) 4720 return 0; 4721 if (rc) 4722 return rc; 4723 4724 pSMB->FileID = searchHandle; 4725 pSMB->ByteCount = 0; 4726 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 4727 cifs_small_buf_release(pSMB); 4728 if (rc) 4729 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc); 4730 4731 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose); 4732 4733 /* Since session is dead, search handle closed on server already */ 4734 if (rc == -EAGAIN) 4735 rc = 0; 4736 4737 return rc; 4738 } 4739 4740 int 4741 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon, 4742 const char *search_name, __u64 *inode_number, 4743 const struct nls_table *nls_codepage, int remap) 4744 { 4745 int rc = 0; 4746 TRANSACTION2_QPI_REQ *pSMB = NULL; 4747 TRANSACTION2_QPI_RSP *pSMBr = NULL; 4748 int name_len, bytes_returned; 4749 __u16 params, byte_count; 4750 4751 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name); 4752 if (tcon == NULL) 4753 return -ENODEV; 4754 4755 GetInodeNumberRetry: 4756 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4757 (void **) &pSMBr); 4758 if (rc) 4759 return rc; 4760 4761 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4762 name_len = 4763 cifsConvertToUTF16((__le16 *) pSMB->FileName, 4764 search_name, PATH_MAX, nls_codepage, 4765 remap); 4766 name_len++; /* trailing null */ 4767 name_len *= 2; 4768 } else { /* BB improve the check for buffer overruns BB */ 4769 name_len = strnlen(search_name, PATH_MAX); 4770 name_len++; /* trailing null */ 4771 strncpy(pSMB->FileName, search_name, name_len); 4772 } 4773 4774 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 4775 pSMB->TotalDataCount = 0; 4776 pSMB->MaxParameterCount = cpu_to_le16(2); 4777 /* BB find exact max data count below from sess structure BB */ 4778 pSMB->MaxDataCount = cpu_to_le16(4000); 4779 pSMB->MaxSetupCount = 0; 4780 pSMB->Reserved = 0; 4781 pSMB->Flags = 0; 4782 pSMB->Timeout = 0; 4783 pSMB->Reserved2 = 0; 4784 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4785 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 4786 pSMB->DataCount = 0; 4787 pSMB->DataOffset = 0; 4788 pSMB->SetupCount = 1; 4789 pSMB->Reserved3 = 0; 4790 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 4791 byte_count = params + 1 /* pad */ ; 4792 pSMB->TotalParameterCount = cpu_to_le16(params); 4793 pSMB->ParameterCount = pSMB->TotalParameterCount; 4794 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO); 4795 pSMB->Reserved4 = 0; 4796 inc_rfc1001_len(pSMB, byte_count); 4797 pSMB->ByteCount = cpu_to_le16(byte_count); 4798 4799 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4800 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4801 if (rc) { 4802 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc); 4803 } else { 4804 /* decode response */ 4805 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4806 /* BB also check enough total bytes returned */ 4807 if (rc || get_bcc(&pSMBr->hdr) < 2) 4808 /* If rc should we check for EOPNOSUPP and 4809 disable the srvino flag? or in caller? */ 4810 rc = -EIO; /* bad smb */ 4811 else { 4812 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4813 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 4814 struct file_internal_info *pfinfo; 4815 /* BB Do we need a cast or hash here ? */ 4816 if (count < 8) { 4817 cifs_dbg(FYI, "Illegal size ret in QryIntrnlInf\n"); 4818 rc = -EIO; 4819 goto GetInodeNumOut; 4820 } 4821 pfinfo = (struct file_internal_info *) 4822 (data_offset + (char *) &pSMBr->hdr.Protocol); 4823 *inode_number = le64_to_cpu(pfinfo->UniqueId); 4824 } 4825 } 4826 GetInodeNumOut: 4827 cifs_buf_release(pSMB); 4828 if (rc == -EAGAIN) 4829 goto GetInodeNumberRetry; 4830 return rc; 4831 } 4832 4833 int 4834 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses, 4835 const char *search_name, struct dfs_info3_param **target_nodes, 4836 unsigned int *num_of_nodes, 4837 const struct nls_table *nls_codepage, int remap) 4838 { 4839 /* TRANS2_GET_DFS_REFERRAL */ 4840 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL; 4841 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL; 4842 int rc = 0; 4843 int bytes_returned; 4844 int name_len; 4845 __u16 params, byte_count; 4846 *num_of_nodes = 0; 4847 *target_nodes = NULL; 4848 4849 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name); 4850 if (ses == NULL || ses->tcon_ipc == NULL) 4851 return -ENODEV; 4852 4853 getDFSRetry: 4854 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, (void **) &pSMB, 4855 (void **) &pSMBr); 4856 if (rc) 4857 return rc; 4858 4859 /* server pointer checked in called function, 4860 but should never be null here anyway */ 4861 pSMB->hdr.Mid = get_next_mid(ses->server); 4862 pSMB->hdr.Tid = ses->tcon_ipc->tid; 4863 pSMB->hdr.Uid = ses->Suid; 4864 if (ses->capabilities & CAP_STATUS32) 4865 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS; 4866 if (ses->capabilities & CAP_DFS) 4867 pSMB->hdr.Flags2 |= SMBFLG2_DFS; 4868 4869 if (ses->capabilities & CAP_UNICODE) { 4870 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; 4871 name_len = 4872 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName, 4873 search_name, PATH_MAX, nls_codepage, 4874 remap); 4875 name_len++; /* trailing null */ 4876 name_len *= 2; 4877 } else { /* BB improve the check for buffer overruns BB */ 4878 name_len = strnlen(search_name, PATH_MAX); 4879 name_len++; /* trailing null */ 4880 strncpy(pSMB->RequestFileName, search_name, name_len); 4881 } 4882 4883 if (ses->server->sign) 4884 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 4885 4886 pSMB->hdr.Uid = ses->Suid; 4887 4888 params = 2 /* level */ + name_len /*includes null */ ; 4889 pSMB->TotalDataCount = 0; 4890 pSMB->DataCount = 0; 4891 pSMB->DataOffset = 0; 4892 pSMB->MaxParameterCount = 0; 4893 /* BB find exact max SMB PDU from sess structure BB */ 4894 pSMB->MaxDataCount = cpu_to_le16(4000); 4895 pSMB->MaxSetupCount = 0; 4896 pSMB->Reserved = 0; 4897 pSMB->Flags = 0; 4898 pSMB->Timeout = 0; 4899 pSMB->Reserved2 = 0; 4900 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4901 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4); 4902 pSMB->SetupCount = 1; 4903 pSMB->Reserved3 = 0; 4904 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL); 4905 byte_count = params + 3 /* pad */ ; 4906 pSMB->ParameterCount = cpu_to_le16(params); 4907 pSMB->TotalParameterCount = pSMB->ParameterCount; 4908 pSMB->MaxReferralLevel = cpu_to_le16(3); 4909 inc_rfc1001_len(pSMB, byte_count); 4910 pSMB->ByteCount = cpu_to_le16(byte_count); 4911 4912 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 4913 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4914 if (rc) { 4915 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc); 4916 goto GetDFSRefExit; 4917 } 4918 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4919 4920 /* BB Also check if enough total bytes returned? */ 4921 if (rc || get_bcc(&pSMBr->hdr) < 17) { 4922 rc = -EIO; /* bad smb */ 4923 goto GetDFSRefExit; 4924 } 4925 4926 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n", 4927 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset)); 4928 4929 /* parse returned result into more usable form */ 4930 rc = parse_dfs_referrals(&pSMBr->dfs_data, 4931 le16_to_cpu(pSMBr->t2.DataCount), 4932 num_of_nodes, target_nodes, nls_codepage, 4933 remap, search_name, 4934 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0); 4935 4936 GetDFSRefExit: 4937 cifs_buf_release(pSMB); 4938 4939 if (rc == -EAGAIN) 4940 goto getDFSRetry; 4941 4942 return rc; 4943 } 4944 4945 /* Query File System Info such as free space to old servers such as Win 9x */ 4946 int 4947 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon, 4948 struct kstatfs *FSData) 4949 { 4950 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */ 4951 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4952 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4953 FILE_SYSTEM_ALLOC_INFO *response_data; 4954 int rc = 0; 4955 int bytes_returned = 0; 4956 __u16 params, byte_count; 4957 4958 cifs_dbg(FYI, "OldQFSInfo\n"); 4959 oldQFSInfoRetry: 4960 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4961 (void **) &pSMBr); 4962 if (rc) 4963 return rc; 4964 4965 params = 2; /* level */ 4966 pSMB->TotalDataCount = 0; 4967 pSMB->MaxParameterCount = cpu_to_le16(2); 4968 pSMB->MaxDataCount = cpu_to_le16(1000); 4969 pSMB->MaxSetupCount = 0; 4970 pSMB->Reserved = 0; 4971 pSMB->Flags = 0; 4972 pSMB->Timeout = 0; 4973 pSMB->Reserved2 = 0; 4974 byte_count = params + 1 /* pad */ ; 4975 pSMB->TotalParameterCount = cpu_to_le16(params); 4976 pSMB->ParameterCount = pSMB->TotalParameterCount; 4977 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4978 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4979 pSMB->DataCount = 0; 4980 pSMB->DataOffset = 0; 4981 pSMB->SetupCount = 1; 4982 pSMB->Reserved3 = 0; 4983 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4984 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION); 4985 inc_rfc1001_len(pSMB, byte_count); 4986 pSMB->ByteCount = cpu_to_le16(byte_count); 4987 4988 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4989 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4990 if (rc) { 4991 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc); 4992 } else { /* decode response */ 4993 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4994 4995 if (rc || get_bcc(&pSMBr->hdr) < 18) 4996 rc = -EIO; /* bad smb */ 4997 else { 4998 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4999 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n", 5000 get_bcc(&pSMBr->hdr), data_offset); 5001 5002 response_data = (FILE_SYSTEM_ALLOC_INFO *) 5003 (((char *) &pSMBr->hdr.Protocol) + data_offset); 5004 FSData->f_bsize = 5005 le16_to_cpu(response_data->BytesPerSector) * 5006 le32_to_cpu(response_data-> 5007 SectorsPerAllocationUnit); 5008 FSData->f_blocks = 5009 le32_to_cpu(response_data->TotalAllocationUnits); 5010 FSData->f_bfree = FSData->f_bavail = 5011 le32_to_cpu(response_data->FreeAllocationUnits); 5012 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n", 5013 (unsigned long long)FSData->f_blocks, 5014 (unsigned long long)FSData->f_bfree, 5015 FSData->f_bsize); 5016 } 5017 } 5018 cifs_buf_release(pSMB); 5019 5020 if (rc == -EAGAIN) 5021 goto oldQFSInfoRetry; 5022 5023 return rc; 5024 } 5025 5026 int 5027 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon, 5028 struct kstatfs *FSData) 5029 { 5030 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */ 5031 TRANSACTION2_QFSI_REQ *pSMB = NULL; 5032 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 5033 FILE_SYSTEM_INFO *response_data; 5034 int rc = 0; 5035 int bytes_returned = 0; 5036 __u16 params, byte_count; 5037 5038 cifs_dbg(FYI, "In QFSInfo\n"); 5039 QFSInfoRetry: 5040 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5041 (void **) &pSMBr); 5042 if (rc) 5043 return rc; 5044 5045 params = 2; /* level */ 5046 pSMB->TotalDataCount = 0; 5047 pSMB->MaxParameterCount = cpu_to_le16(2); 5048 pSMB->MaxDataCount = cpu_to_le16(1000); 5049 pSMB->MaxSetupCount = 0; 5050 pSMB->Reserved = 0; 5051 pSMB->Flags = 0; 5052 pSMB->Timeout = 0; 5053 pSMB->Reserved2 = 0; 5054 byte_count = params + 1 /* pad */ ; 5055 pSMB->TotalParameterCount = cpu_to_le16(params); 5056 pSMB->ParameterCount = pSMB->TotalParameterCount; 5057 pSMB->ParameterOffset = cpu_to_le16(offsetof( 5058 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 5059 pSMB->DataCount = 0; 5060 pSMB->DataOffset = 0; 5061 pSMB->SetupCount = 1; 5062 pSMB->Reserved3 = 0; 5063 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 5064 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO); 5065 inc_rfc1001_len(pSMB, byte_count); 5066 pSMB->ByteCount = cpu_to_le16(byte_count); 5067 5068 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5069 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5070 if (rc) { 5071 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc); 5072 } else { /* decode response */ 5073 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5074 5075 if (rc || get_bcc(&pSMBr->hdr) < 24) 5076 rc = -EIO; /* bad smb */ 5077 else { 5078 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5079 5080 response_data = 5081 (FILE_SYSTEM_INFO 5082 *) (((char *) &pSMBr->hdr.Protocol) + 5083 data_offset); 5084 FSData->f_bsize = 5085 le32_to_cpu(response_data->BytesPerSector) * 5086 le32_to_cpu(response_data-> 5087 SectorsPerAllocationUnit); 5088 FSData->f_blocks = 5089 le64_to_cpu(response_data->TotalAllocationUnits); 5090 FSData->f_bfree = FSData->f_bavail = 5091 le64_to_cpu(response_data->FreeAllocationUnits); 5092 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n", 5093 (unsigned long long)FSData->f_blocks, 5094 (unsigned long long)FSData->f_bfree, 5095 FSData->f_bsize); 5096 } 5097 } 5098 cifs_buf_release(pSMB); 5099 5100 if (rc == -EAGAIN) 5101 goto QFSInfoRetry; 5102 5103 return rc; 5104 } 5105 5106 int 5107 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon) 5108 { 5109 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */ 5110 TRANSACTION2_QFSI_REQ *pSMB = NULL; 5111 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 5112 FILE_SYSTEM_ATTRIBUTE_INFO *response_data; 5113 int rc = 0; 5114 int bytes_returned = 0; 5115 __u16 params, byte_count; 5116 5117 cifs_dbg(FYI, "In QFSAttributeInfo\n"); 5118 QFSAttributeRetry: 5119 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5120 (void **) &pSMBr); 5121 if (rc) 5122 return rc; 5123 5124 params = 2; /* level */ 5125 pSMB->TotalDataCount = 0; 5126 pSMB->MaxParameterCount = cpu_to_le16(2); 5127 /* BB find exact max SMB PDU from sess structure BB */ 5128 pSMB->MaxDataCount = cpu_to_le16(1000); 5129 pSMB->MaxSetupCount = 0; 5130 pSMB->Reserved = 0; 5131 pSMB->Flags = 0; 5132 pSMB->Timeout = 0; 5133 pSMB->Reserved2 = 0; 5134 byte_count = params + 1 /* pad */ ; 5135 pSMB->TotalParameterCount = cpu_to_le16(params); 5136 pSMB->ParameterCount = pSMB->TotalParameterCount; 5137 pSMB->ParameterOffset = cpu_to_le16(offsetof( 5138 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 5139 pSMB->DataCount = 0; 5140 pSMB->DataOffset = 0; 5141 pSMB->SetupCount = 1; 5142 pSMB->Reserved3 = 0; 5143 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 5144 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO); 5145 inc_rfc1001_len(pSMB, byte_count); 5146 pSMB->ByteCount = cpu_to_le16(byte_count); 5147 5148 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5149 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5150 if (rc) { 5151 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc); 5152 } else { /* decode response */ 5153 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5154 5155 if (rc || get_bcc(&pSMBr->hdr) < 13) { 5156 /* BB also check if enough bytes returned */ 5157 rc = -EIO; /* bad smb */ 5158 } else { 5159 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5160 response_data = 5161 (FILE_SYSTEM_ATTRIBUTE_INFO 5162 *) (((char *) &pSMBr->hdr.Protocol) + 5163 data_offset); 5164 memcpy(&tcon->fsAttrInfo, response_data, 5165 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO)); 5166 } 5167 } 5168 cifs_buf_release(pSMB); 5169 5170 if (rc == -EAGAIN) 5171 goto QFSAttributeRetry; 5172 5173 return rc; 5174 } 5175 5176 int 5177 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon) 5178 { 5179 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */ 5180 TRANSACTION2_QFSI_REQ *pSMB = NULL; 5181 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 5182 FILE_SYSTEM_DEVICE_INFO *response_data; 5183 int rc = 0; 5184 int bytes_returned = 0; 5185 __u16 params, byte_count; 5186 5187 cifs_dbg(FYI, "In QFSDeviceInfo\n"); 5188 QFSDeviceRetry: 5189 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5190 (void **) &pSMBr); 5191 if (rc) 5192 return rc; 5193 5194 params = 2; /* level */ 5195 pSMB->TotalDataCount = 0; 5196 pSMB->MaxParameterCount = cpu_to_le16(2); 5197 /* BB find exact max SMB PDU from sess structure BB */ 5198 pSMB->MaxDataCount = cpu_to_le16(1000); 5199 pSMB->MaxSetupCount = 0; 5200 pSMB->Reserved = 0; 5201 pSMB->Flags = 0; 5202 pSMB->Timeout = 0; 5203 pSMB->Reserved2 = 0; 5204 byte_count = params + 1 /* pad */ ; 5205 pSMB->TotalParameterCount = cpu_to_le16(params); 5206 pSMB->ParameterCount = pSMB->TotalParameterCount; 5207 pSMB->ParameterOffset = cpu_to_le16(offsetof( 5208 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 5209 5210 pSMB->DataCount = 0; 5211 pSMB->DataOffset = 0; 5212 pSMB->SetupCount = 1; 5213 pSMB->Reserved3 = 0; 5214 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 5215 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO); 5216 inc_rfc1001_len(pSMB, byte_count); 5217 pSMB->ByteCount = cpu_to_le16(byte_count); 5218 5219 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5220 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5221 if (rc) { 5222 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc); 5223 } else { /* decode response */ 5224 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5225 5226 if (rc || get_bcc(&pSMBr->hdr) < 5227 sizeof(FILE_SYSTEM_DEVICE_INFO)) 5228 rc = -EIO; /* bad smb */ 5229 else { 5230 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5231 response_data = 5232 (FILE_SYSTEM_DEVICE_INFO *) 5233 (((char *) &pSMBr->hdr.Protocol) + 5234 data_offset); 5235 memcpy(&tcon->fsDevInfo, response_data, 5236 sizeof(FILE_SYSTEM_DEVICE_INFO)); 5237 } 5238 } 5239 cifs_buf_release(pSMB); 5240 5241 if (rc == -EAGAIN) 5242 goto QFSDeviceRetry; 5243 5244 return rc; 5245 } 5246 5247 int 5248 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon) 5249 { 5250 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */ 5251 TRANSACTION2_QFSI_REQ *pSMB = NULL; 5252 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 5253 FILE_SYSTEM_UNIX_INFO *response_data; 5254 int rc = 0; 5255 int bytes_returned = 0; 5256 __u16 params, byte_count; 5257 5258 cifs_dbg(FYI, "In QFSUnixInfo\n"); 5259 QFSUnixRetry: 5260 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, 5261 (void **) &pSMB, (void **) &pSMBr); 5262 if (rc) 5263 return rc; 5264 5265 params = 2; /* level */ 5266 pSMB->TotalDataCount = 0; 5267 pSMB->DataCount = 0; 5268 pSMB->DataOffset = 0; 5269 pSMB->MaxParameterCount = cpu_to_le16(2); 5270 /* BB find exact max SMB PDU from sess structure BB */ 5271 pSMB->MaxDataCount = cpu_to_le16(100); 5272 pSMB->MaxSetupCount = 0; 5273 pSMB->Reserved = 0; 5274 pSMB->Flags = 0; 5275 pSMB->Timeout = 0; 5276 pSMB->Reserved2 = 0; 5277 byte_count = params + 1 /* pad */ ; 5278 pSMB->ParameterCount = cpu_to_le16(params); 5279 pSMB->TotalParameterCount = pSMB->ParameterCount; 5280 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct 5281 smb_com_transaction2_qfsi_req, InformationLevel) - 4); 5282 pSMB->SetupCount = 1; 5283 pSMB->Reserved3 = 0; 5284 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 5285 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO); 5286 inc_rfc1001_len(pSMB, byte_count); 5287 pSMB->ByteCount = cpu_to_le16(byte_count); 5288 5289 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5290 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5291 if (rc) { 5292 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc); 5293 } else { /* decode response */ 5294 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5295 5296 if (rc || get_bcc(&pSMBr->hdr) < 13) { 5297 rc = -EIO; /* bad smb */ 5298 } else { 5299 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5300 response_data = 5301 (FILE_SYSTEM_UNIX_INFO 5302 *) (((char *) &pSMBr->hdr.Protocol) + 5303 data_offset); 5304 memcpy(&tcon->fsUnixInfo, response_data, 5305 sizeof(FILE_SYSTEM_UNIX_INFO)); 5306 } 5307 } 5308 cifs_buf_release(pSMB); 5309 5310 if (rc == -EAGAIN) 5311 goto QFSUnixRetry; 5312 5313 5314 return rc; 5315 } 5316 5317 int 5318 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap) 5319 { 5320 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */ 5321 TRANSACTION2_SETFSI_REQ *pSMB = NULL; 5322 TRANSACTION2_SETFSI_RSP *pSMBr = NULL; 5323 int rc = 0; 5324 int bytes_returned = 0; 5325 __u16 params, param_offset, offset, byte_count; 5326 5327 cifs_dbg(FYI, "In SETFSUnixInfo\n"); 5328 SETFSUnixRetry: 5329 /* BB switch to small buf init to save memory */ 5330 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, 5331 (void **) &pSMB, (void **) &pSMBr); 5332 if (rc) 5333 return rc; 5334 5335 params = 4; /* 2 bytes zero followed by info level. */ 5336 pSMB->MaxSetupCount = 0; 5337 pSMB->Reserved = 0; 5338 pSMB->Flags = 0; 5339 pSMB->Timeout = 0; 5340 pSMB->Reserved2 = 0; 5341 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum) 5342 - 4; 5343 offset = param_offset + params; 5344 5345 pSMB->MaxParameterCount = cpu_to_le16(4); 5346 /* BB find exact max SMB PDU from sess structure BB */ 5347 pSMB->MaxDataCount = cpu_to_le16(100); 5348 pSMB->SetupCount = 1; 5349 pSMB->Reserved3 = 0; 5350 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION); 5351 byte_count = 1 /* pad */ + params + 12; 5352 5353 pSMB->DataCount = cpu_to_le16(12); 5354 pSMB->ParameterCount = cpu_to_le16(params); 5355 pSMB->TotalDataCount = pSMB->DataCount; 5356 pSMB->TotalParameterCount = pSMB->ParameterCount; 5357 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5358 pSMB->DataOffset = cpu_to_le16(offset); 5359 5360 /* Params. */ 5361 pSMB->FileNum = 0; 5362 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO); 5363 5364 /* Data. */ 5365 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION); 5366 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION); 5367 pSMB->ClientUnixCap = cpu_to_le64(cap); 5368 5369 inc_rfc1001_len(pSMB, byte_count); 5370 pSMB->ByteCount = cpu_to_le16(byte_count); 5371 5372 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5373 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5374 if (rc) { 5375 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc); 5376 } else { /* decode response */ 5377 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5378 if (rc) 5379 rc = -EIO; /* bad smb */ 5380 } 5381 cifs_buf_release(pSMB); 5382 5383 if (rc == -EAGAIN) 5384 goto SETFSUnixRetry; 5385 5386 return rc; 5387 } 5388 5389 5390 5391 int 5392 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon, 5393 struct kstatfs *FSData) 5394 { 5395 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */ 5396 TRANSACTION2_QFSI_REQ *pSMB = NULL; 5397 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 5398 FILE_SYSTEM_POSIX_INFO *response_data; 5399 int rc = 0; 5400 int bytes_returned = 0; 5401 __u16 params, byte_count; 5402 5403 cifs_dbg(FYI, "In QFSPosixInfo\n"); 5404 QFSPosixRetry: 5405 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5406 (void **) &pSMBr); 5407 if (rc) 5408 return rc; 5409 5410 params = 2; /* level */ 5411 pSMB->TotalDataCount = 0; 5412 pSMB->DataCount = 0; 5413 pSMB->DataOffset = 0; 5414 pSMB->MaxParameterCount = cpu_to_le16(2); 5415 /* BB find exact max SMB PDU from sess structure BB */ 5416 pSMB->MaxDataCount = cpu_to_le16(100); 5417 pSMB->MaxSetupCount = 0; 5418 pSMB->Reserved = 0; 5419 pSMB->Flags = 0; 5420 pSMB->Timeout = 0; 5421 pSMB->Reserved2 = 0; 5422 byte_count = params + 1 /* pad */ ; 5423 pSMB->ParameterCount = cpu_to_le16(params); 5424 pSMB->TotalParameterCount = pSMB->ParameterCount; 5425 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct 5426 smb_com_transaction2_qfsi_req, InformationLevel) - 4); 5427 pSMB->SetupCount = 1; 5428 pSMB->Reserved3 = 0; 5429 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 5430 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO); 5431 inc_rfc1001_len(pSMB, byte_count); 5432 pSMB->ByteCount = cpu_to_le16(byte_count); 5433 5434 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5435 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5436 if (rc) { 5437 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc); 5438 } else { /* decode response */ 5439 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5440 5441 if (rc || get_bcc(&pSMBr->hdr) < 13) { 5442 rc = -EIO; /* bad smb */ 5443 } else { 5444 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5445 response_data = 5446 (FILE_SYSTEM_POSIX_INFO 5447 *) (((char *) &pSMBr->hdr.Protocol) + 5448 data_offset); 5449 FSData->f_bsize = 5450 le32_to_cpu(response_data->BlockSize); 5451 FSData->f_blocks = 5452 le64_to_cpu(response_data->TotalBlocks); 5453 FSData->f_bfree = 5454 le64_to_cpu(response_data->BlocksAvail); 5455 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) { 5456 FSData->f_bavail = FSData->f_bfree; 5457 } else { 5458 FSData->f_bavail = 5459 le64_to_cpu(response_data->UserBlocksAvail); 5460 } 5461 if (response_data->TotalFileNodes != cpu_to_le64(-1)) 5462 FSData->f_files = 5463 le64_to_cpu(response_data->TotalFileNodes); 5464 if (response_data->FreeFileNodes != cpu_to_le64(-1)) 5465 FSData->f_ffree = 5466 le64_to_cpu(response_data->FreeFileNodes); 5467 } 5468 } 5469 cifs_buf_release(pSMB); 5470 5471 if (rc == -EAGAIN) 5472 goto QFSPosixRetry; 5473 5474 return rc; 5475 } 5476 5477 5478 /* 5479 * We can not use write of zero bytes trick to set file size due to need for 5480 * large file support. Also note that this SetPathInfo is preferred to 5481 * SetFileInfo based method in next routine which is only needed to work around 5482 * a sharing violation bugin Samba which this routine can run into. 5483 */ 5484 int 5485 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon, 5486 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb, 5487 bool set_allocation) 5488 { 5489 struct smb_com_transaction2_spi_req *pSMB = NULL; 5490 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 5491 struct file_end_of_file_info *parm_data; 5492 int name_len; 5493 int rc = 0; 5494 int bytes_returned = 0; 5495 int remap = cifs_remap(cifs_sb); 5496 5497 __u16 params, byte_count, data_count, param_offset, offset; 5498 5499 cifs_dbg(FYI, "In SetEOF\n"); 5500 SetEOFRetry: 5501 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5502 (void **) &pSMBr); 5503 if (rc) 5504 return rc; 5505 5506 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5507 name_len = 5508 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name, 5509 PATH_MAX, cifs_sb->local_nls, remap); 5510 name_len++; /* trailing null */ 5511 name_len *= 2; 5512 } else { /* BB improve the check for buffer overruns BB */ 5513 name_len = strnlen(file_name, PATH_MAX); 5514 name_len++; /* trailing null */ 5515 strncpy(pSMB->FileName, file_name, name_len); 5516 } 5517 params = 6 + name_len; 5518 data_count = sizeof(struct file_end_of_file_info); 5519 pSMB->MaxParameterCount = cpu_to_le16(2); 5520 pSMB->MaxDataCount = cpu_to_le16(4100); 5521 pSMB->MaxSetupCount = 0; 5522 pSMB->Reserved = 0; 5523 pSMB->Flags = 0; 5524 pSMB->Timeout = 0; 5525 pSMB->Reserved2 = 0; 5526 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5527 InformationLevel) - 4; 5528 offset = param_offset + params; 5529 if (set_allocation) { 5530 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5531 pSMB->InformationLevel = 5532 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); 5533 else 5534 pSMB->InformationLevel = 5535 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO); 5536 } else /* Set File Size */ { 5537 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5538 pSMB->InformationLevel = 5539 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2); 5540 else 5541 pSMB->InformationLevel = 5542 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); 5543 } 5544 5545 parm_data = 5546 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) + 5547 offset); 5548 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5549 pSMB->DataOffset = cpu_to_le16(offset); 5550 pSMB->SetupCount = 1; 5551 pSMB->Reserved3 = 0; 5552 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5553 byte_count = 3 /* pad */ + params + data_count; 5554 pSMB->DataCount = cpu_to_le16(data_count); 5555 pSMB->TotalDataCount = pSMB->DataCount; 5556 pSMB->ParameterCount = cpu_to_le16(params); 5557 pSMB->TotalParameterCount = pSMB->ParameterCount; 5558 pSMB->Reserved4 = 0; 5559 inc_rfc1001_len(pSMB, byte_count); 5560 parm_data->FileSize = cpu_to_le64(size); 5561 pSMB->ByteCount = cpu_to_le16(byte_count); 5562 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5563 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5564 if (rc) 5565 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc); 5566 5567 cifs_buf_release(pSMB); 5568 5569 if (rc == -EAGAIN) 5570 goto SetEOFRetry; 5571 5572 return rc; 5573 } 5574 5575 int 5576 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, 5577 struct cifsFileInfo *cfile, __u64 size, bool set_allocation) 5578 { 5579 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5580 struct file_end_of_file_info *parm_data; 5581 int rc = 0; 5582 __u16 params, param_offset, offset, byte_count, count; 5583 5584 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n", 5585 (long long)size); 5586 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5587 5588 if (rc) 5589 return rc; 5590 5591 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid); 5592 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16)); 5593 5594 params = 6; 5595 pSMB->MaxSetupCount = 0; 5596 pSMB->Reserved = 0; 5597 pSMB->Flags = 0; 5598 pSMB->Timeout = 0; 5599 pSMB->Reserved2 = 0; 5600 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5601 offset = param_offset + params; 5602 5603 count = sizeof(struct file_end_of_file_info); 5604 pSMB->MaxParameterCount = cpu_to_le16(2); 5605 /* BB find exact max SMB PDU from sess structure BB */ 5606 pSMB->MaxDataCount = cpu_to_le16(1000); 5607 pSMB->SetupCount = 1; 5608 pSMB->Reserved3 = 0; 5609 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5610 byte_count = 3 /* pad */ + params + count; 5611 pSMB->DataCount = cpu_to_le16(count); 5612 pSMB->ParameterCount = cpu_to_le16(params); 5613 pSMB->TotalDataCount = pSMB->DataCount; 5614 pSMB->TotalParameterCount = pSMB->ParameterCount; 5615 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5616 parm_data = 5617 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) 5618 + offset); 5619 pSMB->DataOffset = cpu_to_le16(offset); 5620 parm_data->FileSize = cpu_to_le64(size); 5621 pSMB->Fid = cfile->fid.netfid; 5622 if (set_allocation) { 5623 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5624 pSMB->InformationLevel = 5625 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); 5626 else 5627 pSMB->InformationLevel = 5628 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO); 5629 } else /* Set File Size */ { 5630 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5631 pSMB->InformationLevel = 5632 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2); 5633 else 5634 pSMB->InformationLevel = 5635 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); 5636 } 5637 pSMB->Reserved4 = 0; 5638 inc_rfc1001_len(pSMB, byte_count); 5639 pSMB->ByteCount = cpu_to_le16(byte_count); 5640 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5641 cifs_small_buf_release(pSMB); 5642 if (rc) { 5643 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n", 5644 rc); 5645 } 5646 5647 /* Note: On -EAGAIN error only caller can retry on handle based calls 5648 since file handle passed in no longer valid */ 5649 5650 return rc; 5651 } 5652 5653 /* Some legacy servers such as NT4 require that the file times be set on 5654 an open handle, rather than by pathname - this is awkward due to 5655 potential access conflicts on the open, but it is unavoidable for these 5656 old servers since the only other choice is to go from 100 nanosecond DCE 5657 time and resort to the original setpathinfo level which takes the ancient 5658 DOS time format with 2 second granularity */ 5659 int 5660 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 5661 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener) 5662 { 5663 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5664 char *data_offset; 5665 int rc = 0; 5666 __u16 params, param_offset, offset, byte_count, count; 5667 5668 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n"); 5669 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5670 5671 if (rc) 5672 return rc; 5673 5674 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 5675 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 5676 5677 params = 6; 5678 pSMB->MaxSetupCount = 0; 5679 pSMB->Reserved = 0; 5680 pSMB->Flags = 0; 5681 pSMB->Timeout = 0; 5682 pSMB->Reserved2 = 0; 5683 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5684 offset = param_offset + params; 5685 5686 data_offset = (char *)pSMB + 5687 offsetof(struct smb_hdr, Protocol) + offset; 5688 5689 count = sizeof(FILE_BASIC_INFO); 5690 pSMB->MaxParameterCount = cpu_to_le16(2); 5691 /* BB find max SMB PDU from sess */ 5692 pSMB->MaxDataCount = cpu_to_le16(1000); 5693 pSMB->SetupCount = 1; 5694 pSMB->Reserved3 = 0; 5695 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5696 byte_count = 3 /* pad */ + params + count; 5697 pSMB->DataCount = cpu_to_le16(count); 5698 pSMB->ParameterCount = cpu_to_le16(params); 5699 pSMB->TotalDataCount = pSMB->DataCount; 5700 pSMB->TotalParameterCount = pSMB->ParameterCount; 5701 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5702 pSMB->DataOffset = cpu_to_le16(offset); 5703 pSMB->Fid = fid; 5704 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5705 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2); 5706 else 5707 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); 5708 pSMB->Reserved4 = 0; 5709 inc_rfc1001_len(pSMB, byte_count); 5710 pSMB->ByteCount = cpu_to_le16(byte_count); 5711 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 5712 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5713 cifs_small_buf_release(pSMB); 5714 if (rc) 5715 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n", 5716 rc); 5717 5718 /* Note: On -EAGAIN error only caller can retry on handle based calls 5719 since file handle passed in no longer valid */ 5720 5721 return rc; 5722 } 5723 5724 int 5725 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon, 5726 bool delete_file, __u16 fid, __u32 pid_of_opener) 5727 { 5728 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5729 char *data_offset; 5730 int rc = 0; 5731 __u16 params, param_offset, offset, byte_count, count; 5732 5733 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n"); 5734 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5735 5736 if (rc) 5737 return rc; 5738 5739 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 5740 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 5741 5742 params = 6; 5743 pSMB->MaxSetupCount = 0; 5744 pSMB->Reserved = 0; 5745 pSMB->Flags = 0; 5746 pSMB->Timeout = 0; 5747 pSMB->Reserved2 = 0; 5748 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5749 offset = param_offset + params; 5750 5751 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 5752 5753 count = 1; 5754 pSMB->MaxParameterCount = cpu_to_le16(2); 5755 /* BB find max SMB PDU from sess */ 5756 pSMB->MaxDataCount = cpu_to_le16(1000); 5757 pSMB->SetupCount = 1; 5758 pSMB->Reserved3 = 0; 5759 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5760 byte_count = 3 /* pad */ + params + count; 5761 pSMB->DataCount = cpu_to_le16(count); 5762 pSMB->ParameterCount = cpu_to_le16(params); 5763 pSMB->TotalDataCount = pSMB->DataCount; 5764 pSMB->TotalParameterCount = pSMB->ParameterCount; 5765 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5766 pSMB->DataOffset = cpu_to_le16(offset); 5767 pSMB->Fid = fid; 5768 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO); 5769 pSMB->Reserved4 = 0; 5770 inc_rfc1001_len(pSMB, byte_count); 5771 pSMB->ByteCount = cpu_to_le16(byte_count); 5772 *data_offset = delete_file ? 1 : 0; 5773 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5774 cifs_small_buf_release(pSMB); 5775 if (rc) 5776 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc); 5777 5778 return rc; 5779 } 5780 5781 int 5782 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 5783 const char *fileName, const FILE_BASIC_INFO *data, 5784 const struct nls_table *nls_codepage, int remap) 5785 { 5786 TRANSACTION2_SPI_REQ *pSMB = NULL; 5787 TRANSACTION2_SPI_RSP *pSMBr = NULL; 5788 int name_len; 5789 int rc = 0; 5790 int bytes_returned = 0; 5791 char *data_offset; 5792 __u16 params, param_offset, offset, byte_count, count; 5793 5794 cifs_dbg(FYI, "In SetTimes\n"); 5795 5796 SetTimesRetry: 5797 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5798 (void **) &pSMBr); 5799 if (rc) 5800 return rc; 5801 5802 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5803 name_len = 5804 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 5805 PATH_MAX, nls_codepage, remap); 5806 name_len++; /* trailing null */ 5807 name_len *= 2; 5808 } else { /* BB improve the check for buffer overruns BB */ 5809 name_len = strnlen(fileName, PATH_MAX); 5810 name_len++; /* trailing null */ 5811 strncpy(pSMB->FileName, fileName, name_len); 5812 } 5813 5814 params = 6 + name_len; 5815 count = sizeof(FILE_BASIC_INFO); 5816 pSMB->MaxParameterCount = cpu_to_le16(2); 5817 /* BB find max SMB PDU from sess structure BB */ 5818 pSMB->MaxDataCount = cpu_to_le16(1000); 5819 pSMB->MaxSetupCount = 0; 5820 pSMB->Reserved = 0; 5821 pSMB->Flags = 0; 5822 pSMB->Timeout = 0; 5823 pSMB->Reserved2 = 0; 5824 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5825 InformationLevel) - 4; 5826 offset = param_offset + params; 5827 data_offset = (char *) (&pSMB->hdr.Protocol) + offset; 5828 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5829 pSMB->DataOffset = cpu_to_le16(offset); 5830 pSMB->SetupCount = 1; 5831 pSMB->Reserved3 = 0; 5832 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5833 byte_count = 3 /* pad */ + params + count; 5834 5835 pSMB->DataCount = cpu_to_le16(count); 5836 pSMB->ParameterCount = cpu_to_le16(params); 5837 pSMB->TotalDataCount = pSMB->DataCount; 5838 pSMB->TotalParameterCount = pSMB->ParameterCount; 5839 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5840 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2); 5841 else 5842 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); 5843 pSMB->Reserved4 = 0; 5844 inc_rfc1001_len(pSMB, byte_count); 5845 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 5846 pSMB->ByteCount = cpu_to_le16(byte_count); 5847 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5848 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5849 if (rc) 5850 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc); 5851 5852 cifs_buf_release(pSMB); 5853 5854 if (rc == -EAGAIN) 5855 goto SetTimesRetry; 5856 5857 return rc; 5858 } 5859 5860 /* Can not be used to set time stamps yet (due to old DOS time format) */ 5861 /* Can be used to set attributes */ 5862 #if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug 5863 handling it anyway and NT4 was what we thought it would be needed for 5864 Do not delete it until we prove whether needed for Win9x though */ 5865 int 5866 CIFSSMBSetAttrLegacy(unsigned int xid, struct cifs_tcon *tcon, char *fileName, 5867 __u16 dos_attrs, const struct nls_table *nls_codepage) 5868 { 5869 SETATTR_REQ *pSMB = NULL; 5870 SETATTR_RSP *pSMBr = NULL; 5871 int rc = 0; 5872 int bytes_returned; 5873 int name_len; 5874 5875 cifs_dbg(FYI, "In SetAttrLegacy\n"); 5876 5877 SetAttrLgcyRetry: 5878 rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB, 5879 (void **) &pSMBr); 5880 if (rc) 5881 return rc; 5882 5883 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5884 name_len = 5885 ConvertToUTF16((__le16 *) pSMB->fileName, fileName, 5886 PATH_MAX, nls_codepage); 5887 name_len++; /* trailing null */ 5888 name_len *= 2; 5889 } else { /* BB improve the check for buffer overruns BB */ 5890 name_len = strnlen(fileName, PATH_MAX); 5891 name_len++; /* trailing null */ 5892 strncpy(pSMB->fileName, fileName, name_len); 5893 } 5894 pSMB->attr = cpu_to_le16(dos_attrs); 5895 pSMB->BufferFormat = 0x04; 5896 inc_rfc1001_len(pSMB, name_len + 1); 5897 pSMB->ByteCount = cpu_to_le16(name_len + 1); 5898 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5899 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5900 if (rc) 5901 cifs_dbg(FYI, "Error in LegacySetAttr = %d\n", rc); 5902 5903 cifs_buf_release(pSMB); 5904 5905 if (rc == -EAGAIN) 5906 goto SetAttrLgcyRetry; 5907 5908 return rc; 5909 } 5910 #endif /* temporarily unneeded SetAttr legacy function */ 5911 5912 static void 5913 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset, 5914 const struct cifs_unix_set_info_args *args) 5915 { 5916 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64; 5917 u64 mode = args->mode; 5918 5919 if (uid_valid(args->uid)) 5920 uid = from_kuid(&init_user_ns, args->uid); 5921 if (gid_valid(args->gid)) 5922 gid = from_kgid(&init_user_ns, args->gid); 5923 5924 /* 5925 * Samba server ignores set of file size to zero due to bugs in some 5926 * older clients, but we should be precise - we use SetFileSize to 5927 * set file size and do not want to truncate file size to zero 5928 * accidentally as happened on one Samba server beta by putting 5929 * zero instead of -1 here 5930 */ 5931 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64); 5932 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64); 5933 data_offset->LastStatusChange = cpu_to_le64(args->ctime); 5934 data_offset->LastAccessTime = cpu_to_le64(args->atime); 5935 data_offset->LastModificationTime = cpu_to_le64(args->mtime); 5936 data_offset->Uid = cpu_to_le64(uid); 5937 data_offset->Gid = cpu_to_le64(gid); 5938 /* better to leave device as zero when it is */ 5939 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device)); 5940 data_offset->DevMinor = cpu_to_le64(MINOR(args->device)); 5941 data_offset->Permissions = cpu_to_le64(mode); 5942 5943 if (S_ISREG(mode)) 5944 data_offset->Type = cpu_to_le32(UNIX_FILE); 5945 else if (S_ISDIR(mode)) 5946 data_offset->Type = cpu_to_le32(UNIX_DIR); 5947 else if (S_ISLNK(mode)) 5948 data_offset->Type =