mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 05:48:40 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: [CIFS] remove unknown mount option warning message [CIFS] remove bkl usage from umount begin cifs: Fix incorrect return code being printed in cFYI messages [CIFS] cleanup asn handling for ntlmssp [CIFS] Copy struct *after* setting the port, instead of before. cifs: remove rw/ro options cifs: fix problems with earlier patches cifs: have cifs parse scope_id out of IPv6 addresses and use it [CIFS] Do not send tree disconnect if session is already disconnected [CIFS] Fix build break cifs: display scopeid in /proc/mounts cifs: add new routine for converting AF_INET and AF_INET6 addrs cifs: have cifs_show_options show forceuid/forcegid options cifs: remove unneeded NULL checks from cifs_show_options
This commit is contained in:
commit
aada1bc927
15 changed files with 244 additions and 156 deletions
|
@ -5,7 +5,7 @@ client generated ones by default (mount option "serverino" turned
|
|||
on by default if server supports it). Add forceuid and forcegid
|
||||
mount options (so that when negotiating unix extensions specifying
|
||||
which uid mounted does not immediately force the server's reported
|
||||
uids to be overridden).
|
||||
uids to be overridden). Add support for scope moutn parm.
|
||||
|
||||
Version 1.58
|
||||
------------
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#define ASN1_OJI 6 /* Object Identifier */
|
||||
#define ASN1_OJD 7 /* Object Description */
|
||||
#define ASN1_EXT 8 /* External */
|
||||
#define ASN1_ENUM 10 /* Enumerated */
|
||||
#define ASN1_SEQ 16 /* Sequence */
|
||||
#define ASN1_SET 17 /* Set */
|
||||
#define ASN1_NUMSTR 18 /* Numerical String */
|
||||
|
@ -78,10 +79,12 @@
|
|||
#define SPNEGO_OID_LEN 7
|
||||
#define NTLMSSP_OID_LEN 10
|
||||
#define KRB5_OID_LEN 7
|
||||
#define KRB5U2U_OID_LEN 8
|
||||
#define MSKRB5_OID_LEN 7
|
||||
static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 };
|
||||
static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 };
|
||||
static unsigned long KRB5_OID[7] = { 1, 2, 840, 113554, 1, 2, 2 };
|
||||
static unsigned long KRB5U2U_OID[8] = { 1, 2, 840, 113554, 1, 2, 2, 3 };
|
||||
static unsigned long MSKRB5_OID[7] = { 1, 2, 840, 48018, 1, 2, 2 };
|
||||
|
||||
/*
|
||||
|
@ -122,6 +125,28 @@ asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#if 0 /* will be needed later by spnego decoding/encoding of ntlmssp */
|
||||
static unsigned char
|
||||
asn1_enum_decode(struct asn1_ctx *ctx, __le32 *val)
|
||||
{
|
||||
unsigned char ch;
|
||||
|
||||
if (ctx->pointer >= ctx->end) {
|
||||
ctx->error = ASN1_ERR_DEC_EMPTY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ch = *(ctx->pointer)++; /* ch has 0xa, ptr points to lenght octet */
|
||||
if ((ch) == ASN1_ENUM) /* if ch value is ENUM, 0xa */
|
||||
*val = *(++(ctx->pointer)); /* value has enum value */
|
||||
else
|
||||
return 0;
|
||||
|
||||
ctx->pointer++;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned char
|
||||
asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag)
|
||||
{
|
||||
|
@ -476,10 +501,9 @@ decode_negTokenInit(unsigned char *security_blob, int length,
|
|||
unsigned int cls, con, tag, oidlen, rc;
|
||||
bool use_ntlmssp = false;
|
||||
bool use_kerberos = false;
|
||||
bool use_kerberosu2u = false;
|
||||
bool use_mskerberos = false;
|
||||
|
||||
*secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/
|
||||
|
||||
/* cifs_dump_mem(" Received SecBlob ", security_blob, length); */
|
||||
|
||||
asn1_open(&ctx, security_blob, length);
|
||||
|
@ -515,6 +539,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* SPNEGO */
|
||||
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
|
||||
cFYI(1, ("Error decoding negTokenInit"));
|
||||
return 0;
|
||||
|
@ -526,6 +551,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* negTokenInit */
|
||||
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
|
||||
cFYI(1, ("Error decoding negTokenInit"));
|
||||
return 0;
|
||||
|
@ -537,6 +563,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* sequence */
|
||||
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
|
||||
cFYI(1, ("Error decoding 2nd part of negTokenInit"));
|
||||
return 0;
|
||||
|
@ -548,6 +575,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* sequence of */
|
||||
if (asn1_header_decode
|
||||
(&ctx, &sequence_end, &cls, &con, &tag) == 0) {
|
||||
cFYI(1, ("Error decoding 2nd part of negTokenInit"));
|
||||
|
@ -560,6 +588,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* list of security mechanisms */
|
||||
while (!asn1_eoc_decode(&ctx, sequence_end)) {
|
||||
rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
|
||||
if (!rc) {
|
||||
|
@ -576,11 +605,15 @@ decode_negTokenInit(unsigned char *security_blob, int length,
|
|||
|
||||
if (compare_oid(oid, oidlen, MSKRB5_OID,
|
||||
MSKRB5_OID_LEN) &&
|
||||
!use_kerberos)
|
||||
!use_mskerberos)
|
||||
use_mskerberos = true;
|
||||
else if (compare_oid(oid, oidlen, KRB5U2U_OID,
|
||||
KRB5U2U_OID_LEN) &&
|
||||
!use_kerberosu2u)
|
||||
use_kerberosu2u = true;
|
||||
else if (compare_oid(oid, oidlen, KRB5_OID,
|
||||
KRB5_OID_LEN) &&
|
||||
!use_mskerberos)
|
||||
!use_kerberos)
|
||||
use_kerberos = true;
|
||||
else if (compare_oid(oid, oidlen, NTLMSSP_OID,
|
||||
NTLMSSP_OID_LEN))
|
||||
|
@ -593,7 +626,12 @@ decode_negTokenInit(unsigned char *security_blob, int length,
|
|||
}
|
||||
}
|
||||
|
||||
/* mechlistMIC */
|
||||
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
|
||||
/* Check if we have reached the end of the blob, but with
|
||||
no mechListMic (e.g. NTLMSSP instead of KRB5) */
|
||||
if (ctx.error == ASN1_ERR_DEC_EMPTY)
|
||||
goto decode_negtoken_exit;
|
||||
cFYI(1, ("Error decoding last part negTokenInit exit3"));
|
||||
return 0;
|
||||
} else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
|
||||
|
@ -602,6 +640,8 @@ decode_negTokenInit(unsigned char *security_blob, int length,
|
|||
cls, con, tag, end, *end));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sequence */
|
||||
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
|
||||
cFYI(1, ("Error decoding last part negTokenInit exit5"));
|
||||
return 0;
|
||||
|
@ -611,6 +651,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
|
|||
cls, con, tag, end, *end));
|
||||
}
|
||||
|
||||
/* sequence of */
|
||||
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
|
||||
cFYI(1, ("Error decoding last part negTokenInit exit 7"));
|
||||
return 0;
|
||||
|
@ -619,6 +660,8 @@ decode_negTokenInit(unsigned char *security_blob, int length,
|
|||
cls, con, tag, end, *end));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* general string */
|
||||
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
|
||||
cFYI(1, ("Error decoding last part negTokenInit exit9"));
|
||||
return 0;
|
||||
|
@ -630,13 +673,13 @@ decode_negTokenInit(unsigned char *security_blob, int length,
|
|||
}
|
||||
cFYI(1, ("Need to call asn1_octets_decode() function for %s",
|
||||
ctx.pointer)); /* is this UTF-8 or ASCII? */
|
||||
|
||||
decode_negtoken_exit:
|
||||
if (use_kerberos)
|
||||
*secType = Kerberos;
|
||||
else if (use_mskerberos)
|
||||
*secType = MSKerberos;
|
||||
else if (use_ntlmssp)
|
||||
*secType = NTLMSSP;
|
||||
*secType = RawNTLMSSP;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
155
fs/cifs/cifsfs.c
155
fs/cifs/cifsfs.c
|
@ -333,6 +333,27 @@ cifs_destroy_inode(struct inode *inode)
|
|||
kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
|
||||
}
|
||||
|
||||
static void
|
||||
cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server)
|
||||
{
|
||||
seq_printf(s, ",addr=");
|
||||
|
||||
switch (server->addr.sockAddr.sin_family) {
|
||||
case AF_INET:
|
||||
seq_printf(s, "%pI4", &server->addr.sockAddr.sin_addr.s_addr);
|
||||
break;
|
||||
case AF_INET6:
|
||||
seq_printf(s, "%pI6",
|
||||
&server->addr.sockAddr6.sin6_addr.s6_addr);
|
||||
if (server->addr.sockAddr6.sin6_scope_id)
|
||||
seq_printf(s, "%%%u",
|
||||
server->addr.sockAddr6.sin6_scope_id);
|
||||
break;
|
||||
default:
|
||||
seq_printf(s, "(unknown)");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* cifs_show_options() is for displaying mount options in /proc/mounts.
|
||||
* 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)
|
|||
{
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct TCP_Server_Info *server;
|
||||
|
||||
cifs_sb = CIFS_SB(m->mnt_sb);
|
||||
tcon = cifs_sb->tcon;
|
||||
|
||||
if (cifs_sb) {
|
||||
tcon = cifs_sb->tcon;
|
||||
if (tcon) {
|
||||
seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName);
|
||||
if (tcon->ses) {
|
||||
if (tcon->ses->userName)
|
||||
seq_printf(s, ",username=%s",
|
||||
tcon->ses->userName);
|
||||
if (tcon->ses->domainName)
|
||||
seq_printf(s, ",domain=%s",
|
||||
tcon->ses->domainName);
|
||||
server = tcon->ses->server;
|
||||
if (server) {
|
||||
seq_printf(s, ",addr=");
|
||||
switch (server->addr.sockAddr6.
|
||||
sin6_family) {
|
||||
case AF_INET6:
|
||||
seq_printf(s, "%pI6",
|
||||
&server->addr.sockAddr6.sin6_addr);
|
||||
break;
|
||||
case AF_INET:
|
||||
seq_printf(s, "%pI4",
|
||||
&server->addr.sockAddr.sin_addr.s_addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) ||
|
||||
!(tcon->unix_ext))
|
||||
seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) ||
|
||||
!(tcon->unix_ext))
|
||||
seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
|
||||
if (!tcon->unix_ext) {
|
||||
seq_printf(s, ",file_mode=0%o,dir_mode=0%o",
|
||||
seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName);
|
||||
if (tcon->ses->userName)
|
||||
seq_printf(s, ",username=%s", tcon->ses->userName);
|
||||
if (tcon->ses->domainName)
|
||||
seq_printf(s, ",domain=%s", tcon->ses->domainName);
|
||||
|
||||
seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
|
||||
seq_printf(s, ",forceuid");
|
||||
|
||||
seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
|
||||
seq_printf(s, ",forcegid");
|
||||
|
||||
cifs_show_address(s, tcon->ses->server);
|
||||
|
||||
if (!tcon->unix_ext)
|
||||
seq_printf(s, ",file_mode=0%o,dir_mode=0%o",
|
||||
cifs_sb->mnt_file_mode,
|
||||
cifs_sb->mnt_dir_mode);
|
||||
}
|
||||
if (tcon->seal)
|
||||
seq_printf(s, ",seal");
|
||||
if (tcon->nocase)
|
||||
seq_printf(s, ",nocase");
|
||||
if (tcon->retry)
|
||||
seq_printf(s, ",hard");
|
||||
}
|
||||
if (cifs_sb->prepath)
|
||||
seq_printf(s, ",prepath=%s", cifs_sb->prepath);
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
|
||||
seq_printf(s, ",posixpaths");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
|
||||
seq_printf(s, ",setuids");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
|
||||
seq_printf(s, ",serverino");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
|
||||
seq_printf(s, ",directio");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
|
||||
seq_printf(s, ",nouser_xattr");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
|
||||
seq_printf(s, ",mapchars");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
|
||||
seq_printf(s, ",sfu");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
|
||||
seq_printf(s, ",nobrl");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
|
||||
seq_printf(s, ",cifsacl");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
|
||||
seq_printf(s, ",dynperm");
|
||||
if (m->mnt_sb->s_flags & MS_POSIXACL)
|
||||
seq_printf(s, ",acl");
|
||||
if (tcon->seal)
|
||||
seq_printf(s, ",seal");
|
||||
if (tcon->nocase)
|
||||
seq_printf(s, ",nocase");
|
||||
if (tcon->retry)
|
||||
seq_printf(s, ",hard");
|
||||
if (cifs_sb->prepath)
|
||||
seq_printf(s, ",prepath=%s", cifs_sb->prepath);
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
|
||||
seq_printf(s, ",posixpaths");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
|
||||
seq_printf(s, ",setuids");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
|
||||
seq_printf(s, ",serverino");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
|
||||
seq_printf(s, ",directio");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
|
||||
seq_printf(s, ",nouser_xattr");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
|
||||
seq_printf(s, ",mapchars");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
|
||||
seq_printf(s, ",sfu");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
|
||||
seq_printf(s, ",nobrl");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
|
||||
seq_printf(s, ",cifsacl");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
|
||||
seq_printf(s, ",dynperm");
|
||||
if (m->mnt_sb->s_flags & MS_POSIXACL)
|
||||
seq_printf(s, ",acl");
|
||||
|
||||
seq_printf(s, ",rsize=%d", cifs_sb->rsize);
|
||||
seq_printf(s, ",wsize=%d", cifs_sb->wsize);
|
||||
|
||||
seq_printf(s, ",rsize=%d", cifs_sb->rsize);
|
||||
seq_printf(s, ",wsize=%d", cifs_sb->wsize);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -535,9 +537,14 @@ static void cifs_umount_begin(struct super_block *sb)
|
|||
if (tcon == NULL)
|
||||
return;
|
||||
|
||||
lock_kernel();
|
||||
read_lock(&cifs_tcp_ses_lock);
|
||||
if (tcon->tc_count == 1)
|
||||
if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) {
|
||||
/* we have other mounts to same share or we have
|
||||
already tried to force umount this and woken up
|
||||
all waiting network requests, nothing to do */
|
||||
read_unlock(&cifs_tcp_ses_lock);
|
||||
return;
|
||||
} else if (tcon->tc_count == 1)
|
||||
tcon->tidStatus = CifsExiting;
|
||||
read_unlock(&cifs_tcp_ses_lock);
|
||||
|
||||
|
@ -552,9 +559,7 @@ static void cifs_umount_begin(struct super_block *sb)
|
|||
wake_up_all(&tcon->ses->server->response_q);
|
||||
msleep(1);
|
||||
}
|
||||
/* BB FIXME - finish add checks for tidStatus BB */
|
||||
|
||||
unlock_kernel();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ enum securityEnum {
|
|||
NTLM, /* Legacy NTLM012 auth with NTLM hash */
|
||||
NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */
|
||||
RawNTLMSSP, /* NTLMSSP without SPNEGO, NTLMv2 hash */
|
||||
NTLMSSP, /* NTLMSSP via SPNEGO, NTLMv2 hash */
|
||||
/* NTLMSSP, */ /* can use rawNTLMSSP instead of NTLMSSP via SPNEGO */
|
||||
Kerberos, /* Kerberos via SPNEGO */
|
||||
MSKerberos, /* MS Kerberos via SPNEGO */
|
||||
};
|
||||
|
|
|
@ -74,7 +74,7 @@ extern unsigned int smbCalcSize(struct smb_hdr *ptr);
|
|||
extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
|
||||
extern int decode_negTokenInit(unsigned char *security_blob, int length,
|
||||
enum securityEnum *secType);
|
||||
extern int cifs_inet_pton(const int, const char *source, void *dst);
|
||||
extern int cifs_convert_address(char *src, void *dst);
|
||||
extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr);
|
||||
extern void header_assemble(struct smb_hdr *, char /* command */ ,
|
||||
const struct cifsTconInfo *, int /* length of
|
||||
|
|
|
@ -594,7 +594,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
|
|||
else if (secFlags & CIFSSEC_MAY_KRB5)
|
||||
server->secType = Kerberos;
|
||||
else if (secFlags & CIFSSEC_MAY_NTLMSSP)
|
||||
server->secType = NTLMSSP;
|
||||
server->secType = RawNTLMSSP;
|
||||
else if (secFlags & CIFSSEC_MAY_LANMAN)
|
||||
server->secType = LANMAN;
|
||||
/* #ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
|
@ -729,7 +729,7 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
|
|||
* the tcon is no longer on the list, so no need to take lock before
|
||||
* checking this.
|
||||
*/
|
||||
if (tcon->need_reconnect)
|
||||
if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
|
||||
return 0;
|
||||
|
||||
rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
|
||||
|
|
|
@ -70,7 +70,6 @@ struct smb_vol {
|
|||
mode_t file_mode;
|
||||
mode_t dir_mode;
|
||||
unsigned secFlg;
|
||||
bool rw:1;
|
||||
bool retry:1;
|
||||
bool intr:1;
|
||||
bool setuids:1;
|
||||
|
@ -832,7 +831,6 @@ cifs_parse_mount_options(char *options, const char *devname,
|
|||
vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR;
|
||||
|
||||
/* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
|
||||
vol->rw = true;
|
||||
/* default is always to request posix paths. */
|
||||
vol->posix_paths = 1;
|
||||
/* default to using server inode numbers where available */
|
||||
|
@ -1199,7 +1197,9 @@ cifs_parse_mount_options(char *options, const char *devname,
|
|||
} else if (strnicmp(data, "guest", 5) == 0) {
|
||||
/* ignore */
|
||||
} else if (strnicmp(data, "rw", 2) == 0) {
|
||||
vol->rw = true;
|
||||
/* ignore */
|
||||
} else if (strnicmp(data, "ro", 2) == 0) {
|
||||
/* ignore */
|
||||
} else if (strnicmp(data, "noblocksend", 11) == 0) {
|
||||
vol->noblocksnd = 1;
|
||||
} else if (strnicmp(data, "noautotune", 10) == 0) {
|
||||
|
@ -1218,8 +1218,6 @@ cifs_parse_mount_options(char *options, const char *devname,
|
|||
parse these options again and set anything and it
|
||||
is ok to just ignore them */
|
||||
continue;
|
||||
} else if (strnicmp(data, "ro", 2) == 0) {
|
||||
vol->rw = false;
|
||||
} else if (strnicmp(data, "hard", 4) == 0) {
|
||||
vol->retry = 1;
|
||||
} else if (strnicmp(data, "soft", 4) == 0) {
|
||||
|
@ -1386,8 +1384,10 @@ cifs_find_tcp_session(struct sockaddr_storage *addr)
|
|||
server->addr.sockAddr.sin_addr.s_addr))
|
||||
continue;
|
||||
else if (addr->ss_family == AF_INET6 &&
|
||||
!ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr,
|
||||
&addr6->sin6_addr))
|
||||
(!ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr,
|
||||
&addr6->sin6_addr) ||
|
||||
server->addr.sockAddr6.sin6_scope_id !=
|
||||
addr6->sin6_scope_id))
|
||||
continue;
|
||||
|
||||
++server->srv_count;
|
||||
|
@ -1433,28 +1433,15 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
|
|||
|
||||
memset(&addr, 0, sizeof(struct sockaddr_storage));
|
||||
|
||||
cFYI(1, ("UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip));
|
||||
|
||||
if (volume_info->UNCip && volume_info->UNC) {
|
||||
rc = cifs_inet_pton(AF_INET, volume_info->UNCip,
|
||||
&sin_server->sin_addr.s_addr);
|
||||
|
||||
if (rc <= 0) {
|
||||
/* not ipv4 address, try ipv6 */
|
||||
rc = cifs_inet_pton(AF_INET6, volume_info->UNCip,
|
||||
&sin_server6->sin6_addr.in6_u);
|
||||
if (rc > 0)
|
||||
addr.ss_family = AF_INET6;
|
||||
} else {
|
||||
addr.ss_family = AF_INET;
|
||||
}
|
||||
|
||||
if (rc <= 0) {
|
||||
rc = cifs_convert_address(volume_info->UNCip, &addr);
|
||||
if (!rc) {
|
||||
/* we failed translating address */
|
||||
rc = -EINVAL;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
cFYI(1, ("UNC: %s ip: %s", volume_info->UNC,
|
||||
volume_info->UNCip));
|
||||
} else if (volume_info->UNCip) {
|
||||
/* BB using ip addr as tcp_ses name to connect to the
|
||||
DFS root below */
|
||||
|
@ -1513,14 +1500,14 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
|
|||
cFYI(1, ("attempting ipv6 connect"));
|
||||
/* BB should we allow ipv6 on port 139? */
|
||||
/* other OS never observed in Wild doing 139 with v6 */
|
||||
sin_server6->sin6_port = htons(volume_info->port);
|
||||
memcpy(&tcp_ses->addr.sockAddr6, sin_server6,
|
||||
sizeof(struct sockaddr_in6));
|
||||
sin_server6->sin6_port = htons(volume_info->port);
|
||||
rc = ipv6_connect(tcp_ses);
|
||||
} else {
|
||||
sin_server->sin_port = htons(volume_info->port);
|
||||
memcpy(&tcp_ses->addr.sockAddr, sin_server,
|
||||
sizeof(struct sockaddr_in));
|
||||
sin_server->sin_port = htons(volume_info->port);
|
||||
rc = ipv4_connect(tcp_ses);
|
||||
}
|
||||
if (rc < 0) {
|
||||
|
|
|
@ -307,8 +307,9 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
|||
|
||||
full_path = build_path_from_dentry(direntry);
|
||||
if (full_path == NULL) {
|
||||
rc = -ENOMEM;
|
||||
FreeXid(xid);
|
||||
return -ENOMEM;
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (oplockEnabled)
|
||||
|
@ -540,8 +541,9 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
|
|||
buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
|
||||
if (buf == NULL) {
|
||||
kfree(full_path);
|
||||
rc = -ENOMEM;
|
||||
FreeXid(xid);
|
||||
return -ENOMEM;
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = CIFSSMBOpen(xid, pTcon, full_path,
|
||||
|
|
|
@ -35,26 +35,11 @@
|
|||
* 0 - name is not IP
|
||||
*/
|
||||
static int
|
||||
is_ip(const char *name)
|
||||
is_ip(char *name)
|
||||
{
|
||||
int rc;
|
||||
struct sockaddr_in sin_server;
|
||||
struct sockaddr_in6 sin_server6;
|
||||
struct sockaddr_storage ss;
|
||||
|
||||
rc = cifs_inet_pton(AF_INET, name,
|
||||
&sin_server.sin_addr.s_addr);
|
||||
|
||||
if (rc <= 0) {
|
||||
/* not ipv4 address, try ipv6 */
|
||||
rc = cifs_inet_pton(AF_INET6, name,
|
||||
&sin_server6.sin6_addr.in6_u);
|
||||
if (rc > 0)
|
||||
return 1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
/* we failed translating address */
|
||||
return 0;
|
||||
return cifs_convert_address(name, &ss);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -72,7 +57,7 @@ dns_resolver_instantiate(struct key *key, const void *data,
|
|||
ip[datalen] = '\0';
|
||||
|
||||
/* make sure this looks like an address */
|
||||
if (!is_ip((const char *) ip)) {
|
||||
if (!is_ip(ip)) {
|
||||
kfree(ip);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -300,14 +300,16 @@ int cifs_open(struct inode *inode, struct file *file)
|
|||
pCifsInode = CIFS_I(file->f_path.dentry->d_inode);
|
||||
pCifsFile = cifs_fill_filedata(file);
|
||||
if (pCifsFile) {
|
||||
rc = 0;
|
||||
FreeXid(xid);
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
full_path = build_path_from_dentry(file->f_path.dentry);
|
||||
if (full_path == NULL) {
|
||||
rc = -ENOMEM;
|
||||
FreeXid(xid);
|
||||
return -ENOMEM;
|
||||
return rc;
|
||||
}
|
||||
|
||||
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)
|
|||
mutex_unlock(&pCifsFile->fh_mutex);
|
||||
if (!pCifsFile->invalidHandle) {
|
||||
mutex_lock(&pCifsFile->fh_mutex);
|
||||
rc = 0;
|
||||
FreeXid(xid);
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (file->f_path.dentry == NULL) {
|
||||
|
@ -845,8 +848,9 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
|
|||
tcon = cifs_sb->tcon;
|
||||
|
||||
if (file->private_data == NULL) {
|
||||
rc = -EBADF;
|
||||
FreeXid(xid);
|
||||
return -EBADF;
|
||||
return rc;
|
||||
}
|
||||
netfid = ((struct cifsFileInfo *)file->private_data)->netfid;
|
||||
|
||||
|
@ -1805,8 +1809,9 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
|
|||
pTcon = cifs_sb->tcon;
|
||||
|
||||
if (file->private_data == NULL) {
|
||||
rc = -EBADF;
|
||||
FreeXid(xid);
|
||||
return -EBADF;
|
||||
return rc;
|
||||
}
|
||||
open_file = (struct cifsFileInfo *)file->private_data;
|
||||
|
||||
|
@ -1885,8 +1890,9 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
|
|||
pTcon = cifs_sb->tcon;
|
||||
|
||||
if (file->private_data == NULL) {
|
||||
rc = -EBADF;
|
||||
FreeXid(xid);
|
||||
return -EBADF;
|
||||
return rc;
|
||||
}
|
||||
open_file = (struct cifsFileInfo *)file->private_data;
|
||||
|
||||
|
@ -2019,8 +2025,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
|
|||
|
||||
xid = GetXid();
|
||||
if (file->private_data == NULL) {
|
||||
rc = -EBADF;
|
||||
FreeXid(xid);
|
||||
return -EBADF;
|
||||
return rc;
|
||||
}
|
||||
open_file = (struct cifsFileInfo *)file->private_data;
|
||||
cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
|
||||
|
@ -2185,8 +2192,9 @@ static int cifs_readpage(struct file *file, struct page *page)
|
|||
xid = GetXid();
|
||||
|
||||
if (file->private_data == NULL) {
|
||||
rc = -EBADF;
|
||||
FreeXid(xid);
|
||||
return -EBADF;
|
||||
return rc;
|
||||
}
|
||||
|
||||
cFYI(1, ("readpage %p at offset %d 0x%x\n",
|
||||
|
|
|
@ -988,8 +988,9 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
|
|||
* sb->s_vfs_rename_mutex here */
|
||||
full_path = build_path_from_dentry(dentry);
|
||||
if (full_path == NULL) {
|
||||
rc = -ENOMEM;
|
||||
FreeXid(xid);
|
||||
return -ENOMEM;
|
||||
return rc;
|
||||
}
|
||||
|
||||
if ((tcon->ses->capabilities & CAP_UNIX) &&
|
||||
|
@ -1118,8 +1119,9 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
|
|||
|
||||
full_path = build_path_from_dentry(direntry);
|
||||
if (full_path == NULL) {
|
||||
rc = -ENOMEM;
|
||||
FreeXid(xid);
|
||||
return -ENOMEM;
|
||||
return rc;
|
||||
}
|
||||
|
||||
if ((pTcon->ses->capabilities & CAP_UNIX) &&
|
||||
|
@ -1303,8 +1305,9 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
|
|||
|
||||
full_path = build_path_from_dentry(direntry);
|
||||
if (full_path == NULL) {
|
||||
rc = -ENOMEM;
|
||||
FreeXid(xid);
|
||||
return -ENOMEM;
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls,
|
||||
|
@ -1508,8 +1511,9 @@ int cifs_revalidate(struct dentry *direntry)
|
|||
since that would deadlock */
|
||||
full_path = build_path_from_dentry(direntry);
|
||||
if (full_path == NULL) {
|
||||
rc = -ENOMEM;
|
||||
FreeXid(xid);
|
||||
return -ENOMEM;
|
||||
return rc;
|
||||
}
|
||||
cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
|
||||
"jiffies %ld", full_path, direntry->d_inode,
|
||||
|
@ -1911,8 +1915,9 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
|||
|
||||
full_path = build_path_from_dentry(direntry);
|
||||
if (full_path == NULL) {
|
||||
rc = -ENOMEM;
|
||||
FreeXid(xid);
|
||||
return -ENOMEM;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -172,8 +172,9 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
|
|||
full_path = build_path_from_dentry(direntry);
|
||||
|
||||
if (full_path == NULL) {
|
||||
rc = -ENOMEM;
|
||||
FreeXid(xid);
|
||||
return -ENOMEM;
|
||||
return rc;
|
||||
}
|
||||
|
||||
cFYI(1, ("Full path: %s", full_path));
|
||||
|
|
|
@ -133,10 +133,12 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = {
|
|||
{0, 0}
|
||||
};
|
||||
|
||||
/* Convert string containing dotted ip address to binary form */
|
||||
/* returns 0 if invalid address */
|
||||
|
||||
int
|
||||
/*
|
||||
* Convert a string containing text IPv4 or IPv6 address to binary form.
|
||||
*
|
||||
* Returns 0 on failure.
|
||||
*/
|
||||
static int
|
||||
cifs_inet_pton(const int address_family, const char *cp, void *dst)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -153,6 +155,52 @@ cifs_inet_pton(const int address_family, const char *cp, void *dst)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to convert a string to an IPv4 address and then attempt to convert
|
||||
* it to an IPv6 address if that fails. Set the family field if either
|
||||
* succeeds. If it's an IPv6 address and it has a '%' sign in it, try to
|
||||
* treat the part following it as a numeric sin6_scope_id.
|
||||
*
|
||||
* Returns 0 on failure.
|
||||
*/
|
||||
int
|
||||
cifs_convert_address(char *src, void *dst)
|
||||
{
|
||||
int rc;
|
||||
char *pct, *endp;
|
||||
struct sockaddr_in *s4 = (struct sockaddr_in *) dst;
|
||||
struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) dst;
|
||||
|
||||
/* IPv4 address */
|
||||
if (cifs_inet_pton(AF_INET, src, &s4->sin_addr.s_addr)) {
|
||||
s4->sin_family = AF_INET;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* temporarily terminate string */
|
||||
pct = strchr(src, '%');
|
||||
if (pct)
|
||||
*pct = '\0';
|
||||
|
||||
rc = cifs_inet_pton(AF_INET6, src, &s6->sin6_addr.s6_addr);
|
||||
|
||||
/* repair temp termination (if any) and make pct point to scopeid */
|
||||
if (pct)
|
||||
*pct++ = '%';
|
||||
|
||||
if (!rc)
|
||||
return rc;
|
||||
|
||||
s6->sin6_family = AF_INET6;
|
||||
if (pct) {
|
||||
s6->sin6_scope_id = (u32) simple_strtoul(pct, &endp, 0);
|
||||
if (!*pct || *endp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
convert a NT status code to a dos class/code
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -802,7 +802,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
|
|||
#endif /* CONFIG_CIFS_UPCALL */
|
||||
} else {
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
if ((experimEnabled > 1) && (type == RawNTLMSSP)) {
|
||||
if (type == RawNTLMSSP) {
|
||||
if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
|
||||
cERROR(1, ("NTLMSSP requires Unicode support"));
|
||||
rc = -ENOSYS;
|
||||
|
|
|
@ -64,8 +64,9 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
|
|||
|
||||
full_path = build_path_from_dentry(direntry);
|
||||
if (full_path == NULL) {
|
||||
rc = -ENOMEM;
|
||||
FreeXid(xid);
|
||||
return -ENOMEM;
|
||||
return rc;
|
||||
}
|
||||
if (ea_name == NULL) {
|
||||
cFYI(1, ("Null xattr names not supported"));
|
||||
|
@ -118,8 +119,9 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
|
|||
|
||||
full_path = build_path_from_dentry(direntry);
|
||||
if (full_path == NULL) {
|
||||
rc = -ENOMEM;
|
||||
FreeXid(xid);
|
||||
return -ENOMEM;
|
||||
return rc;
|
||||
}
|
||||
/* return dos attributes as pseudo xattr */
|
||||
/* return alt name if available as pseudo attr */
|
||||
|
@ -225,8 +227,9 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
|
|||
|
||||
full_path = build_path_from_dentry(direntry);
|
||||
if (full_path == NULL) {
|
||||
rc = -ENOMEM;
|
||||
FreeXid(xid);
|
||||
return -ENOMEM;
|
||||
return rc;
|
||||
}
|
||||
/* return dos attributes as pseudo xattr */
|
||||
/* 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)
|
|||
|
||||
full_path = build_path_from_dentry(direntry);
|
||||
if (full_path == NULL) {
|
||||
rc = -ENOMEM;
|
||||
FreeXid(xid);
|
||||
return -ENOMEM;
|
||||
return rc;
|
||||
}
|
||||
/* return dos attributes as pseudo xattr */
|
||||
/* return alt name if available as pseudo attr */
|
||||
|
|
Loading…
Reference in a new issue