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