aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShirish Pargaonkar <shirishp@us.ibm.com>2007-10-03 14:22:19 -0400
committerSteve French <sfrench@us.ibm.com>2007-10-03 14:22:19 -0400
commitd0d66c443aefa51d5dbdd6a1d9b135a2a0e469cc (patch)
treee30ee8cac1bef527cbf9610a82c493e0002fd9c1
parenta8a11d399fc3c70f2aa645c7472235a06e8b8efa (diff)
[CIFS] CIFS ACL support (part 2)
Signed-off-by: Shirish Pargaonkar <shirishp@us.ibm.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
-rw-r--r--fs/cifs/cifsacl.c203
-rw-r--r--fs/cifs/cifsacl.h4
-rw-r--r--fs/cifs/cifsproto.h2
-rw-r--r--fs/cifs/cifssmb.c2
4 files changed, 151 insertions, 60 deletions
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 9b84f373af19..23bff0128e2a 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -24,48 +24,178 @@
24#include <linux/fs.h> 24#include <linux/fs.h>
25#include "cifspdu.h" 25#include "cifspdu.h"
26#include "cifsglob.h" 26#include "cifsglob.h"
27#include "cifsacl.h"
27#include "cifsproto.h" 28#include "cifsproto.h"
28#include "cifs_debug.h" 29#include "cifs_debug.h"
29#include "cifsacl.h"
30 30
31/* security id for everyone */ 31/* security id for everyone */
32static const struct cifs_sid sid_everyone = 32static const struct cifs_sid sid_everyone =
33 {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}}; 33 {1, 1, {0, 0, 0, 0, 0, 0}, {}};
34/* group users */ 34/* group users */
35static const struct cifs_sid sid_user = 35static const struct cifs_sid sid_user =
36 {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; 36 {1, 2 , {0, 0, 0, 0, 0, 5}, {}};
37
38static void parse_ace(struct cifs_ace * pace, char * end_of_acl)
39{
40 int i;
41 int num_subauth;
42 __u32 *psub_auth;
43
44 /* validate that we do not go past end of acl */
45 if (end_of_acl < (char *)pace + sizeof(struct cifs_ace)) {
46 cERROR(1, ("ACL too small to parse ACE"));
47 return;
48 }
49
50 num_subauth = cpu_to_le32(pace->num_subauth);
51 if (num_subauth) {
52 psub_auth = (__u32 *)((char *)pace + sizeof(struct cifs_ace));
53#ifdef CONFIG_CIFS_DEBUG2
54 cFYI(1, ("ACE revision %d num_subauth %d",
55 pace->revision, pace->num_subauth));
56 for (i = 0; i < num_subauth; ++i) {
57 cFYI(1, ("ACE sub_auth[%d]: 0x%x", i,
58 le32_to_cpu(psub_auth[i])));
59 }
60
61 /* BB add length check to make sure that we do not have huge
62 num auths and therefore go off the end */
63
64 cFYI(1, ("RID %d", le32_to_cpu(psub_auth[num_subauth-1])));
65#endif
66 }
67
68 return;
69}
70
71static void parse_ntace(struct cifs_ntace * pntace, char * end_of_acl)
72{
73 /* validate that we do not go past end of acl */
74 if (end_of_acl < (char *)pntace + sizeof(struct cifs_ntace)) {
75 cERROR(1, ("ACL too small to parse NT ACE"));
76 return;
77 }
78
79#ifdef CONFIG_CIFS_DEBUG2
80 cFYI(1, ("NTACE type %d flags 0x%x size %d, access Req 0x%x",
81 pntace->type, pntace->flags, pntace->size,
82 pntace->access_req));
83#endif
84 return;
85}
86
87
88
89static void parse_dacl(struct cifs_acl * pdacl, char * end_of_acl)
90{
91 int i;
92 int num_aces = 0;
93 int acl_size;
94 char *acl_base;
95 struct cifs_ntace **ppntace;
96 struct cifs_ace **ppace;
97
98 /* BB need to add parm so we can store the SID BB */
99
100 /* validate that we do not go past end of acl */
101 if (end_of_acl < (char *)pdacl + pdacl->size) {
102 cERROR(1, ("ACL too small to parse DACL"));
103 return;
104 }
105
106#ifdef CONFIG_CIFS_DEBUG2
107 cFYI(1, ("DACL revision %d size %d num aces %d",
108 pdacl->revision, pdacl->size, pdacl->num_aces));
109#endif
110
111 acl_base = (char *)pdacl;
112 acl_size = sizeof(struct cifs_acl);
113
114 num_aces = cpu_to_le32(pdacl->num_aces);
115 if (num_aces > 0) {
116 ppntace = kmalloc(num_aces * sizeof(struct cifs_ntace *),
117 GFP_KERNEL);
118 ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
119 GFP_KERNEL);
120
121/* cifscred->cecount = pdacl->num_aces;
122 cifscred->ntaces = kmalloc(num_aces *
123 sizeof(struct cifs_ntace *), GFP_KERNEL);
124 cifscred->aces = kmalloc(num_aces *
125 sizeof(struct cifs_ace *), GFP_KERNEL);*/
126
127
128 for (i = 0; i < num_aces; ++i) {
129 ppntace[i] = (struct cifs_ntace *)
130 (acl_base + acl_size);
131 ppace[i] = (struct cifs_ace *) ((char *)ppntace[i] +
132 sizeof(struct cifs_ntace));
133
134 parse_ntace(ppntace[i], end_of_acl);
135 parse_ace(ppace[i], end_of_acl);
136
137/* memcpy((void *)(&(cifscred->ntaces[i])),
138 (void *)ppntace[i],
139 sizeof(struct cifs_ntace));
140 memcpy((void *)(&(cifscred->aces[i])),
141 (void *)ppace[i],
142 sizeof(struct cifs_ace)); */
143
144 acl_base = (char *)ppntace[i];
145 acl_size = cpu_to_le32(ppntace[i]->size);
146 }
147
148 kfree(ppace);
149 kfree(ppntace);
150 }
151
152 return;
153}
154
37 155
38static int parse_sid(struct cifs_sid *psid, char *end_of_acl) 156static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
39{ 157{
158 int i;
159 int num_subauth;
160 __u32 *psub_auth;
161
40 /* BB need to add parm so we can store the SID BB */ 162 /* BB need to add parm so we can store the SID BB */
41 163
42 /* validate that we do not go past end of acl */ 164 /* validate that we do not go past end of acl */
43 if (end_of_acl < (char *)psid + sizeof(struct cifs_sid)) { 165 if (end_of_acl < (char *)psid + sizeof(struct cifs_sid)) {
44 cERROR(1, ("ACL to small to parse SID")); 166 cERROR(1, ("ACL too small to parse SID"));
45 return -EINVAL; 167 return -EINVAL;
46 } 168 }
169
170 num_subauth = cpu_to_le32(psid->num_subauth);
171 if (num_subauth) {
172 psub_auth = (__u32 *)((char *)psid + sizeof(struct cifs_sid));
47#ifdef CONFIG_CIFS_DEBUG2 173#ifdef CONFIG_CIFS_DEBUG2
48 cFYI(1, ("revision %d num_auth %d First subauth 0x%x", 174 cFYI(1, ("SID revision %d num_auth %d First subauth 0x%x",
49 psid->revision, psid->num_subauth, psid->sub_auth[0])); 175 psid->revision, psid->num_subauth, psid->sub_auth[0]));
50 176
51 /* BB add length check to make sure that we do not have huge num auths 177 for (i = 0; i < num_subauth; ++i) {
52 and therefore go off the end */ 178 cFYI(1, ("SID sub_auth[%d]: 0x%x ", i,
53 cFYI(1, ("RID 0x%x", le32_to_cpu(psid->sub_auth[psid->num_subauth]))); 179 le32_to_cpu(psub_auth[i])));
180 }
181
182 /* BB add length check to make sure that we do not have huge
183 num auths and therefore go off the end */
184 cFYI(1, ("RID 0x%x",
185 le32_to_cpu(psid->sub_auth[psid->num_subauth])));
54#endif 186#endif
187 }
188
55 return 0; 189 return 0;
56} 190}
57 191
192
58/* Convert CIFS ACL to POSIX form */ 193/* Convert CIFS ACL to POSIX form */
59int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len) 194int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len)
60{ 195{
61 int i, rc; 196 int rc;
62 int num_aces = 0;
63 int acl_size;
64 struct cifs_sid *owner_sid_ptr, *group_sid_ptr; 197 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
65 struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ 198 struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
66 struct cifs_ntace **ppntace;
67 struct cifs_ace **ppace;
68 char *acl_base;
69 char *end_of_acl = ((char *)pntsd) + acl_len; 199 char *end_of_acl = ((char *)pntsd) + acl_len;
70 200
71 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + 201 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
@@ -89,6 +219,8 @@ int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len)
89 if (rc) 219 if (rc)
90 return rc; 220 return rc;
91 221
222 parse_dacl(dacl_ptr, end_of_acl);
223
92/* cifscred->uid = owner_sid_ptr->rid; 224/* cifscred->uid = owner_sid_ptr->rid;
93 cifscred->gid = group_sid_ptr->rid; 225 cifscred->gid = group_sid_ptr->rid;
94 memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr, 226 memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr,
@@ -96,46 +228,5 @@ int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len)
96 memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, 228 memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr,
97 sizeof (struct cifs_sid)); */ 229 sizeof (struct cifs_sid)); */
98 230
99 num_aces = cpu_to_le32(dacl_ptr->num_aces);
100 cFYI(1, ("num aces %d", num_aces));
101 if (num_aces > 0) {
102 ppntace = kmalloc(num_aces * sizeof(struct cifs_ntace *),
103 GFP_KERNEL);
104 ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
105 GFP_KERNEL);
106
107/* cifscred->cecount = dacl_ptr->num_aces;
108 cifscred->ntaces = kmalloc(num_aces *
109 sizeof(struct cifs_ntace *), GFP_KERNEL);
110 cifscred->aces = kmalloc(num_aces *
111 sizeof(struct cifs_ace *), GFP_KERNEL);*/
112
113 acl_base = (char *)dacl_ptr;
114 acl_size = sizeof(struct cifs_acl);
115
116 for (i = 0; i < num_aces; ++i) {
117 ppntace[i] = (struct cifs_ntace *)
118 (acl_base + acl_size);
119 ppace[i] = (struct cifs_ace *)
120 ((char *)ppntace[i] +
121 sizeof(struct cifs_ntace));
122
123/* memcpy((void *)(&(cifscred->ntaces[i])),
124 (void *)ntace_ptrptr[i],
125 sizeof(struct cifs_ntace));
126 memcpy((void *)(&(cifscred->aces[i])),
127 (void *)ace_ptrptr[i],
128 sizeof(struct cifs_ace)); */
129
130 acl_base = (char *)ppntace[i];
131 acl_size = cpu_to_le32(ppntace[i]->size);
132#ifdef CONFIG_CIFS_DEBUG2
133 cFYI(1, ("ACE revision:%d", ppace[i]->revision));
134#endif
135 }
136 kfree(ppace);
137 kfree(ppntace);
138 }
139
140 return (0); 231 return (0);
141} 232}
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h
index 5e7b56738cc5..bf297ea1905a 100644
--- a/fs/cifs/cifsacl.h
+++ b/fs/cifs/cifsacl.h
@@ -44,14 +44,14 @@ struct cifs_acl {
44 __u32 num_aces; 44 __u32 num_aces;
45} __attribute__((packed)); 45} __attribute__((packed));
46 46
47struct cifs_ntace { 47struct cifs_ntace { /* first part of ACE which contains perms */
48 __u8 type; 48 __u8 type;
49 __u8 flags; 49 __u8 flags;
50 __u16 size; 50 __u16 size;
51 __u32 access_req; 51 __u32 access_req;
52} __attribute__((packed)); 52} __attribute__((packed));
53 53
54struct cifs_ace { 54struct cifs_ace { /* last part of ACE which includes user info */
55 __u8 revision; /* revision level */ 55 __u8 revision; /* revision level */
56 __u8 num_subauth; 56 __u8 num_subauth;
57 __u8 authority[6]; 57 __u8 authority[6];
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 7dbb79b8dd50..001f0dc7e60d 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -310,7 +310,7 @@ extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *,
310#ifdef CONFIG_CIFS_WEAK_PW_HASH 310#ifdef CONFIG_CIFS_WEAK_PW_HASH
311extern void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key); 311extern void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key);
312#endif /* CIFS_WEAK_PW_HASH */ 312#endif /* CIFS_WEAK_PW_HASH */
313extern int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len); 313extern int parse_sec_desc(struct cifs_ntsd *, int);
314extern int CIFSSMBCopy(int xid, 314extern int CIFSSMBCopy(int xid,
315 struct cifsTconInfo *source_tcon, 315 struct cifsTconInfo *source_tcon,
316 const char *fromName, 316 const char *fromName,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index a6ff324bc135..90b8f8d64d6e 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -34,10 +34,10 @@
34#include <asm/uaccess.h> 34#include <asm/uaccess.h>
35#include "cifspdu.h" 35#include "cifspdu.h"
36#include "cifsglob.h" 36#include "cifsglob.h"
37#include "cifsacl.h"
37#include "cifsproto.h" 38#include "cifsproto.h"
38#include "cifs_unicode.h" 39#include "cifs_unicode.h"
39#include "cifs_debug.h" 40#include "cifs_debug.h"
40#include "cifsacl.h"
41 41
42#ifdef CONFIG_CIFS_POSIX 42#ifdef CONFIG_CIFS_POSIX
43static struct { 43static struct {