Commit 56831a1a authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6

* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
  [CIFS] list entry can not return null
  turn cifs_setattr into a multiplexor that calls the correct function
  move file time and dos attribute setting logic into new function
  spin off cifs_setattr with unix extensions to its own function
  [CIFS] Code cleanup in old sessionsetup code
  [CIFS] cifs_mkdir and cifs_create should respect the setgid bit on parent dir
  Rename CIFSSMBSetFileTimes to CIFSSMBSetFileInfo and add PID arg
  change CIFSSMBSetTimes to CIFSSMBSetPathInfo
  [CIFS] fix trailing whitespace
  bundle up Unix SET_PATH_INFO args into a struct and change name
  Fix missing braces in cifs_revalidate()
  remove locking around tcpSesAllocCount atomic variable
  [CIFS] properly account for new user= field in SPNEGO upcall string allocation
  [CIFS] remove level of indentation from decode_negTokenInit
  [CIFS] cifs send2 not retrying enough in some cases on full socket
  [CIFS] oid should also be checked against class in cifs asn
parents 6724cce8 ad8b15f0
Version 1.54
------------
Fix premature write failure on congested networks (we would give up
on EAGAIN from the socket too quickly on large writes).
Cifs_mkdir and cifs_create now respect the setgid bit on parent dir.
Fix endian problems in acl (mode from/to cifs acl) on bigendian
architectures.
Version 1.53 Version 1.53
------------ ------------
DFS support added (Microsoft Distributed File System client support needed DFS support added (Microsoft Distributed File System client support needed
......
...@@ -483,6 +483,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, ...@@ -483,6 +483,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
asn1_open(&ctx, security_blob, length); asn1_open(&ctx, security_blob, length);
/* GSSAPI header */
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1, ("Error decoding negTokenInit header")); cFYI(1, ("Error decoding negTokenInit header"));
return 0; return 0;
...@@ -490,153 +491,142 @@ decode_negTokenInit(unsigned char *security_blob, int length, ...@@ -490,153 +491,142 @@ decode_negTokenInit(unsigned char *security_blob, int length,
|| (tag != ASN1_EOC)) { || (tag != ASN1_EOC)) {
cFYI(1, ("cls = %d con = %d tag = %d", cls, con, tag)); cFYI(1, ("cls = %d con = %d tag = %d", cls, con, tag));
return 0; return 0;
} else { }
/* remember to free obj->oid */
rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
if (rc) {
if ((tag == ASN1_OJI) && (con == ASN1_PRI)) {
rc = asn1_oid_decode(&ctx, end, &oid, &oidlen);
if (rc) {
rc = compare_oid(oid, oidlen,
SPNEGO_OID,
SPNEGO_OID_LEN);
kfree(oid);
}
} else
rc = 0;
}
if (!rc) { /* Check for SPNEGO OID -- remember to free obj->oid */
cFYI(1, ("Error decoding negTokenInit header")); rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
return 0; if (rc) {
} if ((tag == ASN1_OJI) && (con == ASN1_PRI) &&
(cls == ASN1_UNI)) {
rc = asn1_oid_decode(&ctx, end, &oid, &oidlen);
if (rc) {
rc = compare_oid(oid, oidlen, SPNEGO_OID,
SPNEGO_OID_LEN);
kfree(oid);
}
} else
rc = 0;
}
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { /* SPNEGO OID not present or garbled -- bail out */
cFYI(1, ("Error decoding negTokenInit")); if (!rc) {
return 0; cFYI(1, ("Error decoding negTokenInit header"));
} else if ((cls != ASN1_CTX) || (con != ASN1_CON) return 0;
|| (tag != ASN1_EOC)) { }
cFYI(1,
("cls = %d con = %d tag = %d end = %p (%d) exit 0",
cls, con, tag, end, *end));
return 0;
}
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1, ("Error decoding negTokenInit")); cFYI(1, ("Error decoding negTokenInit"));
return 0; return 0;
} else if ((cls != ASN1_UNI) || (con != ASN1_CON) } else if ((cls != ASN1_CTX) || (con != ASN1_CON)
|| (tag != ASN1_SEQ)) { || (tag != ASN1_EOC)) {
cFYI(1, cFYI(1,
("cls = %d con = %d tag = %d end = %p (%d) exit 1", ("cls = %d con = %d tag = %d end = %p (%d) exit 0",
cls, con, tag, end, *end)); cls, con, tag, end, *end));
return 0; return 0;
} }
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1, ("Error decoding 2nd part of negTokenInit")); cFYI(1, ("Error decoding negTokenInit"));
return 0; return 0;
} else if ((cls != ASN1_CTX) || (con != ASN1_CON) } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
|| (tag != ASN1_EOC)) { || (tag != ASN1_SEQ)) {
cFYI(1, cFYI(1,
("cls = %d con = %d tag = %d end = %p (%d) exit 0", ("cls = %d con = %d tag = %d end = %p (%d) exit 1",
cls, con, tag, end, *end)); cls, con, tag, end, *end));
return 0; return 0;
} }
if (asn1_header_decode if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
(&ctx, &sequence_end, &cls, &con, &tag) == 0) { cFYI(1, ("Error decoding 2nd part of negTokenInit"));
cFYI(1, ("Error decoding 2nd part of negTokenInit")); return 0;
return 0; } else if ((cls != ASN1_CTX) || (con != ASN1_CON)
} else if ((cls != ASN1_UNI) || (con != ASN1_CON) || (tag != ASN1_EOC)) {
|| (tag != ASN1_SEQ)) { cFYI(1,
cFYI(1, ("cls = %d con = %d tag = %d end = %p (%d) exit 0",
("cls = %d con = %d tag = %d end = %p (%d) exit 1", cls, con, tag, end, *end));
cls, con, tag, end, *end)); return 0;
return 0; }
}
while (!asn1_eoc_decode(&ctx, sequence_end)) { if (asn1_header_decode
rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); (&ctx, &sequence_end, &cls, &con, &tag) == 0) {
if (!rc) { cFYI(1, ("Error decoding 2nd part of negTokenInit"));
cFYI(1, return 0;
("Error decoding negTokenInit hdr exit2")); } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
return 0; || (tag != ASN1_SEQ)) {
} cFYI(1,
if ((tag == ASN1_OJI) && (con == ASN1_PRI)) { ("cls = %d con = %d tag = %d end = %p (%d) exit 1",
if (asn1_oid_decode(&ctx, end, &oid, &oidlen)) { cls, con, tag, end, *end));
return 0;
cFYI(1, }
("OID len = %d oid = 0x%lx 0x%lx "
"0x%lx 0x%lx",
oidlen, *oid, *(oid + 1),
*(oid + 2), *(oid + 3)));
if (compare_oid(oid, oidlen,
MSKRB5_OID,
MSKRB5_OID_LEN))
use_kerberos = true;
else if (compare_oid(oid, oidlen,
KRB5_OID,
KRB5_OID_LEN))
use_kerberos = true;
else if (compare_oid(oid, oidlen,
NTLMSSP_OID,
NTLMSSP_OID_LEN))
use_ntlmssp = true;
kfree(oid);
}
} else {
cFYI(1, ("Should be an oid what is going on?"));
}
}
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { while (!asn1_eoc_decode(&ctx, sequence_end)) {
cFYI(1, rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
("Error decoding last part negTokenInit exit3")); if (!rc) {
return 0;
} else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
/* tag = 3 indicating mechListMIC */
cFYI(1, cFYI(1,
("Exit 4 cls = %d con = %d tag = %d end = %p (%d)", ("Error decoding negTokenInit hdr exit2"));
cls, con, tag, end, *end));
return 0; return 0;
} }
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { if ((tag == ASN1_OJI) && (con == ASN1_PRI)) {
cFYI(1, if (asn1_oid_decode(&ctx, end, &oid, &oidlen)) {
("Error decoding last part negTokenInit exit5"));
return 0; cFYI(1, ("OID len = %d oid = 0x%lx 0x%lx "
} else if ((cls != ASN1_UNI) || (con != ASN1_CON) "0x%lx 0x%lx", oidlen, *oid,
|| (tag != ASN1_SEQ)) { *(oid + 1), *(oid + 2), *(oid + 3)));
cFYI(1, ("cls = %d con = %d tag = %d end = %p (%d)",
cls, con, tag, end, *end)); if (compare_oid(oid, oidlen, MSKRB5_OID,
MSKRB5_OID_LEN))
use_kerberos = true;
else if (compare_oid(oid, oidlen, KRB5_OID,
KRB5_OID_LEN))
use_kerberos = true;
else if (compare_oid(oid, oidlen, NTLMSSP_OID,
NTLMSSP_OID_LEN))
use_ntlmssp = true;
kfree(oid);
}
} else {
cFYI(1, ("Should be an oid what is going on?"));
} }
}
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1, cFYI(1, ("Error decoding last part negTokenInit exit3"));
("Error decoding last part negTokenInit exit 7")); return 0;
return 0; } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
} else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { /* tag = 3 indicating mechListMIC */
cFYI(1, cFYI(1, ("Exit 4 cls = %d con = %d tag = %d end = %p (%d)",
("Exit 8 cls = %d con = %d tag = %d end = %p (%d)", cls, con, tag, end, *end));
cls, con, tag, end, *end)); return 0;
return 0; }
} if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, ("Error decoding last part negTokenInit exit5"));
cFYI(1, return 0;
("Error decoding last part negTokenInit exit9")); } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
return 0; || (tag != ASN1_SEQ)) {
} else if ((cls != ASN1_UNI) || (con != ASN1_PRI) cFYI(1, ("cls = %d con = %d tag = %d end = %p (%d)",
|| (tag != ASN1_GENSTR)) { cls, con, tag, end, *end));
cFYI(1, }
("Exit10 cls = %d con = %d tag = %d end = %p (%d)",
cls, con, tag, end, *end)); if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
return 0; cFYI(1, ("Error decoding last part negTokenInit exit 7"));
} return 0;
cFYI(1, ("Need to call asn1_octets_decode() function for %s", } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
ctx.pointer)); /* is this UTF-8 or ASCII? */ cFYI(1, ("Exit 8 cls = %d con = %d tag = %d end = %p (%d)",
cls, con, tag, end, *end));
return 0;
}
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1, ("Error decoding last part negTokenInit exit9"));
return 0;
} else if ((cls != ASN1_UNI) || (con != ASN1_PRI)
|| (tag != ASN1_GENSTR)) {
cFYI(1, ("Exit10 cls = %d con = %d tag = %d end = %p (%d)",
cls, con, tag, end, *end));
return 0;
} }
cFYI(1, ("Need to call asn1_octets_decode() function for %s",
ctx.pointer)); /* is this UTF-8 or ASCII? */
if (use_kerberos) if (use_kerberos)
*secType = Kerberos; *secType = Kerberos;
......
...@@ -79,27 +79,25 @@ void cifs_dump_mids(struct TCP_Server_Info *server) ...@@ -79,27 +79,25 @@ void cifs_dump_mids(struct TCP_Server_Info *server)
spin_lock(&GlobalMid_Lock); spin_lock(&GlobalMid_Lock);
list_for_each(tmp, &server->pending_mid_q) { list_for_each(tmp, &server->pending_mid_q) {
mid_entry = list_entry(tmp, struct mid_q_entry, qhead); mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
if (mid_entry) { cERROR(1, ("State: %d Cmd: %d Pid: %d Tsk: %p Mid %d",
cERROR(1, ("State: %d Cmd: %d Pid: %d Tsk: %p Mid %d", mid_entry->midState,
mid_entry->midState, (int)mid_entry->command,
(int)mid_entry->command, mid_entry->pid,
mid_entry->pid, mid_entry->tsk,
mid_entry->tsk, mid_entry->mid));
mid_entry->mid));
#ifdef CONFIG_CIFS_STATS2 #ifdef CONFIG_CIFS_STATS2
cERROR(1, ("IsLarge: %d buf: %p time rcv: %ld now: %ld", cERROR(1, ("IsLarge: %d buf: %p time rcv: %ld now: %ld",
mid_entry->largeBuf, mid_entry->largeBuf,
mid_entry->resp_buf, mid_entry->resp_buf,
mid_entry->when_received, mid_entry->when_received,
jiffies)); jiffies));
#endif /* STATS2 */ #endif /* STATS2 */
cERROR(1, ("IsMult: %d IsEnd: %d", mid_entry->multiRsp, cERROR(1, ("IsMult: %d IsEnd: %d", mid_entry->multiRsp,
mid_entry->multiEnd)); mid_entry->multiEnd));
if (mid_entry->resp_buf) { if (mid_entry->resp_buf) {
cifs_dump_detail(mid_entry->resp_buf); cifs_dump_detail(mid_entry->resp_buf);
cifs_dump_mem("existing buf: ", cifs_dump_mem("existing buf: ",
mid_entry->resp_buf, 62); mid_entry->resp_buf, 62);
}
} }
} }
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
...@@ -163,16 +161,13 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) ...@@ -163,16 +161,13 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
mid_entry = list_entry(tmp1, struct mid_entry = list_entry(tmp1, struct
mid_q_entry, mid_q_entry,
qhead); qhead);
if (mid_entry) { seq_printf(m, "State: %d com: %d pid:"
seq_printf(m, " %d tsk: %p mid %d\n",
"State: %d com: %d pid:" mid_entry->midState,
" %d tsk: %p mid %d\n", (int)mid_entry->command,
mid_entry->midState, mid_entry->pid,
(int)mid_entry->command, mid_entry->tsk,
mid_entry->pid, mid_entry->mid);
mid_entry->tsk,
mid_entry->mid);
}
} }
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
} }
......
...@@ -66,8 +66,8 @@ struct key_type cifs_spnego_key_type = { ...@@ -66,8 +66,8 @@ struct key_type cifs_spnego_key_type = {
.describe = user_describe, .describe = user_describe,
}; };
#define MAX_VER_STR_LEN 9 /* length of longest version string e.g. #define MAX_VER_STR_LEN 8 /* length of longest version string e.g.
strlen(";ver=0xFF") */ strlen("ver=0xFF") */
#define MAX_MECH_STR_LEN 13 /* length of longest security mechanism name, eg #define MAX_MECH_STR_LEN 13 /* length of longest security mechanism name, eg
in future could have strlen(";sec=ntlmsspi") */ in future could have strlen(";sec=ntlmsspi") */
#define MAX_IPV6_ADDR_LEN 42 /* eg FEDC:BA98:7654:3210:FEDC:BA98:7654:3210/60 */ #define MAX_IPV6_ADDR_LEN 42 /* eg FEDC:BA98:7654:3210:FEDC:BA98:7654:3210/60 */
...@@ -81,11 +81,15 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo) ...@@ -81,11 +81,15 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
struct key *spnego_key; struct key *spnego_key;
const char *hostname = server->hostname; const char *hostname = server->hostname;
/* BB: come up with better scheme for determining length */ /* length of fields (with semicolons): ver=0xyz ip4=ipaddress
/* length of fields (with semicolons): ver=0xyz ipv4= ipaddress host= host=hostname sec=mechanism uid=0xFF user=username */
hostname sec=mechanism uid=0x uid */ desc_len = MAX_VER_STR_LEN +
desc_len = MAX_VER_STR_LEN + 5 + MAX_IPV6_ADDR_LEN + 1 + 6 + 6 /* len of "host=" */ + strlen(hostname) +
strlen(hostname) + MAX_MECH_STR_LEN + 8 + (sizeof(uid_t) * 2); 5 /* len of ";ipv4=" */ + MAX_IPV6_ADDR_LEN +
MAX_MECH_STR_LEN +
7 /* len of ";uid=0x" */ + (sizeof(uid_t) * 2) +
6 /* len of ";user=" */ + strlen(sesInfo->userName) + 1;
spnego_key = ERR_PTR(-ENOMEM); spnego_key = ERR_PTR(-ENOMEM);
description = kzalloc(desc_len, GFP_KERNEL); description = kzalloc(desc_len, GFP_KERNEL);
if (description == NULL) if (description == NULL)
......
...@@ -930,36 +930,34 @@ static int cifs_oplock_thread(void *dummyarg) ...@@ -930,36 +930,34 @@ static int cifs_oplock_thread(void *dummyarg)
schedule_timeout(39*HZ); schedule_timeout(39*HZ);
} else { } else {
oplock_item = list_entry(GlobalOplock_Q.next, oplock_item = list_entry(GlobalOplock_Q.next,
struct oplock_q_entry, qhead); struct oplock_q_entry, qhead);
if (oplock_item) { cFYI(1, ("found oplock item to write out"));
cFYI(1, ("found oplock item to write out")); pTcon = oplock_item->tcon;
pTcon = oplock_item->tcon; inode = oplock_item->pinode;
inode = oplock_item->pinode; netfid = oplock_item->netfid;
netfid = oplock_item->netfid; spin_unlock(&GlobalMid_Lock);
spin_unlock(&GlobalMid_Lock); DeleteOplockQEntry(oplock_item);
DeleteOplockQEntry(oplock_item); /* can not grab inode sem here since it would
/* can not grab inode sem here since it would
deadlock when oplock received on delete deadlock when oplock received on delete
since vfs_unlink holds the i_mutex across since vfs_unlink holds the i_mutex across
the call */ the call */
/* mutex_lock(&inode->i_mutex);*/ /* mutex_lock(&inode->i_mutex);*/
if (S_ISREG(inode->i_mode)) { if (S_ISREG(inode->i_mode)) {
rc = rc = filemap_fdatawrite(inode->i_mapping);
filemap_fdatawrite(inode->i_mapping); if (CIFS_I(inode)->clientCanCacheRead == 0) {
if (CIFS_I(inode)->clientCanCacheRead waitrc = filemap_fdatawait(
== 0) { inode->i_mapping);
waitrc = filemap_fdatawait(inode->i_mapping); invalidate_remote_inode(inode);
invalidate_remote_inode(inode); }
} if (rc == 0)
if (rc == 0) rc = waitrc;
rc = waitrc; } else
} else rc = 0;
rc = 0; /* mutex_unlock(&inode->i_mutex);*/
/* mutex_unlock(&inode->i_mutex);*/ if (rc)
if (rc) CIFS_I(inode)->write_behind_rc = rc;
CIFS_I(inode)->write_behind_rc = rc; cFYI(1, ("Oplock flush inode %p rc %d",
cFYI(1, ("Oplock flush inode %p rc %d", inode, rc));
inode, rc));
/* releasing stale oplock after recent reconnect /* releasing stale oplock after recent reconnect
of smb session using a now incorrect file of smb session using a now incorrect file
...@@ -967,15 +965,13 @@ static int cifs_oplock_thread(void *dummyarg) ...@@ -967,15 +965,13 @@ static int cifs_oplock_thread(void *dummyarg)
not bother sending an oplock release if session not bother sending an oplock release if session
to server still is disconnected since oplock to server still is disconnected since oplock
already released by the server in that case */ already released by the server in that case */
if (pTcon->tidStatus != CifsNeedReconnect) { if (pTcon->tidStatus != CifsNeedReconnect) {
rc = CIFSSMBLock(0, pTcon, netfid, rc = CIFSSMBLock(0, pTcon, netfid,
0 /* len */ , 0 /* offset */, 0, 0 /* len */ , 0 /* offset */, 0,
0, LOCKING_ANDX_OPLOCK_RELEASE, 0, LOCKING_ANDX_OPLOCK_RELEASE,
false /* wait flag */); false /* wait flag */);
cFYI(1, ("Oplock release rc = %d", rc)); cFYI(1, ("Oplock release rc = %d", rc));
} }
} else
spin_unlock(&GlobalMid_Lock);
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1); /* yield in case q were corrupt */ schedule_timeout(1); /* yield in case q were corrupt */
} }
...@@ -1001,8 +997,7 @@ static int cifs_dnotify_thread(void *dummyarg) ...@@ -1001,8 +997,7 @@ static int cifs_dnotify_thread(void *dummyarg)
list_for_each(tmp, &GlobalSMBSessionList) { list_for_each(tmp, &GlobalSMBSessionList) {
ses = list_entry(tmp, struct cifsSesInfo, ses = list_entry(tmp, struct cifsSesInfo,
cifsSessionList); cifsSessionList);
if (ses && ses->server && if (ses->server && atomic_read(&ses->server->inFlight))
atomic_read(&ses->server->inFlight))
wake_up_all(&ses->server->response_q); wake_up_all(&ses->server->response_q);
} }
read_unlock(&GlobalSMBSeslock); read_unlock(&GlobalSMBSeslock);
......
...@@ -101,5 +101,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); ...@@ -101,5 +101,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
extern const struct export_operations cifs_export_ops; extern const struct export_operations cifs_export_ops;
#endif /* EXPERIMENTAL */ #endif /* EXPERIMENTAL */
#define CIFS_VERSION "1.53" #define CIFS_VERSION "1.54"
#endif /* _CIFSFS_H */ #endif /* _CIFSFS_H */
...@@ -262,7 +262,7 @@ ...@@ -262,7 +262,7 @@
*/ */
#define CIFS_NO_HANDLE 0xFFFF #define CIFS_NO_HANDLE 0xFFFF
#define NO_CHANGE_64 cpu_to_le64(0xFFFFFFFFFFFFFFFFULL) #define NO_CHANGE_64 0xFFFFFFFFFFFFFFFFULL
#define NO_CHANGE_32 0xFFFFFFFFUL #define NO_CHANGE_32 0xFFFFFFFFUL
/* IPC$ in ASCII */ /* IPC$ in ASCII */
......
...@@ -172,12 +172,13 @@ extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon); ...@@ -172,12 +172,13 @@ extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon);
extern int CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
struct kstatfs *FSData); struct kstatfs *FSData);
extern int CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon,
const char *fileName, const FILE_BASIC_INFO *data, const char *fileName, const FILE_BASIC_INFO *data,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
int remap_special_chars); int remap_special_chars);
extern int CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
const FILE_BASIC_INFO *data, __u16 fid); const FILE_BASIC_INFO *data, __u16 fid,
__u32 pid_of_opener);
#if 0 #if 0
extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon,
char *fileName, __u16 dos_attributes, char *fileName, __u16 dos_attributes,
...@@ -191,9 +192,20 @@ extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, ...@@ -191,9 +192,20 @@ extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon,
extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon,
__u64 size, __u16 fileHandle, __u32 opener_pid, __u64 size, __u16 fileHandle, __u32 opener_pid,
bool AllocSizeFlag); bool AllocSizeFlag);
extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon,
char *full_path, __u64 mode, __u64 uid, struct cifs_unix_set_info_args {
__u64 gid, dev_t dev, __u64 ctime;
__u64 atime;
__u64 mtime;
__u64 mode;
__u64 uid;
__u64 gid;
dev_t device;
};
extern int CIFSSMBUnixSetInfo(const int xid, struct cifsTconInfo *pTcon,
char *fileName,
const struct cifs_unix_set_info_args *args,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
int remap_special_chars); int remap_special_chars);
......
...@@ -128,8 +128,7 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon) ...@@ -128,8 +128,7 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
write_lock(&GlobalSMBSeslock); write_lock(&GlobalSMBSeslock);
list_for_each_safe(tmp, tmp1, &pTcon->openFileList) { list_for_each_safe(tmp, tmp1, &pTcon->openFileList) {
open_file = list_entry(tmp, struct cifsFileInfo, tlist); open_file = list_entry(tmp, struct cifsFileInfo, tlist);
if (open_file) open_file->invalidHandle = true;
open_file->invalidHandle = true;
} }
write_unlock(&GlobalSMBSeslock); write_unlock(&GlobalSMBSeslock);
/* BB Add call to invalidate_inodes(sb) for all superblocks mounted /* BB Add call to invalidate_inodes(sb) for all superblocks mounted
...@@ -4816,8 +4815,8 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, ...@@ -4816,8 +4815,8 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
time and resort to the original setpathinfo level which takes the ancient time and resort to the original setpathinfo level which takes the ancient
DOS time format with 2 second granularity */ DOS time format with 2 second granularity */
int int
CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
const FILE_BASIC_INFO *data, __u16 fid) const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
{ {
struct smb_com_transaction2_sfi_req *pSMB = NULL; struct smb_com_transaction2_sfi_req *pSMB = NULL;
char *data_offset; char *data_offset;
...@@ -4830,11 +4829,8 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, ...@@ -4830,11 +4829,8 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
if (rc) if (rc)
return rc; return rc;
/* At this point there is no need to override the current pid pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
with the pid of the opener, but that could change if we someday pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
use an existing handle (rather than opening one on the fly) */
/* pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));*/
params = 6; params = 6;
pSMB->MaxSetupCount = 0; pSMB->MaxSetupCount = 0;
...@@ -4882,9 +4878,9 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, ...@@ -4882,9 +4878,9 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
int int
CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, const char *fileName, CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon,
const FILE_BASIC_INFO *data, const char *fileName, const FILE_BASIC_INFO *data,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
{ {
TRANSACTION2_SPI_REQ *pSMB = NULL; TRANSACTION2_SPI_REQ *pSMB = NULL;
TRANSACTION2_SPI_RSP *pSMBr = NULL; TRANSACTION2_SPI_RSP *pSMBr = NULL;
...@@ -5013,10 +5009,9 @@ CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, char *fileName, ...@@ -5013,10 +5009,9 @@ CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, char *fileName,
#endif /* temporarily unneeded SetAttr legacy function */ #endif /* temporarily unneeded SetAttr legacy function */
int int
CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon, CIFSSMBUnixSetInfo(const int xid, struct cifsTconInfo *tcon, char *fileName,
char *fileName, __u64 mode, __u64 uid, __u64 gid, const struct cifs_unix_set_info_args *args,
dev_t device, const struct nls_table *nls_codepage, const struct nls_table *nls_codepage, int remap)
int remap)
{ {
TRANSACTION2_SPI_REQ *pSMB = NULL; TRANSACTION2_SPI_REQ *pSMB = NULL;
TRANSACTION2_SPI_RSP *pSMBr = NULL; TRANSACTION2_SPI_RSP *pSMBr = NULL;
...@@ -5025,6 +5020,7 @@ CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon, ...@@ -5025,6 +5020,7 @@ CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon,
int bytes_returned = 0; int bytes_returned = 0;
FILE_UNIX_BASIC_INFO *data_offset; FILE_UNIX_BASIC_INFO *data_offset;
__u16 params, param_offset, offset, count, byte_count; __u16 params, param_offset, offset, count, byte_count;
__u64 mode = args->mode;
cFYI(1, ("In SetUID/GID/Mode")); cFYI(1, ("In SetUID/GID/Mode"));
setPermsRetry: setPermsRetry:
...@@ -5080,16 +5076,16 @@ CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon, ...@@ -5080,16 +5076,16 @@ CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon,
set file size and do not want to truncate file size to zero set file size and do not want to truncate file size to zero
accidently as happened on one Samba server beta by putting accidently as happened on one Samba server beta by putting
zero instead of -1 here */ zero instead of -1 here */
data_offset->EndOfFile = NO_CHANGE_64; data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
data_offset->NumOfBytes = NO_CHANGE_64; data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
data_offset->LastStatusChange = NO_CHANGE_64; data_offset->LastStatusChange = cpu_to_le64(args->ctime);
data_offset->LastAccessTime = NO_CHANGE_64; data_offset->LastAccessTime = cpu_to_le64(args->atime);
data_offset->LastModificationTime = NO_CHANGE_64; data_offset->LastModificationTime = cpu_to_le64(args->mtime);
data_offset->Uid = cpu_to_le64(uid); data_offset->Uid = cpu_to_le64(args->uid);
data_offset->Gid = cpu_to_le64(gid); data_offset->Gid = cpu_to_le64(args->gid);
/* better to leave device as zero when it is */ /* better to leave device as zero when it is */
data_offset->DevMajor = cpu_to_le64(MAJOR(device)); data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
data_offset->DevMinor = cpu_to_le64(MINOR(device)); data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
data_offset->Permissions = cpu_to_le64(mode); data_offset->Permissions = cpu_to_le64(mode);
if (S_ISREG(mode)) if (S_ISREG(mode))
......
...@@ -151,7 +151,7 @@ cifs_reconnect(struct TCP_Server_Info *server) ...@@ -151,7 +151,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
} }
list_for_each(tmp, &GlobalTreeConnectionList) { list_for_each(tmp, &GlobalTreeConnectionList) {
tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
if ((tcon) && (tcon->ses) && (tcon->ses->server == server)) if ((tcon->ses) && (tcon->ses->server == server))
tcon->tidStatus = CifsNeedReconnect; tcon->tidStatus = CifsNeedReconnect;
} }
read_unlock(&GlobalSMBSeslock); read_unlock(&GlobalSMBSeslock);
...@@ -173,14 +173,12 @@ cifs_reconnect(struct TCP_Server_Info *server) ...@@ -173,14 +173,12 @@ cifs_reconnect(struct TCP_Server_Info *server)
mid_entry = list_entry(tmp, struct mid_entry = list_entry(tmp, struct
mid_q_entry, mid_q_entry,
qhead); qhead);
if (mid_entry) { if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
/* Mark other intransit requests as needing /* Mark other intransit requests as needing
retry so we do not immediately mark the retry so we do not immediately mark the
session bad again (ie after we reconnect session bad again (ie after we reconnect
below) as they timeout too */ below) as they timeout too */
mid_entry->midState = MID_RETRY_NEEDED; mid_entry->midState = MID_RETRY_NEEDED;
}
} }
} }
spin_unlock(&GlobalMid_Lock); spin_unlock(&GlobalMid_Lock);
...@@ -351,11 +349,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -351,11 +349,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
current->flags |= PF_MEMALLOC; current->flags |= PF_MEMALLOC;
cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current))); cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current)));
write_lock(&GlobalSMBSeslock);
atomic_inc(&tcpSesAllocCount); length = atomic_inc_return(&tcpSesAllocCount);
length = tcpSesAllocCount.counter; if (length > 1)
write_unlock(&GlobalSMBSeslock);
if (length > 1)
mempool_resize(cifs_req_poolp, length + cifs_min_rcv, mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
GFP_KERNEL); GFP_KERNEL);
...@@ -745,14 +741,11 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -745,14 +741,11 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
coming home not much else we can do but free the memory */ coming home not much else we can do but free the memory */
} }
write_lock(&GlobalSMBSeslock);
atomic_dec(&tcpSesAllocCount);
length = tcpSesAllocCount.counter;
/* last chance to mark ses pointers invalid /* last chance to mark ses pointers invalid
if there are any pointing to this (e.g if there are any pointing to this (e.g
if a crazy root user tried to kill cifsd if a crazy root user tried to kill cifsd
kernel thread explicitly this might happen) */ kernel thread explicitly this might happen) */
write_lock(&GlobalSMBSeslock);
list_for_each(tmp, &GlobalSMBSessionList) { list_for_each(tmp, &GlobalSMBSessionList) {
ses = list_entry(tmp, struct cifsSesInfo, ses = list_entry(tmp, struct cifsSesInfo,
cifsSessionList); cifsSessionList);
...@@ -763,6 +756,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -763,6 +756,8 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
kfree(server->hostname); kfree(server->hostname);
kfree(server); kfree(server);
length = atomic_dec_return(&tcpSesAllocCount);
if (length > 0) if (length > 0)
mempool_resize(cifs_req_poolp, length + cifs_min_rcv, mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
GFP_KERNEL); GFP_KERNEL);
...@@ -3623,97 +3618,91 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, ...@@ -3623,97 +3618,91 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
} }
first_time = 1; first_time = 1;
} }
if (!rc) {
pSesInfo->flags = 0; if (rc)
pSesInfo->capabilities = pSesInfo->server->capabilities; goto ss_err_exit;
if (linuxExtEnabled == 0)
pSesInfo->capabilities &= (~CAP_UNIX); pSesInfo->flags = 0;
pSesInfo->capabilities = pSesInfo->server->capabilities;
if (linuxExtEnabled == 0)
pSesInfo->capabilities &= (~CAP_UNIX);
/* pSesInfo->sequence_number = 0;*/ /* pSesInfo->sequence_number = 0;*/
cFYI(1, cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d", pSesInfo->server->secMode,
pSesInfo->server->secMode, pSesInfo->server->capabilities,
pSesInfo->server->capabilities, pSesInfo->server->timeAdj));
pSesInfo->server->timeAdj)); if (experimEnabled < 2)
if (experimEnabled < 2) rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info);
rc = CIFS_SessSetup(xid, pSesInfo, else if (extended_security
first_time, nls_info); && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
else if (extended_security && (pSesInfo->server->secType == NTLMSSP)) {
&& (pSesInfo->capabilities rc = -EOPNOTSUPP;
& CAP_EXTENDED_SECURITY) } else if (extended_security
&& (pSesInfo->server->secType == NTLMSSP)) { && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
rc = -EOPNOTSUPP; && (pSesInfo->server->secType == RawNTLMSSP)) {
} else if (extended_security cFYI(1, ("NTLMSSP sesssetup"));
&& (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) rc = CIFSNTLMSSPNegotiateSessSetup(xid, pSesInfo, &ntlmv2_flag,
&& (pSesInfo->server->secType == RawNTLMSSP)) { nls_info);
cFYI(1, ("NTLMSSP sesssetup")); if (!rc) {
rc = CIFSNTLMSSPNegotiateSessSetup(xid, if (ntlmv2_flag) {
pSesInfo, char *v2_response;
&ntlmv2_flag, cFYI(1, ("more secure NTLM ver2 hash"));
nls_info); if (CalcNTLMv2_partial_mac_key(pSesInfo,
if (!rc) { nls_info)) {
if (ntlmv2_flag) { rc = -ENOMEM;
char *v2_response; goto ss_err_exit;
cFYI(1, ("more secure NTLM ver2 hash")); } else
if (CalcNTLMv2_partial_mac_key(pSesInfo, v2_response = kmalloc(16 + 64 /* blob*/,
nls_info)) { GFP_KERNEL);
rc = -ENOMEM; if (v2_response) {
goto ss_err_exit; CalcNTLMv2_response(pSesInfo,
} else v2_response);
v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL); /* if (first_time)
if (v2_response) { cifs_calculate_ntlmv2_mac_key */
CalcNTLMv2_response(pSesInfo, kfree(v2_response);
v2_response);
/* if (first_time)
cifs_calculate_ntlmv2_mac_key(
pSesInfo->server->mac_signing_key,
response, ntlm_session_key,*/
kfree(v2_response);
/* BB Put dummy sig in SessSetup PDU? */ /* BB Put dummy sig in SessSetup PDU? */
} else {
rc = -ENOMEM;
goto ss_err_exit;
}
} else { } else {
SMBNTencrypt(pSesInfo->password, rc = -ENOMEM;
pSesInfo->server->cryptKey, goto ss_err_exit;
ntlm_session_key);
if (first_time)
cifs_calculate_mac_key(
&pSesInfo->server->mac_signing_key,
ntlm_session_key,
pSesInfo->password);
} }
} else {
SMBNTencrypt(pSesInfo->password,
pSesInfo->server->cryptKey,
ntlm_session_key);
if (first_time)
cifs_calculate_mac_key(
&pSesInfo->server->mac_signing_key,
ntlm_session_key,
pSesInfo->password);
}
/* for better security the weaker lanman hash not sent /* for better security the weaker lanman hash not sent
in AuthSessSetup so we no longer calculate it */ in AuthSessSetup so we no longer calculate it */
rc = CIFSNTLMSSPAuthSessSetup(xid, rc = CIFSNTLMSSPAuthSessSetup(xid, pSesInfo,
pSesInfo, ntlm_session_key,
ntlm_session_key, ntlmv2_flag,
ntlmv2_flag, nls_info);
nls_info); }
} } else { /* old style NTLM 0.12 session setup */
} else { /* old style NTLM 0.12 session setup */ SMBNTencrypt(pSesInfo->password, pSesInfo->server->cryptKey,
SMBNTencrypt(pSesInfo->password, ntlm_session_key);
pSesInfo->server->cryptKey,
ntlm_session_key);
if (first_time) if (first_time)
cifs_calculate_mac_key( cifs_calculate_mac_key(
&pSesInfo->server->mac_signing_key, &pSesInfo->server->mac_signing_key,
ntlm_session_key, pSesInfo->password); ntlm_session_key, pSesInfo->password);
rc = CIFSSessSetup(xid, pSesInfo, rc = CIFSSessSetup(xid, pSesInfo, ntlm_session_key, nls_info);
ntlm_session_key, nls_info); }
} if (rc) {
if (rc) { cERROR(1, ("Send error in SessSetup = %d", rc));
cERROR(1, ("Send error in SessSetup = %d", rc)); } else {
} else { cFYI(1, ("CIFS Session Established successfully"));
cFYI(1, ("CIFS Session Established successfully"));
pSesInfo->status = CifsGood; pSesInfo->status = CifsGood;
}
} }
ss_err_exit: ss_err_exit:
return rc; return rc;
} }
......
...@@ -226,23 +226,28 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, ...@@ -226,23 +226,28 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
/* If Open reported that we actually created a file /* If Open reported that we actually created a file
then we now have to set the mode if possible */ then we now have to set the mode if possible */
if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
struct cifs_unix_set_info_args args = {
.mode = mode,
.ctime = NO_CHANGE_64,
.atime = NO_CHANGE_64,
.mtime = NO_CHANGE_64,
.device = 0,
};
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, args.uid = (__u64) current->fsuid;
(__u64)current->fsuid, if (inode->i_mode & S_ISGID)
(__u64)current->fsgid, args.gid = (__u64) inode->i_gid;
0 /* dev */, else
cifs_sb->local_nls, args.gid = (__u64) current->fsgid;
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
} else { } else {
CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, args.uid = NO_CHANGE_64;
(__u64)-1, args.gid = NO_CHANGE_64;
(__u64)-1,
0 /* dev */,
cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
} }
CIFSSMBUnixSetInfo(xid, pTcon, full_path, &args,
cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
} else { } else {
/* BB implement mode setting via Windows security /* BB implement mode setting via Windows security
descriptors e.g. */ descriptors e.g. */
...@@ -267,7 +272,12 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, ...@@ -267,7 +272,12 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
(cifs_sb->mnt_cifs_flags & (cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_SET_UID)) { CIFS_MOUNT_SET_UID)) {
newinode->i_uid = current->fsuid; newinode->i_uid = current->fsuid;
newinode->i_gid = current->fsgid; if (inode->i_mode & S_ISGID)
newinode->i_gid =
inode->i_gid;
else
newinode->i_gid =
current->fsgid;
} }
} }
} }
...@@ -357,21 +367,24 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, ...@@ -357,21 +367,24 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
if (full_path == NULL) if (full_path == NULL)
rc = -ENOMEM; rc = -ENOMEM;
else if (pTcon->unix_ext) { else if (pTcon->unix_ext) {
mode &= ~current->fs->umask; struct cifs_unix_set_info_args args = {
.mode = mode & ~current->fs->umask,
.ctime = NO_CHANGE_64,
.atime = NO_CHANGE_64,
.mtime = NO_CHANGE_64,
.device = device_number,
};
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, args.uid = (__u64) current->fsuid;
mode, (__u64)current->fsuid, args.gid = (__u64) current->fsgid;
(__u64)current->fsgid,
device_number, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
} else { } else {
rc = CIFSSMBUnixSetPerms(xid, pTcon, args.uid = NO_CHANGE_64;
full_path, mode, (__u64)-1, (__u64)-1, args.gid = NO_CHANGE_64;
device_number, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
} }
rc = CIFSSMBUnixSetInfo(xid, pTcon, full_path,
&args, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
if (!rc) { if (!rc) {
rc = cifs_get_inode_info_unix(&newinode, full_path, rc = cifs_get_inode_info_unix(&newinode, full_path,
......
...@@ -310,18 +310,19 @@ int cifs_open(struct inode *inode, struct file *file) ...@@ -310,18 +310,19 @@ int cifs_open(struct inode *inode, struct file *file)
/* time to set mode which we can not set earlier due to /* time to set mode which we can not set earlier due to
problems creating new read-only files */ problems creating new read-only files */
if (pTcon->unix_ext) { if (pTcon->unix_ext) {
CIFSSMBUnixSetPerms(xid, pTcon, full_path, struct cifs_unix_set_info_args args = {
inode->i_mode, .mode = inode->i_mode,
(__u64)-1, (__u64)-1, 0 /* dev */, .uid = NO_CHANGE_64,
.gid = NO_CHANGE_64,
.ctime = NO_CHANGE_64,
.atime = NO_CHANGE_64,
.mtime = NO_CHANGE_64,
.device = 0,
};
CIFSSMBUnixSetInfo(xid, pTcon, full_path, &args,
cifs_sb->local_nls, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR); CIFS_MOUNT_MAP_SPECIAL_CHR);
} else {
/* BB implement via Windows security descriptors eg
CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
-1, -1, local_nls);
in the meantime could set r/o dos attribute when
perms are eg: mode & 0222 == 0 */
} }
} }
......
This diff is collapsed.
...@@ -265,6 +265,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec, ...@@ -265,6 +265,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
cFYI(1, ("Sending smb: total_len %d", total_len)); cFYI(1, ("Sending smb: total_len %d", total_len));
dump_smb(smb_buffer, len); dump_smb(smb_buffer, len);
i = 0;
while (total_len) { while (total_len) {
rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec], rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
n_vec - first_vec, total_len); n_vec - first_vec, total_len);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment