4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2012, 2013, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/obdclass/acl.c
38 * Lustre Access Control List.
40 * Author: Fan Yong <fanyong@clusterfs.com>
43 #define DEBUG_SUBSYSTEM S_SEC
44 #include <lu_object.h>
45 #include <lustre_acl.h>
46 #include <lustre_eacl.h>
47 #include <obd_support.h>
48 #ifdef HAVE_SERVER_SUPPORT
49 # include <lustre_idmap.h>
50 # include <md_object.h>
51 #endif /* HAVE_SERVER_SUPPORT */
53 #ifdef CONFIG_FS_POSIX_ACL
55 static inline void lustre_posix_acl_le_to_cpu(posix_acl_xattr_entry *d,
56 posix_acl_xattr_entry *s)
58 d->e_tag = le16_to_cpu(s->e_tag);
59 d->e_perm = le16_to_cpu(s->e_perm);
60 d->e_id = le32_to_cpu(s->e_id);
63 /*static inline void lustre_posix_acl_cpu_to_le(posix_acl_xattr_entry *d,
64 posix_acl_xattr_entry *s)
66 d->e_tag = cpu_to_le16(s->e_tag);
67 d->e_perm = cpu_to_le16(s->e_perm);
68 d->e_id = cpu_to_le32(s->e_id);
72 * Check permission based on POSIX ACL.
74 int lustre_posix_acl_permission(struct lu_ucred *mu, const struct lu_attr *la,
75 int want, posix_acl_xattr_entry *entry,
78 posix_acl_xattr_entry *pa, *pe, *mask_obj;
79 posix_acl_xattr_entry ae, me;
85 for (pa = &entry[0], pe = &entry[count - 1]; pa <= pe; pa++) {
86 lustre_posix_acl_le_to_cpu(&ae, pa);
89 /* (May have been checked already) */
90 if (la->la_uid == mu->uc_fsuid)
94 if (ae.e_id == mu->uc_fsuid)
98 if (lustre_in_group_p(mu, la->la_gid)) {
100 if ((ae.e_perm & want) == want)
105 if (lustre_in_group_p(mu, ae.e_id)) {
107 if ((ae.e_perm & want) == want)
125 for (mask_obj = pa + 1; mask_obj <= pe; mask_obj++) {
126 lustre_posix_acl_le_to_cpu(&me, mask_obj);
127 if (me.e_tag == ACL_MASK) {
128 if ((ae.e_perm & me.e_perm & want) == want)
136 if ((ae.e_perm & want) == want)
141 EXPORT_SYMBOL(lustre_posix_acl_permission);
144 * Modify the ACL for the chmod.
146 int lustre_posix_acl_chmod_masq(posix_acl_xattr_entry *entry, __u32 mode,
149 posix_acl_xattr_entry *group_obj = NULL, *mask_obj = NULL, *pa, *pe;
151 for (pa = &entry[0], pe = &entry[count - 1]; pa <= pe; pa++) {
152 switch (le16_to_cpu(pa->e_tag)) {
154 pa->e_perm = cpu_to_le16((mode & S_IRWXU) >> 6);
166 pa->e_perm = cpu_to_le16(mode & S_IRWXO);
174 mask_obj->e_perm = cpu_to_le16((mode & S_IRWXG) >> 3);
178 group_obj->e_perm = cpu_to_le16((mode & S_IRWXG) >> 3);
183 EXPORT_SYMBOL(lustre_posix_acl_chmod_masq);
186 * Returns 0 if the acl can be exactly represented in the traditional
187 * file mode permission bits, or else 1. Returns -E... on error.
190 lustre_posix_acl_equiv_mode(posix_acl_xattr_entry *entry, mode_t *mode_p,
193 posix_acl_xattr_entry *pa, *pe;
197 for (pa = &entry[0], pe = &entry[count - 1]; pa <= pe; pa++) {
198 __u16 perm = le16_to_cpu(pa->e_perm);
199 switch (le16_to_cpu(pa->e_tag)) {
201 mode |= (perm & S_IRWXO) << 6;
204 mode |= (perm & S_IRWXO) << 3;
207 mode |= perm & S_IRWXO;
210 mode = (mode & ~S_IRWXG) |
211 ((perm & S_IRWXO) << 3);
223 *mode_p = (*mode_p & ~S_IRWXUGO) | mode;
226 EXPORT_SYMBOL(lustre_posix_acl_equiv_mode);
229 * Modify acl when creating a new object.
231 int lustre_posix_acl_create_masq(posix_acl_xattr_entry *entry, __u32 *pmode,
234 posix_acl_xattr_entry *group_obj = NULL, *mask_obj = NULL, *pa, *pe;
235 posix_acl_xattr_entry ae;
239 for (pa = &entry[0], pe = &entry[count - 1]; pa <= pe; pa++) {
240 lustre_posix_acl_le_to_cpu(&ae, pa);
243 ae.e_perm &= (mode >> 6) | ~S_IRWXO;
244 pa->e_perm = cpu_to_le16(ae.e_perm);
245 mode &= (ae.e_perm << 6) | ~S_IRWXU;
255 ae.e_perm &= mode | ~S_IRWXO;
256 pa->e_perm = cpu_to_le16(ae.e_perm);
257 mode &= ae.e_perm | ~S_IRWXO;
269 ae.e_perm = le16_to_cpu(mask_obj->e_perm) &
270 ((mode >> 3) | ~S_IRWXO);
271 mode &= (ae.e_perm << 3) | ~S_IRWXG;
272 mask_obj->e_perm = cpu_to_le16(ae.e_perm);
276 ae.e_perm = le16_to_cpu(group_obj->e_perm) &
277 ((mode >> 3) | ~S_IRWXO);
278 mode &= (ae.e_perm << 3) | ~S_IRWXG;
279 group_obj->e_perm = cpu_to_le16(ae.e_perm);
282 *pmode = (*pmode & ~S_IRWXUGO) | mode;
285 EXPORT_SYMBOL(lustre_posix_acl_create_masq);