Skip to content

Commit f82e7b5

Browse files
committed
Merge tag '5.8-rc-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6
Pull more cifs updates from Steve French: "12 cifs/smb3 fixes, 2 for stable. - add support for idsfromsid on create and chgrp/chown allowing ability to save owner information more naturally for some workloads - improve query info (getattr) when SMB3.1.1 posix extensions are negotiated by using new query info level" * tag '5.8-rc-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6: smb3: Add debug message for new file creation with idsfromsid mount option cifs: fix chown and chgrp when idsfromsid mount option enabled smb3: allow uid and gid owners to be set on create with idsfromsid mount option smb311: Add tracepoints for new compound posix query info smb311: add support for using info level for posix extensions query smb311: Add support for lookup with posix extensions query info smb311: Add support for SMB311 query info (non-compounded) SMB311: Add support for query info using posix extensions (level 100) smb3: add indatalen that can be a non-zero value to calculation of credit charge in smb2 ioctl smb3: fix typo in mount options displayed in /proc/mounts cifs: Add get_security_type_str function to return sec type. smb3: extend fscache mount volume coherency check
2 parents 4f9b3a3 + a7a519a commit f82e7b5

19 files changed

+571
-57
lines changed

fs/cifs/cache.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,6 @@ const struct fscache_cookie_def cifs_fscache_server_index_def = {
5353
.type = FSCACHE_COOKIE_TYPE_INDEX,
5454
};
5555

56-
/*
57-
* Auxiliary data attached to CIFS superblock within the cache
58-
*/
59-
struct cifs_fscache_super_auxdata {
60-
u64 resource_id; /* unique server resource id */
61-
};
62-
6356
char *extract_sharename(const char *treename)
6457
{
6558
const char *src;
@@ -98,6 +91,8 @@ fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data,
9891

9992
memset(&auxdata, 0, sizeof(auxdata));
10093
auxdata.resource_id = tcon->resource_id;
94+
auxdata.vol_create_time = tcon->vol_create_time;
95+
auxdata.vol_serial_number = tcon->vol_serial_number;
10196

10297
if (memcmp(data, &auxdata, datalen) != 0)
10398
return FSCACHE_CHECKAUX_OBSOLETE;

fs/cifs/cifs_debug.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,6 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
221221
struct cifs_ses *ses;
222222
struct cifs_tcon *tcon;
223223
int i, j;
224-
const char *security_types[] = {"Unspecified", "LANMAN", "NTLM",
225-
"NTLMv2", "RawNTLMSSP", "Kerberos"};
226224

227225
seq_puts(m,
228226
"Display Internal CIFS Data Structures for Debugging\n"
@@ -379,7 +377,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
379377
}
380378

381379
seq_printf(m,"Security type: %s\n",
382-
security_types[server->ops->select_sectype(server, ses->sectype)]);
380+
get_security_type_str(server->ops->select_sectype(server, ses->sectype)));
383381

384382
if (server->rdma)
385383
seq_printf(m, "RDMA\n\t");

fs/cifs/cifsacl.c

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,28 @@ unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode)
849849
return ace_size;
850850
}
851851

852+
unsigned int setup_special_user_owner_ACE(struct cifs_ace *pntace)
853+
{
854+
int i;
855+
unsigned int ace_size = 28;
856+
857+
pntace->type = ACCESS_ALLOWED_ACE_TYPE;
858+
pntace->flags = 0x0;
859+
pntace->access_req = cpu_to_le32(GENERIC_ALL);
860+
pntace->sid.num_subauth = 3;
861+
pntace->sid.revision = 1;
862+
for (i = 0; i < NUM_AUTHS; i++)
863+
pntace->sid.authority[i] = sid_unix_NFS_users.authority[i];
864+
865+
pntace->sid.sub_auth[0] = sid_unix_NFS_users.sub_auth[0];
866+
pntace->sid.sub_auth[1] = sid_unix_NFS_users.sub_auth[1];
867+
pntace->sid.sub_auth[2] = cpu_to_le32(current_fsgid().val);
868+
869+
/* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
870+
pntace->size = cpu_to_le16(ace_size);
871+
return ace_size;
872+
}
873+
852874
static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
853875
struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid)
854876
{
@@ -978,7 +1000,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
9781000
/* Convert permission bits from mode to equivalent CIFS ACL */
9791001
static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
9801002
__u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid,
981-
bool mode_from_sid, int *aclflag)
1003+
bool mode_from_sid, bool id_from_sid, int *aclflag)
9821004
{
9831005
int rc = 0;
9841006
__u32 dacloffset;
@@ -1019,12 +1041,23 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
10191041
if (!nowner_sid_ptr)
10201042
return -ENOMEM;
10211043
id = from_kuid(&init_user_ns, uid);
1022-
rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1023-
if (rc) {
1024-
cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1025-
__func__, rc, id);
1026-
kfree(nowner_sid_ptr);
1027-
return rc;
1044+
if (id_from_sid) {
1045+
struct owner_sid *osid = (struct owner_sid *)nowner_sid_ptr;
1046+
/* Populate the user ownership fields S-1-5-88-1 */
1047+
osid->Revision = 1;
1048+
osid->NumAuth = 3;
1049+
osid->Authority[5] = 5;
1050+
osid->SubAuthorities[0] = cpu_to_le32(88);
1051+
osid->SubAuthorities[1] = cpu_to_le32(1);
1052+
osid->SubAuthorities[2] = cpu_to_le32(id);
1053+
} else { /* lookup sid with upcall */
1054+
rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
1055+
if (rc) {
1056+
cifs_dbg(FYI, "%s: Mapping error %d for owner id %d\n",
1057+
__func__, rc, id);
1058+
kfree(nowner_sid_ptr);
1059+
return rc;
1060+
}
10281061
}
10291062
cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
10301063
kfree(nowner_sid_ptr);
@@ -1039,12 +1072,23 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
10391072
if (!ngroup_sid_ptr)
10401073
return -ENOMEM;
10411074
id = from_kgid(&init_user_ns, gid);
1042-
rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1043-
if (rc) {
1044-
cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1045-
__func__, rc, id);
1046-
kfree(ngroup_sid_ptr);
1047-
return rc;
1075+
if (id_from_sid) {
1076+
struct owner_sid *gsid = (struct owner_sid *)ngroup_sid_ptr;
1077+
/* Populate the group ownership fields S-1-5-88-2 */
1078+
gsid->Revision = 1;
1079+
gsid->NumAuth = 3;
1080+
gsid->Authority[5] = 5;
1081+
gsid->SubAuthorities[0] = cpu_to_le32(88);
1082+
gsid->SubAuthorities[1] = cpu_to_le32(2);
1083+
gsid->SubAuthorities[2] = cpu_to_le32(id);
1084+
} else { /* lookup sid with upcall */
1085+
rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
1086+
if (rc) {
1087+
cifs_dbg(FYI, "%s: Mapping error %d for group id %d\n",
1088+
__func__, rc, id);
1089+
kfree(ngroup_sid_ptr);
1090+
return rc;
1091+
}
10481092
}
10491093
cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
10501094
kfree(ngroup_sid_ptr);
@@ -1247,7 +1291,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
12471291
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
12481292
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
12491293
struct smb_version_operations *ops;
1250-
bool mode_from_sid;
1294+
bool mode_from_sid, id_from_sid;
12511295

12521296
if (IS_ERR(tlink))
12531297
return PTR_ERR(tlink);
@@ -1290,8 +1334,13 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
12901334
else
12911335
mode_from_sid = false;
12921336

1337+
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
1338+
id_from_sid = true;
1339+
else
1340+
id_from_sid = false;
1341+
12931342
rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1294-
mode_from_sid, &aclflag);
1343+
mode_from_sid, id_from_sid, &aclflag);
12951344

12961345
cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
12971346

fs/cifs/cifsacl.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,21 @@ struct smb3_acl {
176176
__le16 Sbz2; /* MBZ */
177177
} __packed;
178178

179+
/*
180+
* Used to store the special 'NFS SIDs' used to persist the POSIX uid and gid
181+
* See See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
182+
*/
183+
struct owner_sid {
184+
u8 Revision;
185+
u8 NumAuth;
186+
u8 Authority[6];
187+
__le32 SubAuthorities[3];
188+
} __packed;
189+
190+
struct owner_group_sids {
191+
struct owner_sid owner;
192+
struct owner_sid group;
193+
} __packed;
179194

180195
/*
181196
* Minimum security identifier can be one for system defined Users

fs/cifs/cifsfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
623623
seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ);
624624

625625
if (tcon->ses->chan_max > 1)
626-
seq_printf(s, ",multichannel,max_channel=%zu",
626+
seq_printf(s, ",multichannel,max_channels=%zu",
627627
tcon->ses->chan_max);
628628

629629
return 0;

fs/cifs/cifsglob.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2008,6 +2008,24 @@ extern struct smb_version_values smb302_values;
20082008
extern struct smb_version_operations smb311_operations;
20092009
extern struct smb_version_values smb311_values;
20102010

2011+
static inline char *get_security_type_str(enum securityEnum sectype)
2012+
{
2013+
switch (sectype) {
2014+
case RawNTLMSSP:
2015+
return "RawNTLMSSP";
2016+
case Kerberos:
2017+
return "Kerberos";
2018+
case NTLMv2:
2019+
return "NTLMv2";
2020+
case NTLM:
2021+
return "NTLM";
2022+
case LANMAN:
2023+
return "LANMAN";
2024+
default:
2025+
return "Unknown";
2026+
}
2027+
}
2028+
20112029
static inline bool is_smb1_server(struct TCP_Server_Info *server)
20122030
{
20132031
return strcmp(server->vals->version_string, SMB1_VERSION_STRING) == 0;

fs/cifs/cifsproto.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ extern struct inode *cifs_iget(struct super_block *sb,
198198
extern int cifs_get_inode_info(struct inode **inode, const char *full_path,
199199
FILE_ALL_INFO *data, struct super_block *sb,
200200
int xid, const struct cifs_fid *fid);
201+
extern int smb311_posix_get_inode_info(struct inode **pinode, const char *search_path,
202+
struct super_block *sb, unsigned int xid);
201203
extern int cifs_get_inode_info_unix(struct inode **pinode,
202204
const unsigned char *search_path,
203205
struct super_block *sb, unsigned int xid);
@@ -220,6 +222,7 @@ extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *,
220222
const char *, int);
221223
extern unsigned int setup_authusers_ACE(struct cifs_ace *pace);
222224
extern unsigned int setup_special_mode_ACE(struct cifs_ace *pace, __u64 nmode);
225+
extern unsigned int setup_special_user_owner_ACE(struct cifs_ace *pace);
223226

224227
extern void dequeue_mid(struct mid_q_entry *mid, bool malformed);
225228
extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,

fs/cifs/dir.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
411411
rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb,
412412
xid);
413413
else {
414+
/* TODO: Add support for calling POSIX query info here, but passing in fid */
414415
rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb,
415416
xid, fid);
416417
if (newinode) {
@@ -700,7 +701,9 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
700701
cifs_dbg(FYI, "Full path: %s inode = 0x%p\n",
701702
full_path, d_inode(direntry));
702703

703-
if (pTcon->unix_ext) {
704+
if (pTcon->posix_extensions)
705+
rc = smb311_posix_get_inode_info(&newInode, full_path, parent_dir_inode->i_sb, xid);
706+
else if (pTcon->unix_ext) {
704707
rc = cifs_get_inode_info_unix(&newInode, full_path,
705708
parent_dir_inode->i_sb, xid);
706709
} else {

fs/cifs/file.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
243243
if (rc)
244244
goto out;
245245

246+
/* TODO: Add support for calling posix query info but with passing in fid */
246247
if (tcon->unix_ext)
247248
rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb,
248249
xid);
@@ -800,7 +801,9 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
800801
if (!is_interrupt_error(rc))
801802
mapping_set_error(inode->i_mapping, rc);
802803

803-
if (tcon->unix_ext)
804+
if (tcon->posix_extensions)
805+
rc = smb311_posix_get_inode_info(&inode, full_path, inode->i_sb, xid);
806+
else if (tcon->unix_ext)
804807
rc = cifs_get_inode_info_unix(&inode, full_path,
805808
inode->i_sb, xid);
806809
else

fs/cifs/fscache.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
9696
{
9797
struct TCP_Server_Info *server = tcon->ses->server;
9898
char *sharename;
99+
struct cifs_fscache_super_auxdata auxdata;
99100

100101
sharename = extract_sharename(tcon->treeName);
101102
if (IS_ERR(sharename)) {
@@ -104,11 +105,16 @@ void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
104105
return;
105106
}
106107

108+
memset(&auxdata, 0, sizeof(auxdata));
109+
auxdata.resource_id = tcon->resource_id;
110+
auxdata.vol_create_time = tcon->vol_create_time;
111+
auxdata.vol_serial_number = tcon->vol_serial_number;
112+
107113
tcon->fscache =
108114
fscache_acquire_cookie(server->fscache,
109115
&cifs_fscache_super_index_def,
110116
sharename, strlen(sharename),
111-
&tcon->resource_id, sizeof(tcon->resource_id),
117+
&auxdata, sizeof(auxdata),
112118
tcon, 0, true);
113119
kfree(sharename);
114120
cifs_dbg(FYI, "%s: (0x%p/0x%p)\n",
@@ -117,8 +123,15 @@ void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
117123

118124
void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon)
119125
{
126+
struct cifs_fscache_super_auxdata auxdata;
127+
128+
memset(&auxdata, 0, sizeof(auxdata));
129+
auxdata.resource_id = tcon->resource_id;
130+
auxdata.vol_create_time = tcon->vol_create_time;
131+
auxdata.vol_serial_number = tcon->vol_serial_number;
132+
120133
cifs_dbg(FYI, "%s: (0x%p)\n", __func__, tcon->fscache);
121-
fscache_relinquish_cookie(tcon->fscache, &tcon->resource_id, false);
134+
fscache_relinquish_cookie(tcon->fscache, &auxdata, false);
122135
tcon->fscache = NULL;
123136
}
124137

fs/cifs/fscache.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@
2727

2828
#ifdef CONFIG_CIFS_FSCACHE
2929

30+
/*
31+
* Auxiliary data attached to CIFS superblock within the cache
32+
*/
33+
struct cifs_fscache_super_auxdata {
34+
u64 resource_id; /* unique server resource id */
35+
__le64 vol_create_time;
36+
u32 vol_serial_number;
37+
} __packed;
38+
3039
/*
3140
* Auxiliary data attached to CIFS inode within the cache
3241
*/

0 commit comments

Comments
 (0)