1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <linux/fs.h>
25#include "cifspdu.h"
26#include "cifsglob.h"
27#include "cifsacl.h"
28#include "cifsproto.h"
29#include "cifs_debug.h"
30
31
32#ifdef CONFIG_CIFS_EXPERIMENTAL
33
34static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
35 {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
36 {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
37 {{1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(11), 0, 0, 0, 0} }, "net-users"},
38 {{1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(18), 0, 0, 0, 0} }, "sys"},
39 {{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(544), 0, 0, 0} }, "root"},
40 {{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(545), 0, 0, 0} }, "users"},
41 {{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(546), 0, 0, 0} }, "guest"} }
42;
43
44
45
46static const struct cifs_sid sid_everyone = {
47 1, 1, {0, 0, 0, 0, 0, 1}, {0} };
48
49static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
50
51
52int match_sid(struct cifs_sid *ctsid)
53{
54 int i, j;
55 int num_subauth, num_sat, num_saw;
56 struct cifs_sid *cwsid;
57
58 if (!ctsid)
59 return -1;
60
61 for (i = 0; i < NUM_WK_SIDS; ++i) {
62 cwsid = &(wksidarr[i].cifssid);
63
64
65 if (ctsid->revision != cwsid->revision)
66 continue;
67
68
69 for (j = 0; j < 6; ++j) {
70 if (ctsid->authority[j] != cwsid->authority[j])
71 break;
72 }
73 if (j < 6)
74 continue;
75
76
77 num_sat = ctsid->num_subauth;
78 num_saw = cwsid->num_subauth;
79 num_subauth = num_sat < num_saw ? num_sat : num_saw;
80 if (num_subauth) {
81 for (j = 0; j < num_subauth; ++j) {
82 if (ctsid->sub_auth[j] != cwsid->sub_auth[j])
83 break;
84 }
85 if (j < num_subauth)
86 continue;
87 }
88
89 cFYI(1, ("matching sid: %s\n", wksidarr[i].sidname));
90 return 0;
91 }
92
93 cFYI(1, ("No matching sid"));
94 return -1;
95}
96
97
98
99int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
100{
101 int i;
102 int num_subauth, num_sat, num_saw;
103
104 if ((!ctsid) || (!cwsid))
105 return 0;
106
107
108 if (ctsid->revision != cwsid->revision)
109 return 0;
110
111
112 for (i = 0; i < 6; ++i) {
113 if (ctsid->authority[i] != cwsid->authority[i])
114 return 0;
115 }
116
117
118 num_sat = ctsid->num_subauth;
119 num_saw = cwsid->num_subauth;
120 num_subauth = num_sat < num_saw ? num_sat : num_saw;
121 if (num_subauth) {
122 for (i = 0; i < num_subauth; ++i) {
123 if (ctsid->sub_auth[i] != cwsid->sub_auth[i])
124 return 0;
125 }
126 }
127
128 return 1;
129}
130
131
132
133static void copy_sec_desc(const struct cifs_ntsd *pntsd,
134 struct cifs_ntsd *pnntsd, __u32 sidsoffset)
135{
136 int i;
137
138 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
139 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
140
141
142 pnntsd->revision = pntsd->revision;
143 pnntsd->type = pntsd->type;
144 pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
145 pnntsd->sacloffset = 0;
146 pnntsd->osidoffset = cpu_to_le32(sidsoffset);
147 pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
148
149
150 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
151 le32_to_cpu(pntsd->osidoffset));
152 nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
153
154 nowner_sid_ptr->revision = owner_sid_ptr->revision;
155 nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth;
156 for (i = 0; i < 6; i++)
157 nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i];
158 for (i = 0; i < 5; i++)
159 nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i];
160
161
162 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
163 le32_to_cpu(pntsd->gsidoffset));
164 ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
165 sizeof(struct cifs_sid));
166
167 ngroup_sid_ptr->revision = group_sid_ptr->revision;
168 ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth;
169 for (i = 0; i < 6; i++)
170 ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i];
171 for (i = 0; i < 5; i++)
172 ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i];
173
174 return;
175}
176
177
178
179
180
181
182
183static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
184 umode_t *pbits_to_set)
185{
186 __u32 flags = le32_to_cpu(ace_flags);
187
188
189
190
191
192
193
194
195 if (type == ACCESS_DENIED) {
196 if (flags & GENERIC_ALL)
197 *pbits_to_set &= ~S_IRWXUGO;
198
199 if ((flags & GENERIC_WRITE) ||
200 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
201 *pbits_to_set &= ~S_IWUGO;
202 if ((flags & GENERIC_READ) ||
203 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
204 *pbits_to_set &= ~S_IRUGO;
205 if ((flags & GENERIC_EXECUTE) ||
206 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
207 *pbits_to_set &= ~S_IXUGO;
208 return;
209 } else if (type != ACCESS_ALLOWED) {
210 cERROR(1, ("unknown access control type %d", type));
211 return;
212 }
213
214
215 if (flags & GENERIC_ALL) {
216 *pmode |= (S_IRWXUGO & (*pbits_to_set));
217 cFYI(DBG2, ("all perms"));
218 return;
219 }
220 if ((flags & GENERIC_WRITE) ||
221 ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
222 *pmode |= (S_IWUGO & (*pbits_to_set));
223 if ((flags & GENERIC_READ) ||
224 ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
225 *pmode |= (S_IRUGO & (*pbits_to_set));
226 if ((flags & GENERIC_EXECUTE) ||
227 ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
228 *pmode |= (S_IXUGO & (*pbits_to_set));
229
230 cFYI(DBG2, ("access flags 0x%x mode now 0x%x", flags, *pmode));
231 return;
232}
233
234
235
236
237
238
239
240static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
241 __u32 *pace_flags)
242{
243
244 *pace_flags = 0x0;
245
246
247 mode &= bits_to_use;
248
249
250
251
252 if (mode & S_IRUGO)
253 *pace_flags |= SET_FILE_READ_RIGHTS;
254 if (mode & S_IWUGO)
255 *pace_flags |= SET_FILE_WRITE_RIGHTS;
256 if (mode & S_IXUGO)
257 *pace_flags |= SET_FILE_EXEC_RIGHTS;
258
259 cFYI(DBG2, ("mode: 0x%x, access flags now 0x%x", mode, *pace_flags));
260 return;
261}
262
263static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
264 const struct cifs_sid *psid, __u64 nmode, umode_t bits)
265{
266 int i;
267 __u16 size = 0;
268 __u32 access_req = 0;
269
270 pntace->type = ACCESS_ALLOWED;
271 pntace->flags = 0x0;
272 mode_to_access_flags(nmode, bits, &access_req);
273 if (!access_req)
274 access_req = SET_MINIMUM_RIGHTS;
275 pntace->access_req = cpu_to_le32(access_req);
276
277 pntace->sid.revision = psid->revision;
278 pntace->sid.num_subauth = psid->num_subauth;
279 for (i = 0; i < 6; i++)
280 pntace->sid.authority[i] = psid->authority[i];
281 for (i = 0; i < psid->num_subauth; i++)
282 pntace->sid.sub_auth[i] = psid->sub_auth[i];
283
284 size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
285 pntace->size = cpu_to_le16(size);
286
287 return size;
288}
289
290
291#ifdef CONFIG_CIFS_DEBUG2
292static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
293{
294 int num_subauth;
295
296
297
298 if (le16_to_cpu(pace->size) < 16) {
299 cERROR(1, ("ACE too small, %d", le16_to_cpu(pace->size)));
300 return;
301 }
302
303 if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
304 cERROR(1, ("ACL too small to parse ACE"));
305 return;
306 }
307
308 num_subauth = pace->sid.num_subauth;
309 if (num_subauth) {
310 int i;
311 cFYI(1, ("ACE revision %d num_auth %d type %d flags %d size %d",
312 pace->sid.revision, pace->sid.num_subauth, pace->type,
313 pace->flags, le16_to_cpu(pace->size)));
314 for (i = 0; i < num_subauth; ++i) {
315 cFYI(1, ("ACE sub_auth[%d]: 0x%x", i,
316 le32_to_cpu(pace->sid.sub_auth[i])));
317 }
318
319
320
321 }
322
323 return;
324}
325#endif
326
327
328static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
329 struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
330 struct cifs_fattr *fattr)
331{
332 int i;
333 int num_aces = 0;
334 int acl_size;
335 char *acl_base;
336 struct cifs_ace **ppace;
337
338
339
340 if (!pdacl) {
341
342
343 fattr->cf_mode |= S_IRWXUGO;
344 return;
345 }
346
347
348 if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
349 cERROR(1, ("ACL too small to parse DACL"));
350 return;
351 }
352
353 cFYI(DBG2, ("DACL revision %d size %d num aces %d",
354 le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
355 le32_to_cpu(pdacl->num_aces)));
356
357
358
359
360 fattr->cf_mode &= ~(S_IRWXUGO);
361
362 acl_base = (char *)pdacl;
363 acl_size = sizeof(struct cifs_acl);
364
365 num_aces = le32_to_cpu(pdacl->num_aces);
366 if (num_aces > 0) {
367 umode_t user_mask = S_IRWXU;
368 umode_t group_mask = S_IRWXG;
369 umode_t other_mask = S_IRWXO;
370
371 ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
372 GFP_KERNEL);
373
374 for (i = 0; i < num_aces; ++i) {
375 ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
376#ifdef CONFIG_CIFS_DEBUG2
377 dump_ace(ppace[i], end_of_acl);
378#endif
379 if (compare_sids(&(ppace[i]->sid), pownersid))
380 access_flags_to_mode(ppace[i]->access_req,
381 ppace[i]->type,
382 &fattr->cf_mode,
383 &user_mask);
384 if (compare_sids(&(ppace[i]->sid), pgrpsid))
385 access_flags_to_mode(ppace[i]->access_req,
386 ppace[i]->type,
387 &fattr->cf_mode,
388 &group_mask);
389 if (compare_sids(&(ppace[i]->sid), &sid_everyone))
390 access_flags_to_mode(ppace[i]->access_req,
391 ppace[i]->type,
392 &fattr->cf_mode,
393 &other_mask);
394
395
396
397
398
399 acl_base = (char *)ppace[i];
400 acl_size = le16_to_cpu(ppace[i]->size);
401 }
402
403 kfree(ppace);
404 }
405
406 return;
407}
408
409
410static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
411 struct cifs_sid *pgrpsid, __u64 nmode)
412{
413 u16 size = 0;
414 struct cifs_acl *pnndacl;
415
416 pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
417
418 size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
419 pownersid, nmode, S_IRWXU);
420 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
421 pgrpsid, nmode, S_IRWXG);
422 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
423 &sid_everyone, nmode, S_IRWXO);
424
425 pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
426 pndacl->num_aces = cpu_to_le32(3);
427
428 return 0;
429}
430
431
432static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
433{
434
435
436
437
438 if (end_of_acl < (char *)psid + 8) {
439 cERROR(1, ("ACL too small to parse SID %p", psid));
440 return -EINVAL;
441 }
442
443 if (psid->num_subauth) {
444#ifdef CONFIG_CIFS_DEBUG2
445 int i;
446 cFYI(1, ("SID revision %d num_auth %d",
447 psid->revision, psid->num_subauth));
448
449 for (i = 0; i < psid->num_subauth; i++) {
450 cFYI(1, ("SID sub_auth[%d]: 0x%x ", i,
451 le32_to_cpu(psid->sub_auth[i])));
452 }
453
454
455
456 cFYI(1, ("RID 0x%x",
457 le32_to_cpu(psid->sub_auth[psid->num_subauth-1])));
458#endif
459 }
460
461 return 0;
462}
463
464
465
466static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len,
467 struct cifs_fattr *fattr)
468{
469 int rc;
470 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
471 struct cifs_acl *dacl_ptr;
472 char *end_of_acl = ((char *)pntsd) + acl_len;
473 __u32 dacloffset;
474
475 if (pntsd == NULL)
476 return -EIO;
477
478 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
479 le32_to_cpu(pntsd->osidoffset));
480 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
481 le32_to_cpu(pntsd->gsidoffset));
482 dacloffset = le32_to_cpu(pntsd->dacloffset);
483 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
484 cFYI(DBG2, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x "
485 "sacloffset 0x%x dacloffset 0x%x",
486 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
487 le32_to_cpu(pntsd->gsidoffset),
488 le32_to_cpu(pntsd->sacloffset), dacloffset));
489
490 rc = parse_sid(owner_sid_ptr, end_of_acl);
491 if (rc)
492 return rc;
493
494 rc = parse_sid(group_sid_ptr, end_of_acl);
495 if (rc)
496 return rc;
497
498 if (dacloffset)
499 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
500 group_sid_ptr, fattr);
501 else
502 cFYI(1, ("no ACL"));
503
504
505
506
507
508
509
510
511 return 0;
512}
513
514
515
516static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
517 struct inode *inode, __u64 nmode)
518{
519 int rc = 0;
520 __u32 dacloffset;
521 __u32 ndacloffset;
522 __u32 sidsoffset;
523 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
524 struct cifs_acl *dacl_ptr = NULL;
525 struct cifs_acl *ndacl_ptr = NULL;
526
527 if ((inode == NULL) || (pntsd == NULL) || (pnntsd == NULL))
528 return -EIO;
529
530 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
531 le32_to_cpu(pntsd->osidoffset));
532 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
533 le32_to_cpu(pntsd->gsidoffset));
534
535 dacloffset = le32_to_cpu(pntsd->dacloffset);
536 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
537
538 ndacloffset = sizeof(struct cifs_ntsd);
539 ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
540 ndacl_ptr->revision = dacl_ptr->revision;
541 ndacl_ptr->size = 0;
542 ndacl_ptr->num_aces = 0;
543
544 rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr, nmode);
545
546 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
547
548
549 copy_sec_desc(pntsd, pnntsd, sidsoffset);
550
551 return rc;
552}
553
554static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
555 __u16 fid, u32 *pacllen)
556{
557 struct cifs_ntsd *pntsd = NULL;
558 int xid, rc;
559
560 xid = GetXid();
561 rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen);
562 FreeXid(xid);
563
564
565 cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen));
566 return pntsd;
567}
568
569static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
570 const char *path, u32 *pacllen)
571{
572 struct cifs_ntsd *pntsd = NULL;
573 int oplock = 0;
574 int xid, rc;
575 __u16 fid;
576
577 xid = GetXid();
578
579 rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, READ_CONTROL, 0,
580 &fid, &oplock, NULL, cifs_sb->local_nls,
581 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
582 if (rc) {
583 cERROR(1, ("Unable to open file to get ACL"));
584 goto out;
585 }
586
587 rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen);
588 cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen));
589
590 CIFSSMBClose(xid, cifs_sb->tcon, fid);
591 out:
592 FreeXid(xid);
593 return pntsd;
594}
595
596
597static struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
598 struct inode *inode, const char *path,
599 u32 *pacllen)
600{
601 struct cifs_ntsd *pntsd = NULL;
602 struct cifsFileInfo *open_file = NULL;
603
604 if (inode)
605 open_file = find_readable_file(CIFS_I(inode));
606 if (!open_file)
607 return get_cifs_acl_by_path(cifs_sb, path, pacllen);
608
609 pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->netfid, pacllen);
610 cifsFileInfo_put(open_file);
611 return pntsd;
612}
613
614static int set_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, __u16 fid,
615 struct cifs_ntsd *pnntsd, u32 acllen)
616{
617 int xid, rc;
618
619 xid = GetXid();
620 rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen);
621 FreeXid(xid);
622
623 cFYI(DBG2, ("SetCIFSACL rc = %d", rc));
624 return rc;
625}
626
627static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
628 struct cifs_ntsd *pnntsd, u32 acllen)
629{
630 int oplock = 0;
631 int xid, rc;
632 __u16 fid;
633
634 xid = GetXid();
635
636 rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, WRITE_DAC, 0,
637 &fid, &oplock, NULL, cifs_sb->local_nls,
638 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
639 if (rc) {
640 cERROR(1, ("Unable to open file to set ACL"));
641 goto out;
642 }
643
644 rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen);
645 cFYI(DBG2, ("SetCIFSACL rc = %d", rc));
646
647 CIFSSMBClose(xid, cifs_sb->tcon, fid);
648 out:
649 FreeXid(xid);
650 return rc;
651}
652
653
654static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
655 struct inode *inode, const char *path)
656{
657 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
658 struct cifsFileInfo *open_file;
659 int rc;
660
661 cFYI(DBG2, ("set ACL for %s from mode 0x%x", path, inode->i_mode));
662
663 open_file = find_readable_file(CIFS_I(inode));
664 if (!open_file)
665 return set_cifs_acl_by_path(cifs_sb, path, pnntsd, acllen);
666
667 rc = set_cifs_acl_by_fid(cifs_sb, open_file->netfid, pnntsd, acllen);
668 cifsFileInfo_put(open_file);
669 return rc;
670}
671
672
673void
674cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
675 struct inode *inode, const char *path, const __u16 *pfid)
676{
677 struct cifs_ntsd *pntsd = NULL;
678 u32 acllen = 0;
679 int rc = 0;
680
681 cFYI(DBG2, ("converting ACL to mode for %s", path));
682
683 if (pfid)
684 pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen);
685 else
686 pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
687
688
689 if (pntsd)
690 rc = parse_sec_desc(pntsd, acllen, fattr);
691 if (rc)
692 cFYI(1, ("parse sec desc failed rc = %d", rc));
693
694 kfree(pntsd);
695 return;
696}
697
698
699int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
700{
701 int rc = 0;
702 __u32 secdesclen = 0;
703 struct cifs_ntsd *pntsd = NULL;
704 struct cifs_ntsd *pnntsd = NULL;
705
706 cFYI(DBG2, ("set ACL from mode for %s", path));
707
708
709 pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen);
710
711
712
713
714 if (pntsd) {
715
716
717
718
719 secdesclen = secdesclen < DEFSECDESCLEN ?
720 DEFSECDESCLEN : secdesclen;
721 pnntsd = kmalloc(secdesclen, GFP_KERNEL);
722 if (!pnntsd) {
723 cERROR(1, ("Unable to allocate security descriptor"));
724 kfree(pntsd);
725 return -ENOMEM;
726 }
727
728 rc = build_sec_desc(pntsd, pnntsd, inode, nmode);
729
730 cFYI(DBG2, ("build_sec_desc rc: %d", rc));
731
732 if (!rc) {
733
734 rc = set_cifs_acl(pnntsd, secdesclen, inode, path);
735 cFYI(DBG2, ("set_cifs_acl rc: %d", rc));
736 }
737
738 kfree(pnntsd);
739 kfree(pntsd);
740 }
741
742 return rc;
743}
744#endif
745