diff options
Diffstat (limited to 'fs/cifs')
-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 */ |