diff options
| -rw-r--r-- | fs/cifs/CHANGES | 2 | ||||
| -rw-r--r-- | fs/cifs/asn1.c | 55 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.c | 157 | ||||
| -rw-r--r-- | fs/cifs/cifsglob.h | 2 | ||||
| -rw-r--r-- | fs/cifs/cifsproto.h | 2 | ||||
| -rw-r--r-- | fs/cifs/cifssmb.c | 4 | ||||
| -rw-r--r-- | fs/cifs/connect.c | 39 | ||||
| -rw-r--r-- | fs/cifs/dir.c | 6 | ||||
| -rw-r--r-- | fs/cifs/dns_resolve.c | 25 | ||||
| -rw-r--r-- | fs/cifs/file.c | 24 | ||||
| -rw-r--r-- | fs/cifs/inode.c | 15 | ||||
| -rw-r--r-- | fs/cifs/link.c | 3 | ||||
| -rw-r--r-- | fs/cifs/netmisc.c | 56 | ||||
| -rw-r--r-- | fs/cifs/sess.c | 2 | ||||
| -rw-r--r-- | fs/cifs/xattr.c | 12 |
15 files changed, 246 insertions, 158 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index b48689839428..3a9b7a58a51d 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
| @@ -5,7 +5,7 @@ client generated ones by default (mount option "serverino" turned | |||
| 5 | on by default if server supports it). Add forceuid and forcegid | 5 | on by default if server supports it). Add forceuid and forcegid |
| 6 | mount options (so that when negotiating unix extensions specifying | 6 | mount options (so that when negotiating unix extensions specifying |
| 7 | which uid mounted does not immediately force the server's reported | 7 | which uid mounted does not immediately force the server's reported |
| 8 | uids to be overridden). | 8 | uids to be overridden). Add support for scope moutn parm. |
| 9 | 9 | ||
| 10 | Version 1.58 | 10 | Version 1.58 |
| 11 | ------------ | 11 | ------------ |
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c index 1b09f1670061..20692fbfdb24 100644 --- a/fs/cifs/asn1.c +++ b/fs/cifs/asn1.c | |||
| @@ -49,6 +49,7 @@ | |||
| 49 | #define ASN1_OJI 6 /* Object Identifier */ | 49 | #define ASN1_OJI 6 /* Object Identifier */ |
| 50 | #define ASN1_OJD 7 /* Object Description */ | 50 | #define ASN1_OJD 7 /* Object Description */ |
| 51 | #define ASN1_EXT 8 /* External */ | 51 | #define ASN1_EXT 8 /* External */ |
| 52 | #define ASN1_ENUM 10 /* Enumerated */ | ||
| 52 | #define ASN1_SEQ 16 /* Sequence */ | 53 | #define ASN1_SEQ 16 /* Sequence */ |
| 53 | #define ASN1_SET 17 /* Set */ | 54 | #define ASN1_SET 17 /* Set */ |
| 54 | #define ASN1_NUMSTR 18 /* Numerical String */ | 55 | #define ASN1_NUMSTR 18 /* Numerical String */ |
| @@ -78,10 +79,12 @@ | |||
| 78 | #define SPNEGO_OID_LEN 7 | 79 | #define SPNEGO_OID_LEN 7 |
| 79 | #define NTLMSSP_OID_LEN 10 | 80 | #define NTLMSSP_OID_LEN 10 |
| 80 | #define KRB5_OID_LEN 7 | 81 | #define KRB5_OID_LEN 7 |
| 82 | #define KRB5U2U_OID_LEN 8 | ||
| 81 | #define MSKRB5_OID_LEN 7 | 83 | #define MSKRB5_OID_LEN 7 |
| 82 | static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 }; | 84 | static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 }; |
| 83 | static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 }; | 85 | static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 }; |
| 84 | static unsigned long KRB5_OID[7] = { 1, 2, 840, 113554, 1, 2, 2 }; | 86 | static unsigned long KRB5_OID[7] = { 1, 2, 840, 113554, 1, 2, 2 }; |
| 87 | static unsigned long KRB5U2U_OID[8] = { 1, 2, 840, 113554, 1, 2, 2, 3 }; | ||
| 85 | static unsigned long MSKRB5_OID[7] = { 1, 2, 840, 48018, 1, 2, 2 }; | 88 | static unsigned long MSKRB5_OID[7] = { 1, 2, 840, 48018, 1, 2, 2 }; |
| 86 | 89 | ||
| 87 | /* | 90 | /* |
| @@ -122,6 +125,28 @@ asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch) | |||
| 122 | return 1; | 125 | return 1; |
| 123 | } | 126 | } |
| 124 | 127 | ||
| 128 | #if 0 /* will be needed later by spnego decoding/encoding of ntlmssp */ | ||
| 129 | static unsigned char | ||
| 130 | asn1_enum_decode(struct asn1_ctx *ctx, __le32 *val) | ||
| 131 | { | ||
| 132 | unsigned char ch; | ||
| 133 | |||
| 134 | if (ctx->pointer >= ctx->end) { | ||
| 135 | ctx->error = ASN1_ERR_DEC_EMPTY; | ||
| 136 | return 0; | ||
| 137 | } | ||
| 138 | |||
| 139 | ch = *(ctx->pointer)++; /* ch has 0xa, ptr points to lenght octet */ | ||
| 140 | if ((ch) == ASN1_ENUM) /* if ch value is ENUM, 0xa */ | ||
| 141 | *val = *(++(ctx->pointer)); /* value has enum value */ | ||
| 142 | else | ||
| 143 | return 0; | ||
| 144 | |||
| 145 | ctx->pointer++; | ||
| 146 | return 1; | ||
| 147 | } | ||
| 148 | #endif | ||
| 149 | |||
| 125 | static unsigned char | 150 | static unsigned char |
| 126 | asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag) | 151 | asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag) |
| 127 | { | 152 | { |
| @@ -476,10 +501,9 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
| 476 | unsigned int cls, con, tag, oidlen, rc; | 501 | unsigned int cls, con, tag, oidlen, rc; |
| 477 | bool use_ntlmssp = false; | 502 | bool use_ntlmssp = false; |
| 478 | bool use_kerberos = false; | 503 | bool use_kerberos = false; |
| 504 | bool use_kerberosu2u = false; | ||
| 479 | bool use_mskerberos = false; | 505 | bool use_mskerberos = false; |
| 480 | 506 | ||
| 481 | *secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/ | ||
| 482 | |||
| 483 | /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */ | 507 | /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */ |
| 484 | 508 | ||
| 485 | asn1_open(&ctx, security_blob, length); | 509 | asn1_open(&ctx, security_blob, length); |
| @@ -515,6 +539,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
| 515 | return 0; | 539 | return 0; |
| 516 | } | 540 | } |
| 517 | 541 | ||
| 542 | /* SPNEGO */ | ||
| 518 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 543 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
| 519 | cFYI(1, ("Error decoding negTokenInit")); | 544 | cFYI(1, ("Error decoding negTokenInit")); |
| 520 | return 0; | 545 | return 0; |
| @@ -526,6 +551,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
| 526 | return 0; | 551 | return 0; |
| 527 | } | 552 | } |
| 528 | 553 | ||
| 554 | /* negTokenInit */ | ||
| 529 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 555 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
| 530 | cFYI(1, ("Error decoding negTokenInit")); | 556 | cFYI(1, ("Error decoding negTokenInit")); |
| 531 | return 0; | 557 | return 0; |
| @@ -537,6 +563,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
| 537 | return 0; | 563 | return 0; |
| 538 | } | 564 | } |
| 539 | 565 | ||
| 566 | /* sequence */ | ||
| 540 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 567 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
| 541 | cFYI(1, ("Error decoding 2nd part of negTokenInit")); | 568 | cFYI(1, ("Error decoding 2nd part of negTokenInit")); |
| 542 | return 0; | 569 | return 0; |
| @@ -548,6 +575,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
| 548 | return 0; | 575 | return 0; |
| 549 | } | 576 | } |
| 550 | 577 | ||
| 578 | /* sequence of */ | ||
| 551 | if (asn1_header_decode | 579 | if (asn1_header_decode |
| 552 | (&ctx, &sequence_end, &cls, &con, &tag) == 0) { | 580 | (&ctx, &sequence_end, &cls, &con, &tag) == 0) { |
| 553 | cFYI(1, ("Error decoding 2nd part of negTokenInit")); | 581 | cFYI(1, ("Error decoding 2nd part of negTokenInit")); |
| @@ -560,6 +588,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
| 560 | return 0; | 588 | return 0; |
| 561 | } | 589 | } |
| 562 | 590 | ||
| 591 | /* list of security mechanisms */ | ||
| 563 | while (!asn1_eoc_decode(&ctx, sequence_end)) { | 592 | while (!asn1_eoc_decode(&ctx, sequence_end)) { |
| 564 | rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); | 593 | rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); |
| 565 | if (!rc) { | 594 | if (!rc) { |
| @@ -576,11 +605,15 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
| 576 | 605 | ||
| 577 | if (compare_oid(oid, oidlen, MSKRB5_OID, | 606 | if (compare_oid(oid, oidlen, MSKRB5_OID, |
| 578 | MSKRB5_OID_LEN) && | 607 | MSKRB5_OID_LEN) && |
| 579 | !use_kerberos) | 608 | !use_mskerberos) |
| 580 | use_mskerberos = true; | 609 | use_mskerberos = true; |
| 610 | else if (compare_oid(oid, oidlen, KRB5U2U_OID, | ||
| 611 | KRB5U2U_OID_LEN) && | ||
| 612 | !use_kerberosu2u) | ||
| 613 | use_kerberosu2u = true; | ||
| 581 | else if (compare_oid(oid, oidlen, KRB5_OID, | 614 | else if (compare_oid(oid, oidlen, KRB5_OID, |
| 582 | KRB5_OID_LEN) && | 615 | KRB5_OID_LEN) && |
| 583 | !use_mskerberos) | 616 | !use_kerberos) |
| 584 | use_kerberos = true; | 617 | use_kerberos = true; |
| 585 | else if (compare_oid(oid, oidlen, NTLMSSP_OID, | 618 | else if (compare_oid(oid, oidlen, NTLMSSP_OID, |
| 586 | NTLMSSP_OID_LEN)) | 619 | NTLMSSP_OID_LEN)) |
| @@ -593,7 +626,12 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
| 593 | } | 626 | } |
| 594 | } | 627 | } |
| 595 | 628 | ||
| 629 | /* mechlistMIC */ | ||
| 596 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 630 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
| 631 | /* Check if we have reached the end of the blob, but with | ||
| 632 | no mechListMic (e.g. NTLMSSP instead of KRB5) */ | ||
| 633 | if (ctx.error == ASN1_ERR_DEC_EMPTY) | ||
| 634 | goto decode_negtoken_exit; | ||
| 597 | cFYI(1, ("Error decoding last part negTokenInit exit3")); | 635 | cFYI(1, ("Error decoding last part negTokenInit exit3")); |
| 598 | return 0; | 636 | return 0; |
| 599 | } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { | 637 | } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { |
| @@ -602,6 +640,8 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
| 602 | cls, con, tag, end, *end)); | 640 | cls, con, tag, end, *end)); |
| 603 | return 0; | 641 | return 0; |
| 604 | } | 642 | } |
| 643 | |||
| 644 | /* sequence */ | ||
| 605 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 645 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
| 606 | cFYI(1, ("Error decoding last part negTokenInit exit5")); | 646 | cFYI(1, ("Error decoding last part negTokenInit exit5")); |
| 607 | return 0; | 647 | return 0; |
| @@ -611,6 +651,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
| 611 | cls, con, tag, end, *end)); | 651 | cls, con, tag, end, *end)); |
| 612 | } | 652 | } |
| 613 | 653 | ||
| 654 | /* sequence of */ | ||
| 614 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 655 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
| 615 | cFYI(1, ("Error decoding last part negTokenInit exit 7")); | 656 | cFYI(1, ("Error decoding last part negTokenInit exit 7")); |
| 616 | return 0; | 657 | return 0; |
| @@ -619,6 +660,8 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
| 619 | cls, con, tag, end, *end)); | 660 | cls, con, tag, end, *end)); |
| 620 | return 0; | 661 | return 0; |
| 621 | } | 662 | } |
| 663 | |||
| 664 | /* general string */ | ||
| 622 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 665 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
| 623 | cFYI(1, ("Error decoding last part negTokenInit exit9")); | 666 | cFYI(1, ("Error decoding last part negTokenInit exit9")); |
| 624 | return 0; | 667 | return 0; |
| @@ -630,13 +673,13 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
| 630 | } | 673 | } |
| 631 | cFYI(1, ("Need to call asn1_octets_decode() function for %s", | 674 | cFYI(1, ("Need to call asn1_octets_decode() function for %s", |
| 632 | ctx.pointer)); /* is this UTF-8 or ASCII? */ | 675 | ctx.pointer)); /* is this UTF-8 or ASCII? */ |
| 633 | 676 | decode_negtoken_exit: | |
| 634 | if (use_kerberos) | 677 | if (use_kerberos) |
| 635 | *secType = Kerberos; | 678 | *secType = Kerberos; |
| 636 | else if (use_mskerberos) | 679 | else if (use_mskerberos) |
| 637 | *secType = MSKerberos; | 680 | *secType = MSKerberos; |
| 638 | else if (use_ntlmssp) | 681 | else if (use_ntlmssp) |
| 639 | *secType = NTLMSSP; | 682 | *secType = RawNTLMSSP; |
| 640 | 683 | ||
| 641 | return 1; | 684 | return 1; |
| 642 | } | 685 | } |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 0d92114195ab..9f669f982c4d 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -333,6 +333,27 @@ cifs_destroy_inode(struct inode *inode) | |||
| 333 | kmem_cache_free(cifs_inode_cachep, CIFS_I(inode)); | 333 | kmem_cache_free(cifs_inode_cachep, CIFS_I(inode)); |
| 334 | } | 334 | } |
| 335 | 335 | ||
| 336 | static void | ||
| 337 | cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server) | ||
| 338 | { | ||
| 339 | seq_printf(s, ",addr="); | ||
| 340 | |||
| 341 | switch (server->addr.sockAddr.sin_family) { | ||
| 342 | case AF_INET: | ||
| 343 | seq_printf(s, "%pI4", &server->addr.sockAddr.sin_addr.s_addr); | ||
| 344 | break; | ||
| 345 | case AF_INET6: | ||
| 346 | seq_printf(s, "%pI6", | ||
| 347 | &server->addr.sockAddr6.sin6_addr.s6_addr); | ||
| 348 | if (server->addr.sockAddr6.sin6_scope_id) | ||
| 349 | seq_printf(s, "%%%u", | ||
| 350 | server->addr.sockAddr6.sin6_scope_id); | ||
| 351 | break; | ||
| 352 | default: | ||
| 353 | seq_printf(s, "(unknown)"); | ||
| 354 | } | ||
| 355 | } | ||
| 356 | |||
| 336 | /* | 357 | /* |
| 337 | * cifs_show_options() is for displaying mount options in /proc/mounts. | 358 | * cifs_show_options() is for displaying mount options in /proc/mounts. |
| 338 | * Not all settable options are displayed but most of the important | 359 | * Not all settable options are displayed but most of the important |
| @@ -343,83 +364,64 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) | |||
| 343 | { | 364 | { |
| 344 | struct cifs_sb_info *cifs_sb; | 365 | struct cifs_sb_info *cifs_sb; |
| 345 | struct cifsTconInfo *tcon; | 366 | struct cifsTconInfo *tcon; |
| 346 | struct TCP_Server_Info *server; | ||
| 347 | 367 | ||
| 348 | cifs_sb = CIFS_SB(m->mnt_sb); | 368 | cifs_sb = CIFS_SB(m->mnt_sb); |
| 369 | tcon = cifs_sb->tcon; | ||
| 349 | 370 | ||
| 350 | if (cifs_sb) { | 371 | seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName); |
| 351 | tcon = cifs_sb->tcon; | 372 | if (tcon->ses->userName) |
| 352 | if (tcon) { | 373 | seq_printf(s, ",username=%s", tcon->ses->userName); |
| 353 | seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName); | 374 | if (tcon->ses->domainName) |
| 354 | if (tcon->ses) { | 375 | seq_printf(s, ",domain=%s", tcon->ses->domainName); |
| 355 | if (tcon->ses->userName) | 376 | |
| 356 | seq_printf(s, ",username=%s", | 377 | seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); |
| 357 | tcon->ses->userName); | 378 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) |
| 358 | if (tcon->ses->domainName) | 379 | seq_printf(s, ",forceuid"); |
| 359 | seq_printf(s, ",domain=%s", | 380 | |
| 360 | tcon->ses->domainName); | 381 | seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); |
| 361 | server = tcon->ses->server; | 382 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) |
| 362 | if (server) { | 383 | seq_printf(s, ",forcegid"); |
| 363 | seq_printf(s, ",addr="); | 384 | |
| 364 | switch (server->addr.sockAddr6. | 385 | cifs_show_address(s, tcon->ses->server); |
| 365 | sin6_family) { | 386 | |
| 366 | case AF_INET6: | 387 | if (!tcon->unix_ext) |
| 367 | seq_printf(s, "%pI6", | 388 | seq_printf(s, ",file_mode=0%o,dir_mode=0%o", |
| 368 | &server->addr.sockAddr6.sin6_addr); | ||
| 369 | break; | ||
| 370 | case AF_INET: | ||
| 371 | seq_printf(s, "%pI4", | ||
| 372 | &server->addr.sockAddr.sin_addr.s_addr); | ||
| 373 | break; | ||
| 374 | } | ||
| 375 | } | ||
| 376 | } | ||
| 377 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) || | ||
| 378 | !(tcon->unix_ext)) | ||
| 379 | seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); | ||
| 380 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) || | ||
| 381 | !(tcon->unix_ext)) | ||
| 382 | seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); | ||
| 383 | if (!tcon->unix_ext) { | ||
| 384 | seq_printf(s, ",file_mode=0%o,dir_mode=0%o", | ||
| 385 | cifs_sb->mnt_file_mode, | 389 | cifs_sb->mnt_file_mode, |
| 386 | cifs_sb->mnt_dir_mode); | 390 | cifs_sb->mnt_dir_mode); |
| 387 | } | 391 | if (tcon->seal) |
| 388 | if (tcon->seal) | 392 | seq_printf(s, ",seal"); |
| 389 | seq_printf(s, ",seal"); | 393 | if (tcon->nocase) |
| 390 | if (tcon->nocase) | 394 | seq_printf(s, ",nocase"); |
| 391 | seq_printf(s, ",nocase"); | 395 | if (tcon->retry) |
| 392 | if (tcon->retry) | 396 | seq_printf(s, ",hard"); |
| 393 | seq_printf(s, ",hard"); | 397 | if (cifs_sb->prepath) |
| 394 | } | 398 | seq_printf(s, ",prepath=%s", cifs_sb->prepath); |
| 395 | if (cifs_sb->prepath) | 399 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) |
| 396 | seq_printf(s, ",prepath=%s", cifs_sb->prepath); | 400 | seq_printf(s, ",posixpaths"); |
| 397 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) | 401 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) |
| 398 | seq_printf(s, ",posixpaths"); | 402 | seq_printf(s, ",setuids"); |
| 399 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) | 403 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) |
| 400 | seq_printf(s, ",setuids"); | 404 | seq_printf(s, ",serverino"); |
| 401 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) | 405 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) |
| 402 | seq_printf(s, ",serverino"); | 406 | seq_printf(s, ",directio"); |
| 403 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) | 407 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) |
| 404 | seq_printf(s, ",directio"); | 408 | seq_printf(s, ",nouser_xattr"); |
| 405 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) | 409 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR) |
| 406 | seq_printf(s, ",nouser_xattr"); | 410 | seq_printf(s, ",mapchars"); |
| 407 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR) | 411 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) |
| 408 | seq_printf(s, ",mapchars"); | 412 | seq_printf(s, ",sfu"); |
| 409 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) | 413 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) |
| 410 | seq_printf(s, ",sfu"); | 414 | seq_printf(s, ",nobrl"); |
| 411 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | 415 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) |
| 412 | seq_printf(s, ",nobrl"); | 416 | seq_printf(s, ",cifsacl"); |
| 413 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) | 417 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) |
| 414 | seq_printf(s, ",cifsacl"); | 418 | seq_printf(s, ",dynperm"); |
| 415 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) | 419 | if (m->mnt_sb->s_flags & MS_POSIXACL) |
| 416 | seq_printf(s, ",dynperm"); | 420 | seq_printf(s, ",acl"); |
| 417 | if (m->mnt_sb->s_flags & MS_POSIXACL) | 421 | |
| 418 | seq_printf(s, ",acl"); | 422 | seq_printf(s, ",rsize=%d", cifs_sb->rsize); |
| 419 | 423 | seq_printf(s, ",wsize=%d", cifs_sb->wsize); | |
| 420 | seq_printf(s, ",rsize=%d", cifs_sb->rsize); | 424 | |
| 421 | seq_printf(s, ",wsize=%d", cifs_sb->wsize); | ||
| 422 | } | ||
| 423 | return 0; | 425 | return 0; |
| 424 | } | 426 | } |
| 425 | 427 | ||
| @@ -535,9 +537,14 @@ static void cifs_umount_begin(struct super_block *sb) | |||
| 535 | if (tcon == NULL) | 537 | if (tcon == NULL) |
| 536 | return; | 538 | return; |
| 537 | 539 | ||
| 538 | lock_kernel(); | ||
| 539 | read_lock(&cifs_tcp_ses_lock); | 540 | read_lock(&cifs_tcp_ses_lock); |
| 540 | if (tcon->tc_count == 1) | 541 | if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) { |
| 542 | /* we have other mounts to same share or we have | ||
| 543 | already tried to force umount this and woken up | ||
| 544 | all waiting network requests, nothing to do */ | ||
| 545 | read_unlock(&cifs_tcp_ses_lock); | ||
| 546 | return; | ||
| 547 | } else if (tcon->tc_count == 1) | ||
| 541 | tcon->tidStatus = CifsExiting; | 548 | tcon->tidStatus = CifsExiting; |
| 542 | read_unlock(&cifs_tcp_ses_lock); | 549 | read_unlock(&cifs_tcp_ses_lock); |
| 543 | 550 | ||
| @@ -552,9 +559,7 @@ static void cifs_umount_begin(struct super_block *sb) | |||
| 552 | wake_up_all(&tcon->ses->server->response_q); | 559 | wake_up_all(&tcon->ses->server->response_q); |
| 553 | msleep(1); | 560 | msleep(1); |
| 554 | } | 561 | } |
| 555 | /* BB FIXME - finish add checks for tidStatus BB */ | ||
| 556 | 562 | ||
| 557 | unlock_kernel(); | ||
| 558 | return; | 563 | return; |
| 559 | } | 564 | } |
| 560 | 565 | ||
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index a61ab772c6f6..e1225e6ded2f 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -83,7 +83,7 @@ enum securityEnum { | |||
| 83 | NTLM, /* Legacy NTLM012 auth with NTLM hash */ | 83 | NTLM, /* Legacy NTLM012 auth with NTLM hash */ |
| 84 | NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */ | 84 | NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */ |
| 85 | RawNTLMSSP, /* NTLMSSP without SPNEGO, NTLMv2 hash */ | 85 | RawNTLMSSP, /* NTLMSSP without SPNEGO, NTLMv2 hash */ |
| 86 | NTLMSSP, /* NTLMSSP via SPNEGO, NTLMv2 hash */ | 86 | /* NTLMSSP, */ /* can use rawNTLMSSP instead of NTLMSSP via SPNEGO */ |
| 87 | Kerberos, /* Kerberos via SPNEGO */ | 87 | Kerberos, /* Kerberos via SPNEGO */ |
| 88 | MSKerberos, /* MS Kerberos via SPNEGO */ | 88 | MSKerberos, /* MS Kerberos via SPNEGO */ |
| 89 | }; | 89 | }; |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index f9452329bcce..c419416a42ee 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
| @@ -74,7 +74,7 @@ extern unsigned int smbCalcSize(struct smb_hdr *ptr); | |||
| 74 | extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); | 74 | extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); |
| 75 | extern int decode_negTokenInit(unsigned char *security_blob, int length, | 75 | extern int decode_negTokenInit(unsigned char *security_blob, int length, |
| 76 | enum securityEnum *secType); | 76 | enum securityEnum *secType); |
| 77 | extern int cifs_inet_pton(const int, const char *source, void *dst); | 77 | extern int cifs_convert_address(char *src, void *dst); |
| 78 | extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr); | 78 | extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr); |
| 79 | extern void header_assemble(struct smb_hdr *, char /* command */ , | 79 | extern void header_assemble(struct smb_hdr *, char /* command */ , |
| 80 | const struct cifsTconInfo *, int /* length of | 80 | const struct cifsTconInfo *, int /* length of |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index b84c61d5bca4..61007c627497 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -594,7 +594,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
| 594 | else if (secFlags & CIFSSEC_MAY_KRB5) | 594 | else if (secFlags & CIFSSEC_MAY_KRB5) |
| 595 | server->secType = Kerberos; | 595 | server->secType = Kerberos; |
| 596 | else if (secFlags & CIFSSEC_MAY_NTLMSSP) | 596 | else if (secFlags & CIFSSEC_MAY_NTLMSSP) |
| 597 | server->secType = NTLMSSP; | 597 | server->secType = RawNTLMSSP; |
| 598 | else if (secFlags & CIFSSEC_MAY_LANMAN) | 598 | else if (secFlags & CIFSSEC_MAY_LANMAN) |
| 599 | server->secType = LANMAN; | 599 | server->secType = LANMAN; |
| 600 | /* #ifdef CONFIG_CIFS_EXPERIMENTAL | 600 | /* #ifdef CONFIG_CIFS_EXPERIMENTAL |
| @@ -729,7 +729,7 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon) | |||
| 729 | * the tcon is no longer on the list, so no need to take lock before | 729 | * the tcon is no longer on the list, so no need to take lock before |
| 730 | * checking this. | 730 | * checking this. |
| 731 | */ | 731 | */ |
| 732 | if (tcon->need_reconnect) | 732 | if ((tcon->need_reconnect) || (tcon->ses->need_reconnect)) |
| 733 | return 0; | 733 | return 0; |
| 734 | 734 | ||
| 735 | rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, | 735 | rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 97f4311b9a8e..e16d7592116a 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -70,7 +70,6 @@ struct smb_vol { | |||
| 70 | mode_t file_mode; | 70 | mode_t file_mode; |
| 71 | mode_t dir_mode; | 71 | mode_t dir_mode; |
| 72 | unsigned secFlg; | 72 | unsigned secFlg; |
| 73 | bool rw:1; | ||
| 74 | bool retry:1; | 73 | bool retry:1; |
| 75 | bool intr:1; | 74 | bool intr:1; |
| 76 | bool setuids:1; | 75 | bool setuids:1; |
| @@ -832,7 +831,6 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
| 832 | vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR; | 831 | vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR; |
| 833 | 832 | ||
| 834 | /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ | 833 | /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ |
| 835 | vol->rw = true; | ||
| 836 | /* default is always to request posix paths. */ | 834 | /* default is always to request posix paths. */ |
| 837 | vol->posix_paths = 1; | 835 | vol->posix_paths = 1; |
| 838 | /* default to using server inode numbers where available */ | 836 | /* default to using server inode numbers where available */ |
| @@ -1199,7 +1197,9 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
| 1199 | } else if (strnicmp(data, "guest", 5) == 0) { | 1197 | } else if (strnicmp(data, "guest", 5) == 0) { |
| 1200 | /* ignore */ | 1198 | /* ignore */ |
| 1201 | } else if (strnicmp(data, "rw", 2) == 0) { | 1199 | } else if (strnicmp(data, "rw", 2) == 0) { |
| 1202 | vol->rw = true; | 1200 | /* ignore */ |
| 1201 | } else if (strnicmp(data, "ro", 2) == 0) { | ||
| 1202 | /* ignore */ | ||
| 1203 | } else if (strnicmp(data, "noblocksend", 11) == 0) { | 1203 | } else if (strnicmp(data, "noblocksend", 11) == 0) { |
| 1204 | vol->noblocksnd = 1; | 1204 | vol->noblocksnd = 1; |
| 1205 | } else if (strnicmp(data, "noautotune", 10) == 0) { | 1205 | } else if (strnicmp(data, "noautotune", 10) == 0) { |
| @@ -1218,8 +1218,6 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
| 1218 | parse these options again and set anything and it | 1218 | parse these options again and set anything and it |
| 1219 | is ok to just ignore them */ | 1219 | is ok to just ignore them */ |
| 1220 | continue; | 1220 | continue; |
| 1221 | } else if (strnicmp(data, "ro", 2) == 0) { | ||
| 1222 | vol->rw = false; | ||
| 1223 | } else if (strnicmp(data, "hard", 4) == 0) { | 1221 | } else if (strnicmp(data, "hard", 4) == 0) { |
| 1224 | vol->retry = 1; | 1222 | vol->retry = 1; |
| 1225 | } else if (strnicmp(data, "soft", 4) == 0) { | 1223 | } else if (strnicmp(data, "soft", 4) == 0) { |
| @@ -1386,8 +1384,10 @@ cifs_find_tcp_session(struct sockaddr_storage *addr) | |||
| 1386 | server->addr.sockAddr.sin_addr.s_addr)) | 1384 | server->addr.sockAddr.sin_addr.s_addr)) |
| 1387 | continue; | 1385 | continue; |
| 1388 | else if (addr->ss_family == AF_INET6 && | 1386 | else if (addr->ss_family == AF_INET6 && |
| 1389 | !ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr, | 1387 | (!ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr, |
| 1390 | &addr6->sin6_addr)) | 1388 | &addr6->sin6_addr) || |
| 1389 | server->addr.sockAddr6.sin6_scope_id != | ||
| 1390 | addr6->sin6_scope_id)) | ||
| 1391 | continue; | 1391 | continue; |
| 1392 | 1392 | ||
| 1393 | ++server->srv_count; | 1393 | ++server->srv_count; |
| @@ -1433,28 +1433,15 @@ cifs_get_tcp_session(struct smb_vol *volume_info) | |||
| 1433 | 1433 | ||
| 1434 | memset(&addr, 0, sizeof(struct sockaddr_storage)); | 1434 | memset(&addr, 0, sizeof(struct sockaddr_storage)); |
| 1435 | 1435 | ||
| 1436 | if (volume_info->UNCip && volume_info->UNC) { | 1436 | cFYI(1, ("UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip)); |
| 1437 | rc = cifs_inet_pton(AF_INET, volume_info->UNCip, | ||
| 1438 | &sin_server->sin_addr.s_addr); | ||
| 1439 | |||
| 1440 | if (rc <= 0) { | ||
| 1441 | /* not ipv4 address, try ipv6 */ | ||
| 1442 | rc = cifs_inet_pton(AF_INET6, volume_info->UNCip, | ||
| 1443 | &sin_server6->sin6_addr.in6_u); | ||
| 1444 | if (rc > 0) | ||
| 1445 | addr.ss_family = AF_INET6; | ||
| 1446 | } else { | ||
| 1447 | addr.ss_family = AF_INET; | ||
| 1448 | } | ||
| 1449 | 1437 | ||
| 1450 | if (rc <= 0) { | 1438 | if (volume_info->UNCip && volume_info->UNC) { |
| 1439 | rc = cifs_convert_address(volume_info->UNCip, &addr); | ||
| 1440 | if (!rc) { | ||
| 1451 | /* we failed translating address */ | 1441 | /* we failed translating address */ |
| 1452 | rc = -EINVAL; | 1442 | rc = -EINVAL; |
| 1453 | goto out_err; | 1443 | goto out_err; |
| 1454 | } | 1444 | } |
| 1455 | |||
| 1456 | cFYI(1, ("UNC: %s ip: %s", volume_info->UNC, | ||
| 1457 | volume_info->UNCip)); | ||
| 1458 | } else if (volume_info->UNCip) { | 1445 | } else if (volume_info->UNCip) { |
| 1459 | /* BB using ip addr as tcp_ses name to connect to the | 1446 | /* BB using ip addr as tcp_ses name to connect to the |
| 1460 | DFS root below */ | 1447 | DFS root below */ |
| @@ -1513,14 +1500,14 @@ cifs_get_tcp_session(struct smb_vol *volume_info) | |||
| 1513 | cFYI(1, ("attempting ipv6 connect")); | 1500 | cFYI(1, ("attempting ipv6 connect")); |
| 1514 | /* BB should we allow ipv6 on port 139? */ | 1501 | /* BB should we allow ipv6 on port 139? */ |
| 1515 | /* other OS never observed in Wild doing 139 with v6 */ | 1502 | /* other OS never observed in Wild doing 139 with v6 */ |
| 1503 | sin_server6->sin6_port = htons(volume_info->port); | ||
| 1516 | memcpy(&tcp_ses->addr.sockAddr6, sin_server6, | 1504 | memcpy(&tcp_ses->addr.sockAddr6, sin_server6, |
| 1517 | sizeof(struct sockaddr_in6)); | 1505 | sizeof(struct sockaddr_in6)); |
| 1518 | sin_server6->sin6_port = htons(volume_info->port); | ||
| 1519 | rc = ipv6_connect(tcp_ses); | 1506 | rc = ipv6_connect(tcp_ses); |
| 1520 | } else { | 1507 | } else { |
| 1508 | sin_server->sin_port = htons(volume_info->port); | ||
| 1521 | memcpy(&tcp_ses->addr.sockAddr, sin_server, | 1509 | memcpy(&tcp_ses->addr.sockAddr, sin_server, |
| 1522 | sizeof(struct sockaddr_in)); | 1510 | sizeof(struct sockaddr_in)); |
| 1523 | sin_server->sin_port = htons(volume_info->port); | ||
| 1524 | rc = ipv4_connect(tcp_ses); | 1511 | rc = ipv4_connect(tcp_ses); |
| 1525 | } | 1512 | } |
| 1526 | if (rc < 0) { | 1513 | if (rc < 0) { |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 3758965d73d5..7dc6b74f9def 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
| @@ -307,8 +307,9 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
| 307 | 307 | ||
| 308 | full_path = build_path_from_dentry(direntry); | 308 | full_path = build_path_from_dentry(direntry); |
| 309 | if (full_path == NULL) { | 309 | if (full_path == NULL) { |
| 310 | rc = -ENOMEM; | ||
| 310 | FreeXid(xid); | 311 | FreeXid(xid); |
| 311 | return -ENOMEM; | 312 | return rc; |
| 312 | } | 313 | } |
| 313 | 314 | ||
| 314 | if (oplockEnabled) | 315 | if (oplockEnabled) |
| @@ -540,8 +541,9 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
| 540 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); | 541 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
| 541 | if (buf == NULL) { | 542 | if (buf == NULL) { |
| 542 | kfree(full_path); | 543 | kfree(full_path); |
| 544 | rc = -ENOMEM; | ||
| 543 | FreeXid(xid); | 545 | FreeXid(xid); |
| 544 | return -ENOMEM; | 546 | return rc; |
| 545 | } | 547 | } |
| 546 | 548 | ||
| 547 | rc = CIFSSMBOpen(xid, pTcon, full_path, | 549 | rc = CIFSSMBOpen(xid, pTcon, full_path, |
diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c index df4a306f697e..87948147d7ec 100644 --- a/fs/cifs/dns_resolve.c +++ b/fs/cifs/dns_resolve.c | |||
| @@ -35,26 +35,11 @@ | |||
| 35 | * 0 - name is not IP | 35 | * 0 - name is not IP |
| 36 | */ | 36 | */ |
| 37 | static int | 37 | static int |
| 38 | is_ip(const char *name) | 38 | is_ip(char *name) |
| 39 | { | 39 | { |
| 40 | int rc; | 40 | struct sockaddr_storage ss; |
| 41 | struct sockaddr_in sin_server; | 41 | |
| 42 | struct sockaddr_in6 sin_server6; | 42 | return cifs_convert_address(name, &ss); |
| 43 | |||
| 44 | rc = cifs_inet_pton(AF_INET, name, | ||
| 45 | &sin_server.sin_addr.s_addr); | ||
| 46 | |||
| 47 | if (rc <= 0) { | ||
| 48 | /* not ipv4 address, try ipv6 */ | ||
| 49 | rc = cifs_inet_pton(AF_INET6, name, | ||
| 50 | &sin_server6.sin6_addr.in6_u); | ||
| 51 | if (rc > 0) | ||
| 52 | return 1; | ||
| 53 | } else { | ||
| 54 | return 1; | ||
| 55 | } | ||
| 56 | /* we failed translating address */ | ||
| 57 | return 0; | ||
| 58 | } | 43 | } |
| 59 | 44 | ||
| 60 | static int | 45 | static int |
| @@ -72,7 +57,7 @@ dns_resolver_instantiate(struct key *key, const void *data, | |||
| 72 | ip[datalen] = '\0'; | 57 | ip[datalen] = '\0'; |
| 73 | 58 | ||
| 74 | /* make sure this looks like an address */ | 59 | /* make sure this looks like an address */ |
| 75 | if (!is_ip((const char *) ip)) { | 60 | if (!is_ip(ip)) { |
| 76 | kfree(ip); | 61 | kfree(ip); |
| 77 | return -EINVAL; | 62 | return -EINVAL; |
| 78 | } | 63 | } |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 06866841b97f..ebdbe62a829c 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -300,14 +300,16 @@ int cifs_open(struct inode *inode, struct file *file) | |||
| 300 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); | 300 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); |
| 301 | pCifsFile = cifs_fill_filedata(file); | 301 | pCifsFile = cifs_fill_filedata(file); |
| 302 | if (pCifsFile) { | 302 | if (pCifsFile) { |
| 303 | rc = 0; | ||
| 303 | FreeXid(xid); | 304 | FreeXid(xid); |
| 304 | return 0; | 305 | return rc; |
| 305 | } | 306 | } |
| 306 | 307 | ||
| 307 | full_path = build_path_from_dentry(file->f_path.dentry); | 308 | full_path = build_path_from_dentry(file->f_path.dentry); |
| 308 | if (full_path == NULL) { | 309 | if (full_path == NULL) { |
| 310 | rc = -ENOMEM; | ||
| 309 | FreeXid(xid); | 311 | FreeXid(xid); |
| 310 | return -ENOMEM; | 312 | return rc; |
| 311 | } | 313 | } |
| 312 | 314 | ||
| 313 | cFYI(1, ("inode = 0x%p file flags are 0x%x for %s", | 315 | cFYI(1, ("inode = 0x%p file flags are 0x%x for %s", |
| @@ -494,8 +496,9 @@ static int cifs_reopen_file(struct file *file, bool can_flush) | |||
| 494 | mutex_unlock(&pCifsFile->fh_mutex); | 496 | mutex_unlock(&pCifsFile->fh_mutex); |
| 495 | if (!pCifsFile->invalidHandle) { | 497 | if (!pCifsFile->invalidHandle) { |
| 496 | mutex_lock(&pCifsFile->fh_mutex); | 498 | mutex_lock(&pCifsFile->fh_mutex); |
| 499 | rc = 0; | ||
| 497 | FreeXid(xid); | 500 | FreeXid(xid); |
| 498 | return 0; | 501 | return rc; |
| 499 | } | 502 | } |
| 500 | 503 | ||
| 501 | if (file->f_path.dentry == NULL) { | 504 | if (file->f_path.dentry == NULL) { |
| @@ -845,8 +848,9 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
| 845 | tcon = cifs_sb->tcon; | 848 | tcon = cifs_sb->tcon; |
| 846 | 849 | ||
| 847 | if (file->private_data == NULL) { | 850 | if (file->private_data == NULL) { |
| 851 | rc = -EBADF; | ||
| 848 | FreeXid(xid); | 852 | FreeXid(xid); |
| 849 | return -EBADF; | 853 | return rc; |
| 850 | } | 854 | } |
| 851 | netfid = ((struct cifsFileInfo *)file->private_data)->netfid; | 855 | netfid = ((struct cifsFileInfo *)file->private_data)->netfid; |
| 852 | 856 | ||
| @@ -1805,8 +1809,9 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
| 1805 | pTcon = cifs_sb->tcon; | 1809 | pTcon = cifs_sb->tcon; |
| 1806 | 1810 | ||
| 1807 | if (file->private_data == NULL) { | 1811 | if (file->private_data == NULL) { |
| 1812 | rc = -EBADF; | ||
| 1808 | FreeXid(xid); | 1813 | FreeXid(xid); |
| 1809 | return -EBADF; | 1814 | return rc; |
| 1810 | } | 1815 | } |
| 1811 | open_file = (struct cifsFileInfo *)file->private_data; | 1816 | open_file = (struct cifsFileInfo *)file->private_data; |
| 1812 | 1817 | ||
| @@ -1885,8 +1890,9 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
| 1885 | pTcon = cifs_sb->tcon; | 1890 | pTcon = cifs_sb->tcon; |
| 1886 | 1891 | ||
| 1887 | if (file->private_data == NULL) { | 1892 | if (file->private_data == NULL) { |
| 1893 | rc = -EBADF; | ||
| 1888 | FreeXid(xid); | 1894 | FreeXid(xid); |
| 1889 | return -EBADF; | 1895 | return rc; |
| 1890 | } | 1896 | } |
| 1891 | open_file = (struct cifsFileInfo *)file->private_data; | 1897 | open_file = (struct cifsFileInfo *)file->private_data; |
| 1892 | 1898 | ||
| @@ -2019,8 +2025,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
| 2019 | 2025 | ||
| 2020 | xid = GetXid(); | 2026 | xid = GetXid(); |
| 2021 | if (file->private_data == NULL) { | 2027 | if (file->private_data == NULL) { |
| 2028 | rc = -EBADF; | ||
| 2022 | FreeXid(xid); | 2029 | FreeXid(xid); |
| 2023 | return -EBADF; | 2030 | return rc; |
| 2024 | } | 2031 | } |
| 2025 | open_file = (struct cifsFileInfo *)file->private_data; | 2032 | open_file = (struct cifsFileInfo *)file->private_data; |
| 2026 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 2033 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
| @@ -2185,8 +2192,9 @@ static int cifs_readpage(struct file *file, struct page *page) | |||
| 2185 | xid = GetXid(); | 2192 | xid = GetXid(); |
| 2186 | 2193 | ||
| 2187 | if (file->private_data == NULL) { | 2194 | if (file->private_data == NULL) { |
| 2195 | rc = -EBADF; | ||
| 2188 | FreeXid(xid); | 2196 | FreeXid(xid); |
| 2189 | return -EBADF; | 2197 | return rc; |
| 2190 | } | 2198 | } |
| 2191 | 2199 | ||
| 2192 | cFYI(1, ("readpage %p at offset %d 0x%x\n", | 2200 | cFYI(1, ("readpage %p at offset %d 0x%x\n", |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index fad882b075ba..155c9e785d0c 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -988,8 +988,9 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 988 | * sb->s_vfs_rename_mutex here */ | 988 | * sb->s_vfs_rename_mutex here */ |
| 989 | full_path = build_path_from_dentry(dentry); | 989 | full_path = build_path_from_dentry(dentry); |
| 990 | if (full_path == NULL) { | 990 | if (full_path == NULL) { |
| 991 | rc = -ENOMEM; | ||
| 991 | FreeXid(xid); | 992 | FreeXid(xid); |
| 992 | return -ENOMEM; | 993 | return rc; |
| 993 | } | 994 | } |
| 994 | 995 | ||
| 995 | if ((tcon->ses->capabilities & CAP_UNIX) && | 996 | if ((tcon->ses->capabilities & CAP_UNIX) && |
| @@ -1118,8 +1119,9 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
| 1118 | 1119 | ||
| 1119 | full_path = build_path_from_dentry(direntry); | 1120 | full_path = build_path_from_dentry(direntry); |
| 1120 | if (full_path == NULL) { | 1121 | if (full_path == NULL) { |
| 1122 | rc = -ENOMEM; | ||
| 1121 | FreeXid(xid); | 1123 | FreeXid(xid); |
| 1122 | return -ENOMEM; | 1124 | return rc; |
| 1123 | } | 1125 | } |
| 1124 | 1126 | ||
| 1125 | if ((pTcon->ses->capabilities & CAP_UNIX) && | 1127 | if ((pTcon->ses->capabilities & CAP_UNIX) && |
| @@ -1303,8 +1305,9 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) | |||
| 1303 | 1305 | ||
| 1304 | full_path = build_path_from_dentry(direntry); | 1306 | full_path = build_path_from_dentry(direntry); |
| 1305 | if (full_path == NULL) { | 1307 | if (full_path == NULL) { |
| 1308 | rc = -ENOMEM; | ||
| 1306 | FreeXid(xid); | 1309 | FreeXid(xid); |
| 1307 | return -ENOMEM; | 1310 | return rc; |
| 1308 | } | 1311 | } |
| 1309 | 1312 | ||
| 1310 | rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls, | 1313 | rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls, |
| @@ -1508,8 +1511,9 @@ int cifs_revalidate(struct dentry *direntry) | |||
| 1508 | since that would deadlock */ | 1511 | since that would deadlock */ |
| 1509 | full_path = build_path_from_dentry(direntry); | 1512 | full_path = build_path_from_dentry(direntry); |
| 1510 | if (full_path == NULL) { | 1513 | if (full_path == NULL) { |
| 1514 | rc = -ENOMEM; | ||
| 1511 | FreeXid(xid); | 1515 | FreeXid(xid); |
| 1512 | return -ENOMEM; | 1516 | return rc; |
| 1513 | } | 1517 | } |
| 1514 | cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld " | 1518 | cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld " |
| 1515 | "jiffies %ld", full_path, direntry->d_inode, | 1519 | "jiffies %ld", full_path, direntry->d_inode, |
| @@ -1911,8 +1915,9 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
| 1911 | 1915 | ||
| 1912 | full_path = build_path_from_dentry(direntry); | 1916 | full_path = build_path_from_dentry(direntry); |
| 1913 | if (full_path == NULL) { | 1917 | if (full_path == NULL) { |
| 1918 | rc = -ENOMEM; | ||
| 1914 | FreeXid(xid); | 1919 | FreeXid(xid); |
| 1915 | return -ENOMEM; | 1920 | return rc; |
| 1916 | } | 1921 | } |
| 1917 | 1922 | ||
| 1918 | /* | 1923 | /* |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index cd83c53fcbb5..fc1e0487eaee 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
| @@ -172,8 +172,9 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) | |||
| 172 | full_path = build_path_from_dentry(direntry); | 172 | full_path = build_path_from_dentry(direntry); |
| 173 | 173 | ||
| 174 | if (full_path == NULL) { | 174 | if (full_path == NULL) { |
| 175 | rc = -ENOMEM; | ||
| 175 | FreeXid(xid); | 176 | FreeXid(xid); |
| 176 | return -ENOMEM; | 177 | return rc; |
| 177 | } | 178 | } |
| 178 | 179 | ||
| 179 | cFYI(1, ("Full path: %s", full_path)); | 180 | cFYI(1, ("Full path: %s", full_path)); |
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index 32d6baa0a54f..bd6d6895730d 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c | |||
| @@ -133,10 +133,12 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = { | |||
| 133 | {0, 0} | 133 | {0, 0} |
| 134 | }; | 134 | }; |
| 135 | 135 | ||
| 136 | /* Convert string containing dotted ip address to binary form */ | 136 | /* |
| 137 | /* returns 0 if invalid address */ | 137 | * Convert a string containing text IPv4 or IPv6 address to binary form. |
| 138 | 138 | * | |
| 139 | int | 139 | * Returns 0 on failure. |
| 140 | */ | ||
| 141 | static int | ||
| 140 | cifs_inet_pton(const int address_family, const char *cp, void *dst) | 142 | cifs_inet_pton(const int address_family, const char *cp, void *dst) |
| 141 | { | 143 | { |
| 142 | int ret = 0; | 144 | int ret = 0; |
| @@ -153,6 +155,52 @@ cifs_inet_pton(const int address_family, const char *cp, void *dst) | |||
| 153 | return ret; | 155 | return ret; |
| 154 | } | 156 | } |
| 155 | 157 | ||
| 158 | /* | ||
| 159 | * Try to convert a string to an IPv4 address and then attempt to convert | ||
| 160 | * it to an IPv6 address if that fails. Set the family field if either | ||
| 161 | * succeeds. If it's an IPv6 address and it has a '%' sign in it, try to | ||
| 162 | * treat the part following it as a numeric sin6_scope_id. | ||
| 163 | * | ||
| 164 | * Returns 0 on failure. | ||
| 165 | */ | ||
| 166 | int | ||
| 167 | cifs_convert_address(char *src, void *dst) | ||
| 168 | { | ||
| 169 | int rc; | ||
| 170 | char *pct, *endp; | ||
| 171 | struct sockaddr_in *s4 = (struct sockaddr_in *) dst; | ||
| 172 | struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) dst; | ||
| 173 | |||
| 174 | /* IPv4 address */ | ||
| 175 | if (cifs_inet_pton(AF_INET, src, &s4->sin_addr.s_addr)) { | ||
| 176 | s4->sin_family = AF_INET; | ||
| 177 | return 1; | ||
| 178 | } | ||
| 179 | |||
| 180 | /* temporarily terminate string */ | ||
| 181 | pct = strchr(src, '%'); | ||
| 182 | if (pct) | ||
| 183 | *pct = '\0'; | ||
| 184 | |||
| 185 | rc = cifs_inet_pton(AF_INET6, src, &s6->sin6_addr.s6_addr); | ||
| 186 | |||
| 187 | /* repair temp termination (if any) and make pct point to scopeid */ | ||
| 188 | if (pct) | ||
| 189 | *pct++ = '%'; | ||
| 190 | |||
| 191 | if (!rc) | ||
| 192 | return rc; | ||
| 193 | |||
| 194 | s6->sin6_family = AF_INET6; | ||
| 195 | if (pct) { | ||
| 196 | s6->sin6_scope_id = (u32) simple_strtoul(pct, &endp, 0); | ||
| 197 | if (!*pct || *endp) | ||
| 198 | return 0; | ||
| 199 | } | ||
| 200 | |||
| 201 | return rc; | ||
| 202 | } | ||
| 203 | |||
| 156 | /***************************************************************************** | 204 | /***************************************************************************** |
| 157 | convert a NT status code to a dos class/code | 205 | convert a NT status code to a dos class/code |
| 158 | *****************************************************************************/ | 206 | *****************************************************************************/ |
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 897a052270f9..7085a6275c4c 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
| @@ -802,7 +802,7 @@ ssetup_ntlmssp_authenticate: | |||
| 802 | #endif /* CONFIG_CIFS_UPCALL */ | 802 | #endif /* CONFIG_CIFS_UPCALL */ |
| 803 | } else { | 803 | } else { |
| 804 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 804 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
| 805 | if ((experimEnabled > 1) && (type == RawNTLMSSP)) { | 805 | if (type == RawNTLMSSP) { |
| 806 | if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) { | 806 | if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) { |
| 807 | cERROR(1, ("NTLMSSP requires Unicode support")); | 807 | cERROR(1, ("NTLMSSP requires Unicode support")); |
| 808 | rc = -ENOSYS; | 808 | rc = -ENOSYS; |
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index e9527eedc639..a75afa3dd9e1 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c | |||
| @@ -64,8 +64,9 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name) | |||
| 64 | 64 | ||
| 65 | full_path = build_path_from_dentry(direntry); | 65 | full_path = build_path_from_dentry(direntry); |
| 66 | if (full_path == NULL) { | 66 | if (full_path == NULL) { |
| 67 | rc = -ENOMEM; | ||
| 67 | FreeXid(xid); | 68 | FreeXid(xid); |
| 68 | return -ENOMEM; | 69 | return rc; |
| 69 | } | 70 | } |
| 70 | if (ea_name == NULL) { | 71 | if (ea_name == NULL) { |
| 71 | cFYI(1, ("Null xattr names not supported")); | 72 | cFYI(1, ("Null xattr names not supported")); |
| @@ -118,8 +119,9 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, | |||
| 118 | 119 | ||
| 119 | full_path = build_path_from_dentry(direntry); | 120 | full_path = build_path_from_dentry(direntry); |
| 120 | if (full_path == NULL) { | 121 | if (full_path == NULL) { |
| 122 | rc = -ENOMEM; | ||
| 121 | FreeXid(xid); | 123 | FreeXid(xid); |
| 122 | return -ENOMEM; | 124 | return rc; |
| 123 | } | 125 | } |
| 124 | /* return dos attributes as pseudo xattr */ | 126 | /* return dos attributes as pseudo xattr */ |
| 125 | /* return alt name if available as pseudo attr */ | 127 | /* return alt name if available as pseudo attr */ |
| @@ -225,8 +227,9 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, | |||
| 225 | 227 | ||
| 226 | full_path = build_path_from_dentry(direntry); | 228 | full_path = build_path_from_dentry(direntry); |
| 227 | if (full_path == NULL) { | 229 | if (full_path == NULL) { |
| 230 | rc = -ENOMEM; | ||
| 228 | FreeXid(xid); | 231 | FreeXid(xid); |
| 229 | return -ENOMEM; | 232 | return rc; |
| 230 | } | 233 | } |
| 231 | /* return dos attributes as pseudo xattr */ | 234 | /* return dos attributes as pseudo xattr */ |
| 232 | /* return alt name if available as pseudo attr */ | 235 | /* return alt name if available as pseudo attr */ |
| @@ -351,8 +354,9 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size) | |||
| 351 | 354 | ||
| 352 | full_path = build_path_from_dentry(direntry); | 355 | full_path = build_path_from_dentry(direntry); |
| 353 | if (full_path == NULL) { | 356 | if (full_path == NULL) { |
| 357 | rc = -ENOMEM; | ||
| 354 | FreeXid(xid); | 358 | FreeXid(xid); |
| 355 | return -ENOMEM; | 359 | return rc; |
| 356 | } | 360 | } |
| 357 | /* return dos attributes as pseudo xattr */ | 361 | /* return dos attributes as pseudo xattr */ |
| 358 | /* return alt name if available as pseudo attr */ | 362 | /* return alt name if available as pseudo attr */ |
