4 * Copyright (C) International Business Machines Corp., 2007,2008
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * Contains the routines for mapping CIFS/NTFS ACLs
9 * This library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include <linux/slab.h>
26 #include <linux/string.h>
27 #include <linux/keyctl.h>
28 #include <linux/key-type.h>
29 #include <keys/user-type.h>
33 #include "cifsproto.h"
34 #include "cifs_debug.h"
37 static struct cifs_wksid wksidarr
[NUM_WK_SIDS
] = {
38 {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
39 {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
40 {{1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(11), 0, 0, 0, 0} }, "net-users"},
41 {{1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(18), 0, 0, 0, 0} }, "sys"},
42 {{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(544), 0, 0, 0} }, "root"},
43 {{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(545), 0, 0, 0} }, "users"},
44 {{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(546), 0, 0, 0} }, "guest"} }
48 /* security id for everyone/world system group */
49 static const struct cifs_sid sid_everyone
= {
50 1, 1, {0, 0, 0, 0, 0, 1}, {0} };
51 /* security id for Authenticated Users system group */
52 static const struct cifs_sid sid_authusers
= {
53 1, 1, {0, 0, 0, 0, 0, 5}, {11} };
55 static const struct cifs_sid sid_user
= {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
57 static const struct cred
*root_cred
;
60 * Run idmap cache shrinker.
63 cifs_idmap_shrinker(struct shrinker
*shrink
, int nr_to_scan
, gfp_t gfp_mask
)
65 /* Use a pruning scheme in a subsequent patch instead */
66 cifs_destroy_idmaptrees();
70 static struct shrinker cifs_shrinker
= {
71 .shrink
= cifs_idmap_shrinker
,
72 .seeks
= DEFAULT_SEEKS
,
76 cifs_idmap_key_instantiate(struct key
*key
, const void *data
, size_t datalen
)
80 payload
= kmalloc(datalen
, GFP_KERNEL
);
84 memcpy(payload
, data
, datalen
);
85 key
->payload
.data
= payload
;
90 cifs_idmap_key_destroy(struct key
*key
)
92 kfree(key
->payload
.data
);
96 struct key_type cifs_idmap_key_type
= {
97 .name
= "cifs.cifs_idmap",
98 .instantiate
= cifs_idmap_key_instantiate
,
99 .destroy
= cifs_idmap_key_destroy
,
100 .describe
= user_describe
,
105 init_cifs_idmap(void)
111 cFYI(1, "Registering the %s key type\n", cifs_idmap_key_type
.name
);
113 /* create an override credential set with a special thread keyring in
114 * which requests are cached
116 * this is used to prevent malicious redirections from being installed
119 cred
= prepare_kernel_cred(NULL
);
123 keyring
= key_alloc(&key_type_keyring
, ".cifs_idmap", 0, 0, cred
,
124 (KEY_POS_ALL
& ~KEY_POS_SETATTR
) |
125 KEY_USR_VIEW
| KEY_USR_READ
,
126 KEY_ALLOC_NOT_IN_QUOTA
);
127 if (IS_ERR(keyring
)) {
128 ret
= PTR_ERR(keyring
);
129 goto failed_put_cred
;
132 ret
= key_instantiate_and_link(keyring
, NULL
, 0, NULL
, NULL
);
136 ret
= register_key_type(&cifs_idmap_key_type
);
140 /* instruct request_key() to use this special keyring as a cache for
141 * the results it looks up */
142 cred
->thread_keyring
= keyring
;
143 cred
->jit_keyring
= KEY_REQKEY_DEFL_THREAD_KEYRING
;
146 spin_lock_init(&siduidlock
);
148 spin_lock_init(&sidgidlock
);
151 register_shrinker(&cifs_shrinker
);
153 cFYI(1, "cifs idmap keyring: %d\n", key_serial(keyring
));
164 exit_cifs_idmap(void)
166 key_revoke(root_cred
->thread_keyring
);
167 unregister_key_type(&cifs_idmap_key_type
);
169 unregister_shrinker(&cifs_shrinker
);
170 cFYI(1, "Unregistered %s key type\n", cifs_idmap_key_type
.name
);
174 cifs_destroy_idmaptrees(void)
176 struct rb_root
*root
;
177 struct rb_node
*node
;
180 spin_lock(&siduidlock
);
181 while ((node
= rb_first(root
)))
182 rb_erase(node
, root
);
183 spin_unlock(&siduidlock
);
186 spin_lock(&sidgidlock
);
187 while ((node
= rb_first(root
)))
188 rb_erase(node
, root
);
189 spin_unlock(&sidgidlock
);
192 int match_sid(struct cifs_sid
*ctsid
)
195 int num_subauth
, num_sat
, num_saw
;
196 struct cifs_sid
*cwsid
;
201 for (i
= 0; i
< NUM_WK_SIDS
; ++i
) {
202 cwsid
= &(wksidarr
[i
].cifssid
);
204 /* compare the revision */
205 if (ctsid
->revision
!= cwsid
->revision
)
208 /* compare all of the six auth values */
209 for (j
= 0; j
< 6; ++j
) {
210 if (ctsid
->authority
[j
] != cwsid
->authority
[j
])
214 continue; /* all of the auth values did not match */
216 /* compare all of the subauth values if any */
217 num_sat
= ctsid
->num_subauth
;
218 num_saw
= cwsid
->num_subauth
;
219 num_subauth
= num_sat
< num_saw
? num_sat
: num_saw
;
221 for (j
= 0; j
< num_subauth
; ++j
) {
222 if (ctsid
->sub_auth
[j
] != cwsid
->sub_auth
[j
])
226 continue; /* all sub_auth values do not match */
229 cFYI(1, "matching sid: %s\n", wksidarr
[i
].sidname
);
230 return 0; /* sids compare/match */
233 cFYI(1, "No matching sid");
237 /* if the two SIDs (roughly equivalent to a UUID for a user or group) are
238 the same returns 1, if they do not match returns 0 */
239 int compare_sids(const struct cifs_sid
*ctsid
, const struct cifs_sid
*cwsid
)
242 int num_subauth
, num_sat
, num_saw
;
244 if ((!ctsid
) || (!cwsid
))
247 /* compare the revision */
248 if (ctsid
->revision
!= cwsid
->revision
)
251 /* compare all of the six auth values */
252 for (i
= 0; i
< 6; ++i
) {
253 if (ctsid
->authority
[i
] != cwsid
->authority
[i
])
257 /* compare all of the subauth values if any */
258 num_sat
= ctsid
->num_subauth
;
259 num_saw
= cwsid
->num_subauth
;
260 num_subauth
= num_sat
< num_saw
? num_sat
: num_saw
;
262 for (i
= 0; i
< num_subauth
; ++i
) {
263 if (ctsid
->sub_auth
[i
] != cwsid
->sub_auth
[i
])
268 return 1; /* sids compare/match */
272 /* copy ntsd, owner sid, and group sid from a security descriptor to another */
273 static void copy_sec_desc(const struct cifs_ntsd
*pntsd
,
274 struct cifs_ntsd
*pnntsd
, __u32 sidsoffset
)
278 struct cifs_sid
*owner_sid_ptr
, *group_sid_ptr
;
279 struct cifs_sid
*nowner_sid_ptr
, *ngroup_sid_ptr
;
281 /* copy security descriptor control portion */
282 pnntsd
->revision
= pntsd
->revision
;
283 pnntsd
->type
= pntsd
->type
;
284 pnntsd
->dacloffset
= cpu_to_le32(sizeof(struct cifs_ntsd
));
285 pnntsd
->sacloffset
= 0;
286 pnntsd
->osidoffset
= cpu_to_le32(sidsoffset
);
287 pnntsd
->gsidoffset
= cpu_to_le32(sidsoffset
+ sizeof(struct cifs_sid
));
290 owner_sid_ptr
= (struct cifs_sid
*)((char *)pntsd
+
291 le32_to_cpu(pntsd
->osidoffset
));
292 nowner_sid_ptr
= (struct cifs_sid
*)((char *)pnntsd
+ sidsoffset
);
294 nowner_sid_ptr
->revision
= owner_sid_ptr
->revision
;
295 nowner_sid_ptr
->num_subauth
= owner_sid_ptr
->num_subauth
;
296 for (i
= 0; i
< 6; i
++)
297 nowner_sid_ptr
->authority
[i
] = owner_sid_ptr
->authority
[i
];
298 for (i
= 0; i
< 5; i
++)
299 nowner_sid_ptr
->sub_auth
[i
] = owner_sid_ptr
->sub_auth
[i
];
302 group_sid_ptr
= (struct cifs_sid
*)((char *)pntsd
+
303 le32_to_cpu(pntsd
->gsidoffset
));
304 ngroup_sid_ptr
= (struct cifs_sid
*)((char *)pnntsd
+ sidsoffset
+
305 sizeof(struct cifs_sid
));
307 ngroup_sid_ptr
->revision
= group_sid_ptr
->revision
;
308 ngroup_sid_ptr
->num_subauth
= group_sid_ptr
->num_subauth
;
309 for (i
= 0; i
< 6; i
++)
310 ngroup_sid_ptr
->authority
[i
] = group_sid_ptr
->authority
[i
];
311 for (i
= 0; i
< 5; i
++)
312 ngroup_sid_ptr
->sub_auth
[i
] = group_sid_ptr
->sub_auth
[i
];
319 change posix mode to reflect permissions
320 pmode is the existing mode (we only want to overwrite part of this
321 bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
323 static void access_flags_to_mode(__le32 ace_flags
, int type
, umode_t
*pmode
,
324 umode_t
*pbits_to_set
)
326 __u32 flags
= le32_to_cpu(ace_flags
);
327 /* the order of ACEs is important. The canonical order is to begin with
328 DENY entries followed by ALLOW, otherwise an allow entry could be
329 encountered first, making the subsequent deny entry like "dead code"
330 which would be superflous since Windows stops when a match is made
331 for the operation you are trying to perform for your user */
333 /* For deny ACEs we change the mask so that subsequent allow access
334 control entries do not turn on the bits we are denying */
335 if (type
== ACCESS_DENIED
) {
336 if (flags
& GENERIC_ALL
)
337 *pbits_to_set
&= ~S_IRWXUGO
;
339 if ((flags
& GENERIC_WRITE
) ||
340 ((flags
& FILE_WRITE_RIGHTS
) == FILE_WRITE_RIGHTS
))
341 *pbits_to_set
&= ~S_IWUGO
;
342 if ((flags
& GENERIC_READ
) ||
343 ((flags
& FILE_READ_RIGHTS
) == FILE_READ_RIGHTS
))
344 *pbits_to_set
&= ~S_IRUGO
;
345 if ((flags
& GENERIC_EXECUTE
) ||
346 ((flags
& FILE_EXEC_RIGHTS
) == FILE_EXEC_RIGHTS
))
347 *pbits_to_set
&= ~S_IXUGO
;
349 } else if (type
!= ACCESS_ALLOWED
) {
350 cERROR(1, "unknown access control type %d", type
);
353 /* else ACCESS_ALLOWED type */
355 if (flags
& GENERIC_ALL
) {
356 *pmode
|= (S_IRWXUGO
& (*pbits_to_set
));
357 cFYI(DBG2
, "all perms");
360 if ((flags
& GENERIC_WRITE
) ||
361 ((flags
& FILE_WRITE_RIGHTS
) == FILE_WRITE_RIGHTS
))
362 *pmode
|= (S_IWUGO
& (*pbits_to_set
));
363 if ((flags
& GENERIC_READ
) ||
364 ((flags
& FILE_READ_RIGHTS
) == FILE_READ_RIGHTS
))
365 *pmode
|= (S_IRUGO
& (*pbits_to_set
));
366 if ((flags
& GENERIC_EXECUTE
) ||
367 ((flags
& FILE_EXEC_RIGHTS
) == FILE_EXEC_RIGHTS
))
368 *pmode
|= (S_IXUGO
& (*pbits_to_set
));
370 cFYI(DBG2
, "access flags 0x%x mode now 0x%x", flags
, *pmode
);
375 Generate access flags to reflect permissions mode is the existing mode.
376 This function is called for every ACE in the DACL whose SID matches
377 with either owner or group or everyone.
380 static void mode_to_access_flags(umode_t mode
, umode_t bits_to_use
,
383 /* reset access mask */
386 /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
389 /* check for R/W/X UGO since we do not know whose flags
390 is this but we have cleared all the bits sans RWX for
391 either user or group or other as per bits_to_use */
393 *pace_flags
|= SET_FILE_READ_RIGHTS
;
395 *pace_flags
|= SET_FILE_WRITE_RIGHTS
;
397 *pace_flags
|= SET_FILE_EXEC_RIGHTS
;
399 cFYI(DBG2
, "mode: 0x%x, access flags now 0x%x", mode
, *pace_flags
);
403 static __u16
fill_ace_for_sid(struct cifs_ace
*pntace
,
404 const struct cifs_sid
*psid
, __u64 nmode
, umode_t bits
)
408 __u32 access_req
= 0;
410 pntace
->type
= ACCESS_ALLOWED
;
412 mode_to_access_flags(nmode
, bits
, &access_req
);
414 access_req
= SET_MINIMUM_RIGHTS
;
415 pntace
->access_req
= cpu_to_le32(access_req
);
417 pntace
->sid
.revision
= psid
->revision
;
418 pntace
->sid
.num_subauth
= psid
->num_subauth
;
419 for (i
= 0; i
< 6; i
++)
420 pntace
->sid
.authority
[i
] = psid
->authority
[i
];
421 for (i
= 0; i
< psid
->num_subauth
; i
++)
422 pntace
->sid
.sub_auth
[i
] = psid
->sub_auth
[i
];
424 size
= 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid
->num_subauth
* 4);
425 pntace
->size
= cpu_to_le16(size
);
431 #ifdef CONFIG_CIFS_DEBUG2
432 static void dump_ace(struct cifs_ace
*pace
, char *end_of_acl
)
436 /* validate that we do not go past end of acl */
438 if (le16_to_cpu(pace
->size
) < 16) {
439 cERROR(1, "ACE too small %d", le16_to_cpu(pace
->size
));
443 if (end_of_acl
< (char *)pace
+ le16_to_cpu(pace
->size
)) {
444 cERROR(1, "ACL too small to parse ACE");
448 num_subauth
= pace
->sid
.num_subauth
;
451 cFYI(1, "ACE revision %d num_auth %d type %d flags %d size %d",
452 pace
->sid
.revision
, pace
->sid
.num_subauth
, pace
->type
,
453 pace
->flags
, le16_to_cpu(pace
->size
));
454 for (i
= 0; i
< num_subauth
; ++i
) {
455 cFYI(1, "ACE sub_auth[%d]: 0x%x", i
,
456 le32_to_cpu(pace
->sid
.sub_auth
[i
]));
459 /* BB add length check to make sure that we do not have huge
460 num auths and therefore go off the end */
468 static void parse_dacl(struct cifs_acl
*pdacl
, char *end_of_acl
,
469 struct cifs_sid
*pownersid
, struct cifs_sid
*pgrpsid
,
470 struct cifs_fattr
*fattr
)
476 struct cifs_ace
**ppace
;
478 /* BB need to add parm so we can store the SID BB */
481 /* no DACL in the security descriptor, set
482 all the permissions for user/group/other */
483 fattr
->cf_mode
|= S_IRWXUGO
;
487 /* validate that we do not go past end of acl */
488 if (end_of_acl
< (char *)pdacl
+ le16_to_cpu(pdacl
->size
)) {
489 cERROR(1, "ACL too small to parse DACL");
493 cFYI(DBG2
, "DACL revision %d size %d num aces %d",
494 le16_to_cpu(pdacl
->revision
), le16_to_cpu(pdacl
->size
),
495 le32_to_cpu(pdacl
->num_aces
));
497 /* reset rwx permissions for user/group/other.
498 Also, if num_aces is 0 i.e. DACL has no ACEs,
499 user/group/other have no permissions */
500 fattr
->cf_mode
&= ~(S_IRWXUGO
);
502 acl_base
= (char *)pdacl
;
503 acl_size
= sizeof(struct cifs_acl
);
505 num_aces
= le32_to_cpu(pdacl
->num_aces
);
507 umode_t user_mask
= S_IRWXU
;
508 umode_t group_mask
= S_IRWXG
;
509 umode_t other_mask
= S_IRWXU
| S_IRWXG
| S_IRWXO
;
511 ppace
= kmalloc(num_aces
* sizeof(struct cifs_ace
*),
514 cERROR(1, "DACL memory allocation error");
518 for (i
= 0; i
< num_aces
; ++i
) {
519 ppace
[i
] = (struct cifs_ace
*) (acl_base
+ acl_size
);
520 #ifdef CONFIG_CIFS_DEBUG2
521 dump_ace(ppace
[i
], end_of_acl
);
523 if (compare_sids(&(ppace
[i
]->sid
), pownersid
))
524 access_flags_to_mode(ppace
[i
]->access_req
,
528 if (compare_sids(&(ppace
[i
]->sid
), pgrpsid
))
529 access_flags_to_mode(ppace
[i
]->access_req
,
533 if (compare_sids(&(ppace
[i
]->sid
), &sid_everyone
))
534 access_flags_to_mode(ppace
[i
]->access_req
,
538 if (compare_sids(&(ppace
[i
]->sid
), &sid_authusers
))
539 access_flags_to_mode(ppace
[i
]->access_req
,
545 /* memcpy((void *)(&(cifscred->aces[i])),
547 sizeof(struct cifs_ace)); */
549 acl_base
= (char *)ppace
[i
];
550 acl_size
= le16_to_cpu(ppace
[i
]->size
);
560 static int set_chmod_dacl(struct cifs_acl
*pndacl
, struct cifs_sid
*pownersid
,
561 struct cifs_sid
*pgrpsid
, __u64 nmode
)
564 struct cifs_acl
*pnndacl
;
566 pnndacl
= (struct cifs_acl
*)((char *)pndacl
+ sizeof(struct cifs_acl
));
568 size
+= fill_ace_for_sid((struct cifs_ace
*) ((char *)pnndacl
+ size
),
569 pownersid
, nmode
, S_IRWXU
);
570 size
+= fill_ace_for_sid((struct cifs_ace
*)((char *)pnndacl
+ size
),
571 pgrpsid
, nmode
, S_IRWXG
);
572 size
+= fill_ace_for_sid((struct cifs_ace
*)((char *)pnndacl
+ size
),
573 &sid_everyone
, nmode
, S_IRWXO
);
575 pndacl
->size
= cpu_to_le16(size
+ sizeof(struct cifs_acl
));
576 pndacl
->num_aces
= cpu_to_le32(3);
582 static int parse_sid(struct cifs_sid
*psid
, char *end_of_acl
)
584 /* BB need to add parm so we can store the SID BB */
586 /* validate that we do not go past end of ACL - sid must be at least 8
587 bytes long (assuming no sub-auths - e.g. the null SID */
588 if (end_of_acl
< (char *)psid
+ 8) {
589 cERROR(1, "ACL too small to parse SID %p", psid
);
593 if (psid
->num_subauth
) {
594 #ifdef CONFIG_CIFS_DEBUG2
596 cFYI(1, "SID revision %d num_auth %d",
597 psid
->revision
, psid
->num_subauth
);
599 for (i
= 0; i
< psid
->num_subauth
; i
++) {
600 cFYI(1, "SID sub_auth[%d]: 0x%x ", i
,
601 le32_to_cpu(psid
->sub_auth
[i
]));
604 /* BB add length check to make sure that we do not have huge
605 num auths and therefore go off the end */
607 le32_to_cpu(psid
->sub_auth
[psid
->num_subauth
-1]));
615 /* Convert CIFS ACL to POSIX form */
616 static int parse_sec_desc(struct cifs_ntsd
*pntsd
, int acl_len
,
617 struct cifs_fattr
*fattr
)
620 struct cifs_sid
*owner_sid_ptr
, *group_sid_ptr
;
621 struct cifs_acl
*dacl_ptr
; /* no need for SACL ptr */
622 char *end_of_acl
= ((char *)pntsd
) + acl_len
;
628 owner_sid_ptr
= (struct cifs_sid
*)((char *)pntsd
+
629 le32_to_cpu(pntsd
->osidoffset
));
630 group_sid_ptr
= (struct cifs_sid
*)((char *)pntsd
+
631 le32_to_cpu(pntsd
->gsidoffset
));
632 dacloffset
= le32_to_cpu(pntsd
->dacloffset
);
633 dacl_ptr
= (struct cifs_acl
*)((char *)pntsd
+ dacloffset
);
634 cFYI(DBG2
, "revision %d type 0x%x ooffset 0x%x goffset 0x%x "
635 "sacloffset 0x%x dacloffset 0x%x",
636 pntsd
->revision
, pntsd
->type
, le32_to_cpu(pntsd
->osidoffset
),
637 le32_to_cpu(pntsd
->gsidoffset
),
638 le32_to_cpu(pntsd
->sacloffset
), dacloffset
);
639 /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
640 rc
= parse_sid(owner_sid_ptr
, end_of_acl
);
644 rc
= parse_sid(group_sid_ptr
, end_of_acl
);
649 parse_dacl(dacl_ptr
, end_of_acl
, owner_sid_ptr
,
650 group_sid_ptr
, fattr
);
652 cFYI(1, "no ACL"); /* BB grant all or default perms? */
654 /* cifscred->uid = owner_sid_ptr->rid;
655 cifscred->gid = group_sid_ptr->rid;
656 memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr,
657 sizeof(struct cifs_sid));
658 memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr,
659 sizeof(struct cifs_sid)); */
665 /* Convert permission bits from mode to equivalent CIFS ACL */
666 static int build_sec_desc(struct cifs_ntsd
*pntsd
, struct cifs_ntsd
*pnntsd
,
667 struct inode
*inode
, __u64 nmode
)
673 struct cifs_sid
*owner_sid_ptr
, *group_sid_ptr
;
674 struct cifs_acl
*dacl_ptr
= NULL
; /* no need for SACL ptr */
675 struct cifs_acl
*ndacl_ptr
= NULL
; /* no need for SACL ptr */
677 if ((inode
== NULL
) || (pntsd
== NULL
) || (pnntsd
== NULL
))
680 owner_sid_ptr
= (struct cifs_sid
*)((char *)pntsd
+
681 le32_to_cpu(pntsd
->osidoffset
));
682 group_sid_ptr
= (struct cifs_sid
*)((char *)pntsd
+
683 le32_to_cpu(pntsd
->gsidoffset
));
685 dacloffset
= le32_to_cpu(pntsd
->dacloffset
);
686 dacl_ptr
= (struct cifs_acl
*)((char *)pntsd
+ dacloffset
);
688 ndacloffset
= sizeof(struct cifs_ntsd
);
689 ndacl_ptr
= (struct cifs_acl
*)((char *)pnntsd
+ ndacloffset
);
690 ndacl_ptr
->revision
= dacl_ptr
->revision
;
692 ndacl_ptr
->num_aces
= 0;
694 rc
= set_chmod_dacl(ndacl_ptr
, owner_sid_ptr
, group_sid_ptr
, nmode
);
696 sidsoffset
= ndacloffset
+ le16_to_cpu(ndacl_ptr
->size
);
698 /* copy security descriptor control portion and owner and group sid */
699 copy_sec_desc(pntsd
, pnntsd
, sidsoffset
);
704 static struct cifs_ntsd
*get_cifs_acl_by_fid(struct cifs_sb_info
*cifs_sb
,
705 __u16 fid
, u32
*pacllen
)
707 struct cifs_ntsd
*pntsd
= NULL
;
709 struct tcon_link
*tlink
= cifs_sb_tlink(cifs_sb
);
712 return ERR_CAST(tlink
);
715 rc
= CIFSSMBGetCIFSACL(xid
, tlink_tcon(tlink
), fid
, &pntsd
, pacllen
);
718 cifs_put_tlink(tlink
);
720 cFYI(1, "%s: rc = %d ACL len %d", __func__
, rc
, *pacllen
);
726 static struct cifs_ntsd
*get_cifs_acl_by_path(struct cifs_sb_info
*cifs_sb
,
727 const char *path
, u32
*pacllen
)
729 struct cifs_ntsd
*pntsd
= NULL
;
733 struct cifsTconInfo
*tcon
;
734 struct tcon_link
*tlink
= cifs_sb_tlink(cifs_sb
);
737 return ERR_CAST(tlink
);
739 tcon
= tlink_tcon(tlink
);
742 rc
= CIFSSMBOpen(xid
, tcon
, path
, FILE_OPEN
, READ_CONTROL
, 0,
743 &fid
, &oplock
, NULL
, cifs_sb
->local_nls
,
744 cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
);
746 rc
= CIFSSMBGetCIFSACL(xid
, tcon
, fid
, &pntsd
, pacllen
);
747 CIFSSMBClose(xid
, tcon
, fid
);
750 cifs_put_tlink(tlink
);
753 cFYI(1, "%s: rc = %d ACL len %d", __func__
, rc
, *pacllen
);
759 /* Retrieve an ACL from the server */
760 struct cifs_ntsd
*get_cifs_acl(struct cifs_sb_info
*cifs_sb
,
761 struct inode
*inode
, const char *path
,
764 struct cifs_ntsd
*pntsd
= NULL
;
765 struct cifsFileInfo
*open_file
= NULL
;
768 open_file
= find_readable_file(CIFS_I(inode
), true);
770 return get_cifs_acl_by_path(cifs_sb
, path
, pacllen
);
772 pntsd
= get_cifs_acl_by_fid(cifs_sb
, open_file
->netfid
, pacllen
);
773 cifsFileInfo_put(open_file
);
777 static int set_cifs_acl_by_fid(struct cifs_sb_info
*cifs_sb
, __u16 fid
,
778 struct cifs_ntsd
*pnntsd
, u32 acllen
)
781 struct tcon_link
*tlink
= cifs_sb_tlink(cifs_sb
);
784 return PTR_ERR(tlink
);
787 rc
= CIFSSMBSetCIFSACL(xid
, tlink_tcon(tlink
), fid
, pnntsd
, acllen
);
789 cifs_put_tlink(tlink
);
791 cFYI(DBG2
, "SetCIFSACL rc = %d", rc
);
795 static int set_cifs_acl_by_path(struct cifs_sb_info
*cifs_sb
, const char *path
,
796 struct cifs_ntsd
*pnntsd
, u32 acllen
)
801 struct cifsTconInfo
*tcon
;
802 struct tcon_link
*tlink
= cifs_sb_tlink(cifs_sb
);
805 return PTR_ERR(tlink
);
807 tcon
= tlink_tcon(tlink
);
810 rc
= CIFSSMBOpen(xid
, tcon
, path
, FILE_OPEN
, WRITE_DAC
, 0,
811 &fid
, &oplock
, NULL
, cifs_sb
->local_nls
,
812 cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
);
814 cERROR(1, "Unable to open file to set ACL");
818 rc
= CIFSSMBSetCIFSACL(xid
, tcon
, fid
, pnntsd
, acllen
);
819 cFYI(DBG2
, "SetCIFSACL rc = %d", rc
);
821 CIFSSMBClose(xid
, tcon
, fid
);
824 cifs_put_tlink(tlink
);
828 /* Set an ACL on the server */
829 int set_cifs_acl(struct cifs_ntsd
*pnntsd
, __u32 acllen
,
830 struct inode
*inode
, const char *path
)
832 struct cifs_sb_info
*cifs_sb
= CIFS_SB(inode
->i_sb
);
833 struct cifsFileInfo
*open_file
;
836 cFYI(DBG2
, "set ACL for %s from mode 0x%x", path
, inode
->i_mode
);
838 open_file
= find_readable_file(CIFS_I(inode
), true);
840 return set_cifs_acl_by_path(cifs_sb
, path
, pnntsd
, acllen
);
842 rc
= set_cifs_acl_by_fid(cifs_sb
, open_file
->netfid
, pnntsd
, acllen
);
843 cifsFileInfo_put(open_file
);
847 /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
849 cifs_acl_to_fattr(struct cifs_sb_info
*cifs_sb
, struct cifs_fattr
*fattr
,
850 struct inode
*inode
, const char *path
, const __u16
*pfid
)
852 struct cifs_ntsd
*pntsd
= NULL
;
856 cFYI(DBG2
, "converting ACL to mode for %s", path
);
859 pntsd
= get_cifs_acl_by_fid(cifs_sb
, *pfid
, &acllen
);
861 pntsd
= get_cifs_acl(cifs_sb
, inode
, path
, &acllen
);
863 /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
866 cERROR(1, "%s: error %d getting sec desc", __func__
, rc
);
868 rc
= parse_sec_desc(pntsd
, acllen
, fattr
);
871 cERROR(1, "parse sec desc failed rc = %d", rc
);
877 /* Convert mode bits to an ACL so we can update the ACL on the server */
878 int mode_to_cifs_acl(struct inode
*inode
, const char *path
, __u64 nmode
)
881 __u32 secdesclen
= 0;
882 struct cifs_ntsd
*pntsd
= NULL
; /* acl obtained from server */
883 struct cifs_ntsd
*pnntsd
= NULL
; /* modified acl to be sent to server */
885 cFYI(DBG2
, "set ACL from mode for %s", path
);
887 /* Get the security descriptor */
888 pntsd
= get_cifs_acl(CIFS_SB(inode
->i_sb
), inode
, path
, &secdesclen
);
890 /* Add three ACEs for owner, group, everyone getting rid of
891 other ACEs as chmod disables ACEs and set the security descriptor */
895 cERROR(1, "%s: error %d getting sec desc", __func__
, rc
);
897 /* allocate memory for the smb header,
898 set security descriptor request security descriptor
899 parameters, and secuirty descriptor itself */
901 secdesclen
= secdesclen
< DEFSECDESCLEN
?
902 DEFSECDESCLEN
: secdesclen
;
903 pnntsd
= kmalloc(secdesclen
, GFP_KERNEL
);
905 cERROR(1, "Unable to allocate security descriptor");
910 rc
= build_sec_desc(pntsd
, pnntsd
, inode
, nmode
);
912 cFYI(DBG2
, "build_sec_desc rc: %d", rc
);
915 /* Set the security descriptor */
916 rc
= set_cifs_acl(pnntsd
, secdesclen
, inode
, path
);
917 cFYI(DBG2
, "set_cifs_acl rc: %d", rc
);