aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifsacl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/cifsacl.c')
-rw-r--r--fs/cifs/cifsacl.c346
1 files changed, 272 insertions, 74 deletions
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index e8e56353f5a1..dabbce00712b 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -38,13 +38,13 @@ static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
38 {{1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(18), 0, 0, 0, 0} }, "sys"}, 38 {{1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(18), 0, 0, 0, 0} }, "sys"},
39 {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(544), 0, 0, 0} }, "root"}, 39 {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(544), 0, 0, 0} }, "root"},
40 {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(545), 0, 0, 0} }, "users"}, 40 {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(545), 0, 0, 0} }, "users"},
41 {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(546), 0, 0, 0} }, "guest"} 41 {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(546), 0, 0, 0} }, "guest"} }
42}; 42;
43 43
44 44
45/* security id for everyone */ 45/* security id for everyone */
46static const struct cifs_sid sid_everyone = 46static const struct cifs_sid sid_everyone = {
47 {1, 1, {0, 0, 0, 0, 0, 0}, {} }; 47 1, 1, {0, 0, 0, 0, 0, 1}, {0} };
48/* group users */ 48/* group users */
49static const struct cifs_sid sid_user = 49static const struct cifs_sid sid_user =
50 {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; 50 {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
@@ -97,7 +97,7 @@ int match_sid(struct cifs_sid *ctsid)
97 97
98/* if the two SIDs (roughly equivalent to a UUID for a user or group) are 98/* if the two SIDs (roughly equivalent to a UUID for a user or group) are
99 the same returns 1, if they do not match returns 0 */ 99 the same returns 1, if they do not match returns 0 */
100int compare_sids(struct cifs_sid *ctsid, struct cifs_sid *cwsid) 100int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
101{ 101{
102 int i; 102 int i;
103 int num_subauth, num_sat, num_saw; 103 int num_subauth, num_sat, num_saw;
@@ -129,66 +129,142 @@ int compare_sids(struct cifs_sid *ctsid, struct cifs_sid *cwsid)
129 return (1); /* sids compare/match */ 129 return (1); /* sids compare/match */
130} 130}
131 131
132/*
133 change posix mode to reflect permissions
134 pmode is the existing mode (we only want to overwrite part of this
135 bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
136*/
137static void access_flags_to_mode(__u32 ace_flags, int type, umode_t *pmode,
138 umode_t *pbits_to_set)
139{
140 /* the order of ACEs is important. The canonical order is to begin with
141 DENY entries followed by ALLOW, otherwise an allow entry could be
142 encountered first, making the subsequent deny entry like "dead code"
143 which would be superflous since Windows stops when a match is made
144 for the operation you are trying to perform for your user */
145
146 /* For deny ACEs we change the mask so that subsequent allow access
147 control entries do not turn on the bits we are denying */
148 if (type == ACCESS_DENIED) {
149 if (ace_flags & GENERIC_ALL) {
150 *pbits_to_set &= ~S_IRWXUGO;
151 }
152 if ((ace_flags & GENERIC_WRITE) ||
153 ((ace_flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
154 *pbits_to_set &= ~S_IWUGO;
155 if ((ace_flags & GENERIC_READ) ||
156 ((ace_flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
157 *pbits_to_set &= ~S_IRUGO;
158 if ((ace_flags & GENERIC_EXECUTE) ||
159 ((ace_flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
160 *pbits_to_set &= ~S_IXUGO;
161 return;
162 } else if (type != ACCESS_ALLOWED) {
163 cERROR(1, ("unknown access control type %d", type));
164 return;
165 }
166 /* else ACCESS_ALLOWED type */
167
168 if (ace_flags & GENERIC_ALL) {
169 *pmode |= (S_IRWXUGO & (*pbits_to_set));
170#ifdef CONFIG_CIFS_DEBUG2
171 cFYI(1, ("all perms"));
172#endif
173 return;
174 }
175 if ((ace_flags & GENERIC_WRITE) ||
176 ((ace_flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
177 *pmode |= (S_IWUGO & (*pbits_to_set));
178 if ((ace_flags & GENERIC_READ) ||
179 ((ace_flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
180 *pmode |= (S_IRUGO & (*pbits_to_set));
181 if ((ace_flags & GENERIC_EXECUTE) ||
182 ((ace_flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
183 *pmode |= (S_IXUGO & (*pbits_to_set));
184
185#ifdef CONFIG_CIFS_DEBUG2
186 cFYI(1, ("access flags 0x%x mode now 0x%x", ace_flags, *pmode));
187#endif
188 return;
189}
190
191/*
192 Generate access flags to reflect permissions mode is the existing mode.
193 This function is called for every ACE in the DACL whose SID matches
194 with either owner or group or everyone.
195*/
196
197static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
198 __u32 *pace_flags)
199{
200 /* reset access mask */
201 *pace_flags = 0x0;
202
203 /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
204 mode &= bits_to_use;
205
206 /* check for R/W/X UGO since we do not know whose flags
207 is this but we have cleared all the bits sans RWX for
208 either user or group or other as per bits_to_use */
209 if (mode & S_IRUGO)
210 *pace_flags |= SET_FILE_READ_RIGHTS;
211 if (mode & S_IWUGO)
212 *pace_flags |= SET_FILE_WRITE_RIGHTS;
213 if (mode & S_IXUGO)
214 *pace_flags |= SET_FILE_EXEC_RIGHTS;
215
216#ifdef CONFIG_CIFS_DEBUG2
217 cFYI(1, ("mode: 0x%x, access flags now 0x%x", mode, *pace_flags));
218#endif
219 return;
220}
221
132 222
133static void parse_ace(struct cifs_ace *pace, char *end_of_acl) 223#ifdef CONFIG_CIFS_DEBUG2
224static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
134{ 225{
135 int num_subauth; 226 int num_subauth;
136 227
137 /* validate that we do not go past end of acl */ 228 /* validate that we do not go past end of acl */
138 229
139 /* XXX this if statement can be removed 230 if (le16_to_cpu(pace->size) < 16) {
140 if (end_of_acl < (char *)pace + sizeof(struct cifs_ace)) { 231 cERROR(1, ("ACE too small, %d", le16_to_cpu(pace->size)));
232 return;
233 }
234
235 if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
141 cERROR(1, ("ACL too small to parse ACE")); 236 cERROR(1, ("ACL too small to parse ACE"));
142 return; 237 return;
143 } */ 238 }
144 239
145 num_subauth = pace->num_subauth; 240 num_subauth = pace->sid.num_subauth;
146 if (num_subauth) { 241 if (num_subauth) {
147#ifdef CONFIG_CIFS_DEBUG2
148 int i; 242 int i;
149 cFYI(1, ("ACE revision %d num_subauth %d", 243 cFYI(1, ("ACE revision %d num_auth %d type %d flags %d size %d",
150 pace->revision, pace->num_subauth)); 244 pace->sid.revision, pace->sid.num_subauth, pace->type,
245 pace->flags, pace->size));
151 for (i = 0; i < num_subauth; ++i) { 246 for (i = 0; i < num_subauth; ++i) {
152 cFYI(1, ("ACE sub_auth[%d]: 0x%x", i, 247 cFYI(1, ("ACE sub_auth[%d]: 0x%x", i,
153 le32_to_cpu(pace->sub_auth[i]))); 248 le32_to_cpu(pace->sid.sub_auth[i])));
154 } 249 }
155 250
156 /* BB add length check to make sure that we do not have huge 251 /* BB add length check to make sure that we do not have huge
157 num auths and therefore go off the end */ 252 num auths and therefore go off the end */
158
159 cFYI(1, ("RID %d", le32_to_cpu(pace->sub_auth[num_subauth-1])));
160#endif
161 } 253 }
162 254
163 return; 255 return;
164} 256}
165
166static void parse_ntace(struct cifs_ntace *pntace, char *end_of_acl)
167{
168 /* validate that we do not go past end of acl */
169 if (end_of_acl < (char *)pntace + sizeof(struct cifs_ntace)) {
170 cERROR(1, ("ACL too small to parse NT ACE"));
171 return;
172 }
173
174#ifdef CONFIG_CIFS_DEBUG2
175 cFYI(1, ("NTACE type %d flags 0x%x size %d, access Req 0x%x",
176 pntace->type, pntace->flags, pntace->size,
177 pntace->access_req));
178#endif 257#endif
179 return;
180}
181
182 258
183 259
184static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, 260static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
185 struct cifs_sid *pownersid, struct cifs_sid *pgrpsid) 261 struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
262 struct inode *inode)
186{ 263{
187 int i; 264 int i;
188 int num_aces = 0; 265 int num_aces = 0;
189 int acl_size; 266 int acl_size;
190 char *acl_base; 267 char *acl_base;
191 struct cifs_ntace **ppntace;
192 struct cifs_ace **ppace; 268 struct cifs_ace **ppace;
193 269
194 /* BB need to add parm so we can store the SID BB */ 270 /* BB need to add parm so we can store the SID BB */
@@ -205,50 +281,63 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
205 le32_to_cpu(pdacl->num_aces))); 281 le32_to_cpu(pdacl->num_aces)));
206#endif 282#endif
207 283
284 /* reset rwx permissions for user/group/other.
285 Also, if num_aces is 0 i.e. DACL has no ACEs,
286 user/group/other have no permissions */
287 inode->i_mode &= ~(S_IRWXUGO);
288
289 if (!pdacl) {
290 /* no DACL in the security descriptor, set
291 all the permissions for user/group/other */
292 inode->i_mode |= S_IRWXUGO;
293 return;
294 }
208 acl_base = (char *)pdacl; 295 acl_base = (char *)pdacl;
209 acl_size = sizeof(struct cifs_acl); 296 acl_size = sizeof(struct cifs_acl);
210 297
211 num_aces = le32_to_cpu(pdacl->num_aces); 298 num_aces = le32_to_cpu(pdacl->num_aces);
212 if (num_aces > 0) { 299 if (num_aces > 0) {
213 ppntace = kmalloc(num_aces * sizeof(struct cifs_ntace *), 300 umode_t user_mask = S_IRWXU;
214 GFP_KERNEL); 301 umode_t group_mask = S_IRWXG;
302 umode_t other_mask = S_IRWXO;
303
215 ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), 304 ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
216 GFP_KERNEL); 305 GFP_KERNEL);
217 306
218/* cifscred->cecount = pdacl->num_aces; 307/* cifscred->cecount = pdacl->num_aces;
219 cifscred->ntaces = kmalloc(num_aces *
220 sizeof(struct cifs_ntace *), GFP_KERNEL);
221 cifscred->aces = kmalloc(num_aces * 308 cifscred->aces = kmalloc(num_aces *
222 sizeof(struct cifs_ace *), GFP_KERNEL);*/ 309 sizeof(struct cifs_ace *), GFP_KERNEL);*/
223 310
224 for (i = 0; i < num_aces; ++i) { 311 for (i = 0; i < num_aces; ++i) {
225 ppntace[i] = (struct cifs_ntace *) 312 ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
226 (acl_base + acl_size); 313#ifdef CONFIG_CIFS_DEBUG2
227 ppace[i] = (struct cifs_ace *) ((char *)ppntace[i] + 314 dump_ace(ppace[i], end_of_acl);
228 sizeof(struct cifs_ntace)); 315#endif
229 316 if (compare_sids(&(ppace[i]->sid), pownersid))
230 parse_ntace(ppntace[i], end_of_acl); 317 access_flags_to_mode(ppace[i]->access_req,
231 if (end_of_acl < ((char *)ppace[i] + 318 ppace[i]->type,
232 (le16_to_cpu(ppntace[i]->size) - 319 &(inode->i_mode),
233 sizeof(struct cifs_ntace)))) { 320 &user_mask);
234 cERROR(1, ("ACL too small to parse ACE")); 321 if (compare_sids(&(ppace[i]->sid), pgrpsid))
235 break; 322 access_flags_to_mode(ppace[i]->access_req,
236 } else 323 ppace[i]->type,
237 parse_ace(ppace[i], end_of_acl); 324 &(inode->i_mode),
238 325 &group_mask);
239/* memcpy((void *)(&(cifscred->ntaces[i])), 326 if (compare_sids(&(ppace[i]->sid), &sid_everyone))
240 (void *)ppntace[i], 327 access_flags_to_mode(ppace[i]->access_req,
241 sizeof(struct cifs_ntace)); 328 ppace[i]->type,
242 memcpy((void *)(&(cifscred->aces[i])), 329 &(inode->i_mode),
330 &other_mask);
331
332/* memcpy((void *)(&(cifscred->aces[i])),
243 (void *)ppace[i], 333 (void *)ppace[i],
244 sizeof(struct cifs_ace)); */ 334 sizeof(struct cifs_ace)); */
245 335
246 acl_base = (char *)ppntace[i]; 336 acl_base = (char *)ppace[i];
247 acl_size = le16_to_cpu(ppntace[i]->size); 337 acl_size = le16_to_cpu(ppace[i]->size);
248 } 338 }
249 339
250 kfree(ppace); 340 kfree(ppace);
251 kfree(ppntace);
252 } 341 }
253 342
254 return; 343 return;
@@ -257,20 +346,20 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
257 346
258static int parse_sid(struct cifs_sid *psid, char *end_of_acl) 347static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
259{ 348{
260
261 /* BB need to add parm so we can store the SID BB */ 349 /* BB need to add parm so we can store the SID BB */
262 350
263 /* validate that we do not go past end of acl */ 351 /* validate that we do not go past end of ACL - sid must be at least 8
264 if (end_of_acl < (char *)psid + sizeof(struct cifs_sid)) { 352 bytes long (assuming no sub-auths - e.g. the null SID */
265 cERROR(1, ("ACL too small to parse SID")); 353 if (end_of_acl < (char *)psid + 8) {
354 cERROR(1, ("ACL too small to parse SID %p", psid));
266 return -EINVAL; 355 return -EINVAL;
267 } 356 }
268 357
269 if (psid->num_subauth) { 358 if (psid->num_subauth) {
270#ifdef CONFIG_CIFS_DEBUG2 359#ifdef CONFIG_CIFS_DEBUG2
271 int i; 360 int i;
272 cFYI(1, ("SID revision %d num_auth %d First subauth 0x%x", 361 cFYI(1, ("SID revision %d num_auth %d",
273 psid->revision, psid->num_subauth, psid->sub_auth[0])); 362 psid->revision, psid->num_subauth));
274 363
275 for (i = 0; i < psid->num_subauth; i++) { 364 for (i = 0; i < psid->num_subauth; i++) {
276 cFYI(1, ("SID sub_auth[%d]: 0x%x ", i, 365 cFYI(1, ("SID sub_auth[%d]: 0x%x ", i,
@@ -289,27 +378,32 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
289 378
290 379
291/* Convert CIFS ACL to POSIX form */ 380/* Convert CIFS ACL to POSIX form */
292int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len) 381static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len,
382 struct inode *inode)
293{ 383{
294 int rc; 384 int rc;
295 struct cifs_sid *owner_sid_ptr, *group_sid_ptr; 385 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
296 struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ 386 struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
297 char *end_of_acl = ((char *)pntsd) + acl_len; 387 char *end_of_acl = ((char *)pntsd) + acl_len;
388 __u32 dacloffset;
389
390 if ((inode == NULL) || (pntsd == NULL))
391 return -EIO;
298 392
299 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + 393 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
300 le32_to_cpu(pntsd->osidoffset)); 394 le32_to_cpu(pntsd->osidoffset));
301 group_sid_ptr = (struct cifs_sid *)((char *)pntsd + 395 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
302 le32_to_cpu(pntsd->gsidoffset)); 396 le32_to_cpu(pntsd->gsidoffset));
303 dacl_ptr = (struct cifs_acl *)((char *)pntsd + 397 dacloffset = le32_to_cpu(pntsd->dacloffset);
304 le32_to_cpu(pntsd->dacloffset)); 398 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
305#ifdef CONFIG_CIFS_DEBUG2 399#ifdef CONFIG_CIFS_DEBUG2
306 cFYI(1, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x " 400 cFYI(1, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x "
307 "sacloffset 0x%x dacloffset 0x%x", 401 "sacloffset 0x%x dacloffset 0x%x",
308 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset), 402 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
309 le32_to_cpu(pntsd->gsidoffset), 403 le32_to_cpu(pntsd->gsidoffset),
310 le32_to_cpu(pntsd->sacloffset), 404 le32_to_cpu(pntsd->sacloffset), dacloffset));
311 le32_to_cpu(pntsd->dacloffset)));
312#endif 405#endif
406/* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
313 rc = parse_sid(owner_sid_ptr, end_of_acl); 407 rc = parse_sid(owner_sid_ptr, end_of_acl);
314 if (rc) 408 if (rc)
315 return rc; 409 return rc;
@@ -318,16 +412,120 @@ int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len)
318 if (rc) 412 if (rc)
319 return rc; 413 return rc;
320 414
321 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr); 415 if (dacloffset)
416 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
417 group_sid_ptr, inode);
418 else
419 cFYI(1, ("no ACL")); /* BB grant all or default perms? */
322 420
323/* cifscred->uid = owner_sid_ptr->rid; 421/* cifscred->uid = owner_sid_ptr->rid;
324 cifscred->gid = group_sid_ptr->rid; 422 cifscred->gid = group_sid_ptr->rid;
325 memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr, 423 memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr,
326 sizeof (struct cifs_sid)); 424 sizeof(struct cifs_sid));
327 memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, 425 memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr,
328 sizeof (struct cifs_sid)); */ 426 sizeof(struct cifs_sid)); */
329 427
330 428
331 return (0); 429 return (0);
332} 430}
431
432
433/* Retrieve an ACL from the server */
434static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode,
435 const char *path)
436{
437 struct cifsFileInfo *open_file;
438 int unlock_file = FALSE;
439 int xid;
440 int rc = -EIO;
441 __u16 fid;
442 struct super_block *sb;
443 struct cifs_sb_info *cifs_sb;
444 struct cifs_ntsd *pntsd = NULL;
445
446 cFYI(1, ("get mode from ACL for %s", path));
447
448 if (inode == NULL)
449 return NULL;
450
451 xid = GetXid();
452 open_file = find_readable_file(CIFS_I(inode));
453 sb = inode->i_sb;
454 if (sb == NULL) {
455 FreeXid(xid);
456 return NULL;
457 }
458 cifs_sb = CIFS_SB(sb);
459
460 if (open_file) {
461 unlock_file = TRUE;
462 fid = open_file->netfid;
463 } else {
464 int oplock = FALSE;
465 /* open file */
466 rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN,
467 READ_CONTROL, 0, &fid, &oplock, NULL,
468 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
469 CIFS_MOUNT_MAP_SPECIAL_CHR);
470 if (rc != 0) {
471 cERROR(1, ("Unable to open file to get ACL"));
472 FreeXid(xid);
473 return NULL;
474 }
475 }
476
477 rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen);
478 cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen));
479 if (unlock_file == TRUE)
480 atomic_dec(&open_file->wrtPending);
481 else
482 CIFSSMBClose(xid, cifs_sb->tcon, fid);
483
484 FreeXid(xid);
485 return pntsd;
486}
487
488/* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
489void acl_to_uid_mode(struct inode *inode, const char *path)
490{
491 struct cifs_ntsd *pntsd = NULL;
492 u32 acllen = 0;
493 int rc = 0;
494
495#ifdef CONFIG_CIFS_DEBUG2
496 cFYI(1, ("converting ACL to mode for %s", path));
497#endif
498 pntsd = get_cifs_acl(&acllen, inode, path);
499
500 /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
501 if (pntsd)
502 rc = parse_sec_desc(pntsd, acllen, inode);
503 if (rc)
504 cFYI(1, ("parse sec desc failed rc = %d", rc));
505
506 kfree(pntsd);
507 return;
508}
509
510/* Convert mode bits to an ACL so we can update the ACL on the server */
511int mode_to_acl(struct inode *inode, const char *path)
512{
513 int rc = 0;
514 __u32 acllen = 0;
515 struct cifs_ntsd *pntsd = NULL;
516
517 cFYI(1, ("set ACL from mode for %s", path));
518
519 /* Get the security descriptor */
520 pntsd = get_cifs_acl(&acllen, inode, path);
521
522 /* Add/Modify the three ACEs for owner, group, everyone
523 while retaining the other ACEs */
524
525 /* Set the security descriptor */
526
527
528 kfree(pntsd);
529 return rc;
530}
333#endif /* CONFIG_CIFS_EXPERIMENTAL */ 531#endif /* CONFIG_CIFS_EXPERIMENTAL */