Commit 297647c2 authored by Steve French's avatar Steve French

[CIFS] CIFS ACL support part 3

Signed-off-by: default avatarShirish Pargaonkar <shirishp@us.ibm.com>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent a013689d
...@@ -6,7 +6,10 @@ which support the current POSIX Extensions to provide better semantics ...@@ -6,7 +6,10 @@ which support the current POSIX Extensions to provide better semantics
(e.g. delete for open files opened with posix open). Take into (e.g. delete for open files opened with posix open). Take into
account umask on posix mkdir not just older style mkdir. Add account umask on posix mkdir not just older style mkdir. Add
ability to mount to IPC$ share (which allows CIFS named pipes to be ability to mount to IPC$ share (which allows CIFS named pipes to be
opened, read and written as if they were files). opened, read and written as if they were files). When 1st tree
connect fails (e.g. due to signing negotiation failure) fix
leak that causes cifsd not to stop and rmmod to fail to cleanup
cifs_request_buffers pool.
Version 1.50 Version 1.50
------------ ------------
......
...@@ -28,6 +28,20 @@ ...@@ -28,6 +28,20 @@
#include "cifsproto.h" #include "cifsproto.h"
#include "cifs_debug.h" #include "cifs_debug.h"
#ifdef CONFIG_CIFS_EXPERIMENTAL
struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
{{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
{{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
{{1, 1, {0, 0, 0, 0, 0, 5}, {11, 0, 0, 0, 0} }, "net-users"},
{{1, 1, {0, 0, 0, 0, 0, 5}, {18, 0, 0, 0, 0} }, "sys"},
{{1, 2, {0, 0, 0, 0, 0, 5}, {32, 544, 0, 0, 0} }, "root"},
{{1, 2, {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0, 0} }, "users"},
{{1, 2, {0, 0, 0, 0, 0, 5}, {32, 546, 0, 0, 0} }, "guest"}
};
/* security id for everyone */ /* security id for everyone */
static const struct cifs_sid sid_everyone = static const struct cifs_sid sid_everyone =
{1, 1, {0, 0, 0, 0, 0, 0}, {} }; {1, 1, {0, 0, 0, 0, 0, 0}, {} };
...@@ -35,33 +49,113 @@ static const struct cifs_sid sid_everyone = ...@@ -35,33 +49,113 @@ static const struct cifs_sid sid_everyone =
static const struct cifs_sid sid_user = static const struct cifs_sid sid_user =
{1, 2 , {0, 0, 0, 0, 0, 5}, {} }; {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
int match_sid(struct cifs_sid *ctsid)
{
int i, j;
int num_subauth, num_sat, num_saw;
struct cifs_sid *cwsid;
if (!ctsid)
return (-1);
for (i = 0; i < NUM_WK_SIDS; ++i) {
cwsid = &(wksidarr[i].cifssid);
/* compare the revision */
if (ctsid->revision != cwsid->revision)
continue;
/* compare all of the six auth values */
for (j = 0; j < 6; ++j) {
if (ctsid->authority[j] != cwsid->authority[j])
break;
}
if (j < 6)
continue; /* all of the auth values did not match */
/* compare all of the subauth values if any */
num_sat = cpu_to_le32(ctsid->num_subauth);
num_saw = cpu_to_le32(cwsid->num_subauth);
num_subauth = num_sat < num_saw ? num_sat : num_saw;
if (num_subauth) {
for (j = 0; j < num_subauth; ++j) {
if (ctsid->sub_auth[j] != cwsid->sub_auth[j])
break;
}
if (j < num_subauth)
continue; /* all sub_auth values do not match */
}
cFYI(1, ("matching sid: %s\n", wksidarr[i].sidname));
return (0); /* sids compare/match */
}
cFYI(1, ("No matching sid"));
return (-1);
}
int compare_sids(struct cifs_sid *ctsid, struct cifs_sid *cwsid)
{
int i;
int num_subauth, num_sat, num_saw;
if ((!ctsid) || (!cwsid))
return (-1);
/* compare the revision */
if (ctsid->revision != cwsid->revision)
return (-1);
/* compare all of the six auth values */
for (i = 0; i < 6; ++i) {
if (ctsid->authority[i] != cwsid->authority[i])
return (-1);
}
/* compare all of the subauth values if any */
num_sat = cpu_to_le32(ctsid->num_subauth);
num_saw = cpu_to_le32(cwsid->num_subauth);
num_subauth = num_sat < num_saw ? num_sat : num_saw;
if (num_subauth) {
for (i = 0; i < num_subauth; ++i) {
if (ctsid->sub_auth[i] != cwsid->sub_auth[i])
return (-1);
}
}
return (0); /* sids compare/match */
}
static void parse_ace(struct cifs_ace *pace, char *end_of_acl) static void parse_ace(struct cifs_ace *pace, char *end_of_acl)
{ {
int i; int i;
int num_subauth; int num_subauth;
__u32 *psub_auth;
/* validate that we do not go past end of acl */ /* validate that we do not go past end of acl */
/* XXX this if statement can be removed
if (end_of_acl < (char *)pace + sizeof(struct cifs_ace)) { if (end_of_acl < (char *)pace + sizeof(struct cifs_ace)) {
cERROR(1, ("ACL too small to parse ACE")); cERROR(1, ("ACL too small to parse ACE"));
return; return;
} } */
num_subauth = cpu_to_le32(pace->num_subauth); num_subauth = cpu_to_le32(pace->num_subauth);
if (num_subauth) { if (num_subauth) {
psub_auth = (__u32 *)((char *)pace + sizeof(struct cifs_ace));
#ifdef CONFIG_CIFS_DEBUG2 #ifdef CONFIG_CIFS_DEBUG2
cFYI(1, ("ACE revision %d num_subauth %d", cFYI(1, ("ACE revision %d num_subauth %d",
pace->revision, pace->num_subauth)); pace->revision, pace->num_subauth));
for (i = 0; i < num_subauth; ++i) { for (i = 0; i < num_subauth; ++i) {
cFYI(1, ("ACE sub_auth[%d]: 0x%x", i, cFYI(1, ("ACE sub_auth[%d]: 0x%x", i,
le32_to_cpu(psub_auth[i]))); le32_to_cpu(pace->sub_auth[i])));
} }
/* BB add length check to make sure that we do not have huge /* BB add length check to make sure that we do not have huge
num auths and therefore go off the end */ num auths and therefore go off the end */
cFYI(1, ("RID %d", le32_to_cpu(psub_auth[num_subauth-1]))); cFYI(1, ("RID %d", le32_to_cpu(pace->sub_auth[num_subauth-1])));
#endif #endif
} }
...@@ -132,6 +226,12 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl) ...@@ -132,6 +226,12 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl)
sizeof(struct cifs_ntace)); sizeof(struct cifs_ntace));
parse_ntace(ppntace[i], end_of_acl); parse_ntace(ppntace[i], end_of_acl);
if (end_of_acl < ((char *)ppace[i] +
(ppntace[i]->size -
sizeof(struct cifs_ntace)))) {
cERROR(1, ("ACL too small to parse ACE"));
break;
} else
parse_ace(ppace[i], end_of_acl); parse_ace(ppace[i], end_of_acl);
/* memcpy((void *)(&(cifscred->ntaces[i])), /* memcpy((void *)(&(cifscred->ntaces[i])),
...@@ -157,7 +257,6 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl) ...@@ -157,7 +257,6 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
{ {
int i; int i;
int num_subauth; int num_subauth;
__u32 *psub_auth;
/* BB need to add parm so we can store the SID BB */ /* BB need to add parm so we can store the SID BB */
...@@ -169,20 +268,19 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl) ...@@ -169,20 +268,19 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
num_subauth = cpu_to_le32(psid->num_subauth); num_subauth = cpu_to_le32(psid->num_subauth);
if (num_subauth) { if (num_subauth) {
psub_auth = (__u32 *)((char *)psid + sizeof(struct cifs_sid));
#ifdef CONFIG_CIFS_DEBUG2 #ifdef CONFIG_CIFS_DEBUG2
cFYI(1, ("SID revision %d num_auth %d First subauth 0x%x", cFYI(1, ("SID revision %d num_auth %d First subauth 0x%x",
psid->revision, psid->num_subauth, psid->sub_auth[0])); psid->revision, psid->num_subauth, psid->sub_auth[0]));
for (i = 0; i < num_subauth; ++i) { for (i = 0; i < num_subauth; ++i) {
cFYI(1, ("SID sub_auth[%d]: 0x%x ", i, cFYI(1, ("SID sub_auth[%d]: 0x%x ", i,
le32_to_cpu(psub_auth[i]))); le32_to_cpu(psid->sub_auth[i])));
} }
/* BB add length check to make sure that we do not have huge /* BB add length check to make sure that we do not have huge
num auths and therefore go off the end */ num auths and therefore go off the end */
cFYI(1, ("RID 0x%x", cFYI(1, ("RID 0x%x",
le32_to_cpu(psid->sub_auth[psid->num_subauth]))); le32_to_cpu(psid->sub_auth[num_subauth-1])));
#endif #endif
} }
...@@ -228,5 +326,7 @@ int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len) ...@@ -228,5 +326,7 @@ int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len)
memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr,
sizeof (struct cifs_sid)); */ sizeof (struct cifs_sid)); */
return (0); return (0);
} }
#endif /* CONFIG_CIFS_EXPERIMENTAL */
...@@ -22,6 +22,10 @@ ...@@ -22,6 +22,10 @@
#ifndef _CIFSACL_H #ifndef _CIFSACL_H
#define _CIFSACL_H #define _CIFSACL_H
#define NUM_WK_SIDS 7 /* number of well known sids */
#define SIDNAMELENGTH 20 /* long enough for the ones we care about */
struct cifs_ntsd { struct cifs_ntsd {
__u16 revision; /* revision level */ __u16 revision; /* revision level */
__u16 type; __u16 type;
...@@ -35,7 +39,7 @@ struct cifs_sid { ...@@ -35,7 +39,7 @@ struct cifs_sid {
__u8 revision; /* revision level */ __u8 revision; /* revision level */
__u8 num_subauth; __u8 num_subauth;
__u8 authority[6]; __u8 authority[6];
__u32 sub_auth[0]; /* sub_auth[num_subauth] */ __u32 sub_auth[5]; /* sub_auth[num_subauth] */
} __attribute__((packed)); } __attribute__((packed));
struct cifs_acl { struct cifs_acl {
...@@ -55,12 +59,20 @@ struct cifs_ace { /* last part of ACE which includes user info */ ...@@ -55,12 +59,20 @@ struct cifs_ace { /* last part of ACE which includes user info */
__u8 revision; /* revision level */ __u8 revision; /* revision level */
__u8 num_subauth; __u8 num_subauth;
__u8 authority[6]; __u8 authority[6];
__u32 sub_auth[0]; __u32 sub_auth[5];
} __attribute__((packed));
struct cifs_wksid {
struct cifs_sid cifssid;
char sidname[SIDNAMELENGTH];
} __attribute__((packed)); } __attribute__((packed));
/* everyone */ #ifdef CONFIG_CIFS_EXPERIMENTAL
/* extern const struct cifs_sid sid_everyone;*/
/* group users */ extern struct cifs_wksid wksidarr[NUM_WK_SIDS];
/* extern const struct cifs_sid sid_user;*/ extern int match_sid(struct cifs_sid *);
extern int compare_sids(struct cifs_sid *, struct cifs_sid *);
#endif /* CONFIG_CIFS_EXPERIMENTAL */
#endif /* _CIFSACL_H */ #endif /* _CIFSACL_H */
...@@ -49,10 +49,6 @@ ...@@ -49,10 +49,6 @@
static struct quotactl_ops cifs_quotactl_ops; static struct quotactl_ops cifs_quotactl_ops;
#endif /* QUOTA */ #endif /* QUOTA */
#ifdef CONFIG_CIFS_EXPERIMENTAL
extern struct export_operations cifs_export_ops;
#endif /* EXPERIMENTAL */
int cifsFYI = 0; int cifsFYI = 0;
int cifsERROR = 1; int cifsERROR = 1;
int traceSMB = 0; int traceSMB = 0;
......
/* /*
* fs/cifs/cifsfs.h * fs/cifs/cifsfs.h
* *
* Copyright (c) International Business Machines Corp., 2002, 2005 * Copyright (c) International Business Machines Corp., 2002, 2007
* Author(s): Steve French (sfrench@us.ibm.com) * Author(s): Steve French (sfrench@us.ibm.com)
* *
* This library is free software; you can redistribute it and/or modify * This library is free software; you can redistribute it and/or modify
...@@ -101,5 +101,10 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); ...@@ -101,5 +101,10 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
extern int cifs_ioctl(struct inode *inode, struct file *filep, extern int cifs_ioctl(struct inode *inode, struct file *filep,
unsigned int command, unsigned long arg); unsigned int command, unsigned long arg);
#ifdef CONFIG_CIFS_EXPERIMENTAL
extern struct export_operations cifs_export_ops;
#endif /* EXPERIMENTAL */
#define CIFS_VERSION "1.51" #define CIFS_VERSION "1.51"
#endif /* _CIFSFS_H */ #endif /* _CIFSFS_H */
...@@ -3058,6 +3058,7 @@ CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, ...@@ -3058,6 +3058,7 @@ CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
#endif /* CONFIG_POSIX */ #endif /* CONFIG_POSIX */
#ifdef CONFIG_CIFS_EXPERIMENTAL
/* Get Security Descriptor (by handle) from remote server for a file or dir */ /* Get Security Descriptor (by handle) from remote server for a file or dir */
int int
CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
...@@ -3129,6 +3130,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, ...@@ -3129,6 +3130,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
return rc; return rc;
} }
#endif /* CONFIG_CIFS_EXPERIMENTAL */
/* Legacy Query Path Information call for lookup to old servers such /* Legacy Query Path Information call for lookup to old servers such
as Win9x/WinME */ as Win9x/WinME */
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <linux/exportfs.h> #include <linux/exportfs.h>
#include "cifsglob.h" #include "cifsglob.h"
#include "cifs_debug.h" #include "cifs_debug.h"
#include "cifsfs.h"
#ifdef CONFIG_CIFS_EXPERIMENTAL #ifdef CONFIG_CIFS_EXPERIMENTAL
static struct dentry *cifs_get_parent(struct dentry *dentry) static struct dentry *cifs_get_parent(struct dentry *dentry)
......
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