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