Skip to content

Commit cabb468

Browse files
committed
Merge tag 'v6.14-rc-smb3-client-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6
Pull more smb client updates from Steve French: - various updates for special file handling: symlink handling, support for creating sockets, cleanups, new mount options (e.g. to allow disabling using reparse points for them, and to allow overriding the way symlinks are saved), and fixes to error paths - fix for kerberos mounts (allow IAKerb) - SMB1 fix for stat and for setting SACL (auditing) - fix an incorrect error code mapping - cleanups" * tag 'v6.14-rc-smb3-client-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6: (21 commits) cifs: Fix parsing native symlinks directory/file type cifs: update internal version number cifs: Add support for creating WSL-style symlinks smb3: add support for IAKerb cifs: Fix struct FILE_ALL_INFO cifs: Add support for creating NFS-style symlinks cifs: Add support for creating native Windows sockets cifs: Add mount option -o reparse=none cifs: Add mount option -o symlink= for choosing symlink create type cifs: Fix creating and resolving absolute NT-style symlinks cifs: Simplify reparse point check in cifs_query_path_info() function cifs: Remove symlink member from cifs_open_info_data union cifs: Update description about ACL permissions cifs: Rename struct reparse_posix_data to reparse_nfs_data_buffer and move to common/smb2pdu.h cifs: Remove struct reparse_posix_data from struct cifs_open_info_data cifs: Remove unicode parameter from parse_reparse_point() function cifs: Fix getting and setting SACLs over SMB1 cifs: Remove intermediate object of failed create SFU call cifs: Validate EAs for WSL reparse points cifs: Change translation of STATUS_PRIVILEGE_NOT_HELD to -EPERM ...
2 parents 8c198ff + a49da4e commit cabb468

28 files changed

+884
-192
lines changed

fs/smb/client/asn1.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ int cifs_neg_token_init_mech_type(void *context, size_t hdrlen,
5252
server->sec_kerberos = true;
5353
else if (oid == OID_ntlmssp)
5454
server->sec_ntlmssp = true;
55+
else if (oid == OID_IAKerb)
56+
server->sec_iakerb = true;
5557
else {
5658
char buf[50];
5759

fs/smb/client/cifs_spnego.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,13 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo,
138138

139139
dp = description + strlen(description);
140140

141-
/* for now, only sec=krb5 and sec=mskrb5 are valid */
141+
/* for now, only sec=krb5 and sec=mskrb5 and iakerb are valid */
142142
if (server->sec_kerberos)
143143
sprintf(dp, ";sec=krb5");
144144
else if (server->sec_mskerberos)
145145
sprintf(dp, ";sec=mskrb5");
146+
else if (server->sec_iakerb)
147+
sprintf(dp, ";sec=iakerb");
146148
else {
147149
cifs_dbg(VFS, "unknown or missing server auth type, use krb5\n");
148150
sprintf(dp, ";sec=krb5");

fs/smb/client/cifsacl.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,7 +1395,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
13951395
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
13961396
struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
13971397
const struct cifs_fid *cifsfid, u32 *pacllen,
1398-
u32 __maybe_unused unused)
1398+
u32 info)
13991399
{
14001400
struct smb_ntsd *pntsd = NULL;
14011401
unsigned int xid;
@@ -1407,7 +1407,7 @@ struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
14071407

14081408
xid = get_xid();
14091409
rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd,
1410-
pacllen);
1410+
pacllen, info);
14111411
free_xid(xid);
14121412

14131413
cifs_put_tlink(tlink);
@@ -1419,7 +1419,7 @@ struct smb_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
14191419
}
14201420

14211421
static struct smb_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1422-
const char *path, u32 *pacllen)
1422+
const char *path, u32 *pacllen, u32 info)
14231423
{
14241424
struct smb_ntsd *pntsd = NULL;
14251425
int oplock = 0;
@@ -1446,9 +1446,12 @@ static struct smb_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
14461446
.fid = &fid,
14471447
};
14481448

1449+
if (info & SACL_SECINFO)
1450+
oparms.desired_access |= SYSTEM_SECURITY;
1451+
14491452
rc = CIFS_open(xid, &oparms, &oplock, NULL);
14501453
if (!rc) {
1451-
rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen);
1454+
rc = CIFSSMBGetCIFSACL(xid, tcon, fid.netfid, &pntsd, pacllen, info);
14521455
CIFSSMBClose(xid, tcon, fid.netfid);
14531456
}
14541457

@@ -1472,7 +1475,7 @@ struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
14721475
if (inode)
14731476
open_file = find_readable_file(CIFS_I(inode), true);
14741477
if (!open_file)
1475-
return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1478+
return get_cifs_acl_by_path(cifs_sb, path, pacllen, info);
14761479

14771480
pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen, info);
14781481
cifsFileInfo_put(open_file);
@@ -1485,7 +1488,7 @@ int set_cifs_acl(struct smb_ntsd *pnntsd, __u32 acllen,
14851488
{
14861489
int oplock = 0;
14871490
unsigned int xid;
1488-
int rc, access_flags;
1491+
int rc, access_flags = 0;
14891492
struct cifs_tcon *tcon;
14901493
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
14911494
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
@@ -1498,10 +1501,12 @@ int set_cifs_acl(struct smb_ntsd *pnntsd, __u32 acllen,
14981501
tcon = tlink_tcon(tlink);
14991502
xid = get_xid();
15001503

1501-
if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1502-
access_flags = WRITE_OWNER;
1503-
else
1504-
access_flags = WRITE_DAC;
1504+
if (aclflag & CIFS_ACL_OWNER || aclflag & CIFS_ACL_GROUP)
1505+
access_flags |= WRITE_OWNER;
1506+
if (aclflag & CIFS_ACL_SACL)
1507+
access_flags |= SYSTEM_SECURITY;
1508+
if (aclflag & CIFS_ACL_DACL)
1509+
access_flags |= WRITE_DAC;
15051510

15061511
oparms = (struct cifs_open_parms) {
15071512
.tcon = tcon,

fs/smb/client/cifsfs.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,12 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
715715
cifs_sb->ctx->backupgid));
716716
seq_show_option(s, "reparse",
717717
cifs_reparse_type_str(cifs_sb->ctx->reparse_type));
718+
if (cifs_sb->ctx->nonativesocket)
719+
seq_puts(s, ",nonativesocket");
720+
else
721+
seq_puts(s, ",nativesocket");
722+
seq_show_option(s, "symlink",
723+
cifs_symlink_type_str(get_cifs_symlink_type(cifs_sb)));
718724

719725
seq_printf(s, ",rsize=%u", cifs_sb->ctx->rsize);
720726
seq_printf(s, ",wsize=%u", cifs_sb->ctx->wsize);

fs/smb/client/cifsfs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,6 @@ extern const struct export_operations cifs_export_ops;
146146
#endif /* CONFIG_CIFS_NFSD_EXPORT */
147147

148148
/* when changing internal version - update following two lines at same time */
149-
#define SMB3_PRODUCT_BUILD 52
150-
#define CIFS_VERSION "2.52"
149+
#define SMB3_PRODUCT_BUILD 53
150+
#define CIFS_VERSION "2.53"
151151
#endif /* _CIFSFS_H */

fs/smb/client/cifsglob.h

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ enum securityEnum {
151151
NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */
152152
RawNTLMSSP, /* NTLMSSP without SPNEGO, NTLMv2 hash */
153153
Kerberos, /* Kerberos via SPNEGO */
154+
IAKerb, /* Kerberos proxy */
154155
};
155156

156157
enum upcall_target_enum {
@@ -160,6 +161,7 @@ enum upcall_target_enum {
160161
};
161162

162163
enum cifs_reparse_type {
164+
CIFS_REPARSE_TYPE_NONE,
163165
CIFS_REPARSE_TYPE_NFS,
164166
CIFS_REPARSE_TYPE_WSL,
165167
CIFS_REPARSE_TYPE_DEFAULT = CIFS_REPARSE_TYPE_NFS,
@@ -168,6 +170,8 @@ enum cifs_reparse_type {
168170
static inline const char *cifs_reparse_type_str(enum cifs_reparse_type type)
169171
{
170172
switch (type) {
173+
case CIFS_REPARSE_TYPE_NONE:
174+
return "none";
171175
case CIFS_REPARSE_TYPE_NFS:
172176
return "nfs";
173177
case CIFS_REPARSE_TYPE_WSL:
@@ -177,6 +181,39 @@ static inline const char *cifs_reparse_type_str(enum cifs_reparse_type type)
177181
}
178182
}
179183

184+
enum cifs_symlink_type {
185+
CIFS_SYMLINK_TYPE_DEFAULT,
186+
CIFS_SYMLINK_TYPE_NONE,
187+
CIFS_SYMLINK_TYPE_NATIVE,
188+
CIFS_SYMLINK_TYPE_UNIX,
189+
CIFS_SYMLINK_TYPE_MFSYMLINKS,
190+
CIFS_SYMLINK_TYPE_SFU,
191+
CIFS_SYMLINK_TYPE_NFS,
192+
CIFS_SYMLINK_TYPE_WSL,
193+
};
194+
195+
static inline const char *cifs_symlink_type_str(enum cifs_symlink_type type)
196+
{
197+
switch (type) {
198+
case CIFS_SYMLINK_TYPE_NONE:
199+
return "none";
200+
case CIFS_SYMLINK_TYPE_NATIVE:
201+
return "native";
202+
case CIFS_SYMLINK_TYPE_UNIX:
203+
return "unix";
204+
case CIFS_SYMLINK_TYPE_MFSYMLINKS:
205+
return "mfsymlinks";
206+
case CIFS_SYMLINK_TYPE_SFU:
207+
return "sfu";
208+
case CIFS_SYMLINK_TYPE_NFS:
209+
return "nfs";
210+
case CIFS_SYMLINK_TYPE_WSL:
211+
return "wsl";
212+
default:
213+
return "unknown";
214+
}
215+
}
216+
180217
struct session_key {
181218
unsigned int len;
182219
char *response;
@@ -215,21 +252,15 @@ struct cifs_cred {
215252

216253
struct cifs_open_info_data {
217254
bool adjust_tz;
218-
union {
219-
bool reparse_point;
220-
bool symlink;
221-
};
255+
bool reparse_point;
222256
struct {
223257
/* ioctl response buffer */
224258
struct {
225259
int buftype;
226260
struct kvec iov;
227261
} io;
228262
__u32 tag;
229-
union {
230-
struct reparse_data_buffer *buf;
231-
struct reparse_posix_data *posix;
232-
};
263+
struct reparse_data_buffer *buf;
233264
} reparse;
234265
struct {
235266
__u8 eas[SMB2_WSL_MAX_QUERY_EA_RESP_SIZE];
@@ -751,6 +782,7 @@ struct TCP_Server_Info {
751782
bool sec_kerberosu2u; /* supports U2U Kerberos */
752783
bool sec_kerberos; /* supports plain Kerberos */
753784
bool sec_mskerberos; /* supports legacy MS Kerberos */
785+
bool sec_iakerb; /* supports pass-through auth for Kerberos (krb5 proxy) */
754786
bool large_buf; /* is current buffer large? */
755787
/* use SMBD connection instead of socket */
756788
bool rdma;
@@ -2118,6 +2150,8 @@ static inline char *get_security_type_str(enum securityEnum sectype)
21182150
return "Kerberos";
21192151
case NTLMv2:
21202152
return "NTLMv2";
2153+
case IAKerb:
2154+
return "IAKerb";
21212155
default:
21222156
return "Unknown";
21232157
}
@@ -2173,11 +2207,13 @@ static inline size_t ntlmssp_workstation_name_size(const struct cifs_ses *ses)
21732207

21742208
static inline void move_cifs_info_to_smb2(struct smb2_file_all_info *dst, const FILE_ALL_INFO *src)
21752209
{
2176-
memcpy(dst, src, (size_t)((u8 *)&src->AccessFlags - (u8 *)src));
2177-
dst->AccessFlags = src->AccessFlags;
2178-
dst->CurrentByteOffset = src->CurrentByteOffset;
2179-
dst->Mode = src->Mode;
2180-
dst->AlignmentRequirement = src->AlignmentRequirement;
2210+
memcpy(dst, src, (size_t)((u8 *)&src->EASize - (u8 *)src));
2211+
dst->IndexNumber = 0;
2212+
dst->EASize = src->EASize;
2213+
dst->AccessFlags = 0;
2214+
dst->CurrentByteOffset = 0;
2215+
dst->Mode = 0;
2216+
dst->AlignmentRequirement = 0;
21812217
dst->FileNameLength = src->FileNameLength;
21822218
}
21832219

fs/smb/client/cifspdu.h

Lines changed: 61 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -190,42 +190,82 @@
190190
*/
191191

192192
#define FILE_READ_DATA 0x00000001 /* Data can be read from the file */
193+
/* or directory child entries can */
194+
/* be listed together with the */
195+
/* associated child attributes */
196+
/* (so the FILE_READ_ATTRIBUTES on */
197+
/* the child entry is not needed) */
193198
#define FILE_WRITE_DATA 0x00000002 /* Data can be written to the file */
199+
/* or new file can be created in */
200+
/* the directory */
194201
#define FILE_APPEND_DATA 0x00000004 /* Data can be appended to the file */
202+
/* (for non-local files over SMB it */
203+
/* is same as FILE_WRITE_DATA) */
204+
/* or new subdirectory can be */
205+
/* created in the directory */
195206
#define FILE_READ_EA 0x00000008 /* Extended attributes associated */
196207
/* with the file can be read */
197208
#define FILE_WRITE_EA 0x00000010 /* Extended attributes associated */
198209
/* with the file can be written */
199210
#define FILE_EXECUTE 0x00000020 /*Data can be read into memory from */
200211
/* the file using system paging I/O */
201-
#define FILE_DELETE_CHILD 0x00000040
212+
/* for executing the file / script */
213+
/* or right to traverse directory */
214+
/* (but by default all users have */
215+
/* directory bypass traverse */
216+
/* privilege and do not need this */
217+
/* permission on directories at all)*/
218+
#define FILE_DELETE_CHILD 0x00000040 /* Child entry can be deleted from */
219+
/* the directory (so the DELETE on */
220+
/* the child entry is not needed) */
202221
#define FILE_READ_ATTRIBUTES 0x00000080 /* Attributes associated with the */
203-
/* file can be read */
222+
/* file or directory can be read */
204223
#define FILE_WRITE_ATTRIBUTES 0x00000100 /* Attributes associated with the */
205-
/* file can be written */
206-
#define DELETE 0x00010000 /* The file can be deleted */
207-
#define READ_CONTROL 0x00020000 /* The access control list and */
208-
/* ownership associated with the */
209-
/* file can be read */
210-
#define WRITE_DAC 0x00040000 /* The access control list and */
211-
/* ownership associated with the */
212-
/* file can be written. */
224+
/* file or directory can be written */
225+
#define DELETE 0x00010000 /* The file or dir can be deleted */
226+
#define READ_CONTROL 0x00020000 /* The discretionary access control */
227+
/* list and ownership associated */
228+
/* with the file or dir can be read */
229+
#define WRITE_DAC 0x00040000 /* The discretionary access control */
230+
/* list associated with the file or */
231+
/* directory can be written */
213232
#define WRITE_OWNER 0x00080000 /* Ownership information associated */
214-
/* with the file can be written */
233+
/* with the file/dir can be written */
215234
#define SYNCHRONIZE 0x00100000 /* The file handle can waited on to */
216235
/* synchronize with the completion */
217236
/* of an input/output request */
218237
#define SYSTEM_SECURITY 0x01000000 /* The system access control list */
219-
/* can be read and changed */
220-
#define GENERIC_ALL 0x10000000
221-
#define GENERIC_EXECUTE 0x20000000
222-
#define GENERIC_WRITE 0x40000000
223-
#define GENERIC_READ 0x80000000
224-
/* In summary - Relevant file */
225-
/* access flags from CIFS are */
226-
/* file_read_data, file_write_data */
227-
/* file_execute, file_read_attributes*/
228-
/* write_dac, and delete. */
238+
/* associated with the file or */
239+
/* directory can be read or written */
240+
/* (cannot be in DACL, can in SACL) */
241+
#define MAXIMUM_ALLOWED 0x02000000 /* Maximal subset of GENERIC_ALL */
242+
/* permissions which can be granted */
243+
/* (cannot be in DACL nor SACL) */
244+
#define GENERIC_ALL 0x10000000 /* Same as: GENERIC_EXECUTE | */
245+
/* GENERIC_WRITE | */
246+
/* GENERIC_READ | */
247+
/* FILE_DELETE_CHILD | */
248+
/* DELETE | */
249+
/* WRITE_DAC | */
250+
/* WRITE_OWNER */
251+
/* So GENERIC_ALL contains all bits */
252+
/* mentioned above except these two */
253+
/* SYSTEM_SECURITY MAXIMUM_ALLOWED */
254+
#define GENERIC_EXECUTE 0x20000000 /* Same as: FILE_EXECUTE | */
255+
/* FILE_READ_ATTRIBUTES | */
256+
/* READ_CONTROL | */
257+
/* SYNCHRONIZE */
258+
#define GENERIC_WRITE 0x40000000 /* Same as: FILE_WRITE_DATA | */
259+
/* FILE_APPEND_DATA | */
260+
/* FILE_WRITE_EA | */
261+
/* FILE_WRITE_ATTRIBUTES | */
262+
/* READ_CONTROL | */
263+
/* SYNCHRONIZE */
264+
#define GENERIC_READ 0x80000000 /* Same as: FILE_READ_DATA | */
265+
/* FILE_READ_EA | */
266+
/* FILE_READ_ATTRIBUTES | */
267+
/* READ_CONTROL | */
268+
/* SYNCHRONIZE */
229269

230270
#define FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES)
231271
#define FILE_WRITE_RIGHTS (FILE_WRITE_DATA | FILE_APPEND_DATA \
@@ -1484,20 +1524,6 @@ struct file_notify_information {
14841524
__u8 FileName[];
14851525
} __attribute__((packed));
14861526

1487-
/* For IO_REPARSE_TAG_NFS */
1488-
#define NFS_SPECFILE_LNK 0x00000000014B4E4C
1489-
#define NFS_SPECFILE_CHR 0x0000000000524843
1490-
#define NFS_SPECFILE_BLK 0x00000000004B4C42
1491-
#define NFS_SPECFILE_FIFO 0x000000004F464946
1492-
#define NFS_SPECFILE_SOCK 0x000000004B434F53
1493-
struct reparse_posix_data {
1494-
__le32 ReparseTag;
1495-
__le16 ReparseDataLength;
1496-
__u16 Reserved;
1497-
__le64 InodeType; /* LNK, FIFO, CHR etc. */
1498-
__u8 DataBuffer[];
1499-
} __attribute__((packed));
1500-
15011527
struct cifs_quota_data {
15021528
__u32 rsrvd1; /* 0 */
15031529
__u32 sid_size;
@@ -2264,13 +2290,7 @@ typedef struct { /* data block encoding of response to level 263 QPathInfo */
22642290
__u8 DeletePending;
22652291
__u8 Directory;
22662292
__u16 Pad2;
2267-
__le64 IndexNumber;
22682293
__le32 EASize;
2269-
__le32 AccessFlags;
2270-
__u64 IndexNumber1;
2271-
__le64 CurrentByteOffset;
2272-
__le32 Mode;
2273-
__le32 AlignmentRequirement;
22742294
__le32 FileNameLength;
22752295
union {
22762296
char __pad;

0 commit comments

Comments
 (0)