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 trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_progress); 1342 netfs_read_subreq_terminated(&rdata->subreq); 1343 release_mid(mid); 1344 add_credits(server, &credits, 0); 1345 } 1346 1347 /* cifs_async_readv - send an async write, and set up mid to handle result */ 1348 int 1349 cifs_async_readv(struct cifs_io_subrequest *rdata) 1350 { 1351 int rc; 1352 READ_REQ *smb = NULL; 1353 int wct; 1354 struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink); 1355 struct smb_rqst rqst = { .rq_iov = rdata->iov, 1356 .rq_nvec = 2 }; 1357 1358 cifs_dbg(FYI, "%s: offset=%llu bytes=%zu\n", 1359 __func__, rdata->subreq.start, rdata->subreq.len); 1360 1361 if (tcon->ses->capabilities & CAP_LARGE_FILES) 1362 wct = 12; 1363 else { 1364 wct = 10; /* old style read */ 1365 if ((rdata->subreq.start >> 32) > 0) { 1366 /* can not handle this big offset for old */ 1367 return -EIO; 1368 } 1369 } 1370 1371 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb); 1372 if (rc) 1373 return rc; 1374 1375 smb->hdr.Pid = cpu_to_le16((__u16)rdata->req->pid); 1376 smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->req->pid >> 16)); 1377 1378 smb->AndXCommand = 0xFF; /* none */ 1379 smb->Fid = rdata->req->cfile->fid.netfid; 1380 smb->OffsetLow = cpu_to_le32(rdata->subreq.start & 0xFFFFFFFF); 1381 if (wct == 12) 1382 smb->OffsetHigh = cpu_to_le32(rdata->subreq.start >> 32); 1383 smb->Remaining = 0; 1384 smb->MaxCount = cpu_to_le16(rdata->subreq.len & 0xFFFF); 1385 smb->MaxCountHigh = cpu_to_le32(rdata->subreq.len >> 16); 1386 if (wct == 12) 1387 smb->ByteCount = 0; 1388 else { 1389 /* old style read */ 1390 struct smb_com_readx_req *smbr = 1391 (struct smb_com_readx_req *)smb; 1392 smbr->ByteCount = 0; 1393 } 1394 1395 /* 4 for RFC1001 length + 1 for BCC */ 1396 rdata->iov[0].iov_base = smb; 1397 rdata->iov[0].iov_len = 4; 1398 rdata->iov[1].iov_base = (char *)smb + 4; 1399 rdata->iov[1].iov_len = get_rfc1002_length(smb); 1400 1401 rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive, 1402 cifs_readv_callback, NULL, rdata, 0, NULL); 1403 1404 if (rc == 0) 1405 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads); 1406 cifs_small_buf_release(smb); 1407 return rc; 1408 } 1409 1410 int 1411 CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms, 1412 unsigned int *nbytes, char **buf, int *pbuf_type) 1413 { 1414 int rc = -EACCES; 1415 READ_REQ *pSMB = NULL; 1416 READ_RSP *pSMBr = NULL; 1417 char *pReadData = NULL; 1418 int wct; 1419 int resp_buf_type = 0; 1420 struct kvec iov[1]; 1421 struct kvec rsp_iov; 1422 __u32 pid = io_parms->pid; 1423 __u16 netfid = io_parms->netfid; 1424 __u64 offset = io_parms->offset; 1425 struct cifs_tcon *tcon = io_parms->tcon; 1426 unsigned int count = io_parms->length; 1427 1428 cifs_dbg(FYI, "Reading %d bytes on fid %d\n", count, netfid); 1429 if (tcon->ses->capabilities & CAP_LARGE_FILES) 1430 wct = 12; 1431 else { 1432 wct = 10; /* old style read */ 1433 if ((offset >> 32) > 0) { 1434 /* can not handle this big offset for old */ 1435 return -EIO; 1436 } 1437 } 1438 1439 *nbytes = 0; 1440 rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB); 1441 if (rc) 1442 return rc; 1443 1444 pSMB->hdr.Pid = cpu_to_le16((__u16)pid); 1445 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16)); 1446 1447 /* tcon and ses pointer are checked in smb_init */ 1448 if (tcon->ses->server == NULL) 1449 return -ECONNABORTED; 1450 1451 pSMB->AndXCommand = 0xFF; /* none */ 1452 pSMB->Fid = netfid; 1453 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1454 if (wct == 12) 1455 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1456 1457 pSMB->Remaining = 0; 1458 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); 1459 pSMB->MaxCountHigh = cpu_to_le32(count >> 16); 1460 if (wct == 12) 1461 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */ 1462 else { 1463 /* old style read */ 1464 struct smb_com_readx_req *pSMBW = 1465 (struct smb_com_readx_req *)pSMB; 1466 pSMBW->ByteCount = 0; 1467 } 1468 1469 iov[0].iov_base = (char *)pSMB; 1470 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4; 1471 rc = SendReceive2(xid, tcon->ses, iov, 1, &resp_buf_type, 1472 CIFS_LOG_ERROR, &rsp_iov); 1473 cifs_small_buf_release(pSMB); 1474 cifs_stats_inc(&tcon->stats.cifs_stats.num_reads); 1475 pSMBr = (READ_RSP *)rsp_iov.iov_base; 1476 if (rc) { 1477 cifs_dbg(VFS, "Send error in read = %d\n", rc); 1478 } else { 1479 int data_length = le16_to_cpu(pSMBr->DataLengthHigh); 1480 data_length = data_length << 16; 1481 data_length += le16_to_cpu(pSMBr->DataLength); 1482 *nbytes = data_length; 1483 1484 /*check that DataLength would not go beyond end of SMB */ 1485 if ((data_length > CIFSMaxBufSize) 1486 || (data_length > count)) { 1487 cifs_dbg(FYI, "bad length %d for count %d\n", 1488 data_length, count); 1489 rc = -EIO; 1490 *nbytes = 0; 1491 } else { 1492 pReadData = (char *) (&pSMBr->hdr.Protocol) + 1493 le16_to_cpu(pSMBr->DataOffset); 1494 /* if (rc = copy_to_user(buf, pReadData, data_length)) { 1495 cifs_dbg(VFS, "Faulting on read rc = %d\n",rc); 1496 rc = -EFAULT; 1497 }*/ /* can not use copy_to_user when using page cache*/ 1498 if (*buf) 1499 memcpy(*buf, pReadData, data_length); 1500 } 1501 } 1502 1503 if (*buf) { 1504 free_rsp_buf(resp_buf_type, rsp_iov.iov_base); 1505 } else if (resp_buf_type != CIFS_NO_BUFFER) { 1506 /* return buffer to caller to free */ 1507 *buf = rsp_iov.iov_base; 1508 if (resp_buf_type == CIFS_SMALL_BUFFER) 1509 *pbuf_type = CIFS_SMALL_BUFFER; 1510 else if (resp_buf_type == CIFS_LARGE_BUFFER) 1511 *pbuf_type = CIFS_LARGE_BUFFER; 1512 } /* else no valid buffer on return - leave as null */ 1513 1514 /* Note: On -EAGAIN error only caller can retry on handle based calls 1515 since file handle passed in no longer valid */ 1516 return rc; 1517 } 1518 1519 1520 int 1521 CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms, 1522 unsigned int *nbytes, const char *buf) 1523 { 1524 int rc = -EACCES; 1525 WRITE_REQ *pSMB = NULL; 1526 WRITE_RSP *pSMBr = NULL; 1527 int bytes_returned, wct; 1528 __u32 bytes_sent; 1529 __u16 byte_count; 1530 __u32 pid = io_parms->pid; 1531 __u16 netfid = io_parms->netfid; 1532 __u64 offset = io_parms->offset; 1533 struct cifs_tcon *tcon = io_parms->tcon; 1534 unsigned int count = io_parms->length; 1535 1536 *nbytes = 0; 1537 1538 /* cifs_dbg(FYI, "write at %lld %d bytes\n", offset, count);*/ 1539 if (tcon->ses == NULL) 1540 return -ECONNABORTED; 1541 1542 if (tcon->ses->capabilities & CAP_LARGE_FILES) 1543 wct = 14; 1544 else { 1545 wct = 12; 1546 if ((offset >> 32) > 0) { 1547 /* can not handle big offset for old srv */ 1548 return -EIO; 1549 } 1550 } 1551 1552 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB, 1553 (void **) &pSMBr); 1554 if (rc) 1555 return rc; 1556 1557 pSMB->hdr.Pid = cpu_to_le16((__u16)pid); 1558 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16)); 1559 1560 /* tcon and ses pointer are checked in smb_init */ 1561 if (tcon->ses->server == NULL) 1562 return -ECONNABORTED; 1563 1564 pSMB->AndXCommand = 0xFF; /* none */ 1565 pSMB->Fid = netfid; 1566 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1567 if (wct == 14) 1568 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1569 1570 pSMB->Reserved = 0xFFFFFFFF; 1571 pSMB->WriteMode = 0; 1572 pSMB->Remaining = 0; 1573 1574 /* Can increase buffer size if buffer is big enough in some cases ie we 1575 can send more if LARGE_WRITE_X capability returned by the server and if 1576 our buffer is big enough or if we convert to iovecs on socket writes 1577 and eliminate the copy to the CIFS buffer */ 1578 if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) { 1579 bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count); 1580 } else { 1581 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) 1582 & ~0xFF; 1583 } 1584 1585 if (bytes_sent > count) 1586 bytes_sent = count; 1587 pSMB->DataOffset = 1588 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4); 1589 if (buf) 1590 memcpy(pSMB->Data, buf, bytes_sent); 1591 else if (count != 0) { 1592 /* No buffer */ 1593 cifs_buf_release(pSMB); 1594 return -EINVAL; 1595 } /* else setting file size with write of zero bytes */ 1596 if (wct == 14) 1597 byte_count = bytes_sent + 1; /* pad */ 1598 else /* wct == 12 */ 1599 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */ 1600 1601 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF); 1602 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); 1603 inc_rfc1001_len(pSMB, byte_count); 1604 1605 if (wct == 14) 1606 pSMB->ByteCount = cpu_to_le16(byte_count); 1607 else { /* old style write has byte count 4 bytes earlier 1608 so 4 bytes pad */ 1609 struct smb_com_writex_req *pSMBW = 1610 (struct smb_com_writex_req *)pSMB; 1611 pSMBW->ByteCount = cpu_to_le16(byte_count); 1612 } 1613 1614 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1615 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1616 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); 1617 if (rc) { 1618 cifs_dbg(FYI, "Send error in write = %d\n", rc); 1619 } else { 1620 *nbytes = le16_to_cpu(pSMBr->CountHigh); 1621 *nbytes = (*nbytes) << 16; 1622 *nbytes += le16_to_cpu(pSMBr->Count); 1623 1624 /* 1625 * Mask off high 16 bits when bytes written as returned by the 1626 * server is greater than bytes requested by the client. Some 1627 * OS/2 servers are known to set incorrect CountHigh values. 1628 */ 1629 if (*nbytes > count) 1630 *nbytes &= 0xFFFF; 1631 } 1632 1633 cifs_buf_release(pSMB); 1634 1635 /* Note: On -EAGAIN error only caller can retry on handle based calls 1636 since file handle passed in no longer valid */ 1637 1638 return rc; 1639 } 1640 1641 /* 1642 * Check the mid_state and signature on received buffer (if any), and queue the 1643 * workqueue completion task. 1644 */ 1645 static void 1646 cifs_writev_callback(struct mid_q_entry *mid) 1647 { 1648 struct cifs_io_subrequest *wdata = mid->callback_data; 1649 struct TCP_Server_Info *server = wdata->server; 1650 struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink); 1651 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf; 1652 struct cifs_credits credits = { 1653 .value = 1, 1654 .instance = 0, 1655 .rreq_debug_id = wdata->rreq->debug_id, 1656 .rreq_debug_index = wdata->subreq.debug_index, 1657 }; 1658 ssize_t result; 1659 size_t written; 1660 1661 switch (mid->mid_state) { 1662 case MID_RESPONSE_RECEIVED: 1663 result = cifs_check_receive(mid, tcon->ses->server, 0); 1664 if (result != 0) 1665 break; 1666 1667 written = le16_to_cpu(smb->CountHigh); 1668 written <<= 16; 1669 written += le16_to_cpu(smb->Count); 1670 /* 1671 * Mask off high 16 bits when bytes written as returned 1672 * by the server is greater than bytes requested by the 1673 * client. OS/2 servers are known to set incorrect 1674 * CountHigh values. 1675 */ 1676 if (written > wdata->subreq.len) 1677 written &= 0xFFFF; 1678 1679 if (written < wdata->subreq.len) { 1680 result = -ENOSPC; 1681 } else { 1682 result = written; 1683 if (written > 0) 1684 __set_bit(NETFS_SREQ_MADE_PROGRESS, &wdata->subreq.flags); 1685 } 1686 break; 1687 case MID_REQUEST_SUBMITTED: 1688 case MID_RETRY_NEEDED: 1689 result = -EAGAIN; 1690 break; 1691 default: 1692 result = -EIO; 1693 break; 1694 } 1695 1696 trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 1697 wdata->credits.value, 1698 server->credits, server->in_flight, 1699 0, cifs_trace_rw_credits_write_response_clear); 1700 wdata->credits.value = 0; 1701 cifs_write_subrequest_terminated(wdata, result, true); 1702 release_mid(mid); 1703 trace_smb3_rw_credits(credits.rreq_debug_id, credits.rreq_debug_index, 0, 1704 server->credits, server->in_flight, 1705 credits.value, cifs_trace_rw_credits_write_response_add); 1706 add_credits(tcon->ses->server, &credits, 0); 1707 } 1708 1709 /* cifs_async_writev - send an async write, and set up mid to handle result */ 1710 void 1711 cifs_async_writev(struct cifs_io_subrequest *wdata) 1712 { 1713 int rc = -EACCES; 1714 WRITE_REQ *smb = NULL; 1715 int wct; 1716 struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink); 1717 struct kvec iov[2]; 1718 struct smb_rqst rqst = { }; 1719 1720 if (tcon->ses->capabilities & CAP_LARGE_FILES) { 1721 wct = 14; 1722 } else { 1723 wct = 12; 1724 if (wdata->subreq.start >> 32 > 0) { 1725 /* can not handle big offset for old srv */ 1726 rc = -EIO; 1727 goto out; 1728 } 1729 } 1730 1731 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb); 1732 if (rc) 1733 goto async_writev_out; 1734 1735 smb->hdr.Pid = cpu_to_le16((__u16)wdata->req->pid); 1736 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->req->pid >> 16)); 1737 1738 smb->AndXCommand = 0xFF; /* none */ 1739 smb->Fid = wdata->req->cfile->fid.netfid; 1740 smb->OffsetLow = cpu_to_le32(wdata->subreq.start & 0xFFFFFFFF); 1741 if (wct == 14) 1742 smb->OffsetHigh = cpu_to_le32(wdata->subreq.start >> 32); 1743 smb->Reserved = 0xFFFFFFFF; 1744 smb->WriteMode = 0; 1745 smb->Remaining = 0; 1746 1747 smb->DataOffset = 1748 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4); 1749 1750 /* 4 for RFC1001 length + 1 for BCC */ 1751 iov[0].iov_len = 4; 1752 iov[0].iov_base = smb; 1753 iov[1].iov_len = get_rfc1002_length(smb) + 1; 1754 iov[1].iov_base = (char *)smb + 4; 1755 1756 rqst.rq_iov = iov; 1757 rqst.rq_nvec = 2; 1758 rqst.rq_iter = wdata->subreq.io_iter; 1759 1760 cifs_dbg(FYI, "async write at %llu %zu bytes\n", 1761 wdata->subreq.start, wdata->subreq.len); 1762 1763 smb->DataLengthLow = cpu_to_le16(wdata->subreq.len & 0xFFFF); 1764 smb->DataLengthHigh = cpu_to_le16(wdata->subreq.len >> 16); 1765 1766 if (wct == 14) { 1767 inc_rfc1001_len(&smb->hdr, wdata->subreq.len + 1); 1768 put_bcc(wdata->subreq.len + 1, &smb->hdr); 1769 } else { 1770 /* wct == 12 */ 1771 struct smb_com_writex_req *smbw = 1772 (struct smb_com_writex_req *)smb; 1773 inc_rfc1001_len(&smbw->hdr, wdata->subreq.len + 5); 1774 put_bcc(wdata->subreq.len + 5, &smbw->hdr); 1775 iov[1].iov_len += 4; /* pad bigger by four bytes */ 1776 } 1777 1778 rc = cifs_call_async(tcon->ses->server, &rqst, NULL, 1779 cifs_writev_callback, NULL, wdata, 0, NULL); 1780 /* Can't touch wdata if rc == 0 */ 1781 if (rc == 0) 1782 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); 1783 1784 async_writev_out: 1785 cifs_small_buf_release(smb); 1786 out: 1787 if (rc) { 1788 add_credits_and_wake_if(wdata->server, &wdata->credits, 0); 1789 cifs_write_subrequest_terminated(wdata, rc, false); 1790 } 1791 } 1792 1793 int 1794 CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms, 1795 unsigned int *nbytes, struct kvec *iov, int n_vec) 1796 { 1797 int rc; 1798 WRITE_REQ *pSMB = NULL; 1799 int wct; 1800 int smb_hdr_len; 1801 int resp_buf_type = 0; 1802 __u32 pid = io_parms->pid; 1803 __u16 netfid = io_parms->netfid; 1804 __u64 offset = io_parms->offset; 1805 struct cifs_tcon *tcon = io_parms->tcon; 1806 unsigned int count = io_parms->length; 1807 struct kvec rsp_iov; 1808 1809 *nbytes = 0; 1810 1811 cifs_dbg(FYI, "write2 at %lld %d bytes\n", (long long)offset, count); 1812 1813 if (tcon->ses->capabilities & CAP_LARGE_FILES) { 1814 wct = 14; 1815 } else { 1816 wct = 12; 1817 if ((offset >> 32) > 0) { 1818 /* can not handle big offset for old srv */ 1819 return -EIO; 1820 } 1821 } 1822 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB); 1823 if (rc) 1824 return rc; 1825 1826 pSMB->hdr.Pid = cpu_to_le16((__u16)pid); 1827 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16)); 1828 1829 /* tcon and ses pointer are checked in smb_init */ 1830 if (tcon->ses->server == NULL) 1831 return -ECONNABORTED; 1832 1833 pSMB->AndXCommand = 0xFF; /* none */ 1834 pSMB->Fid = netfid; 1835 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1836 if (wct == 14) 1837 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1838 pSMB->Reserved = 0xFFFFFFFF; 1839 pSMB->WriteMode = 0; 1840 pSMB->Remaining = 0; 1841 1842 pSMB->DataOffset = 1843 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4); 1844 1845 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF); 1846 pSMB->DataLengthHigh = cpu_to_le16(count >> 16); 1847 /* header + 1 byte pad */ 1848 smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1; 1849 if (wct == 14) 1850 inc_rfc1001_len(pSMB, count + 1); 1851 else /* wct == 12 */ 1852 inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */ 1853 if (wct == 14) 1854 pSMB->ByteCount = cpu_to_le16(count + 1); 1855 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ { 1856 struct smb_com_writex_req *pSMBW = 1857 (struct smb_com_writex_req *)pSMB; 1858 pSMBW->ByteCount = cpu_to_le16(count + 5); 1859 } 1860 iov[0].iov_base = pSMB; 1861 if (wct == 14) 1862 iov[0].iov_len = smb_hdr_len + 4; 1863 else /* wct == 12 pad bigger by four bytes */ 1864 iov[0].iov_len = smb_hdr_len + 8; 1865 1866 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, 0, 1867 &rsp_iov); 1868 cifs_small_buf_release(pSMB); 1869 cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); 1870 if (rc) { 1871 cifs_dbg(FYI, "Send error Write2 = %d\n", rc); 1872 } else if (resp_buf_type == 0) { 1873 /* presumably this can not happen, but best to be safe */ 1874 rc = -EIO; 1875 } else { 1876 WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base; 1877 *nbytes = le16_to_cpu(pSMBr->CountHigh); 1878 *nbytes = (*nbytes) << 16; 1879 *nbytes += le16_to_cpu(pSMBr->Count); 1880 1881 /* 1882 * Mask off high 16 bits when bytes written as returned by the 1883 * server is greater than bytes requested by the client. OS/2 1884 * servers are known to set incorrect CountHigh values. 1885 */ 1886 if (*nbytes > count) 1887 *nbytes &= 0xFFFF; 1888 } 1889 1890 free_rsp_buf(resp_buf_type, rsp_iov.iov_base); 1891 1892 /* Note: On -EAGAIN error only caller can retry on handle based calls 1893 since file handle passed in no longer valid */ 1894 1895 return rc; 1896 } 1897 1898 int cifs_lockv(const unsigned int xid, struct cifs_tcon *tcon, 1899 const __u16 netfid, const __u8 lock_type, const __u32 num_unlock, 1900 const __u32 num_lock, LOCKING_ANDX_RANGE *buf) 1901 { 1902 int rc = 0; 1903 LOCK_REQ *pSMB = NULL; 1904 struct kvec iov[2]; 1905 struct kvec rsp_iov; 1906 int resp_buf_type; 1907 __u16 count; 1908 1909 cifs_dbg(FYI, "cifs_lockv num lock %d num unlock %d\n", 1910 num_lock, num_unlock); 1911 1912 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); 1913 if (rc) 1914 return rc; 1915 1916 pSMB->Timeout = 0; 1917 pSMB->NumberOfLocks = cpu_to_le16(num_lock); 1918 pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock); 1919 pSMB->LockType = lock_type; 1920 pSMB->AndXCommand = 0xFF; /* none */ 1921 pSMB->Fid = netfid; /* netfid stays le */ 1922 1923 count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE); 1924 inc_rfc1001_len(pSMB, count); 1925 pSMB->ByteCount = cpu_to_le16(count); 1926 1927 iov[0].iov_base = (char *)pSMB; 1928 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 - 1929 (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE); 1930 iov[1].iov_base = (char *)buf; 1931 iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE); 1932 1933 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks); 1934 rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, 1935 CIFS_NO_RSP_BUF, &rsp_iov); 1936 cifs_small_buf_release(pSMB); 1937 if (rc) 1938 cifs_dbg(FYI, "Send error in cifs_lockv = %d\n", rc); 1939 1940 return rc; 1941 } 1942 1943 int 1944 CIFSSMBLock(const unsigned int xid, struct cifs_tcon *tcon, 1945 const __u16 smb_file_id, const __u32 netpid, const __u64 len, 1946 const __u64 offset, const __u32 numUnlock, 1947 const __u32 numLock, const __u8 lockType, 1948 const bool waitFlag, const __u8 oplock_level) 1949 { 1950 int rc = 0; 1951 LOCK_REQ *pSMB = NULL; 1952 /* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */ 1953 int bytes_returned; 1954 int flags = 0; 1955 __u16 count; 1956 1957 cifs_dbg(FYI, "CIFSSMBLock timeout %d numLock %d\n", 1958 (int)waitFlag, numLock); 1959 rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB); 1960 1961 if (rc) 1962 return rc; 1963 1964 if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) { 1965 /* no response expected */ 1966 flags = CIFS_NO_SRV_RSP | CIFS_NON_BLOCKING | CIFS_OBREAK_OP; 1967 pSMB->Timeout = 0; 1968 } else if (waitFlag) { 1969 flags = CIFS_BLOCKING_OP; /* blocking operation, no timeout */ 1970 pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */ 1971 } else { 1972 pSMB->Timeout = 0; 1973 } 1974 1975 pSMB->NumberOfLocks = cpu_to_le16(numLock); 1976 pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock); 1977 pSMB->LockType = lockType; 1978 pSMB->OplockLevel = oplock_level; 1979 pSMB->AndXCommand = 0xFF; /* none */ 1980 pSMB->Fid = smb_file_id; /* netfid stays le */ 1981 1982 if ((numLock != 0) || (numUnlock != 0)) { 1983 pSMB->Locks[0].Pid = cpu_to_le16(netpid); 1984 /* BB where to store pid high? */ 1985 pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len); 1986 pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32)); 1987 pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset); 1988 pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32)); 1989 count = sizeof(LOCKING_ANDX_RANGE); 1990 } else { 1991 /* oplock break */ 1992 count = 0; 1993 } 1994 inc_rfc1001_len(pSMB, count); 1995 pSMB->ByteCount = cpu_to_le16(count); 1996 1997 if (waitFlag) 1998 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, 1999 (struct smb_hdr *) pSMB, &bytes_returned); 2000 else 2001 rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, flags); 2002 cifs_small_buf_release(pSMB); 2003 cifs_stats_inc(&tcon->stats.cifs_stats.num_locks); 2004 if (rc) 2005 cifs_dbg(FYI, "Send error in Lock = %d\n", rc); 2006 2007 /* Note: On -EAGAIN error only caller can retry on handle based calls 2008 since file handle passed in no longer valid */ 2009 return rc; 2010 } 2011 2012 int 2013 CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon, 2014 const __u16 smb_file_id, const __u32 netpid, 2015 const loff_t start_offset, const __u64 len, 2016 struct file_lock *pLockData, const __u16 lock_type, 2017 const bool waitFlag) 2018 { 2019 struct smb_com_transaction2_sfi_req *pSMB = NULL; 2020 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 2021 struct cifs_posix_lock *parm_data; 2022 int rc = 0; 2023 int timeout = 0; 2024 int bytes_returned = 0; 2025 int resp_buf_type = 0; 2026 __u16 params, param_offset, offset, byte_count, count; 2027 struct kvec iov[1]; 2028 struct kvec rsp_iov; 2029 2030 cifs_dbg(FYI, "Posix Lock\n"); 2031 2032 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 2033 2034 if (rc) 2035 return rc; 2036 2037 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB; 2038 2039 params = 6; 2040 pSMB->MaxSetupCount = 0; 2041 pSMB->Reserved = 0; 2042 pSMB->Flags = 0; 2043 pSMB->Reserved2 = 0; 2044 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 2045 offset = param_offset + params; 2046 2047 count = sizeof(struct cifs_posix_lock); 2048 pSMB->MaxParameterCount = cpu_to_le16(2); 2049 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */ 2050 pSMB->SetupCount = 1; 2051 pSMB->Reserved3 = 0; 2052 if (pLockData) 2053 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 2054 else 2055 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 2056 byte_count = 3 /* pad */ + params + count; 2057 pSMB->DataCount = cpu_to_le16(count); 2058 pSMB->ParameterCount = cpu_to_le16(params); 2059 pSMB->TotalDataCount = pSMB->DataCount; 2060 pSMB->TotalParameterCount = pSMB->ParameterCount; 2061 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2062 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 2063 parm_data = (struct cifs_posix_lock *) 2064 (((char *)pSMB) + offset + 4); 2065 2066 parm_data->lock_type = cpu_to_le16(lock_type); 2067 if (waitFlag) { 2068 timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */ 2069 parm_data->lock_flags = cpu_to_le16(1); 2070 pSMB->Timeout = cpu_to_le32(-1); 2071 } else 2072 pSMB->Timeout = 0; 2073 2074 parm_data->pid = cpu_to_le32(netpid); 2075 parm_data->start = cpu_to_le64(start_offset); 2076 parm_data->length = cpu_to_le64(len); /* normalize negative numbers */ 2077 2078 pSMB->DataOffset = cpu_to_le16(offset); 2079 pSMB->Fid = smb_file_id; 2080 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK); 2081 pSMB->Reserved4 = 0; 2082 inc_rfc1001_len(pSMB, byte_count); 2083 pSMB->ByteCount = cpu_to_le16(byte_count); 2084 if (waitFlag) { 2085 rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, 2086 (struct smb_hdr *) pSMBr, &bytes_returned); 2087 } else { 2088 iov[0].iov_base = (char *)pSMB; 2089 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4; 2090 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, 2091 &resp_buf_type, timeout, &rsp_iov); 2092 pSMBr = (struct smb_com_transaction2_sfi_rsp *)rsp_iov.iov_base; 2093 } 2094 cifs_small_buf_release(pSMB); 2095 2096 if (rc) { 2097 cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc); 2098 } else if (pLockData) { 2099 /* lock structure can be returned on get */ 2100 __u16 data_offset; 2101 __u16 data_count; 2102 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2103 2104 if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) { 2105 rc = -EIO; /* bad smb */ 2106 goto plk_err_exit; 2107 } 2108 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 2109 data_count = le16_to_cpu(pSMBr->t2.DataCount); 2110 if (data_count < sizeof(struct cifs_posix_lock)) { 2111 rc = -EIO; 2112 goto plk_err_exit; 2113 } 2114 parm_data = (struct cifs_posix_lock *) 2115 ((char *)&pSMBr->hdr.Protocol + data_offset); 2116 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK)) 2117 pLockData->c.flc_type = F_UNLCK; 2118 else { 2119 if (parm_data->lock_type == 2120 cpu_to_le16(CIFS_RDLCK)) 2121 pLockData->c.flc_type = F_RDLCK; 2122 else if (parm_data->lock_type == 2123 cpu_to_le16(CIFS_WRLCK)) 2124 pLockData->c.flc_type = F_WRLCK; 2125 2126 pLockData->fl_start = le64_to_cpu(parm_data->start); 2127 pLockData->fl_end = pLockData->fl_start + 2128 (le64_to_cpu(parm_data->length) ? 2129 le64_to_cpu(parm_data->length) - 1 : 0); 2130 pLockData->c.flc_pid = -le32_to_cpu(parm_data->pid); 2131 } 2132 } 2133 2134 plk_err_exit: 2135 free_rsp_buf(resp_buf_type, rsp_iov.iov_base); 2136 2137 /* Note: On -EAGAIN error only caller can retry on handle based calls 2138 since file handle passed in no longer valid */ 2139 2140 return rc; 2141 } 2142 2143 2144 int 2145 CIFSSMBClose(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id) 2146 { 2147 int rc = 0; 2148 CLOSE_REQ *pSMB = NULL; 2149 cifs_dbg(FYI, "In CIFSSMBClose\n"); 2150 2151 /* do not retry on dead session on close */ 2152 rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB); 2153 if (rc == -EAGAIN) 2154 return 0; 2155 if (rc) 2156 return rc; 2157 2158 pSMB->FileID = (__u16) smb_file_id; 2159 pSMB->LastWriteTime = 0xFFFFFFFF; 2160 pSMB->ByteCount = 0; 2161 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 2162 cifs_small_buf_release(pSMB); 2163 cifs_stats_inc(&tcon->stats.cifs_stats.num_closes); 2164 if (rc) { 2165 if (rc != -EINTR) { 2166 /* EINTR is expected when user ctl-c to kill app */ 2167 cifs_dbg(VFS, "Send error in Close = %d\n", rc); 2168 } 2169 } 2170 2171 /* Since session is dead, file will be closed on server already */ 2172 if (rc == -EAGAIN) 2173 rc = 0; 2174 2175 return rc; 2176 } 2177 2178 int 2179 CIFSSMBFlush(const unsigned int xid, struct cifs_tcon *tcon, int smb_file_id) 2180 { 2181 int rc = 0; 2182 FLUSH_REQ *pSMB = NULL; 2183 cifs_dbg(FYI, "In CIFSSMBFlush\n"); 2184 2185 rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB); 2186 if (rc) 2187 return rc; 2188 2189 pSMB->FileID = (__u16) smb_file_id; 2190 pSMB->ByteCount = 0; 2191 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 2192 cifs_small_buf_release(pSMB); 2193 cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes); 2194 if (rc) 2195 cifs_dbg(VFS, "Send error in Flush = %d\n", rc); 2196 2197 return rc; 2198 } 2199 2200 int CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon, 2201 struct dentry *source_dentry, 2202 const char *from_name, const char *to_name, 2203 struct cifs_sb_info *cifs_sb) 2204 { 2205 int rc = 0; 2206 RENAME_REQ *pSMB = NULL; 2207 RENAME_RSP *pSMBr = NULL; 2208 int bytes_returned; 2209 int name_len, name_len2; 2210 __u16 count; 2211 int remap = cifs_remap(cifs_sb); 2212 2213 cifs_dbg(FYI, "In CIFSSMBRename\n"); 2214 renameRetry: 2215 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB, 2216 (void **) &pSMBr); 2217 if (rc) 2218 return rc; 2219 2220 pSMB->BufferFormat = 0x04; 2221 pSMB->SearchAttributes = 2222 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 2223 ATTR_DIRECTORY); 2224 2225 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2226 name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName, 2227 from_name, PATH_MAX, 2228 cifs_sb->local_nls, remap); 2229 name_len++; /* trailing null */ 2230 name_len *= 2; 2231 pSMB->OldFileName[name_len] = 0x04; /* pad */ 2232 /* protocol requires ASCII signature byte on Unicode string */ 2233 pSMB->OldFileName[name_len + 1] = 0x00; 2234 name_len2 = 2235 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2], 2236 to_name, PATH_MAX, cifs_sb->local_nls, 2237 remap); 2238 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 2239 name_len2 *= 2; /* convert to bytes */ 2240 } else { 2241 name_len = copy_path_name(pSMB->OldFileName, from_name); 2242 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name); 2243 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ 2244 name_len2++; /* signature byte */ 2245 } 2246 2247 count = 1 /* 1st signature byte */ + name_len + name_len2; 2248 inc_rfc1001_len(pSMB, count); 2249 pSMB->ByteCount = cpu_to_le16(count); 2250 2251 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2252 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2253 cifs_stats_inc(&tcon->stats.cifs_stats.num_renames); 2254 if (rc) 2255 cifs_dbg(FYI, "Send error in rename = %d\n", rc); 2256 2257 cifs_buf_release(pSMB); 2258 2259 if (rc == -EAGAIN) 2260 goto renameRetry; 2261 2262 return rc; 2263 } 2264 2265 int CIFSSMBRenameOpenFile(const unsigned int xid, struct cifs_tcon *pTcon, 2266 int netfid, const char *target_name, 2267 const struct nls_table *nls_codepage, int remap) 2268 { 2269 struct smb_com_transaction2_sfi_req *pSMB = NULL; 2270 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; 2271 struct set_file_rename *rename_info; 2272 char *data_offset; 2273 char dummy_string[30]; 2274 int rc = 0; 2275 int bytes_returned = 0; 2276 int len_of_str; 2277 __u16 params, param_offset, offset, count, byte_count; 2278 2279 cifs_dbg(FYI, "Rename to File by handle\n"); 2280 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB, 2281 (void **) &pSMBr); 2282 if (rc) 2283 return rc; 2284 2285 params = 6; 2286 pSMB->MaxSetupCount = 0; 2287 pSMB->Reserved = 0; 2288 pSMB->Flags = 0; 2289 pSMB->Timeout = 0; 2290 pSMB->Reserved2 = 0; 2291 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 2292 offset = param_offset + params; 2293 2294 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 2295 data_offset = (char *)(pSMB) + offset + 4; 2296 rename_info = (struct set_file_rename *) data_offset; 2297 pSMB->MaxParameterCount = cpu_to_le16(2); 2298 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */ 2299 pSMB->SetupCount = 1; 2300 pSMB->Reserved3 = 0; 2301 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 2302 byte_count = 3 /* pad */ + params; 2303 pSMB->ParameterCount = cpu_to_le16(params); 2304 pSMB->TotalParameterCount = pSMB->ParameterCount; 2305 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2306 pSMB->DataOffset = cpu_to_le16(offset); 2307 /* construct random name ".cifs_tmp<inodenum><mid>" */ 2308 rename_info->overwrite = cpu_to_le32(1); 2309 rename_info->root_fid = 0; 2310 /* unicode only call */ 2311 if (target_name == NULL) { 2312 sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid); 2313 len_of_str = 2314 cifsConvertToUTF16((__le16 *)rename_info->target_name, 2315 dummy_string, 24, nls_codepage, remap); 2316 } else { 2317 len_of_str = 2318 cifsConvertToUTF16((__le16 *)rename_info->target_name, 2319 target_name, PATH_MAX, nls_codepage, 2320 remap); 2321 } 2322 rename_info->target_name_len = cpu_to_le32(2 * len_of_str); 2323 count = sizeof(struct set_file_rename) + (2 * len_of_str); 2324 byte_count += count; 2325 pSMB->DataCount = cpu_to_le16(count); 2326 pSMB->TotalDataCount = pSMB->DataCount; 2327 pSMB->Fid = netfid; 2328 pSMB->InformationLevel = 2329 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION); 2330 pSMB->Reserved4 = 0; 2331 inc_rfc1001_len(pSMB, byte_count); 2332 pSMB->ByteCount = cpu_to_le16(byte_count); 2333 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, 2334 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2335 cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames); 2336 if (rc) 2337 cifs_dbg(FYI, "Send error in Rename (by file handle) = %d\n", 2338 rc); 2339 2340 cifs_buf_release(pSMB); 2341 2342 /* Note: On -EAGAIN error only caller can retry on handle based calls 2343 since file handle passed in no longer valid */ 2344 2345 return rc; 2346 } 2347 2348 int 2349 CIFSUnixCreateSymLink(const unsigned int xid, struct cifs_tcon *tcon, 2350 const char *fromName, const char *toName, 2351 const struct nls_table *nls_codepage, int remap) 2352 { 2353 TRANSACTION2_SPI_REQ *pSMB = NULL; 2354 TRANSACTION2_SPI_RSP *pSMBr = NULL; 2355 char *data_offset; 2356 int name_len; 2357 int name_len_target; 2358 int rc = 0; 2359 int bytes_returned = 0; 2360 __u16 params, param_offset, offset, byte_count; 2361 2362 cifs_dbg(FYI, "In Symlink Unix style\n"); 2363 createSymLinkRetry: 2364 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 2365 (void **) &pSMBr); 2366 if (rc) 2367 return rc; 2368 2369 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2370 name_len = 2371 cifsConvertToUTF16((__le16 *) pSMB->FileName, fromName, 2372 /* find define for this maxpathcomponent */ 2373 PATH_MAX, nls_codepage, remap); 2374 name_len++; /* trailing null */ 2375 name_len *= 2; 2376 2377 } else { 2378 name_len = copy_path_name(pSMB->FileName, fromName); 2379 } 2380 params = 6 + name_len; 2381 pSMB->MaxSetupCount = 0; 2382 pSMB->Reserved = 0; 2383 pSMB->Flags = 0; 2384 pSMB->Timeout = 0; 2385 pSMB->Reserved2 = 0; 2386 param_offset = offsetof(struct smb_com_transaction2_spi_req, 2387 InformationLevel) - 4; 2388 offset = param_offset + params; 2389 2390 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 2391 data_offset = (char *)pSMB + offset + 4; 2392 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2393 name_len_target = 2394 cifsConvertToUTF16((__le16 *) data_offset, toName, 2395 /* find define for this maxpathcomponent */ 2396 PATH_MAX, nls_codepage, remap); 2397 name_len_target++; /* trailing null */ 2398 name_len_target *= 2; 2399 } else { 2400 name_len_target = copy_path_name(data_offset, toName); 2401 } 2402 2403 pSMB->MaxParameterCount = cpu_to_le16(2); 2404 /* BB find exact max on data count below from sess */ 2405 pSMB->MaxDataCount = cpu_to_le16(1000); 2406 pSMB->SetupCount = 1; 2407 pSMB->Reserved3 = 0; 2408 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 2409 byte_count = 3 /* pad */ + params + name_len_target; 2410 pSMB->DataCount = cpu_to_le16(name_len_target); 2411 pSMB->ParameterCount = cpu_to_le16(params); 2412 pSMB->TotalDataCount = pSMB->DataCount; 2413 pSMB->TotalParameterCount = pSMB->ParameterCount; 2414 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2415 pSMB->DataOffset = cpu_to_le16(offset); 2416 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK); 2417 pSMB->Reserved4 = 0; 2418 inc_rfc1001_len(pSMB, byte_count); 2419 pSMB->ByteCount = cpu_to_le16(byte_count); 2420 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2421 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2422 cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks); 2423 if (rc) 2424 cifs_dbg(FYI, "Send error in SetPathInfo create symlink = %d\n", 2425 rc); 2426 2427 cifs_buf_release(pSMB); 2428 2429 if (rc == -EAGAIN) 2430 goto createSymLinkRetry; 2431 2432 return rc; 2433 } 2434 2435 int 2436 CIFSUnixCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon, 2437 const char *fromName, const char *toName, 2438 const struct nls_table *nls_codepage, int remap) 2439 { 2440 TRANSACTION2_SPI_REQ *pSMB = NULL; 2441 TRANSACTION2_SPI_RSP *pSMBr = NULL; 2442 char *data_offset; 2443 int name_len; 2444 int name_len_target; 2445 int rc = 0; 2446 int bytes_returned = 0; 2447 __u16 params, param_offset, offset, byte_count; 2448 2449 cifs_dbg(FYI, "In Create Hard link Unix style\n"); 2450 createHardLinkRetry: 2451 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 2452 (void **) &pSMBr); 2453 if (rc) 2454 return rc; 2455 2456 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2457 name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName, 2458 PATH_MAX, nls_codepage, remap); 2459 name_len++; /* trailing null */ 2460 name_len *= 2; 2461 2462 } else { 2463 name_len = copy_path_name(pSMB->FileName, toName); 2464 } 2465 params = 6 + name_len; 2466 pSMB->MaxSetupCount = 0; 2467 pSMB->Reserved = 0; 2468 pSMB->Flags = 0; 2469 pSMB->Timeout = 0; 2470 pSMB->Reserved2 = 0; 2471 param_offset = offsetof(struct smb_com_transaction2_spi_req, 2472 InformationLevel) - 4; 2473 offset = param_offset + params; 2474 2475 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 2476 data_offset = (char *)pSMB + offset + 4; 2477 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2478 name_len_target = 2479 cifsConvertToUTF16((__le16 *) data_offset, fromName, 2480 PATH_MAX, nls_codepage, remap); 2481 name_len_target++; /* trailing null */ 2482 name_len_target *= 2; 2483 } else { 2484 name_len_target = copy_path_name(data_offset, fromName); 2485 } 2486 2487 pSMB->MaxParameterCount = cpu_to_le16(2); 2488 /* BB find exact max on data count below from sess*/ 2489 pSMB->MaxDataCount = cpu_to_le16(1000); 2490 pSMB->SetupCount = 1; 2491 pSMB->Reserved3 = 0; 2492 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 2493 byte_count = 3 /* pad */ + params + name_len_target; 2494 pSMB->ParameterCount = cpu_to_le16(params); 2495 pSMB->TotalParameterCount = pSMB->ParameterCount; 2496 pSMB->DataCount = cpu_to_le16(name_len_target); 2497 pSMB->TotalDataCount = pSMB->DataCount; 2498 pSMB->ParameterOffset = cpu_to_le16(param_offset); 2499 pSMB->DataOffset = cpu_to_le16(offset); 2500 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK); 2501 pSMB->Reserved4 = 0; 2502 inc_rfc1001_len(pSMB, byte_count); 2503 pSMB->ByteCount = cpu_to_le16(byte_count); 2504 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2505 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2506 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks); 2507 if (rc) 2508 cifs_dbg(FYI, "Send error in SetPathInfo (hard link) = %d\n", 2509 rc); 2510 2511 cifs_buf_release(pSMB); 2512 if (rc == -EAGAIN) 2513 goto createHardLinkRetry; 2514 2515 return rc; 2516 } 2517 2518 int CIFSCreateHardLink(const unsigned int xid, 2519 struct cifs_tcon *tcon, 2520 struct dentry *source_dentry, 2521 const char *from_name, const char *to_name, 2522 struct cifs_sb_info *cifs_sb) 2523 { 2524 int rc = 0; 2525 NT_RENAME_REQ *pSMB = NULL; 2526 RENAME_RSP *pSMBr = NULL; 2527 int bytes_returned; 2528 int name_len, name_len2; 2529 __u16 count; 2530 int remap = cifs_remap(cifs_sb); 2531 2532 cifs_dbg(FYI, "In CIFSCreateHardLink\n"); 2533 winCreateHardLinkRetry: 2534 2535 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB, 2536 (void **) &pSMBr); 2537 if (rc) 2538 return rc; 2539 2540 pSMB->SearchAttributes = 2541 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 2542 ATTR_DIRECTORY); 2543 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK); 2544 pSMB->ClusterCount = 0; 2545 2546 pSMB->BufferFormat = 0x04; 2547 2548 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2549 name_len = 2550 cifsConvertToUTF16((__le16 *) pSMB->OldFileName, from_name, 2551 PATH_MAX, cifs_sb->local_nls, remap); 2552 name_len++; /* trailing null */ 2553 name_len *= 2; 2554 2555 /* protocol specifies ASCII buffer format (0x04) for unicode */ 2556 pSMB->OldFileName[name_len] = 0x04; 2557 pSMB->OldFileName[name_len + 1] = 0x00; /* pad */ 2558 name_len2 = 2559 cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2], 2560 to_name, PATH_MAX, cifs_sb->local_nls, 2561 remap); 2562 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; 2563 name_len2 *= 2; /* convert to bytes */ 2564 } else { 2565 name_len = copy_path_name(pSMB->OldFileName, from_name); 2566 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */ 2567 name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name); 2568 name_len2++; /* signature byte */ 2569 } 2570 2571 count = 1 /* string type byte */ + name_len + name_len2; 2572 inc_rfc1001_len(pSMB, count); 2573 pSMB->ByteCount = cpu_to_le16(count); 2574 2575 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2576 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2577 cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks); 2578 if (rc) 2579 cifs_dbg(FYI, "Send error in hard link (NT rename) = %d\n", rc); 2580 2581 cifs_buf_release(pSMB); 2582 if (rc == -EAGAIN) 2583 goto winCreateHardLinkRetry; 2584 2585 return rc; 2586 } 2587 2588 int 2589 CIFSSMBUnixQuerySymLink(const unsigned int xid, struct cifs_tcon *tcon, 2590 const unsigned char *searchName, char **symlinkinfo, 2591 const struct nls_table *nls_codepage, int remap) 2592 { 2593 /* SMB_QUERY_FILE_UNIX_LINK */ 2594 TRANSACTION2_QPI_REQ *pSMB = NULL; 2595 TRANSACTION2_QPI_RSP *pSMBr = NULL; 2596 int rc = 0; 2597 int bytes_returned; 2598 int name_len; 2599 __u16 params, byte_count; 2600 char *data_start; 2601 2602 cifs_dbg(FYI, "In QPathSymLinkInfo (Unix) for path %s\n", searchName); 2603 2604 querySymLinkRetry: 2605 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 2606 (void **) &pSMBr); 2607 if (rc) 2608 return rc; 2609 2610 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 2611 name_len = 2612 cifsConvertToUTF16((__le16 *) pSMB->FileName, 2613 searchName, PATH_MAX, nls_codepage, 2614 remap); 2615 name_len++; /* trailing null */ 2616 name_len *= 2; 2617 } else { 2618 name_len = copy_path_name(pSMB->FileName, searchName); 2619 } 2620 2621 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 2622 pSMB->TotalDataCount = 0; 2623 pSMB->MaxParameterCount = cpu_to_le16(2); 2624 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 2625 pSMB->MaxSetupCount = 0; 2626 pSMB->Reserved = 0; 2627 pSMB->Flags = 0; 2628 pSMB->Timeout = 0; 2629 pSMB->Reserved2 = 0; 2630 pSMB->ParameterOffset = cpu_to_le16(offsetof( 2631 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 2632 pSMB->DataCount = 0; 2633 pSMB->DataOffset = 0; 2634 pSMB->SetupCount = 1; 2635 pSMB->Reserved3 = 0; 2636 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 2637 byte_count = params + 1 /* pad */ ; 2638 pSMB->TotalParameterCount = cpu_to_le16(params); 2639 pSMB->ParameterCount = pSMB->TotalParameterCount; 2640 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK); 2641 pSMB->Reserved4 = 0; 2642 inc_rfc1001_len(pSMB, byte_count); 2643 pSMB->ByteCount = cpu_to_le16(byte_count); 2644 2645 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2646 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2647 if (rc) { 2648 cifs_dbg(FYI, "Send error in QuerySymLinkInfo = %d\n", rc); 2649 } else { 2650 /* decode response */ 2651 2652 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 2653 /* BB also check enough total bytes returned */ 2654 if (rc || get_bcc(&pSMBr->hdr) < 2) 2655 rc = -EIO; 2656 else { 2657 bool is_unicode; 2658 u16 count = le16_to_cpu(pSMBr->t2.DataCount); 2659 2660 data_start = ((char *) &pSMBr->hdr.Protocol) + 2661 le16_to_cpu(pSMBr->t2.DataOffset); 2662 2663 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) 2664 is_unicode = true; 2665 else 2666 is_unicode = false; 2667 2668 /* BB FIXME investigate remapping reserved chars here */ 2669 *symlinkinfo = cifs_strndup_from_utf16(data_start, 2670 count, is_unicode, nls_codepage); 2671 if (!*symlinkinfo) 2672 rc = -ENOMEM; 2673 } 2674 } 2675 cifs_buf_release(pSMB); 2676 if (rc == -EAGAIN) 2677 goto querySymLinkRetry; 2678 return rc; 2679 } 2680 2681 int cifs_query_reparse_point(const unsigned int xid, 2682 struct cifs_tcon *tcon, 2683 struct cifs_sb_info *cifs_sb, 2684 const char *full_path, 2685 u32 *tag, struct kvec *rsp, 2686 int *rsp_buftype) 2687 { 2688 struct reparse_data_buffer *buf; 2689 struct cifs_open_parms oparms; 2690 TRANSACT_IOCTL_REQ *io_req = NULL; 2691 TRANSACT_IOCTL_RSP *io_rsp = NULL; 2692 struct cifs_fid fid; 2693 __u32 data_offset, data_count, len; 2694 __u8 *start, *end; 2695 int io_rsp_len; 2696 int oplock = 0; 2697 int rc; 2698 2699 cifs_tcon_dbg(FYI, "%s: path=%s\n", __func__, full_path); 2700 2701 if (cap_unix(tcon->ses)) 2702 return -EOPNOTSUPP; 2703 2704 oparms = (struct cifs_open_parms) { 2705 .tcon = tcon, 2706 .cifs_sb = cifs_sb, 2707 .desired_access = FILE_READ_ATTRIBUTES, 2708 .create_options = cifs_create_options(cifs_sb, 2709 OPEN_REPARSE_POINT), 2710 .disposition = FILE_OPEN, 2711 .path = full_path, 2712 .fid = &fid, 2713 }; 2714 2715 rc = CIFS_open(xid, &oparms, &oplock, NULL); 2716 if (rc) 2717 return rc; 2718 2719 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, 2720 (void **)&io_req, (void **)&io_rsp); 2721 if (rc) 2722 goto error; 2723 2724 io_req->TotalParameterCount = 0; 2725 io_req->TotalDataCount = 0; 2726 io_req->MaxParameterCount = cpu_to_le32(2); 2727 /* BB find exact data count max from sess structure BB */ 2728 io_req->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00); 2729 io_req->MaxSetupCount = 4; 2730 io_req->Reserved = 0; 2731 io_req->ParameterOffset = 0; 2732 io_req->DataCount = 0; 2733 io_req->DataOffset = 0; 2734 io_req->SetupCount = 4; 2735 io_req->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL); 2736 io_req->ParameterCount = io_req->TotalParameterCount; 2737 io_req->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT); 2738 io_req->IsFsctl = 1; 2739 io_req->IsRootFlag = 0; 2740 io_req->Fid = fid.netfid; 2741 io_req->ByteCount = 0; 2742 2743 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *)io_req, 2744 (struct smb_hdr *)io_rsp, &io_rsp_len, 0); 2745 if (rc) 2746 goto error; 2747 2748 data_offset = le32_to_cpu(io_rsp->DataOffset); 2749 data_count = le32_to_cpu(io_rsp->DataCount); 2750 if (get_bcc(&io_rsp->hdr) < 2 || data_offset > 512 || 2751 !data_count || data_count > 2048) { 2752 rc = -EIO; 2753 goto error; 2754 } 2755 2756 end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount; 2757 start = (__u8 *)&io_rsp->hdr.Protocol + data_offset; 2758 if (start >= end) { 2759 rc = -EIO; 2760 goto error; 2761 } 2762 2763 data_count = le16_to_cpu(io_rsp->ByteCount); 2764 buf = (struct reparse_data_buffer *)start; 2765 len = sizeof(*buf); 2766 if (data_count < len || 2767 data_count < le16_to_cpu(buf->ReparseDataLength) + len) { 2768 rc = -EIO; 2769 goto error; 2770 } 2771 2772 *tag = le32_to_cpu(buf->ReparseTag); 2773 rsp->iov_base = io_rsp; 2774 rsp->iov_len = io_rsp_len; 2775 *rsp_buftype = CIFS_LARGE_BUFFER; 2776 CIFSSMBClose(xid, tcon, fid.netfid); 2777 return 0; 2778 2779 error: 2780 cifs_buf_release(io_req); 2781 CIFSSMBClose(xid, tcon, fid.netfid); 2782 return rc; 2783 } 2784 2785 int 2786 CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon, 2787 __u16 fid) 2788 { 2789 int rc = 0; 2790 int bytes_returned; 2791 struct smb_com_transaction_compr_ioctl_req *pSMB; 2792 struct smb_com_transaction_ioctl_rsp *pSMBr; 2793 2794 cifs_dbg(FYI, "Set compression for %u\n", fid); 2795 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB, 2796 (void **) &pSMBr); 2797 if (rc) 2798 return rc; 2799 2800 pSMB->compression_state = cpu_to_le16(COMPRESSION_FORMAT_DEFAULT); 2801 2802 pSMB->TotalParameterCount = 0; 2803 pSMB->TotalDataCount = cpu_to_le32(2); 2804 pSMB->MaxParameterCount = 0; 2805 pSMB->MaxDataCount = 0; 2806 pSMB->MaxSetupCount = 4; 2807 pSMB->Reserved = 0; 2808 pSMB->ParameterOffset = 0; 2809 pSMB->DataCount = cpu_to_le32(2); 2810 pSMB->DataOffset = 2811 cpu_to_le32(offsetof(struct smb_com_transaction_compr_ioctl_req, 2812 compression_state) - 4); /* 84 */ 2813 pSMB->SetupCount = 4; 2814 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL); 2815 pSMB->ParameterCount = 0; 2816 pSMB->FunctionCode = cpu_to_le32(FSCTL_SET_COMPRESSION); 2817 pSMB->IsFsctl = 1; /* FSCTL */ 2818 pSMB->IsRootFlag = 0; 2819 pSMB->Fid = fid; /* file handle always le */ 2820 /* 3 byte pad, followed by 2 byte compress state */ 2821 pSMB->ByteCount = cpu_to_le16(5); 2822 inc_rfc1001_len(pSMB, 5); 2823 2824 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2825 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2826 if (rc) 2827 cifs_dbg(FYI, "Send error in SetCompression = %d\n", rc); 2828 2829 cifs_buf_release(pSMB); 2830 2831 /* 2832 * Note: On -EAGAIN error only caller can retry on handle based calls 2833 * since file handle passed in no longer valid. 2834 */ 2835 return rc; 2836 } 2837 2838 2839 #ifdef CONFIG_CIFS_POSIX 2840 2841 #ifdef CONFIG_FS_POSIX_ACL 2842 /** 2843 * cifs_init_posix_acl - convert ACL from cifs to POSIX ACL format 2844 * @ace: POSIX ACL entry to store converted ACL into 2845 * @cifs_ace: ACL in cifs format 2846 * 2847 * Convert an Access Control Entry from wire format to local POSIX xattr 2848 * format. 2849 * 2850 * Note that the @cifs_uid member is used to store both {g,u}id_t. 2851 */ 2852 static void cifs_init_posix_acl(struct posix_acl_entry *ace, 2853 struct cifs_posix_ace *cifs_ace) 2854 { 2855 /* u8 cifs fields do not need le conversion */ 2856 ace->e_perm = cifs_ace->cifs_e_perm; 2857 ace->e_tag = cifs_ace->cifs_e_tag; 2858 2859 switch (ace->e_tag) { 2860 case ACL_USER: 2861 ace->e_uid = make_kuid(&init_user_ns, 2862 le64_to_cpu(cifs_ace->cifs_uid)); 2863 break; 2864 case ACL_GROUP: 2865 ace->e_gid = make_kgid(&init_user_ns, 2866 le64_to_cpu(cifs_ace->cifs_uid)); 2867 break; 2868 } 2869 return; 2870 } 2871 2872 /** 2873 * cifs_to_posix_acl - copy cifs ACL format to POSIX ACL format 2874 * @acl: ACLs returned in POSIX ACL format 2875 * @src: ACLs in cifs format 2876 * @acl_type: type of POSIX ACL requested 2877 * @size_of_data_area: size of SMB we got 2878 * 2879 * This function converts ACLs from cifs format to POSIX ACL format. 2880 * If @acl is NULL then the size of the buffer required to store POSIX ACLs in 2881 * their uapi format is returned. 2882 */ 2883 static int cifs_to_posix_acl(struct posix_acl **acl, char *src, 2884 const int acl_type, const int size_of_data_area) 2885 { 2886 int size = 0; 2887 __u16 count; 2888 struct cifs_posix_ace *pACE; 2889 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src; 2890 struct posix_acl *kacl = NULL; 2891 struct posix_acl_entry *pa, *pe; 2892 2893 if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION) 2894 return -EOPNOTSUPP; 2895 2896 if (acl_type == ACL_TYPE_ACCESS) { 2897 count = le16_to_cpu(cifs_acl->access_entry_count); 2898 pACE = &cifs_acl->ace_array[0]; 2899 size = sizeof(struct cifs_posix_acl); 2900 size += sizeof(struct cifs_posix_ace) * count; 2901 /* check if we would go beyond end of SMB */ 2902 if (size_of_data_area < size) { 2903 cifs_dbg(FYI, "bad CIFS POSIX ACL size %d vs. %d\n", 2904 size_of_data_area, size); 2905 return -EINVAL; 2906 } 2907 } else if (acl_type == ACL_TYPE_DEFAULT) { 2908 count = le16_to_cpu(cifs_acl->access_entry_count); 2909 size = sizeof(struct cifs_posix_acl); 2910 size += sizeof(struct cifs_posix_ace) * count; 2911 /* skip past access ACEs to get to default ACEs */ 2912 pACE = &cifs_acl->ace_array[count]; 2913 count = le16_to_cpu(cifs_acl->default_entry_count); 2914 size += sizeof(struct cifs_posix_ace) * count; 2915 /* check if we would go beyond end of SMB */ 2916 if (size_of_data_area < size) 2917 return -EINVAL; 2918 } else { 2919 /* illegal type */ 2920 return -EINVAL; 2921 } 2922 2923 /* Allocate number of POSIX ACLs to store in VFS format. */ 2924 kacl = posix_acl_alloc(count, GFP_NOFS); 2925 if (!kacl) 2926 return -ENOMEM; 2927 2928 FOREACH_ACL_ENTRY(pa, kacl, pe) { 2929 cifs_init_posix_acl(pa, pACE); 2930 pACE++; 2931 } 2932 2933 *acl = kacl; 2934 return 0; 2935 } 2936 2937 /** 2938 * cifs_init_ace - convert ACL entry from POSIX ACL to cifs format 2939 * @cifs_ace: the cifs ACL entry to store into 2940 * @local_ace: the POSIX ACL entry to convert 2941 */ 2942 static void cifs_init_ace(struct cifs_posix_ace *cifs_ace, 2943 const struct posix_acl_entry *local_ace) 2944 { 2945 cifs_ace->cifs_e_perm = local_ace->e_perm; 2946 cifs_ace->cifs_e_tag = local_ace->e_tag; 2947 2948 switch (local_ace->e_tag) { 2949 case ACL_USER: 2950 cifs_ace->cifs_uid = 2951 cpu_to_le64(from_kuid(&init_user_ns, local_ace->e_uid)); 2952 break; 2953 case ACL_GROUP: 2954 cifs_ace->cifs_uid = 2955 cpu_to_le64(from_kgid(&init_user_ns, local_ace->e_gid)); 2956 break; 2957 default: 2958 cifs_ace->cifs_uid = cpu_to_le64(-1); 2959 } 2960 } 2961 2962 /** 2963 * posix_acl_to_cifs - convert ACLs from POSIX ACL to cifs format 2964 * @parm_data: ACLs in cifs format to convert to 2965 * @acl: ACLs in POSIX ACL format to convert from 2966 * @acl_type: the type of POSIX ACLs stored in @acl 2967 * 2968 * Return: the number cifs ACL entries after conversion 2969 */ 2970 static __u16 posix_acl_to_cifs(char *parm_data, const struct posix_acl *acl, 2971 const int acl_type) 2972 { 2973 __u16 rc = 0; 2974 struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data; 2975 const struct posix_acl_entry *pa, *pe; 2976 int count; 2977 int i = 0; 2978 2979 if ((acl == NULL) || (cifs_acl == NULL)) 2980 return 0; 2981 2982 count = acl->a_count; 2983 cifs_dbg(FYI, "setting acl with %d entries\n", count); 2984 2985 /* 2986 * Note that the uapi POSIX ACL version is verified by the VFS and is 2987 * independent of the cifs ACL version. Changing the POSIX ACL version 2988 * is a uapi change and if it's changed we will pass down the POSIX ACL 2989 * version in struct posix_acl from the VFS. For now there's really 2990 * only one that all filesystems know how to deal with. 2991 */ 2992 cifs_acl->version = cpu_to_le16(1); 2993 if (acl_type == ACL_TYPE_ACCESS) { 2994 cifs_acl->access_entry_count = cpu_to_le16(count); 2995 cifs_acl->default_entry_count = cpu_to_le16(0xFFFF); 2996 } else if (acl_type == ACL_TYPE_DEFAULT) { 2997 cifs_acl->default_entry_count = cpu_to_le16(count); 2998 cifs_acl->access_entry_count = cpu_to_le16(0xFFFF); 2999 } else { 3000 cifs_dbg(FYI, "unknown ACL type %d\n", acl_type); 3001 return 0; 3002 } 3003 FOREACH_ACL_ENTRY(pa, acl, pe) { 3004 cifs_init_ace(&cifs_acl->ace_array[i++], pa); 3005 } 3006 if (rc == 0) { 3007 rc = (__u16)(count * sizeof(struct cifs_posix_ace)); 3008 rc += sizeof(struct cifs_posix_acl); 3009 /* BB add check to make sure ACL does not overflow SMB */ 3010 } 3011 return rc; 3012 } 3013 3014 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon, 3015 const unsigned char *searchName, struct posix_acl **acl, 3016 const int acl_type, const struct nls_table *nls_codepage, 3017 int remap) 3018 { 3019 /* SMB_QUERY_POSIX_ACL */ 3020 TRANSACTION2_QPI_REQ *pSMB = NULL; 3021 TRANSACTION2_QPI_RSP *pSMBr = NULL; 3022 int rc = 0; 3023 int bytes_returned; 3024 int name_len; 3025 __u16 params, byte_count; 3026 3027 cifs_dbg(FYI, "In GetPosixACL (Unix) for path %s\n", searchName); 3028 3029 queryAclRetry: 3030 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3031 (void **) &pSMBr); 3032 if (rc) 3033 return rc; 3034 3035 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3036 name_len = 3037 cifsConvertToUTF16((__le16 *) pSMB->FileName, 3038 searchName, PATH_MAX, nls_codepage, 3039 remap); 3040 name_len++; /* trailing null */ 3041 name_len *= 2; 3042 pSMB->FileName[name_len] = 0; 3043 pSMB->FileName[name_len+1] = 0; 3044 } else { 3045 name_len = copy_path_name(pSMB->FileName, searchName); 3046 } 3047 3048 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 3049 pSMB->TotalDataCount = 0; 3050 pSMB->MaxParameterCount = cpu_to_le16(2); 3051 /* BB find exact max data count below from sess structure BB */ 3052 pSMB->MaxDataCount = cpu_to_le16(4000); 3053 pSMB->MaxSetupCount = 0; 3054 pSMB->Reserved = 0; 3055 pSMB->Flags = 0; 3056 pSMB->Timeout = 0; 3057 pSMB->Reserved2 = 0; 3058 pSMB->ParameterOffset = cpu_to_le16( 3059 offsetof(struct smb_com_transaction2_qpi_req, 3060 InformationLevel) - 4); 3061 pSMB->DataCount = 0; 3062 pSMB->DataOffset = 0; 3063 pSMB->SetupCount = 1; 3064 pSMB->Reserved3 = 0; 3065 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 3066 byte_count = params + 1 /* pad */ ; 3067 pSMB->TotalParameterCount = cpu_to_le16(params); 3068 pSMB->ParameterCount = pSMB->TotalParameterCount; 3069 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL); 3070 pSMB->Reserved4 = 0; 3071 inc_rfc1001_len(pSMB, byte_count); 3072 pSMB->ByteCount = cpu_to_le16(byte_count); 3073 3074 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3075 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3076 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get); 3077 if (rc) { 3078 cifs_dbg(FYI, "Send error in Query POSIX ACL = %d\n", rc); 3079 } else { 3080 /* decode response */ 3081 3082 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3083 /* BB also check enough total bytes returned */ 3084 if (rc || get_bcc(&pSMBr->hdr) < 2) 3085 rc = -EIO; /* bad smb */ 3086 else { 3087 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3088 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 3089 rc = cifs_to_posix_acl(acl, 3090 (char *)&pSMBr->hdr.Protocol+data_offset, 3091 acl_type, count); 3092 } 3093 } 3094 cifs_buf_release(pSMB); 3095 /* 3096 * The else branch after SendReceive() doesn't return EAGAIN so if we 3097 * allocated @acl in cifs_to_posix_acl() we are guaranteed to return 3098 * here and don't leak POSIX ACLs. 3099 */ 3100 if (rc == -EAGAIN) 3101 goto queryAclRetry; 3102 return rc; 3103 } 3104 3105 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon, 3106 const unsigned char *fileName, const struct posix_acl *acl, 3107 const int acl_type, const struct nls_table *nls_codepage, 3108 int remap) 3109 { 3110 struct smb_com_transaction2_spi_req *pSMB = NULL; 3111 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 3112 char *parm_data; 3113 int name_len; 3114 int rc = 0; 3115 int bytes_returned = 0; 3116 __u16 params, byte_count, data_count, param_offset, offset; 3117 3118 cifs_dbg(FYI, "In SetPosixACL (Unix) for path %s\n", fileName); 3119 setAclRetry: 3120 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3121 (void **) &pSMBr); 3122 if (rc) 3123 return rc; 3124 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3125 name_len = 3126 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 3127 PATH_MAX, nls_codepage, remap); 3128 name_len++; /* trailing null */ 3129 name_len *= 2; 3130 } else { 3131 name_len = copy_path_name(pSMB->FileName, fileName); 3132 } 3133 params = 6 + name_len; 3134 pSMB->MaxParameterCount = cpu_to_le16(2); 3135 /* BB find max SMB size from sess */ 3136 pSMB->MaxDataCount = cpu_to_le16(1000); 3137 pSMB->MaxSetupCount = 0; 3138 pSMB->Reserved = 0; 3139 pSMB->Flags = 0; 3140 pSMB->Timeout = 0; 3141 pSMB->Reserved2 = 0; 3142 param_offset = offsetof(struct smb_com_transaction2_spi_req, 3143 InformationLevel) - 4; 3144 offset = param_offset + params; 3145 parm_data = ((char *)pSMB) + sizeof(pSMB->hdr.smb_buf_length) + offset; 3146 pSMB->ParameterOffset = cpu_to_le16(param_offset); 3147 3148 /* convert to on the wire format for POSIX ACL */ 3149 data_count = posix_acl_to_cifs(parm_data, acl, acl_type); 3150 3151 if (data_count == 0) { 3152 rc = -EOPNOTSUPP; 3153 goto setACLerrorExit; 3154 } 3155 pSMB->DataOffset = cpu_to_le16(offset); 3156 pSMB->SetupCount = 1; 3157 pSMB->Reserved3 = 0; 3158 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 3159 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL); 3160 byte_count = 3 /* pad */ + params + data_count; 3161 pSMB->DataCount = cpu_to_le16(data_count); 3162 pSMB->TotalDataCount = pSMB->DataCount; 3163 pSMB->ParameterCount = cpu_to_le16(params); 3164 pSMB->TotalParameterCount = pSMB->ParameterCount; 3165 pSMB->Reserved4 = 0; 3166 inc_rfc1001_len(pSMB, byte_count); 3167 pSMB->ByteCount = cpu_to_le16(byte_count); 3168 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3169 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3170 if (rc) 3171 cifs_dbg(FYI, "Set POSIX ACL returned %d\n", rc); 3172 3173 setACLerrorExit: 3174 cifs_buf_release(pSMB); 3175 if (rc == -EAGAIN) 3176 goto setAclRetry; 3177 return rc; 3178 } 3179 #else 3180 int cifs_do_get_acl(const unsigned int xid, struct cifs_tcon *tcon, 3181 const unsigned char *searchName, struct posix_acl **acl, 3182 const int acl_type, const struct nls_table *nls_codepage, 3183 int remap) 3184 { 3185 return -EOPNOTSUPP; 3186 } 3187 3188 int cifs_do_set_acl(const unsigned int xid, struct cifs_tcon *tcon, 3189 const unsigned char *fileName, const struct posix_acl *acl, 3190 const int acl_type, const struct nls_table *nls_codepage, 3191 int remap) 3192 { 3193 return -EOPNOTSUPP; 3194 } 3195 #endif /* CONFIG_FS_POSIX_ACL */ 3196 3197 int 3198 CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon, 3199 const int netfid, __u64 *pExtAttrBits, __u64 *pMask) 3200 { 3201 int rc = 0; 3202 struct smb_t2_qfi_req *pSMB = NULL; 3203 struct smb_t2_qfi_rsp *pSMBr = NULL; 3204 int bytes_returned; 3205 __u16 params, byte_count; 3206 3207 cifs_dbg(FYI, "In GetExtAttr\n"); 3208 if (tcon == NULL) 3209 return -ENODEV; 3210 3211 GetExtAttrRetry: 3212 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3213 (void **) &pSMBr); 3214 if (rc) 3215 return rc; 3216 3217 params = 2 /* level */ + 2 /* fid */; 3218 pSMB->t2.TotalDataCount = 0; 3219 pSMB->t2.MaxParameterCount = cpu_to_le16(4); 3220 /* BB find exact max data count below from sess structure BB */ 3221 pSMB->t2.MaxDataCount = cpu_to_le16(4000); 3222 pSMB->t2.MaxSetupCount = 0; 3223 pSMB->t2.Reserved = 0; 3224 pSMB->t2.Flags = 0; 3225 pSMB->t2.Timeout = 0; 3226 pSMB->t2.Reserved2 = 0; 3227 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 3228 Fid) - 4); 3229 pSMB->t2.DataCount = 0; 3230 pSMB->t2.DataOffset = 0; 3231 pSMB->t2.SetupCount = 1; 3232 pSMB->t2.Reserved3 = 0; 3233 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 3234 byte_count = params + 1 /* pad */ ; 3235 pSMB->t2.TotalParameterCount = cpu_to_le16(params); 3236 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 3237 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS); 3238 pSMB->Pad = 0; 3239 pSMB->Fid = netfid; 3240 inc_rfc1001_len(pSMB, byte_count); 3241 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 3242 3243 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3244 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3245 if (rc) { 3246 cifs_dbg(FYI, "error %d in GetExtAttr\n", rc); 3247 } else { 3248 /* decode response */ 3249 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3250 /* BB also check enough total bytes returned */ 3251 if (rc || get_bcc(&pSMBr->hdr) < 2) 3252 /* If rc should we check for EOPNOSUPP and 3253 disable the srvino flag? or in caller? */ 3254 rc = -EIO; /* bad smb */ 3255 else { 3256 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3257 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 3258 struct file_chattr_info *pfinfo; 3259 3260 if (count != 16) { 3261 cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n"); 3262 rc = -EIO; 3263 goto GetExtAttrOut; 3264 } 3265 pfinfo = (struct file_chattr_info *) 3266 (data_offset + (char *) &pSMBr->hdr.Protocol); 3267 *pExtAttrBits = le64_to_cpu(pfinfo->mode); 3268 *pMask = le64_to_cpu(pfinfo->mask); 3269 } 3270 } 3271 GetExtAttrOut: 3272 cifs_buf_release(pSMB); 3273 if (rc == -EAGAIN) 3274 goto GetExtAttrRetry; 3275 return rc; 3276 } 3277 3278 #endif /* CONFIG_POSIX */ 3279 3280 /* 3281 * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that 3282 * all NT TRANSACTS that we init here have total parm and data under about 400 3283 * bytes (to fit in small cifs buffer size), which is the case so far, it 3284 * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of 3285 * returned setup area) and MaxParameterCount (returned parms size) must be set 3286 * by caller 3287 */ 3288 static int 3289 smb_init_nttransact(const __u16 sub_command, const int setup_count, 3290 const int parm_len, struct cifs_tcon *tcon, 3291 void **ret_buf) 3292 { 3293 int rc; 3294 __u32 temp_offset; 3295 struct smb_com_ntransact_req *pSMB; 3296 3297 rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon, 3298 (void **)&pSMB); 3299 if (rc) 3300 return rc; 3301 *ret_buf = (void *)pSMB; 3302 pSMB->Reserved = 0; 3303 pSMB->TotalParameterCount = cpu_to_le32(parm_len); 3304 pSMB->TotalDataCount = 0; 3305 pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00); 3306 pSMB->ParameterCount = pSMB->TotalParameterCount; 3307 pSMB->DataCount = pSMB->TotalDataCount; 3308 temp_offset = offsetof(struct smb_com_ntransact_req, Parms) + 3309 (setup_count * 2) - 4 /* for rfc1001 length itself */; 3310 pSMB->ParameterOffset = cpu_to_le32(temp_offset); 3311 pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len); 3312 pSMB->SetupCount = setup_count; /* no need to le convert byte fields */ 3313 pSMB->SubCommand = cpu_to_le16(sub_command); 3314 return 0; 3315 } 3316 3317 static int 3318 validate_ntransact(char *buf, char **ppparm, char **ppdata, 3319 __u32 *pparmlen, __u32 *pdatalen) 3320 { 3321 char *end_of_smb; 3322 __u32 data_count, data_offset, parm_count, parm_offset; 3323 struct smb_com_ntransact_rsp *pSMBr; 3324 u16 bcc; 3325 3326 *pdatalen = 0; 3327 *pparmlen = 0; 3328 3329 if (buf == NULL) 3330 return -EINVAL; 3331 3332 pSMBr = (struct smb_com_ntransact_rsp *)buf; 3333 3334 bcc = get_bcc(&pSMBr->hdr); 3335 end_of_smb = 2 /* sizeof byte count */ + bcc + 3336 (char *)&pSMBr->ByteCount; 3337 3338 data_offset = le32_to_cpu(pSMBr->DataOffset); 3339 data_count = le32_to_cpu(pSMBr->DataCount); 3340 parm_offset = le32_to_cpu(pSMBr->ParameterOffset); 3341 parm_count = le32_to_cpu(pSMBr->ParameterCount); 3342 3343 *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset; 3344 *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset; 3345 3346 /* should we also check that parm and data areas do not overlap? */ 3347 if (*ppparm > end_of_smb) { 3348 cifs_dbg(FYI, "parms start after end of smb\n"); 3349 return -EINVAL; 3350 } else if (parm_count + *ppparm > end_of_smb) { 3351 cifs_dbg(FYI, "parm end after end of smb\n"); 3352 return -EINVAL; 3353 } else if (*ppdata > end_of_smb) { 3354 cifs_dbg(FYI, "data starts after end of smb\n"); 3355 return -EINVAL; 3356 } else if (data_count + *ppdata > end_of_smb) { 3357 cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n", 3358 *ppdata, data_count, (data_count + *ppdata), 3359 end_of_smb, pSMBr); 3360 return -EINVAL; 3361 } else if (parm_count + data_count > bcc) { 3362 cifs_dbg(FYI, "parm count and data count larger than SMB\n"); 3363 return -EINVAL; 3364 } 3365 *pdatalen = data_count; 3366 *pparmlen = parm_count; 3367 return 0; 3368 } 3369 3370 /* Get Security Descriptor (by handle) from remote server for a file or dir */ 3371 int 3372 CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, 3373 struct smb_ntsd **acl_inf, __u32 *pbuflen, __u32 info) 3374 { 3375 int rc = 0; 3376 int buf_type = 0; 3377 QUERY_SEC_DESC_REQ *pSMB; 3378 struct kvec iov[1]; 3379 struct kvec rsp_iov; 3380 3381 cifs_dbg(FYI, "GetCifsACL\n"); 3382 3383 *pbuflen = 0; 3384 *acl_inf = NULL; 3385 3386 rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0, 3387 8 /* parm len */, tcon, (void **) &pSMB); 3388 if (rc) 3389 return rc; 3390 3391 pSMB->MaxParameterCount = cpu_to_le32(4); 3392 /* BB TEST with big acls that might need to be e.g. larger than 16K */ 3393 pSMB->MaxSetupCount = 0; 3394 pSMB->Fid = fid; /* file handle always le */ 3395 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP | 3396 CIFS_ACL_DACL | info); 3397 pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */ 3398 inc_rfc1001_len(pSMB, 11); 3399 iov[0].iov_base = (char *)pSMB; 3400 iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4; 3401 3402 rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 3403 0, &rsp_iov); 3404 cifs_small_buf_release(pSMB); 3405 cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get); 3406 if (rc) { 3407 cifs_dbg(FYI, "Send error in QuerySecDesc = %d\n", rc); 3408 } else { /* decode response */ 3409 __le32 *parm; 3410 __u32 parm_len; 3411 __u32 acl_len; 3412 struct smb_com_ntransact_rsp *pSMBr; 3413 char *pdata; 3414 3415 /* validate_nttransact */ 3416 rc = validate_ntransact(rsp_iov.iov_base, (char **)&parm, 3417 &pdata, &parm_len, pbuflen); 3418 if (rc) 3419 goto qsec_out; 3420 pSMBr = (struct smb_com_ntransact_rsp *)rsp_iov.iov_base; 3421 3422 cifs_dbg(FYI, "smb %p parm %p data %p\n", 3423 pSMBr, parm, *acl_inf); 3424 3425 if (le32_to_cpu(pSMBr->ParameterCount) != 4) { 3426 rc = -EIO; /* bad smb */ 3427 *pbuflen = 0; 3428 goto qsec_out; 3429 } 3430 3431 /* BB check that data area is minimum length and as big as acl_len */ 3432 3433 acl_len = le32_to_cpu(*parm); 3434 if (acl_len != *pbuflen) { 3435 cifs_dbg(VFS, "acl length %d does not match %d\n", 3436 acl_len, *pbuflen); 3437 if (*pbuflen > acl_len) 3438 *pbuflen = acl_len; 3439 } 3440 3441 /* check if buffer is big enough for the acl 3442 header followed by the smallest SID */ 3443 if ((*pbuflen < sizeof(struct smb_ntsd) + 8) || 3444 (*pbuflen >= 64 * 1024)) { 3445 cifs_dbg(VFS, "bad acl length %d\n", *pbuflen); 3446 rc = -EINVAL; 3447 *pbuflen = 0; 3448 } else { 3449 *acl_inf = kmemdup(pdata, *pbuflen, GFP_KERNEL); 3450 if (*acl_inf == NULL) { 3451 *pbuflen = 0; 3452 rc = -ENOMEM; 3453 } 3454 } 3455 } 3456 qsec_out: 3457 free_rsp_buf(buf_type, rsp_iov.iov_base); 3458 return rc; 3459 } 3460 3461 int 3462 CIFSSMBSetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid, 3463 struct smb_ntsd *pntsd, __u32 acllen, int aclflag) 3464 { 3465 __u16 byte_count, param_count, data_count, param_offset, data_offset; 3466 int rc = 0; 3467 int bytes_returned = 0; 3468 SET_SEC_DESC_REQ *pSMB = NULL; 3469 void *pSMBr; 3470 3471 setCifsAclRetry: 3472 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr); 3473 if (rc) 3474 return rc; 3475 3476 pSMB->MaxSetupCount = 0; 3477 pSMB->Reserved = 0; 3478 3479 param_count = 8; 3480 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4; 3481 data_count = acllen; 3482 data_offset = param_offset + param_count; 3483 byte_count = 3 /* pad */ + param_count; 3484 3485 pSMB->DataCount = cpu_to_le32(data_count); 3486 pSMB->TotalDataCount = pSMB->DataCount; 3487 pSMB->MaxParameterCount = cpu_to_le32(4); 3488 pSMB->MaxDataCount = cpu_to_le32(16384); 3489 pSMB->ParameterCount = cpu_to_le32(param_count); 3490 pSMB->ParameterOffset = cpu_to_le32(param_offset); 3491 pSMB->TotalParameterCount = pSMB->ParameterCount; 3492 pSMB->DataOffset = cpu_to_le32(data_offset); 3493 pSMB->SetupCount = 0; 3494 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC); 3495 pSMB->ByteCount = cpu_to_le16(byte_count+data_count); 3496 3497 pSMB->Fid = fid; /* file handle always le */ 3498 pSMB->Reserved2 = 0; 3499 pSMB->AclFlags = cpu_to_le32(aclflag); 3500 3501 if (pntsd && acllen) { 3502 memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) + 3503 data_offset, pntsd, acllen); 3504 inc_rfc1001_len(pSMB, byte_count + data_count); 3505 } else 3506 inc_rfc1001_len(pSMB, byte_count); 3507 3508 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3509 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3510 3511 cifs_dbg(FYI, "SetCIFSACL bytes_returned: %d, rc: %d\n", 3512 bytes_returned, rc); 3513 if (rc) 3514 cifs_dbg(FYI, "Set CIFS ACL returned %d\n", rc); 3515 cifs_buf_release(pSMB); 3516 3517 if (rc == -EAGAIN) 3518 goto setCifsAclRetry; 3519 3520 return (rc); 3521 } 3522 3523 3524 /* Legacy Query Path Information call for lookup to old servers such 3525 as Win9x/WinME */ 3526 int 3527 SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon, 3528 const char *search_name, FILE_ALL_INFO *data, 3529 const struct nls_table *nls_codepage, int remap) 3530 { 3531 QUERY_INFORMATION_REQ *pSMB; 3532 QUERY_INFORMATION_RSP *pSMBr; 3533 int rc = 0; 3534 int bytes_returned; 3535 int name_len; 3536 3537 cifs_dbg(FYI, "In SMBQPath path %s\n", search_name); 3538 QInfRetry: 3539 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB, 3540 (void **) &pSMBr); 3541 if (rc) 3542 return rc; 3543 3544 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3545 name_len = 3546 cifsConvertToUTF16((__le16 *) pSMB->FileName, 3547 search_name, PATH_MAX, nls_codepage, 3548 remap); 3549 name_len++; /* trailing null */ 3550 name_len *= 2; 3551 } else { 3552 name_len = copy_path_name(pSMB->FileName, search_name); 3553 } 3554 pSMB->BufferFormat = 0x04; 3555 name_len++; /* account for buffer type byte */ 3556 inc_rfc1001_len(pSMB, (__u16)name_len); 3557 pSMB->ByteCount = cpu_to_le16(name_len); 3558 3559 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3560 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3561 if (rc) { 3562 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc); 3563 } else if (data) { 3564 struct timespec64 ts; 3565 __u32 time = le32_to_cpu(pSMBr->last_write_time); 3566 3567 /* decode response */ 3568 /* BB FIXME - add time zone adjustment BB */ 3569 memset(data, 0, sizeof(FILE_ALL_INFO)); 3570 ts.tv_nsec = 0; 3571 ts.tv_sec = time; 3572 /* decode time fields */ 3573 data->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts)); 3574 data->LastWriteTime = data->ChangeTime; 3575 data->LastAccessTime = 0; 3576 data->AllocationSize = 3577 cpu_to_le64(le32_to_cpu(pSMBr->size)); 3578 data->EndOfFile = data->AllocationSize; 3579 data->Attributes = 3580 cpu_to_le32(le16_to_cpu(pSMBr->attr)); 3581 } else 3582 rc = -EIO; /* bad buffer passed in */ 3583 3584 cifs_buf_release(pSMB); 3585 3586 if (rc == -EAGAIN) 3587 goto QInfRetry; 3588 3589 return rc; 3590 } 3591 3592 int 3593 CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 3594 u16 netfid, FILE_ALL_INFO *pFindData) 3595 { 3596 struct smb_t2_qfi_req *pSMB = NULL; 3597 struct smb_t2_qfi_rsp *pSMBr = NULL; 3598 int rc = 0; 3599 int bytes_returned; 3600 __u16 params, byte_count; 3601 3602 QFileInfoRetry: 3603 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3604 (void **) &pSMBr); 3605 if (rc) 3606 return rc; 3607 3608 params = 2 /* level */ + 2 /* fid */; 3609 pSMB->t2.TotalDataCount = 0; 3610 pSMB->t2.MaxParameterCount = cpu_to_le16(4); 3611 /* BB find exact max data count below from sess structure BB */ 3612 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 3613 pSMB->t2.MaxSetupCount = 0; 3614 pSMB->t2.Reserved = 0; 3615 pSMB->t2.Flags = 0; 3616 pSMB->t2.Timeout = 0; 3617 pSMB->t2.Reserved2 = 0; 3618 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 3619 Fid) - 4); 3620 pSMB->t2.DataCount = 0; 3621 pSMB->t2.DataOffset = 0; 3622 pSMB->t2.SetupCount = 1; 3623 pSMB->t2.Reserved3 = 0; 3624 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 3625 byte_count = params + 1 /* pad */ ; 3626 pSMB->t2.TotalParameterCount = cpu_to_le16(params); 3627 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 3628 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 3629 pSMB->Pad = 0; 3630 pSMB->Fid = netfid; 3631 inc_rfc1001_len(pSMB, byte_count); 3632 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 3633 3634 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3635 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3636 if (rc) { 3637 cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc); 3638 } else { /* decode response */ 3639 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3640 3641 if (rc) /* BB add auto retry on EOPNOTSUPP? */ 3642 rc = -EIO; 3643 else if (get_bcc(&pSMBr->hdr) < 40) 3644 rc = -EIO; /* bad smb */ 3645 else if (pFindData) { 3646 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3647 memcpy((char *) pFindData, 3648 (char *) &pSMBr->hdr.Protocol + 3649 data_offset, sizeof(FILE_ALL_INFO)); 3650 } else 3651 rc = -ENOMEM; 3652 } 3653 cifs_buf_release(pSMB); 3654 if (rc == -EAGAIN) 3655 goto QFileInfoRetry; 3656 3657 return rc; 3658 } 3659 3660 int 3661 CIFSSMBQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 3662 const char *search_name, FILE_ALL_INFO *data, 3663 int legacy /* old style infolevel */, 3664 const struct nls_table *nls_codepage, int remap) 3665 { 3666 /* level 263 SMB_QUERY_FILE_ALL_INFO */ 3667 TRANSACTION2_QPI_REQ *pSMB = NULL; 3668 TRANSACTION2_QPI_RSP *pSMBr = NULL; 3669 int rc = 0; 3670 int bytes_returned; 3671 int name_len; 3672 __u16 params, byte_count; 3673 3674 /* cifs_dbg(FYI, "In QPathInfo path %s\n", search_name); */ 3675 QPathInfoRetry: 3676 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3677 (void **) &pSMBr); 3678 if (rc) 3679 return rc; 3680 3681 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3682 name_len = 3683 cifsConvertToUTF16((__le16 *) pSMB->FileName, search_name, 3684 PATH_MAX, nls_codepage, remap); 3685 name_len++; /* trailing null */ 3686 name_len *= 2; 3687 } else { 3688 name_len = copy_path_name(pSMB->FileName, search_name); 3689 } 3690 3691 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; 3692 pSMB->TotalDataCount = 0; 3693 pSMB->MaxParameterCount = cpu_to_le16(2); 3694 /* BB find exact max SMB PDU from sess structure BB */ 3695 pSMB->MaxDataCount = cpu_to_le16(4000); 3696 pSMB->MaxSetupCount = 0; 3697 pSMB->Reserved = 0; 3698 pSMB->Flags = 0; 3699 pSMB->Timeout = 0; 3700 pSMB->Reserved2 = 0; 3701 pSMB->ParameterOffset = cpu_to_le16(offsetof( 3702 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 3703 pSMB->DataCount = 0; 3704 pSMB->DataOffset = 0; 3705 pSMB->SetupCount = 1; 3706 pSMB->Reserved3 = 0; 3707 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 3708 byte_count = params + 1 /* pad */ ; 3709 pSMB->TotalParameterCount = cpu_to_le16(params); 3710 pSMB->ParameterCount = pSMB->TotalParameterCount; 3711 if (legacy) 3712 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD); 3713 else 3714 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 3715 pSMB->Reserved4 = 0; 3716 inc_rfc1001_len(pSMB, byte_count); 3717 pSMB->ByteCount = cpu_to_le16(byte_count); 3718 3719 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3720 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3721 if (rc) { 3722 cifs_dbg(FYI, "Send error in QPathInfo = %d\n", rc); 3723 } else { /* decode response */ 3724 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3725 3726 if (rc) /* BB add auto retry on EOPNOTSUPP? */ 3727 rc = -EIO; 3728 else if (!legacy && get_bcc(&pSMBr->hdr) < 40) 3729 rc = -EIO; /* bad smb */ 3730 else if (legacy && get_bcc(&pSMBr->hdr) < 24) 3731 rc = -EIO; /* 24 or 26 expected but we do not read 3732 last field */ 3733 else if (data) { 3734 int size; 3735 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3736 3737 /* 3738 * On legacy responses we do not read the last field, 3739 * EAsize, fortunately since it varies by subdialect and 3740 * also note it differs on Set vs Get, ie two bytes or 4 3741 * bytes depending but we don't care here. 3742 */ 3743 if (legacy) 3744 size = sizeof(FILE_INFO_STANDARD); 3745 else 3746 size = sizeof(FILE_ALL_INFO); 3747 memcpy((char *) data, (char *) &pSMBr->hdr.Protocol + 3748 data_offset, size); 3749 } else 3750 rc = -ENOMEM; 3751 } 3752 cifs_buf_release(pSMB); 3753 if (rc == -EAGAIN) 3754 goto QPathInfoRetry; 3755 3756 return rc; 3757 } 3758 3759 int 3760 CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 3761 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData) 3762 { 3763 struct smb_t2_qfi_req *pSMB = NULL; 3764 struct smb_t2_qfi_rsp *pSMBr = NULL; 3765 int rc = 0; 3766 int bytes_returned; 3767 __u16 params, byte_count; 3768 3769 UnixQFileInfoRetry: 3770 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3771 (void **) &pSMBr); 3772 if (rc) 3773 return rc; 3774 3775 params = 2 /* level */ + 2 /* fid */; 3776 pSMB->t2.TotalDataCount = 0; 3777 pSMB->t2.MaxParameterCount = cpu_to_le16(4); 3778 /* BB find exact max data count below from sess structure BB */ 3779 pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 3780 pSMB->t2.MaxSetupCount = 0; 3781 pSMB->t2.Reserved = 0; 3782 pSMB->t2.Flags = 0; 3783 pSMB->t2.Timeout = 0; 3784 pSMB->t2.Reserved2 = 0; 3785 pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req, 3786 Fid) - 4); 3787 pSMB->t2.DataCount = 0; 3788 pSMB->t2.DataOffset = 0; 3789 pSMB->t2.SetupCount = 1; 3790 pSMB->t2.Reserved3 = 0; 3791 pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION); 3792 byte_count = params + 1 /* pad */ ; 3793 pSMB->t2.TotalParameterCount = cpu_to_le16(params); 3794 pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount; 3795 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); 3796 pSMB->Pad = 0; 3797 pSMB->Fid = netfid; 3798 inc_rfc1001_len(pSMB, byte_count); 3799 pSMB->t2.ByteCount = cpu_to_le16(byte_count); 3800 3801 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3802 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3803 if (rc) { 3804 cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc); 3805 } else { /* decode response */ 3806 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3807 3808 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) { 3809 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n"); 3810 rc = -EIO; /* bad smb */ 3811 } else { 3812 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3813 memcpy((char *) pFindData, 3814 (char *) &pSMBr->hdr.Protocol + 3815 data_offset, 3816 sizeof(FILE_UNIX_BASIC_INFO)); 3817 } 3818 } 3819 3820 cifs_buf_release(pSMB); 3821 if (rc == -EAGAIN) 3822 goto UnixQFileInfoRetry; 3823 3824 return rc; 3825 } 3826 3827 int 3828 CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 3829 const unsigned char *searchName, 3830 FILE_UNIX_BASIC_INFO *pFindData, 3831 const struct nls_table *nls_codepage, int remap) 3832 { 3833 /* SMB_QUERY_FILE_UNIX_BASIC */ 3834 TRANSACTION2_QPI_REQ *pSMB = NULL; 3835 TRANSACTION2_QPI_RSP *pSMBr = NULL; 3836 int rc = 0; 3837 int bytes_returned = 0; 3838 int name_len; 3839 __u16 params, byte_count; 3840 3841 cifs_dbg(FYI, "In QPathInfo (Unix) the path %s\n", searchName); 3842 UnixQPathInfoRetry: 3843 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3844 (void **) &pSMBr); 3845 if (rc) 3846 return rc; 3847 3848 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3849 name_len = 3850 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, 3851 PATH_MAX, nls_codepage, remap); 3852 name_len++; /* trailing null */ 3853 name_len *= 2; 3854 } else { 3855 name_len = copy_path_name(pSMB->FileName, searchName); 3856 } 3857 3858 params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */; 3859 pSMB->TotalDataCount = 0; 3860 pSMB->MaxParameterCount = cpu_to_le16(2); 3861 /* BB find exact max SMB PDU from sess structure BB */ 3862 pSMB->MaxDataCount = cpu_to_le16(4000); 3863 pSMB->MaxSetupCount = 0; 3864 pSMB->Reserved = 0; 3865 pSMB->Flags = 0; 3866 pSMB->Timeout = 0; 3867 pSMB->Reserved2 = 0; 3868 pSMB->ParameterOffset = cpu_to_le16(offsetof( 3869 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 3870 pSMB->DataCount = 0; 3871 pSMB->DataOffset = 0; 3872 pSMB->SetupCount = 1; 3873 pSMB->Reserved3 = 0; 3874 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 3875 byte_count = params + 1 /* pad */ ; 3876 pSMB->TotalParameterCount = cpu_to_le16(params); 3877 pSMB->ParameterCount = pSMB->TotalParameterCount; 3878 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); 3879 pSMB->Reserved4 = 0; 3880 inc_rfc1001_len(pSMB, byte_count); 3881 pSMB->ByteCount = cpu_to_le16(byte_count); 3882 3883 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3884 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3885 if (rc) { 3886 cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc); 3887 } else { /* decode response */ 3888 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3889 3890 if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) { 3891 cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n"); 3892 rc = -EIO; /* bad smb */ 3893 } else { 3894 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3895 memcpy((char *) pFindData, 3896 (char *) &pSMBr->hdr.Protocol + 3897 data_offset, 3898 sizeof(FILE_UNIX_BASIC_INFO)); 3899 } 3900 } 3901 cifs_buf_release(pSMB); 3902 if (rc == -EAGAIN) 3903 goto UnixQPathInfoRetry; 3904 3905 return rc; 3906 } 3907 3908 /* xid, tcon, searchName and codepage are input parms, rest are returned */ 3909 int 3910 CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon, 3911 const char *searchName, struct cifs_sb_info *cifs_sb, 3912 __u16 *pnetfid, __u16 search_flags, 3913 struct cifs_search_info *psrch_inf, bool msearch) 3914 { 3915 /* level 257 SMB_ */ 3916 TRANSACTION2_FFIRST_REQ *pSMB = NULL; 3917 TRANSACTION2_FFIRST_RSP *pSMBr = NULL; 3918 T2_FFIRST_RSP_PARMS *parms; 3919 struct nls_table *nls_codepage; 3920 unsigned int lnoff; 3921 __u16 params, byte_count; 3922 int bytes_returned = 0; 3923 int name_len, remap; 3924 int rc = 0; 3925 3926 cifs_dbg(FYI, "In FindFirst for %s\n", searchName); 3927 3928 findFirstRetry: 3929 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3930 (void **) &pSMBr); 3931 if (rc) 3932 return rc; 3933 3934 nls_codepage = cifs_sb->local_nls; 3935 remap = cifs_remap(cifs_sb); 3936 3937 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 3938 name_len = 3939 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, 3940 PATH_MAX, nls_codepage, remap); 3941 /* We can not add the asterisk earlier in case 3942 it got remapped to 0xF03A as if it were part of the 3943 directory name instead of a wildcard */ 3944 name_len *= 2; 3945 if (msearch) { 3946 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb); 3947 pSMB->FileName[name_len+1] = 0; 3948 pSMB->FileName[name_len+2] = '*'; 3949 pSMB->FileName[name_len+3] = 0; 3950 name_len += 4; /* now the trailing null */ 3951 /* null terminate just in case */ 3952 pSMB->FileName[name_len] = 0; 3953 pSMB->FileName[name_len+1] = 0; 3954 name_len += 2; 3955 } 3956 } else { 3957 name_len = copy_path_name(pSMB->FileName, searchName); 3958 if (msearch) { 3959 if (WARN_ON_ONCE(name_len > PATH_MAX-2)) 3960 name_len = PATH_MAX-2; 3961 /* overwrite nul byte */ 3962 pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb); 3963 pSMB->FileName[name_len] = '*'; 3964 pSMB->FileName[name_len+1] = 0; 3965 name_len += 2; 3966 } 3967 } 3968 3969 params = 12 + name_len /* includes null */ ; 3970 pSMB->TotalDataCount = 0; /* no EAs */ 3971 pSMB->MaxParameterCount = cpu_to_le16(10); 3972 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00); 3973 pSMB->MaxSetupCount = 0; 3974 pSMB->Reserved = 0; 3975 pSMB->Flags = 0; 3976 pSMB->Timeout = 0; 3977 pSMB->Reserved2 = 0; 3978 byte_count = params + 1 /* pad */ ; 3979 pSMB->TotalParameterCount = cpu_to_le16(params); 3980 pSMB->ParameterCount = pSMB->TotalParameterCount; 3981 pSMB->ParameterOffset = cpu_to_le16( 3982 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes) 3983 - 4); 3984 pSMB->DataCount = 0; 3985 pSMB->DataOffset = 0; 3986 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */ 3987 pSMB->Reserved3 = 0; 3988 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST); 3989 pSMB->SearchAttributes = 3990 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 3991 ATTR_DIRECTORY); 3992 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO)); 3993 pSMB->SearchFlags = cpu_to_le16(search_flags); 3994 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 3995 3996 /* BB what should we set StorageType to? Does it matter? BB */ 3997 pSMB->SearchStorageType = 0; 3998 inc_rfc1001_len(pSMB, byte_count); 3999 pSMB->ByteCount = cpu_to_le16(byte_count); 4000 4001 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4002 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4003 cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst); 4004 4005 if (rc) { 4006 /* 4007 * BB: add logic to retry regular search if Unix search rejected 4008 * unexpectedly by server. 4009 */ 4010 /* BB: add code to handle unsupported level rc */ 4011 cifs_dbg(FYI, "Error in FindFirst = %d\n", rc); 4012 cifs_buf_release(pSMB); 4013 /* 4014 * BB: eventually could optimize out free and realloc of buf for 4015 * this case. 4016 */ 4017 if (rc == -EAGAIN) 4018 goto findFirstRetry; 4019 return rc; 4020 } 4021 /* decode response */ 4022 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4023 if (rc) { 4024 cifs_buf_release(pSMB); 4025 return rc; 4026 } 4027 4028 psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE); 4029 psrch_inf->ntwrk_buf_start = (char *)pSMBr; 4030 psrch_inf->smallBuf = false; 4031 psrch_inf->srch_entries_start = (char *)&pSMBr->hdr.Protocol + 4032 le16_to_cpu(pSMBr->t2.DataOffset); 4033 4034 parms = (T2_FFIRST_RSP_PARMS *)((char *)&pSMBr->hdr.Protocol + 4035 le16_to_cpu(pSMBr->t2.ParameterOffset)); 4036 psrch_inf->endOfSearch = !!parms->EndofSearch; 4037 4038 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); 4039 psrch_inf->index_of_last_entry = 2 /* skip . and .. */ + 4040 psrch_inf->entries_in_buffer; 4041 lnoff = le16_to_cpu(parms->LastNameOffset); 4042 if (CIFSMaxBufSize < lnoff) { 4043 cifs_dbg(VFS, "ignoring corrupt resume name\n"); 4044 psrch_inf->last_entry = NULL; 4045 } else { 4046 psrch_inf->last_entry = psrch_inf->srch_entries_start + lnoff; 4047 if (pnetfid) 4048 *pnetfid = parms->SearchHandle; 4049 } 4050 return 0; 4051 } 4052 4053 int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon, 4054 __u16 searchHandle, __u16 search_flags, 4055 struct cifs_search_info *psrch_inf) 4056 { 4057 TRANSACTION2_FNEXT_REQ *pSMB = NULL; 4058 TRANSACTION2_FNEXT_RSP *pSMBr = NULL; 4059 T2_FNEXT_RSP_PARMS *parms; 4060 unsigned int name_len; 4061 unsigned int lnoff; 4062 __u16 params, byte_count; 4063 char *response_data; 4064 int bytes_returned; 4065 int rc = 0; 4066 4067 cifs_dbg(FYI, "In FindNext\n"); 4068 4069 if (psrch_inf->endOfSearch) 4070 return -ENOENT; 4071 4072 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4073 (void **) &pSMBr); 4074 if (rc) 4075 return rc; 4076 4077 params = 14; /* includes 2 bytes of null string, converted to LE below*/ 4078 byte_count = 0; 4079 pSMB->TotalDataCount = 0; /* no EAs */ 4080 pSMB->MaxParameterCount = cpu_to_le16(8); 4081 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00); 4082 pSMB->MaxSetupCount = 0; 4083 pSMB->Reserved = 0; 4084 pSMB->Flags = 0; 4085 pSMB->Timeout = 0; 4086 pSMB->Reserved2 = 0; 4087 pSMB->ParameterOffset = cpu_to_le16( 4088 offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4); 4089 pSMB->DataCount = 0; 4090 pSMB->DataOffset = 0; 4091 pSMB->SetupCount = 1; 4092 pSMB->Reserved3 = 0; 4093 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT); 4094 pSMB->SearchHandle = searchHandle; /* always kept as le */ 4095 pSMB->SearchCount = 4096 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO)); 4097 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 4098 pSMB->ResumeKey = psrch_inf->resume_key; 4099 pSMB->SearchFlags = cpu_to_le16(search_flags); 4100 4101 name_len = psrch_inf->resume_name_len; 4102 params += name_len; 4103 if (name_len < PATH_MAX) { 4104 memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len); 4105 byte_count += name_len; 4106 /* 14 byte parm len above enough for 2 byte null terminator */ 4107 pSMB->ResumeFileName[name_len] = 0; 4108 pSMB->ResumeFileName[name_len+1] = 0; 4109 } else { 4110 cifs_buf_release(pSMB); 4111 return -EINVAL; 4112 } 4113 byte_count = params + 1 /* pad */ ; 4114 pSMB->TotalParameterCount = cpu_to_le16(params); 4115 pSMB->ParameterCount = pSMB->TotalParameterCount; 4116 inc_rfc1001_len(pSMB, byte_count); 4117 pSMB->ByteCount = cpu_to_le16(byte_count); 4118 4119 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4120 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4121 cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext); 4122 4123 if (rc) { 4124 cifs_buf_release(pSMB); 4125 if (rc == -EBADF) { 4126 psrch_inf->endOfSearch = true; 4127 rc = 0; /* search probably was closed at end of search*/ 4128 } else { 4129 cifs_dbg(FYI, "FindNext returned = %d\n", rc); 4130 } 4131 return rc; 4132 } 4133 4134 /* decode response */ 4135 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4136 if (rc) { 4137 cifs_buf_release(pSMB); 4138 return rc; 4139 } 4140 /* BB fixme add lock for file (srch_info) struct here */ 4141 psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE); 4142 response_data = (char *)&pSMBr->hdr.Protocol + 4143 le16_to_cpu(pSMBr->t2.ParameterOffset); 4144 parms = (T2_FNEXT_RSP_PARMS *)response_data; 4145 response_data = (char *)&pSMBr->hdr.Protocol + 4146 le16_to_cpu(pSMBr->t2.DataOffset); 4147 4148 if (psrch_inf->smallBuf) 4149 cifs_small_buf_release(psrch_inf->ntwrk_buf_start); 4150 else 4151 cifs_buf_release(psrch_inf->ntwrk_buf_start); 4152 4153 psrch_inf->srch_entries_start = response_data; 4154 psrch_inf->ntwrk_buf_start = (char *)pSMB; 4155 psrch_inf->smallBuf = false; 4156 psrch_inf->endOfSearch = !!parms->EndofSearch; 4157 psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); 4158 psrch_inf->index_of_last_entry += psrch_inf->entries_in_buffer; 4159 lnoff = le16_to_cpu(parms->LastNameOffset); 4160 if (CIFSMaxBufSize < lnoff) { 4161 cifs_dbg(VFS, "ignoring corrupt resume name\n"); 4162 psrch_inf->last_entry = NULL; 4163 } else { 4164 psrch_inf->last_entry = 4165 psrch_inf->srch_entries_start + lnoff; 4166 } 4167 /* BB fixme add unlock here */ 4168 4169 /* 4170 * BB: On error, should we leave previous search buf 4171 * (and count and last entry fields) intact or free the previous one? 4172 * 4173 * Note: On -EAGAIN error only caller can retry on handle based calls 4174 * since file handle passed in no longer valid. 4175 */ 4176 return 0; 4177 } 4178 4179 int 4180 CIFSFindClose(const unsigned int xid, struct cifs_tcon *tcon, 4181 const __u16 searchHandle) 4182 { 4183 int rc = 0; 4184 FINDCLOSE_REQ *pSMB = NULL; 4185 4186 cifs_dbg(FYI, "In CIFSSMBFindClose\n"); 4187 rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB); 4188 4189 /* no sense returning error if session restarted 4190 as file handle has been closed */ 4191 if (rc == -EAGAIN) 4192 return 0; 4193 if (rc) 4194 return rc; 4195 4196 pSMB->FileID = searchHandle; 4197 pSMB->ByteCount = 0; 4198 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 4199 cifs_small_buf_release(pSMB); 4200 if (rc) 4201 cifs_dbg(VFS, "Send error in FindClose = %d\n", rc); 4202 4203 cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose); 4204 4205 /* Since session is dead, search handle closed on server already */ 4206 if (rc == -EAGAIN) 4207 rc = 0; 4208 4209 return rc; 4210 } 4211 4212 int 4213 CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon, 4214 const char *search_name, __u64 *inode_number, 4215 const struct nls_table *nls_codepage, int remap) 4216 { 4217 int rc = 0; 4218 TRANSACTION2_QPI_REQ *pSMB = NULL; 4219 TRANSACTION2_QPI_RSP *pSMBr = NULL; 4220 int name_len, bytes_returned; 4221 __u16 params, byte_count; 4222 4223 cifs_dbg(FYI, "In GetSrvInodeNum for %s\n", search_name); 4224 if (tcon == NULL) 4225 return -ENODEV; 4226 4227 GetInodeNumberRetry: 4228 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4229 (void **) &pSMBr); 4230 if (rc) 4231 return rc; 4232 4233 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4234 name_len = 4235 cifsConvertToUTF16((__le16 *) pSMB->FileName, 4236 search_name, PATH_MAX, nls_codepage, 4237 remap); 4238 name_len++; /* trailing null */ 4239 name_len *= 2; 4240 } else { 4241 name_len = copy_path_name(pSMB->FileName, search_name); 4242 } 4243 4244 params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; 4245 pSMB->TotalDataCount = 0; 4246 pSMB->MaxParameterCount = cpu_to_le16(2); 4247 /* BB find exact max data count below from sess structure BB */ 4248 pSMB->MaxDataCount = cpu_to_le16(4000); 4249 pSMB->MaxSetupCount = 0; 4250 pSMB->Reserved = 0; 4251 pSMB->Flags = 0; 4252 pSMB->Timeout = 0; 4253 pSMB->Reserved2 = 0; 4254 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4255 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 4256 pSMB->DataCount = 0; 4257 pSMB->DataOffset = 0; 4258 pSMB->SetupCount = 1; 4259 pSMB->Reserved3 = 0; 4260 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 4261 byte_count = params + 1 /* pad */ ; 4262 pSMB->TotalParameterCount = cpu_to_le16(params); 4263 pSMB->ParameterCount = pSMB->TotalParameterCount; 4264 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO); 4265 pSMB->Reserved4 = 0; 4266 inc_rfc1001_len(pSMB, byte_count); 4267 pSMB->ByteCount = cpu_to_le16(byte_count); 4268 4269 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4270 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4271 if (rc) { 4272 cifs_dbg(FYI, "error %d in QueryInternalInfo\n", rc); 4273 } else { 4274 /* decode response */ 4275 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4276 /* BB also check enough total bytes returned */ 4277 if (rc || get_bcc(&pSMBr->hdr) < 2) 4278 /* If rc should we check for EOPNOSUPP and 4279 disable the srvino flag? or in caller? */ 4280 rc = -EIO; /* bad smb */ 4281 else { 4282 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4283 __u16 count = le16_to_cpu(pSMBr->t2.DataCount); 4284 struct file_internal_info *pfinfo; 4285 /* BB Do we need a cast or hash here ? */ 4286 if (count < 8) { 4287 cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n"); 4288 rc = -EIO; 4289 goto GetInodeNumOut; 4290 } 4291 pfinfo = (struct file_internal_info *) 4292 (data_offset + (char *) &pSMBr->hdr.Protocol); 4293 *inode_number = le64_to_cpu(pfinfo->UniqueId); 4294 } 4295 } 4296 GetInodeNumOut: 4297 cifs_buf_release(pSMB); 4298 if (rc == -EAGAIN) 4299 goto GetInodeNumberRetry; 4300 return rc; 4301 } 4302 4303 int 4304 CIFSGetDFSRefer(const unsigned int xid, struct cifs_ses *ses, 4305 const char *search_name, struct dfs_info3_param **target_nodes, 4306 unsigned int *num_of_nodes, 4307 const struct nls_table *nls_codepage, int remap) 4308 { 4309 /* TRANS2_GET_DFS_REFERRAL */ 4310 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL; 4311 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL; 4312 int rc = 0; 4313 int bytes_returned; 4314 int name_len; 4315 __u16 params, byte_count; 4316 *num_of_nodes = 0; 4317 *target_nodes = NULL; 4318 4319 cifs_dbg(FYI, "In GetDFSRefer the path %s\n", search_name); 4320 if (ses == NULL || ses->tcon_ipc == NULL) 4321 return -ENODEV; 4322 4323 getDFSRetry: 4324 /* 4325 * Use smb_init_no_reconnect() instead of smb_init() as 4326 * CIFSGetDFSRefer() may be called from cifs_reconnect_tcon() and thus 4327 * causing an infinite recursion. 4328 */ 4329 rc = smb_init(SMB_COM_TRANSACTION2, 15, ses->tcon_ipc, 4330 (void **)&pSMB, (void **)&pSMBr); 4331 if (rc) 4332 return rc; 4333 4334 /* server pointer checked in called function, 4335 but should never be null here anyway */ 4336 pSMB->hdr.Mid = get_next_mid(ses->server); 4337 pSMB->hdr.Tid = ses->tcon_ipc->tid; 4338 pSMB->hdr.Uid = ses->Suid; 4339 if (ses->capabilities & CAP_STATUS32) 4340 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS; 4341 if (ses->capabilities & CAP_DFS) 4342 pSMB->hdr.Flags2 |= SMBFLG2_DFS; 4343 4344 if (ses->capabilities & CAP_UNICODE) { 4345 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; 4346 name_len = 4347 cifsConvertToUTF16((__le16 *) pSMB->RequestFileName, 4348 search_name, PATH_MAX, nls_codepage, 4349 remap); 4350 name_len++; /* trailing null */ 4351 name_len *= 2; 4352 } else { /* BB improve the check for buffer overruns BB */ 4353 name_len = copy_path_name(pSMB->RequestFileName, search_name); 4354 } 4355 4356 if (ses->server->sign) 4357 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 4358 4359 pSMB->hdr.Uid = ses->Suid; 4360 4361 params = 2 /* level */ + name_len /*includes null */ ; 4362 pSMB->TotalDataCount = 0; 4363 pSMB->DataCount = 0; 4364 pSMB->DataOffset = 0; 4365 pSMB->MaxParameterCount = 0; 4366 /* BB find exact max SMB PDU from sess structure BB */ 4367 pSMB->MaxDataCount = cpu_to_le16(4000); 4368 pSMB->MaxSetupCount = 0; 4369 pSMB->Reserved = 0; 4370 pSMB->Flags = 0; 4371 pSMB->Timeout = 0; 4372 pSMB->Reserved2 = 0; 4373 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4374 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4); 4375 pSMB->SetupCount = 1; 4376 pSMB->Reserved3 = 0; 4377 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL); 4378 byte_count = params + 3 /* pad */ ; 4379 pSMB->ParameterCount = cpu_to_le16(params); 4380 pSMB->TotalParameterCount = pSMB->ParameterCount; 4381 pSMB->MaxReferralLevel = cpu_to_le16(3); 4382 inc_rfc1001_len(pSMB, byte_count); 4383 pSMB->ByteCount = cpu_to_le16(byte_count); 4384 4385 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, 4386 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4387 if (rc) { 4388 cifs_dbg(FYI, "Send error in GetDFSRefer = %d\n", rc); 4389 goto GetDFSRefExit; 4390 } 4391 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4392 4393 /* BB Also check if enough total bytes returned? */ 4394 if (rc || get_bcc(&pSMBr->hdr) < 17) { 4395 rc = -EIO; /* bad smb */ 4396 goto GetDFSRefExit; 4397 } 4398 4399 cifs_dbg(FYI, "Decoding GetDFSRefer response BCC: %d Offset %d\n", 4400 get_bcc(&pSMBr->hdr), le16_to_cpu(pSMBr->t2.DataOffset)); 4401 4402 /* parse returned result into more usable form */ 4403 rc = parse_dfs_referrals(&pSMBr->dfs_data, 4404 le16_to_cpu(pSMBr->t2.DataCount), 4405 num_of_nodes, target_nodes, nls_codepage, 4406 remap, search_name, 4407 (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) != 0); 4408 4409 GetDFSRefExit: 4410 cifs_buf_release(pSMB); 4411 4412 if (rc == -EAGAIN) 4413 goto getDFSRetry; 4414 4415 return rc; 4416 } 4417 4418 /* Query File System Info such as free space to old servers such as Win 9x */ 4419 int 4420 SMBOldQFSInfo(const unsigned int xid, struct cifs_tcon *tcon, 4421 struct kstatfs *FSData) 4422 { 4423 /* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */ 4424 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4425 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4426 FILE_SYSTEM_ALLOC_INFO *response_data; 4427 int rc = 0; 4428 int bytes_returned = 0; 4429 __u16 params, byte_count; 4430 4431 cifs_dbg(FYI, "OldQFSInfo\n"); 4432 oldQFSInfoRetry: 4433 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4434 (void **) &pSMBr); 4435 if (rc) 4436 return rc; 4437 4438 params = 2; /* level */ 4439 pSMB->TotalDataCount = 0; 4440 pSMB->MaxParameterCount = cpu_to_le16(2); 4441 pSMB->MaxDataCount = cpu_to_le16(1000); 4442 pSMB->MaxSetupCount = 0; 4443 pSMB->Reserved = 0; 4444 pSMB->Flags = 0; 4445 pSMB->Timeout = 0; 4446 pSMB->Reserved2 = 0; 4447 byte_count = params + 1 /* pad */ ; 4448 pSMB->TotalParameterCount = cpu_to_le16(params); 4449 pSMB->ParameterCount = pSMB->TotalParameterCount; 4450 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4451 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4452 pSMB->DataCount = 0; 4453 pSMB->DataOffset = 0; 4454 pSMB->SetupCount = 1; 4455 pSMB->Reserved3 = 0; 4456 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4457 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION); 4458 inc_rfc1001_len(pSMB, byte_count); 4459 pSMB->ByteCount = cpu_to_le16(byte_count); 4460 4461 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4462 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4463 if (rc) { 4464 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc); 4465 } else { /* decode response */ 4466 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4467 4468 if (rc || get_bcc(&pSMBr->hdr) < 18) 4469 rc = -EIO; /* bad smb */ 4470 else { 4471 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4472 cifs_dbg(FYI, "qfsinf resp BCC: %d Offset %d\n", 4473 get_bcc(&pSMBr->hdr), data_offset); 4474 4475 response_data = (FILE_SYSTEM_ALLOC_INFO *) 4476 (((char *) &pSMBr->hdr.Protocol) + data_offset); 4477 FSData->f_bsize = 4478 le16_to_cpu(response_data->BytesPerSector) * 4479 le32_to_cpu(response_data-> 4480 SectorsPerAllocationUnit); 4481 /* 4482 * much prefer larger but if server doesn't report 4483 * a valid size than 4K is a reasonable minimum 4484 */ 4485 if (FSData->f_bsize < 512) 4486 FSData->f_bsize = 4096; 4487 4488 FSData->f_blocks = 4489 le32_to_cpu(response_data->TotalAllocationUnits); 4490 FSData->f_bfree = FSData->f_bavail = 4491 le32_to_cpu(response_data->FreeAllocationUnits); 4492 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n", 4493 (unsigned long long)FSData->f_blocks, 4494 (unsigned long long)FSData->f_bfree, 4495 FSData->f_bsize); 4496 } 4497 } 4498 cifs_buf_release(pSMB); 4499 4500 if (rc == -EAGAIN) 4501 goto oldQFSInfoRetry; 4502 4503 return rc; 4504 } 4505 4506 int 4507 CIFSSMBQFSInfo(const unsigned int xid, struct cifs_tcon *tcon, 4508 struct kstatfs *FSData) 4509 { 4510 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */ 4511 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4512 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4513 FILE_SYSTEM_INFO *response_data; 4514 int rc = 0; 4515 int bytes_returned = 0; 4516 __u16 params, byte_count; 4517 4518 cifs_dbg(FYI, "In QFSInfo\n"); 4519 QFSInfoRetry: 4520 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4521 (void **) &pSMBr); 4522 if (rc) 4523 return rc; 4524 4525 params = 2; /* level */ 4526 pSMB->TotalDataCount = 0; 4527 pSMB->MaxParameterCount = cpu_to_le16(2); 4528 pSMB->MaxDataCount = cpu_to_le16(1000); 4529 pSMB->MaxSetupCount = 0; 4530 pSMB->Reserved = 0; 4531 pSMB->Flags = 0; 4532 pSMB->Timeout = 0; 4533 pSMB->Reserved2 = 0; 4534 byte_count = params + 1 /* pad */ ; 4535 pSMB->TotalParameterCount = cpu_to_le16(params); 4536 pSMB->ParameterCount = pSMB->TotalParameterCount; 4537 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4538 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4539 pSMB->DataCount = 0; 4540 pSMB->DataOffset = 0; 4541 pSMB->SetupCount = 1; 4542 pSMB->Reserved3 = 0; 4543 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4544 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO); 4545 inc_rfc1001_len(pSMB, byte_count); 4546 pSMB->ByteCount = cpu_to_le16(byte_count); 4547 4548 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4549 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4550 if (rc) { 4551 cifs_dbg(FYI, "Send error in QFSInfo = %d\n", rc); 4552 } else { /* decode response */ 4553 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4554 4555 if (rc || get_bcc(&pSMBr->hdr) < 24) 4556 rc = -EIO; /* bad smb */ 4557 else { 4558 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4559 4560 response_data = 4561 (FILE_SYSTEM_INFO 4562 *) (((char *) &pSMBr->hdr.Protocol) + 4563 data_offset); 4564 FSData->f_bsize = 4565 le32_to_cpu(response_data->BytesPerSector) * 4566 le32_to_cpu(response_data-> 4567 SectorsPerAllocationUnit); 4568 /* 4569 * much prefer larger but if server doesn't report 4570 * a valid size than 4K is a reasonable minimum 4571 */ 4572 if (FSData->f_bsize < 512) 4573 FSData->f_bsize = 4096; 4574 4575 FSData->f_blocks = 4576 le64_to_cpu(response_data->TotalAllocationUnits); 4577 FSData->f_bfree = FSData->f_bavail = 4578 le64_to_cpu(response_data->FreeAllocationUnits); 4579 cifs_dbg(FYI, "Blocks: %lld Free: %lld Block size %ld\n", 4580 (unsigned long long)FSData->f_blocks, 4581 (unsigned long long)FSData->f_bfree, 4582 FSData->f_bsize); 4583 } 4584 } 4585 cifs_buf_release(pSMB); 4586 4587 if (rc == -EAGAIN) 4588 goto QFSInfoRetry; 4589 4590 return rc; 4591 } 4592 4593 int 4594 CIFSSMBQFSAttributeInfo(const unsigned int xid, struct cifs_tcon *tcon) 4595 { 4596 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */ 4597 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4598 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4599 FILE_SYSTEM_ATTRIBUTE_INFO *response_data; 4600 int rc = 0; 4601 int bytes_returned = 0; 4602 __u16 params, byte_count; 4603 4604 cifs_dbg(FYI, "In QFSAttributeInfo\n"); 4605 QFSAttributeRetry: 4606 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4607 (void **) &pSMBr); 4608 if (rc) 4609 return rc; 4610 4611 params = 2; /* level */ 4612 pSMB->TotalDataCount = 0; 4613 pSMB->MaxParameterCount = cpu_to_le16(2); 4614 /* BB find exact max SMB PDU from sess structure BB */ 4615 pSMB->MaxDataCount = cpu_to_le16(1000); 4616 pSMB->MaxSetupCount = 0; 4617 pSMB->Reserved = 0; 4618 pSMB->Flags = 0; 4619 pSMB->Timeout = 0; 4620 pSMB->Reserved2 = 0; 4621 byte_count = params + 1 /* pad */ ; 4622 pSMB->TotalParameterCount = cpu_to_le16(params); 4623 pSMB->ParameterCount = pSMB->TotalParameterCount; 4624 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4625 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4626 pSMB->DataCount = 0; 4627 pSMB->DataOffset = 0; 4628 pSMB->SetupCount = 1; 4629 pSMB->Reserved3 = 0; 4630 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4631 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO); 4632 inc_rfc1001_len(pSMB, byte_count); 4633 pSMB->ByteCount = cpu_to_le16(byte_count); 4634 4635 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4636 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4637 if (rc) { 4638 cifs_dbg(VFS, "Send error in QFSAttributeInfo = %d\n", rc); 4639 } else { /* decode response */ 4640 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4641 4642 if (rc || get_bcc(&pSMBr->hdr) < 13) { 4643 /* BB also check if enough bytes returned */ 4644 rc = -EIO; /* bad smb */ 4645 } else { 4646 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4647 response_data = 4648 (FILE_SYSTEM_ATTRIBUTE_INFO 4649 *) (((char *) &pSMBr->hdr.Protocol) + 4650 data_offset); 4651 memcpy(&tcon->fsAttrInfo, response_data, 4652 sizeof(FILE_SYSTEM_ATTRIBUTE_INFO)); 4653 } 4654 } 4655 cifs_buf_release(pSMB); 4656 4657 if (rc == -EAGAIN) 4658 goto QFSAttributeRetry; 4659 4660 return rc; 4661 } 4662 4663 int 4664 CIFSSMBQFSDeviceInfo(const unsigned int xid, struct cifs_tcon *tcon) 4665 { 4666 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */ 4667 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4668 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4669 FILE_SYSTEM_DEVICE_INFO *response_data; 4670 int rc = 0; 4671 int bytes_returned = 0; 4672 __u16 params, byte_count; 4673 4674 cifs_dbg(FYI, "In QFSDeviceInfo\n"); 4675 QFSDeviceRetry: 4676 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4677 (void **) &pSMBr); 4678 if (rc) 4679 return rc; 4680 4681 params = 2; /* level */ 4682 pSMB->TotalDataCount = 0; 4683 pSMB->MaxParameterCount = cpu_to_le16(2); 4684 /* BB find exact max SMB PDU from sess structure BB */ 4685 pSMB->MaxDataCount = cpu_to_le16(1000); 4686 pSMB->MaxSetupCount = 0; 4687 pSMB->Reserved = 0; 4688 pSMB->Flags = 0; 4689 pSMB->Timeout = 0; 4690 pSMB->Reserved2 = 0; 4691 byte_count = params + 1 /* pad */ ; 4692 pSMB->TotalParameterCount = cpu_to_le16(params); 4693 pSMB->ParameterCount = pSMB->TotalParameterCount; 4694 pSMB->ParameterOffset = cpu_to_le16(offsetof( 4695 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4696 4697 pSMB->DataCount = 0; 4698 pSMB->DataOffset = 0; 4699 pSMB->SetupCount = 1; 4700 pSMB->Reserved3 = 0; 4701 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4702 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO); 4703 inc_rfc1001_len(pSMB, byte_count); 4704 pSMB->ByteCount = cpu_to_le16(byte_count); 4705 4706 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4707 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4708 if (rc) { 4709 cifs_dbg(FYI, "Send error in QFSDeviceInfo = %d\n", rc); 4710 } else { /* decode response */ 4711 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4712 4713 if (rc || get_bcc(&pSMBr->hdr) < 4714 sizeof(FILE_SYSTEM_DEVICE_INFO)) 4715 rc = -EIO; /* bad smb */ 4716 else { 4717 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4718 response_data = 4719 (FILE_SYSTEM_DEVICE_INFO *) 4720 (((char *) &pSMBr->hdr.Protocol) + 4721 data_offset); 4722 memcpy(&tcon->fsDevInfo, response_data, 4723 sizeof(FILE_SYSTEM_DEVICE_INFO)); 4724 } 4725 } 4726 cifs_buf_release(pSMB); 4727 4728 if (rc == -EAGAIN) 4729 goto QFSDeviceRetry; 4730 4731 return rc; 4732 } 4733 4734 int 4735 CIFSSMBQFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon) 4736 { 4737 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */ 4738 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4739 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4740 FILE_SYSTEM_UNIX_INFO *response_data; 4741 int rc = 0; 4742 int bytes_returned = 0; 4743 __u16 params, byte_count; 4744 4745 cifs_dbg(FYI, "In QFSUnixInfo\n"); 4746 QFSUnixRetry: 4747 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, 4748 (void **) &pSMB, (void **) &pSMBr); 4749 if (rc) 4750 return rc; 4751 4752 params = 2; /* level */ 4753 pSMB->TotalDataCount = 0; 4754 pSMB->DataCount = 0; 4755 pSMB->DataOffset = 0; 4756 pSMB->MaxParameterCount = cpu_to_le16(2); 4757 /* BB find exact max SMB PDU from sess structure BB */ 4758 pSMB->MaxDataCount = cpu_to_le16(100); 4759 pSMB->MaxSetupCount = 0; 4760 pSMB->Reserved = 0; 4761 pSMB->Flags = 0; 4762 pSMB->Timeout = 0; 4763 pSMB->Reserved2 = 0; 4764 byte_count = params + 1 /* pad */ ; 4765 pSMB->ParameterCount = cpu_to_le16(params); 4766 pSMB->TotalParameterCount = pSMB->ParameterCount; 4767 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct 4768 smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4769 pSMB->SetupCount = 1; 4770 pSMB->Reserved3 = 0; 4771 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4772 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO); 4773 inc_rfc1001_len(pSMB, byte_count); 4774 pSMB->ByteCount = cpu_to_le16(byte_count); 4775 4776 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4777 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4778 if (rc) { 4779 cifs_dbg(VFS, "Send error in QFSUnixInfo = %d\n", rc); 4780 } else { /* decode response */ 4781 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4782 4783 if (rc || get_bcc(&pSMBr->hdr) < 13) { 4784 rc = -EIO; /* bad smb */ 4785 } else { 4786 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4787 response_data = 4788 (FILE_SYSTEM_UNIX_INFO 4789 *) (((char *) &pSMBr->hdr.Protocol) + 4790 data_offset); 4791 memcpy(&tcon->fsUnixInfo, response_data, 4792 sizeof(FILE_SYSTEM_UNIX_INFO)); 4793 } 4794 } 4795 cifs_buf_release(pSMB); 4796 4797 if (rc == -EAGAIN) 4798 goto QFSUnixRetry; 4799 4800 4801 return rc; 4802 } 4803 4804 int 4805 CIFSSMBSetFSUnixInfo(const unsigned int xid, struct cifs_tcon *tcon, __u64 cap) 4806 { 4807 /* level 0x200 SMB_SET_CIFS_UNIX_INFO */ 4808 TRANSACTION2_SETFSI_REQ *pSMB = NULL; 4809 TRANSACTION2_SETFSI_RSP *pSMBr = NULL; 4810 int rc = 0; 4811 int bytes_returned = 0; 4812 __u16 params, param_offset, offset, byte_count; 4813 4814 cifs_dbg(FYI, "In SETFSUnixInfo\n"); 4815 SETFSUnixRetry: 4816 /* BB switch to small buf init to save memory */ 4817 rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon, 4818 (void **) &pSMB, (void **) &pSMBr); 4819 if (rc) 4820 return rc; 4821 4822 params = 4; /* 2 bytes zero followed by info level. */ 4823 pSMB->MaxSetupCount = 0; 4824 pSMB->Reserved = 0; 4825 pSMB->Flags = 0; 4826 pSMB->Timeout = 0; 4827 pSMB->Reserved2 = 0; 4828 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum) 4829 - 4; 4830 offset = param_offset + params; 4831 4832 pSMB->MaxParameterCount = cpu_to_le16(4); 4833 /* BB find exact max SMB PDU from sess structure BB */ 4834 pSMB->MaxDataCount = cpu_to_le16(100); 4835 pSMB->SetupCount = 1; 4836 pSMB->Reserved3 = 0; 4837 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION); 4838 byte_count = 1 /* pad */ + params + 12; 4839 4840 pSMB->DataCount = cpu_to_le16(12); 4841 pSMB->ParameterCount = cpu_to_le16(params); 4842 pSMB->TotalDataCount = pSMB->DataCount; 4843 pSMB->TotalParameterCount = pSMB->ParameterCount; 4844 pSMB->ParameterOffset = cpu_to_le16(param_offset); 4845 pSMB->DataOffset = cpu_to_le16(offset); 4846 4847 /* Params. */ 4848 pSMB->FileNum = 0; 4849 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO); 4850 4851 /* Data. */ 4852 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION); 4853 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION); 4854 pSMB->ClientUnixCap = cpu_to_le64(cap); 4855 4856 inc_rfc1001_len(pSMB, byte_count); 4857 pSMB->ByteCount = cpu_to_le16(byte_count); 4858 4859 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4860 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4861 if (rc) { 4862 cifs_dbg(VFS, "Send error in SETFSUnixInfo = %d\n", rc); 4863 } else { /* decode response */ 4864 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4865 if (rc) 4866 rc = -EIO; /* bad smb */ 4867 } 4868 cifs_buf_release(pSMB); 4869 4870 if (rc == -EAGAIN) 4871 goto SETFSUnixRetry; 4872 4873 return rc; 4874 } 4875 4876 4877 4878 int 4879 CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon, 4880 struct kstatfs *FSData) 4881 { 4882 /* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */ 4883 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4884 TRANSACTION2_QFSI_RSP *pSMBr = NULL; 4885 FILE_SYSTEM_POSIX_INFO *response_data; 4886 int rc = 0; 4887 int bytes_returned = 0; 4888 __u16 params, byte_count; 4889 4890 cifs_dbg(FYI, "In QFSPosixInfo\n"); 4891 QFSPosixRetry: 4892 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4893 (void **) &pSMBr); 4894 if (rc) 4895 return rc; 4896 4897 params = 2; /* level */ 4898 pSMB->TotalDataCount = 0; 4899 pSMB->DataCount = 0; 4900 pSMB->DataOffset = 0; 4901 pSMB->MaxParameterCount = cpu_to_le16(2); 4902 /* BB find exact max SMB PDU from sess structure BB */ 4903 pSMB->MaxDataCount = cpu_to_le16(100); 4904 pSMB->MaxSetupCount = 0; 4905 pSMB->Reserved = 0; 4906 pSMB->Flags = 0; 4907 pSMB->Timeout = 0; 4908 pSMB->Reserved2 = 0; 4909 byte_count = params + 1 /* pad */ ; 4910 pSMB->ParameterCount = cpu_to_le16(params); 4911 pSMB->TotalParameterCount = pSMB->ParameterCount; 4912 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct 4913 smb_com_transaction2_qfsi_req, InformationLevel) - 4); 4914 pSMB->SetupCount = 1; 4915 pSMB->Reserved3 = 0; 4916 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); 4917 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO); 4918 inc_rfc1001_len(pSMB, byte_count); 4919 pSMB->ByteCount = cpu_to_le16(byte_count); 4920 4921 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 4922 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 4923 if (rc) { 4924 cifs_dbg(FYI, "Send error in QFSUnixInfo = %d\n", rc); 4925 } else { /* decode response */ 4926 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 4927 4928 if (rc || get_bcc(&pSMBr->hdr) < 13) { 4929 rc = -EIO; /* bad smb */ 4930 } else { 4931 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 4932 response_data = 4933 (FILE_SYSTEM_POSIX_INFO 4934 *) (((char *) &pSMBr->hdr.Protocol) + 4935 data_offset); 4936 FSData->f_bsize = 4937 le32_to_cpu(response_data->BlockSize); 4938 /* 4939 * much prefer larger but if server doesn't report 4940 * a valid size than 4K is a reasonable minimum 4941 */ 4942 if (FSData->f_bsize < 512) 4943 FSData->f_bsize = 4096; 4944 4945 FSData->f_blocks = 4946 le64_to_cpu(response_data->TotalBlocks); 4947 FSData->f_bfree = 4948 le64_to_cpu(response_data->BlocksAvail); 4949 if (response_data->UserBlocksAvail == cpu_to_le64(-1)) { 4950 FSData->f_bavail = FSData->f_bfree; 4951 } else { 4952 FSData->f_bavail = 4953 le64_to_cpu(response_data->UserBlocksAvail); 4954 } 4955 if (response_data->TotalFileNodes != cpu_to_le64(-1)) 4956 FSData->f_files = 4957 le64_to_cpu(response_data->TotalFileNodes); 4958 if (response_data->FreeFileNodes != cpu_to_le64(-1)) 4959 FSData->f_ffree = 4960 le64_to_cpu(response_data->FreeFileNodes); 4961 } 4962 } 4963 cifs_buf_release(pSMB); 4964 4965 if (rc == -EAGAIN) 4966 goto QFSPosixRetry; 4967 4968 return rc; 4969 } 4970 4971 4972 /* 4973 * We can not use write of zero bytes trick to set file size due to need for 4974 * large file support. Also note that this SetPathInfo is preferred to 4975 * SetFileInfo based method in next routine which is only needed to work around 4976 * a sharing violation bugin Samba which this routine can run into. 4977 */ 4978 int 4979 CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon, 4980 const char *file_name, __u64 size, struct cifs_sb_info *cifs_sb, 4981 bool set_allocation, struct dentry *dentry) 4982 { 4983 struct smb_com_transaction2_spi_req *pSMB = NULL; 4984 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 4985 struct file_end_of_file_info *parm_data; 4986 int name_len; 4987 int rc = 0; 4988 int bytes_returned = 0; 4989 int remap = cifs_remap(cifs_sb); 4990 4991 __u16 params, byte_count, data_count, param_offset, offset; 4992 4993 cifs_dbg(FYI, "In SetEOF\n"); 4994 SetEOFRetry: 4995 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 4996 (void **) &pSMBr); 4997 if (rc) 4998 return rc; 4999 5000 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5001 name_len = 5002 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name, 5003 PATH_MAX, cifs_sb->local_nls, remap); 5004 name_len++; /* trailing null */ 5005 name_len *= 2; 5006 } else { 5007 name_len = copy_path_name(pSMB->FileName, file_name); 5008 } 5009 params = 6 + name_len; 5010 data_count = sizeof(struct file_end_of_file_info); 5011 pSMB->MaxParameterCount = cpu_to_le16(2); 5012 pSMB->MaxDataCount = cpu_to_le16(4100); 5013 pSMB->MaxSetupCount = 0; 5014 pSMB->Reserved = 0; 5015 pSMB->Flags = 0; 5016 pSMB->Timeout = 0; 5017 pSMB->Reserved2 = 0; 5018 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5019 InformationLevel) - 4; 5020 offset = param_offset + params; 5021 if (set_allocation) { 5022 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5023 pSMB->InformationLevel = 5024 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); 5025 else 5026 pSMB->InformationLevel = 5027 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO); 5028 } else /* Set File Size */ { 5029 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5030 pSMB->InformationLevel = 5031 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2); 5032 else 5033 pSMB->InformationLevel = 5034 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); 5035 } 5036 5037 parm_data = 5038 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) + 5039 offset); 5040 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5041 pSMB->DataOffset = cpu_to_le16(offset); 5042 pSMB->SetupCount = 1; 5043 pSMB->Reserved3 = 0; 5044 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5045 byte_count = 3 /* pad */ + params + data_count; 5046 pSMB->DataCount = cpu_to_le16(data_count); 5047 pSMB->TotalDataCount = pSMB->DataCount; 5048 pSMB->ParameterCount = cpu_to_le16(params); 5049 pSMB->TotalParameterCount = pSMB->ParameterCount; 5050 pSMB->Reserved4 = 0; 5051 inc_rfc1001_len(pSMB, byte_count); 5052 parm_data->FileSize = cpu_to_le64(size); 5053 pSMB->ByteCount = cpu_to_le16(byte_count); 5054 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5055 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5056 if (rc) 5057 cifs_dbg(FYI, "SetPathInfo (file size) returned %d\n", rc); 5058 5059 cifs_buf_release(pSMB); 5060 5061 if (rc == -EAGAIN) 5062 goto SetEOFRetry; 5063 5064 return rc; 5065 } 5066 5067 int 5068 CIFSSMBSetFileSize(const unsigned int xid, struct cifs_tcon *tcon, 5069 struct cifsFileInfo *cfile, __u64 size, bool set_allocation) 5070 { 5071 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5072 struct file_end_of_file_info *parm_data; 5073 int rc = 0; 5074 __u16 params, param_offset, offset, byte_count, count; 5075 5076 cifs_dbg(FYI, "SetFileSize (via SetFileInfo) %lld\n", 5077 (long long)size); 5078 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5079 5080 if (rc) 5081 return rc; 5082 5083 pSMB->hdr.Pid = cpu_to_le16((__u16)cfile->pid); 5084 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(cfile->pid >> 16)); 5085 5086 params = 6; 5087 pSMB->MaxSetupCount = 0; 5088 pSMB->Reserved = 0; 5089 pSMB->Flags = 0; 5090 pSMB->Timeout = 0; 5091 pSMB->Reserved2 = 0; 5092 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5093 offset = param_offset + params; 5094 5095 count = sizeof(struct file_end_of_file_info); 5096 pSMB->MaxParameterCount = cpu_to_le16(2); 5097 /* BB find exact max SMB PDU from sess structure BB */ 5098 pSMB->MaxDataCount = cpu_to_le16(1000); 5099 pSMB->SetupCount = 1; 5100 pSMB->Reserved3 = 0; 5101 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5102 byte_count = 3 /* pad */ + params + count; 5103 pSMB->DataCount = cpu_to_le16(count); 5104 pSMB->ParameterCount = cpu_to_le16(params); 5105 pSMB->TotalDataCount = pSMB->DataCount; 5106 pSMB->TotalParameterCount = pSMB->ParameterCount; 5107 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5108 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 5109 parm_data = 5110 (struct file_end_of_file_info *)(((char *)pSMB) + offset + 4); 5111 pSMB->DataOffset = cpu_to_le16(offset); 5112 parm_data->FileSize = cpu_to_le64(size); 5113 pSMB->Fid = cfile->fid.netfid; 5114 if (set_allocation) { 5115 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5116 pSMB->InformationLevel = 5117 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2); 5118 else 5119 pSMB->InformationLevel = 5120 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO); 5121 } else /* Set File Size */ { 5122 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5123 pSMB->InformationLevel = 5124 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2); 5125 else 5126 pSMB->InformationLevel = 5127 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO); 5128 } 5129 pSMB->Reserved4 = 0; 5130 inc_rfc1001_len(pSMB, byte_count); 5131 pSMB->ByteCount = cpu_to_le16(byte_count); 5132 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5133 cifs_small_buf_release(pSMB); 5134 if (rc) { 5135 cifs_dbg(FYI, "Send error in SetFileInfo (SetFileSize) = %d\n", 5136 rc); 5137 } 5138 5139 /* Note: On -EAGAIN error only caller can retry on handle based calls 5140 since file handle passed in no longer valid */ 5141 5142 return rc; 5143 } 5144 5145 /* Some legacy servers such as NT4 require that the file times be set on 5146 an open handle, rather than by pathname - this is awkward due to 5147 potential access conflicts on the open, but it is unavoidable for these 5148 old servers since the only other choice is to go from 100 nanosecond DCE 5149 time and resort to the original setpathinfo level which takes the ancient 5150 DOS time format with 2 second granularity */ 5151 int 5152 CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 5153 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener) 5154 { 5155 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5156 char *data_offset; 5157 int rc = 0; 5158 __u16 params, param_offset, offset, byte_count, count; 5159 5160 cifs_dbg(FYI, "Set Times (via SetFileInfo)\n"); 5161 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5162 5163 if (rc) 5164 return rc; 5165 5166 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 5167 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 5168 5169 params = 6; 5170 pSMB->MaxSetupCount = 0; 5171 pSMB->Reserved = 0; 5172 pSMB->Flags = 0; 5173 pSMB->Timeout = 0; 5174 pSMB->Reserved2 = 0; 5175 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5176 offset = param_offset + params; 5177 5178 data_offset = (char *)pSMB + 5179 offsetof(struct smb_hdr, Protocol) + offset; 5180 5181 count = sizeof(FILE_BASIC_INFO); 5182 pSMB->MaxParameterCount = cpu_to_le16(2); 5183 /* BB find max SMB PDU from sess */ 5184 pSMB->MaxDataCount = cpu_to_le16(1000); 5185 pSMB->SetupCount = 1; 5186 pSMB->Reserved3 = 0; 5187 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5188 byte_count = 3 /* pad */ + params + count; 5189 pSMB->DataCount = cpu_to_le16(count); 5190 pSMB->ParameterCount = cpu_to_le16(params); 5191 pSMB->TotalDataCount = pSMB->DataCount; 5192 pSMB->TotalParameterCount = pSMB->ParameterCount; 5193 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5194 pSMB->DataOffset = cpu_to_le16(offset); 5195 pSMB->Fid = fid; 5196 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5197 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2); 5198 else 5199 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); 5200 pSMB->Reserved4 = 0; 5201 inc_rfc1001_len(pSMB, byte_count); 5202 pSMB->ByteCount = cpu_to_le16(byte_count); 5203 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 5204 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5205 cifs_small_buf_release(pSMB); 5206 if (rc) 5207 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n", 5208 rc); 5209 5210 /* Note: On -EAGAIN error only caller can retry on handle based calls 5211 since file handle passed in no longer valid */ 5212 5213 return rc; 5214 } 5215 5216 int 5217 CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon, 5218 bool delete_file, __u16 fid, __u32 pid_of_opener) 5219 { 5220 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5221 char *data_offset; 5222 int rc = 0; 5223 __u16 params, param_offset, offset, byte_count, count; 5224 5225 cifs_dbg(FYI, "Set File Disposition (via SetFileInfo)\n"); 5226 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5227 5228 if (rc) 5229 return rc; 5230 5231 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 5232 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 5233 5234 params = 6; 5235 pSMB->MaxSetupCount = 0; 5236 pSMB->Reserved = 0; 5237 pSMB->Flags = 0; 5238 pSMB->Timeout = 0; 5239 pSMB->Reserved2 = 0; 5240 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5241 offset = param_offset + params; 5242 5243 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 5244 data_offset = (char *)(pSMB) + offset + 4; 5245 5246 count = 1; 5247 pSMB->MaxParameterCount = cpu_to_le16(2); 5248 /* BB find max SMB PDU from sess */ 5249 pSMB->MaxDataCount = cpu_to_le16(1000); 5250 pSMB->SetupCount = 1; 5251 pSMB->Reserved3 = 0; 5252 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5253 byte_count = 3 /* pad */ + params + count; 5254 pSMB->DataCount = cpu_to_le16(count); 5255 pSMB->ParameterCount = cpu_to_le16(params); 5256 pSMB->TotalDataCount = pSMB->DataCount; 5257 pSMB->TotalParameterCount = pSMB->ParameterCount; 5258 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5259 pSMB->DataOffset = cpu_to_le16(offset); 5260 pSMB->Fid = fid; 5261 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO); 5262 pSMB->Reserved4 = 0; 5263 inc_rfc1001_len(pSMB, byte_count); 5264 pSMB->ByteCount = cpu_to_le16(byte_count); 5265 *data_offset = delete_file ? 1 : 0; 5266 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5267 cifs_small_buf_release(pSMB); 5268 if (rc) 5269 cifs_dbg(FYI, "Send error in SetFileDisposition = %d\n", rc); 5270 5271 return rc; 5272 } 5273 5274 static int 5275 CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon, 5276 const char *fileName, const FILE_BASIC_INFO *data, 5277 const struct nls_table *nls_codepage, 5278 struct cifs_sb_info *cifs_sb) 5279 { 5280 int oplock = 0; 5281 struct cifs_open_parms oparms; 5282 struct cifs_fid fid; 5283 int rc; 5284 5285 oparms = (struct cifs_open_parms) { 5286 .tcon = tcon, 5287 .cifs_sb = cifs_sb, 5288 .desired_access = GENERIC_WRITE, 5289 .create_options = cifs_create_options(cifs_sb, 0), 5290 .disposition = FILE_OPEN, 5291 .path = fileName, 5292 .fid = &fid, 5293 }; 5294 5295 rc = CIFS_open(xid, &oparms, &oplock, NULL); 5296 if (rc) 5297 goto out; 5298 5299 rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid); 5300 CIFSSMBClose(xid, tcon, fid.netfid); 5301 out: 5302 5303 return rc; 5304 } 5305 5306 int 5307 CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 5308 const char *fileName, const FILE_BASIC_INFO *data, 5309 const struct nls_table *nls_codepage, 5310 struct cifs_sb_info *cifs_sb) 5311 { 5312 TRANSACTION2_SPI_REQ *pSMB = NULL; 5313 TRANSACTION2_SPI_RSP *pSMBr = NULL; 5314 int name_len; 5315 int rc = 0; 5316 int bytes_returned = 0; 5317 char *data_offset; 5318 __u16 params, param_offset, offset, byte_count, count; 5319 int remap = cifs_remap(cifs_sb); 5320 5321 cifs_dbg(FYI, "In SetTimes\n"); 5322 5323 SetTimesRetry: 5324 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5325 (void **) &pSMBr); 5326 if (rc) 5327 return rc; 5328 5329 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5330 name_len = 5331 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 5332 PATH_MAX, nls_codepage, remap); 5333 name_len++; /* trailing null */ 5334 name_len *= 2; 5335 } else { 5336 name_len = copy_path_name(pSMB->FileName, fileName); 5337 } 5338 5339 params = 6 + name_len; 5340 count = sizeof(FILE_BASIC_INFO); 5341 pSMB->MaxParameterCount = cpu_to_le16(2); 5342 /* BB find max SMB PDU from sess structure BB */ 5343 pSMB->MaxDataCount = cpu_to_le16(1000); 5344 pSMB->MaxSetupCount = 0; 5345 pSMB->Reserved = 0; 5346 pSMB->Flags = 0; 5347 pSMB->Timeout = 0; 5348 pSMB->Reserved2 = 0; 5349 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5350 InformationLevel) - 4; 5351 offset = param_offset + params; 5352 data_offset = (char *)pSMB + offsetof(typeof(*pSMB), hdr.Protocol) + offset; 5353 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5354 pSMB->DataOffset = cpu_to_le16(offset); 5355 pSMB->SetupCount = 1; 5356 pSMB->Reserved3 = 0; 5357 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5358 byte_count = 3 /* pad */ + params + count; 5359 5360 pSMB->DataCount = cpu_to_le16(count); 5361 pSMB->ParameterCount = cpu_to_le16(params); 5362 pSMB->TotalDataCount = pSMB->DataCount; 5363 pSMB->TotalParameterCount = pSMB->ParameterCount; 5364 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) 5365 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2); 5366 else 5367 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); 5368 pSMB->Reserved4 = 0; 5369 inc_rfc1001_len(pSMB, byte_count); 5370 memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); 5371 pSMB->ByteCount = cpu_to_le16(byte_count); 5372 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5373 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5374 if (rc) 5375 cifs_dbg(FYI, "SetPathInfo (times) returned %d\n", rc); 5376 5377 cifs_buf_release(pSMB); 5378 5379 if (rc == -EAGAIN) 5380 goto SetTimesRetry; 5381 5382 if (rc == -EOPNOTSUPP) 5383 return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data, 5384 nls_codepage, cifs_sb); 5385 5386 return rc; 5387 } 5388 5389 static void 5390 cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset, 5391 const struct cifs_unix_set_info_args *args) 5392 { 5393 u64 uid = NO_CHANGE_64, gid = NO_CHANGE_64; 5394 u64 mode = args->mode; 5395 5396 if (uid_valid(args->uid)) 5397 uid = from_kuid(&init_user_ns, args->uid); 5398 if (gid_valid(args->gid)) 5399 gid = from_kgid(&init_user_ns, args->gid); 5400 5401 /* 5402 * Samba server ignores set of file size to zero due to bugs in some 5403 * older clients, but we should be precise - we use SetFileSize to 5404 * set file size and do not want to truncate file size to zero 5405 * accidentally as happened on one Samba server beta by putting 5406 * zero instead of -1 here 5407 */ 5408 data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64); 5409 data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64); 5410 data_offset->LastStatusChange = cpu_to_le64(args->ctime); 5411 data_offset->LastAccessTime = cpu_to_le64(args->atime); 5412 data_offset->LastModificationTime = cpu_to_le64(args->mtime); 5413 data_offset->Uid = cpu_to_le64(uid); 5414 data_offset->Gid = cpu_to_le64(gid); 5415 /* better to leave device as zero when it is */ 5416 data_offset->DevMajor = cpu_to_le64(MAJOR(args->device)); 5417 data_offset->DevMinor = cpu_to_le64(MINOR(args->device)); 5418 data_offset->Permissions = cpu_to_le64(mode); 5419 5420 if (S_ISREG(mode)) 5421 data_offset->Type = cpu_to_le32(UNIX_FILE); 5422 else if (S_ISDIR(mode)) 5423 data_offset->Type = cpu_to_le32(UNIX_DIR); 5424 else if (S_ISLNK(mode)) 5425 data_offset->Type = cpu_to_le32(UNIX_SYMLINK); 5426 else if (S_ISCHR(mode)) 5427 data_offset->Type = cpu_to_le32(UNIX_CHARDEV); 5428 else if (S_ISBLK(mode)) 5429 data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV); 5430 else if (S_ISFIFO(mode)) 5431 data_offset->Type = cpu_to_le32(UNIX_FIFO); 5432 else if (S_ISSOCK(mode)) 5433 data_offset->Type = cpu_to_le32(UNIX_SOCKET); 5434 } 5435 5436 int 5437 CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon, 5438 const struct cifs_unix_set_info_args *args, 5439 u16 fid, u32 pid_of_opener) 5440 { 5441 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5442 char *data_offset; 5443 int rc = 0; 5444 u16 params, param_offset, offset, byte_count, count; 5445 5446 cifs_dbg(FYI, "Set Unix Info (via SetFileInfo)\n"); 5447 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5448 5449 if (rc) 5450 return rc; 5451 5452 pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 5453 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 5454 5455 params = 6; 5456 pSMB->MaxSetupCount = 0; 5457 pSMB->Reserved = 0; 5458 pSMB->Flags = 0; 5459 pSMB->Timeout = 0; 5460 pSMB->Reserved2 = 0; 5461 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5462 offset = param_offset + params; 5463 5464 data_offset = (char *)pSMB + 5465 offsetof(struct smb_hdr, Protocol) + offset; 5466 5467 count = sizeof(FILE_UNIX_BASIC_INFO); 5468 5469 pSMB->MaxParameterCount = cpu_to_le16(2); 5470 /* BB find max SMB PDU from sess */ 5471 pSMB->MaxDataCount = cpu_to_le16(1000); 5472 pSMB->SetupCount = 1; 5473 pSMB->Reserved3 = 0; 5474 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5475 byte_count = 3 /* pad */ + params + count; 5476 pSMB->DataCount = cpu_to_le16(count); 5477 pSMB->ParameterCount = cpu_to_le16(params); 5478 pSMB->TotalDataCount = pSMB->DataCount; 5479 pSMB->TotalParameterCount = pSMB->ParameterCount; 5480 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5481 pSMB->DataOffset = cpu_to_le16(offset); 5482 pSMB->Fid = fid; 5483 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); 5484 pSMB->Reserved4 = 0; 5485 inc_rfc1001_len(pSMB, byte_count); 5486 pSMB->ByteCount = cpu_to_le16(byte_count); 5487 5488 cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args); 5489 5490 rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); 5491 cifs_small_buf_release(pSMB); 5492 if (rc) 5493 cifs_dbg(FYI, "Send error in Set Time (SetFileInfo) = %d\n", 5494 rc); 5495 5496 /* Note: On -EAGAIN error only caller can retry on handle based calls 5497 since file handle passed in no longer valid */ 5498 5499 return rc; 5500 } 5501 5502 int 5503 CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, 5504 const char *file_name, 5505 const struct cifs_unix_set_info_args *args, 5506 const struct nls_table *nls_codepage, int remap) 5507 { 5508 TRANSACTION2_SPI_REQ *pSMB = NULL; 5509 TRANSACTION2_SPI_RSP *pSMBr = NULL; 5510 int name_len; 5511 int rc = 0; 5512 int bytes_returned = 0; 5513 FILE_UNIX_BASIC_INFO *data_offset; 5514 __u16 params, param_offset, offset, count, byte_count; 5515 5516 cifs_dbg(FYI, "In SetUID/GID/Mode\n"); 5517 setPermsRetry: 5518 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5519 (void **) &pSMBr); 5520 if (rc) 5521 return rc; 5522 5523 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5524 name_len = 5525 cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name, 5526 PATH_MAX, nls_codepage, remap); 5527 name_len++; /* trailing null */ 5528 name_len *= 2; 5529 } else { 5530 name_len = copy_path_name(pSMB->FileName, file_name); 5531 } 5532 5533 params = 6 + name_len; 5534 count = sizeof(FILE_UNIX_BASIC_INFO); 5535 pSMB->MaxParameterCount = cpu_to_le16(2); 5536 /* BB find max SMB PDU from sess structure BB */ 5537 pSMB->MaxDataCount = cpu_to_le16(1000); 5538 pSMB->MaxSetupCount = 0; 5539 pSMB->Reserved = 0; 5540 pSMB->Flags = 0; 5541 pSMB->Timeout = 0; 5542 pSMB->Reserved2 = 0; 5543 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5544 InformationLevel) - 4; 5545 offset = param_offset + params; 5546 /* SMB offsets are from the beginning of SMB which is 4 bytes in, after RFC1001 field */ 5547 data_offset = (FILE_UNIX_BASIC_INFO *)((char *) pSMB + offset + 4); 5548 memset(data_offset, 0, count); 5549 pSMB->DataOffset = cpu_to_le16(offset); 5550 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5551 pSMB->SetupCount = 1; 5552 pSMB->Reserved3 = 0; 5553 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5554 byte_count = 3 /* pad */ + params + count; 5555 pSMB->ParameterCount = cpu_to_le16(params); 5556 pSMB->DataCount = cpu_to_le16(count); 5557 pSMB->TotalParameterCount = pSMB->ParameterCount; 5558 pSMB->TotalDataCount = pSMB->DataCount; 5559 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); 5560 pSMB->Reserved4 = 0; 5561 inc_rfc1001_len(pSMB, byte_count); 5562 5563 cifs_fill_unix_set_info(data_offset, args); 5564 5565 pSMB->ByteCount = cpu_to_le16(byte_count); 5566 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5567 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5568 if (rc) 5569 cifs_dbg(FYI, "SetPathInfo (perms) returned %d\n", rc); 5570 5571 cifs_buf_release(pSMB); 5572 if (rc == -EAGAIN) 5573 goto setPermsRetry; 5574 return rc; 5575 } 5576 5577 #ifdef CONFIG_CIFS_XATTR 5578 /* 5579 * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common 5580 * function used by listxattr and getxattr type calls. When ea_name is set, 5581 * it looks for that attribute name and stuffs that value into the EAData 5582 * buffer. When ea_name is NULL, it stuffs a list of attribute names into the 5583 * buffer. In both cases, the return value is either the length of the 5584 * resulting data or a negative error code. If EAData is a NULL pointer then 5585 * the data isn't copied to it, but the length is returned. 5586 */ 5587 ssize_t 5588 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon, 5589 const unsigned char *searchName, const unsigned char *ea_name, 5590 char *EAData, size_t buf_size, 5591 struct cifs_sb_info *cifs_sb) 5592 { 5593 /* BB assumes one setup word */ 5594 TRANSACTION2_QPI_REQ *pSMB = NULL; 5595 TRANSACTION2_QPI_RSP *pSMBr = NULL; 5596 int remap = cifs_remap(cifs_sb); 5597 struct nls_table *nls_codepage = cifs_sb->local_nls; 5598 int rc = 0; 5599 int bytes_returned; 5600 int list_len; 5601 struct fealist *ea_response_data; 5602 struct fea *temp_fea; 5603 char *temp_ptr; 5604 char *end_of_smb; 5605 __u16 params, byte_count, data_offset; 5606 unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0; 5607 5608 cifs_dbg(FYI, "In Query All EAs path %s\n", searchName); 5609 QAllEAsRetry: 5610 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5611 (void **) &pSMBr); 5612 if (rc) 5613 return rc; 5614 5615 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5616 list_len = 5617 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, 5618 PATH_MAX, nls_codepage, remap); 5619 list_len++; /* trailing null */ 5620 list_len *= 2; 5621 } else { 5622 list_len = copy_path_name(pSMB->FileName, searchName); 5623 } 5624 5625 params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */; 5626 pSMB->TotalDataCount = 0; 5627 pSMB->MaxParameterCount = cpu_to_le16(2); 5628 /* BB find exact max SMB PDU from sess structure BB */ 5629 pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize); 5630 pSMB->MaxSetupCount = 0; 5631 pSMB->Reserved = 0; 5632 pSMB->Flags = 0; 5633 pSMB->Timeout = 0; 5634 pSMB->Reserved2 = 0; 5635 pSMB->ParameterOffset = cpu_to_le16(offsetof( 5636 struct smb_com_transaction2_qpi_req, InformationLevel) - 4); 5637 pSMB->DataCount = 0; 5638 pSMB->DataOffset = 0; 5639 pSMB->SetupCount = 1; 5640 pSMB->Reserved3 = 0; 5641 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); 5642 byte_count = params + 1 /* pad */ ; 5643 pSMB->TotalParameterCount = cpu_to_le16(params); 5644 pSMB->ParameterCount = pSMB->TotalParameterCount; 5645 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS); 5646 pSMB->Reserved4 = 0; 5647 inc_rfc1001_len(pSMB, byte_count); 5648 pSMB->ByteCount = cpu_to_le16(byte_count); 5649 5650 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5651 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5652 if (rc) { 5653 cifs_dbg(FYI, "Send error in QueryAllEAs = %d\n", rc); 5654 goto QAllEAsOut; 5655 } 5656 5657 5658 /* BB also check enough total bytes returned */ 5659 /* BB we need to improve the validity checking 5660 of these trans2 responses */ 5661 5662 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 5663 if (rc || get_bcc(&pSMBr->hdr) < 4) { 5664 rc = -EIO; /* bad smb */ 5665 goto QAllEAsOut; 5666 } 5667 5668 /* check that length of list is not more than bcc */ 5669 /* check that each entry does not go beyond length 5670 of list */ 5671 /* check that each element of each entry does not 5672 go beyond end of list */ 5673 /* validate_trans2_offsets() */ 5674 /* BB check if start of smb + data_offset > &bcc+ bcc */ 5675 5676 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 5677 ea_response_data = (struct fealist *) 5678 (((char *) &pSMBr->hdr.Protocol) + data_offset); 5679 5680 list_len = le32_to_cpu(ea_response_data->list_len); 5681 cifs_dbg(FYI, "ea length %d\n", list_len); 5682 if (list_len <= 8) { 5683 cifs_dbg(FYI, "empty EA list returned from server\n"); 5684 /* didn't find the named attribute */ 5685 if (ea_name) 5686 rc = -ENODATA; 5687 goto QAllEAsOut; 5688 } 5689 5690 /* make sure list_len doesn't go past end of SMB */ 5691 end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr); 5692 if ((char *)ea_response_data + list_len > end_of_smb) { 5693 cifs_dbg(FYI, "EA list appears to go beyond SMB\n"); 5694 rc = -EIO; 5695 goto QAllEAsOut; 5696 } 5697 5698 /* account for ea list len */ 5699 list_len -= 4; 5700 temp_fea = &ea_response_data->list; 5701 temp_ptr = (char *)temp_fea; 5702 while (list_len > 0) { 5703 unsigned int name_len; 5704 __u16 value_len; 5705 5706 list_len -= 4; 5707 temp_ptr += 4; 5708 /* make sure we can read name_len and value_len */ 5709 if (list_len < 0) { 5710 cifs_dbg(FYI, "EA entry goes beyond length of list\n"); 5711 rc = -EIO; 5712 goto QAllEAsOut; 5713 } 5714 5715 name_len = temp_fea->name_len; 5716 value_len = le16_to_cpu(temp_fea->value_len); 5717 list_len -= name_len + 1 + value_len; 5718 if (list_len < 0) { 5719 cifs_dbg(FYI, "EA entry goes beyond length of list\n"); 5720 rc = -EIO; 5721 goto QAllEAsOut; 5722 } 5723 5724 if (ea_name) { 5725 if (ea_name_len == name_len && 5726 memcmp(ea_name, temp_ptr, name_len) == 0) { 5727 temp_ptr += name_len + 1; 5728 rc = value_len; 5729 if (buf_size == 0) 5730 goto QAllEAsOut; 5731 if ((size_t)value_len > buf_size) { 5732 rc = -ERANGE; 5733 goto QAllEAsOut; 5734 } 5735 memcpy(EAData, temp_ptr, value_len); 5736 goto QAllEAsOut; 5737 } 5738 } else { 5739 /* account for prefix user. and trailing null */ 5740 rc += (5 + 1 + name_len); 5741 if (rc < (int) buf_size) { 5742 memcpy(EAData, "user.", 5); 5743 EAData += 5; 5744 memcpy(EAData, temp_ptr, name_len); 5745 EAData += name_len; 5746 /* null terminate name */ 5747 *EAData = 0; 5748 ++EAData; 5749 } else if (buf_size == 0) { 5750 /* skip copy - calc size only */ 5751 } else { 5752 /* stop before overrun buffer */ 5753 rc = -ERANGE; 5754 break; 5755 } 5756 } 5757 temp_ptr += name_len + 1 + value_len; 5758 temp_fea = (struct fea *)temp_ptr; 5759 } 5760 5761 /* didn't find the named attribute */ 5762 if (ea_name) 5763 rc = -ENODATA; 5764 5765 QAllEAsOut: 5766 cifs_buf_release(pSMB); 5767 if (rc == -EAGAIN) 5768 goto QAllEAsRetry; 5769 5770 return (ssize_t)rc; 5771 } 5772 5773 int 5774 CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon, 5775 const char *fileName, const char *ea_name, const void *ea_value, 5776 const __u16 ea_value_len, const struct nls_table *nls_codepage, 5777 struct cifs_sb_info *cifs_sb) 5778 { 5779 struct smb_com_transaction2_spi_req *pSMB = NULL; 5780 struct smb_com_transaction2_spi_rsp *pSMBr = NULL; 5781 struct fealist *parm_data; 5782 int name_len; 5783 int rc = 0; 5784 int bytes_returned = 0; 5785 __u16 params, param_offset, byte_count, offset, count; 5786 int remap = cifs_remap(cifs_sb); 5787 5788 cifs_dbg(FYI, "In SetEA\n"); 5789 SetEARetry: 5790 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 5791 (void **) &pSMBr); 5792 if (rc) 5793 return rc; 5794 5795 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 5796 name_len = 5797 cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, 5798 PATH_MAX, nls_codepage, remap); 5799 name_len++; /* trailing null */ 5800 name_len *= 2; 5801 } else { 5802 name_len = copy_path_name(pSMB->FileName, fileName); 5803 } 5804 5805 params = 6 + name_len; 5806 5807 /* done calculating parms using name_len of file name, 5808 now use name_len to calculate length of ea name 5809 we are going to create in the inode xattrs */ 5810 if (ea_name == NULL) 5811 name_len = 0; 5812 else 5813 name_len = strnlen(ea_name, 255); 5814 5815 count = sizeof(*parm_data) + 1 + ea_value_len + name_len; 5816 pSMB->MaxParameterCount = cpu_to_le16(2); 5817 /* BB find max SMB PDU from sess */ 5818 pSMB->MaxDataCount = cpu_to_le16(1000); 5819 pSMB->MaxSetupCount = 0; 5820 pSMB->Reserved = 0; 5821 pSMB->Flags = 0; 5822 pSMB->Timeout = 0; 5823 pSMB->Reserved2 = 0; 5824 param_offset = offsetof(struct smb_com_transaction2_spi_req, 5825 InformationLevel) - 4; 5826 offset = param_offset + params; 5827 pSMB->InformationLevel = 5828 cpu_to_le16(SMB_SET_FILE_EA); 5829 5830 parm_data = (void *)pSMB + offsetof(struct smb_hdr, Protocol) + offset; 5831 pSMB->ParameterOffset = cpu_to_le16(param_offset); 5832 pSMB->DataOffset = cpu_to_le16(offset); 5833 pSMB->SetupCount = 1; 5834 pSMB->Reserved3 = 0; 5835 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); 5836 byte_count = 3 /* pad */ + params + count; 5837 pSMB->DataCount = cpu_to_le16(count); 5838 parm_data->list_len = cpu_to_le32(count); 5839 parm_data->list.EA_flags = 0; 5840 /* we checked above that name len is less than 255 */ 5841 parm_data->list.name_len = (__u8)name_len; 5842 /* EA names are always ASCII and NUL-terminated */ 5843 strscpy(parm_data->list.name, ea_name ?: "", name_len + 1); 5844 parm_data->list.value_len = cpu_to_le16(ea_value_len); 5845 /* caller ensures that ea_value_len is less than 64K but 5846 we need to ensure that it fits within the smb */ 5847 5848 /*BB add length check to see if it would fit in 5849 negotiated SMB buffer size BB */ 5850 /* if (ea_value_len > buffer_size - 512 (enough for header)) */ 5851 if (ea_value_len) 5852 memcpy(parm_data->list.name + name_len + 1, 5853 ea_value, ea_value_len); 5854 5855 pSMB->TotalDataCount = pSMB->DataCount; 5856 pSMB->ParameterCount = cpu_to_le16(params); 5857 pSMB->TotalParameterCount = pSMB->ParameterCount; 5858 pSMB->Reserved4 = 0; 5859 inc_rfc1001_len(pSMB, byte_count); 5860 pSMB->ByteCount = cpu_to_le16(byte_count); 5861 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 5862 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 5863 if (rc) 5864 cifs_dbg(FYI, "SetPathInfo (EA) returned %d\n", rc); 5865 5866 cifs_buf_release(pSMB); 5867 5868 if (rc == -EAGAIN) 5869 goto SetEARetry; 5870 5871 return rc; 5872 } 5873 #endif 5874