1 /*
2 * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
3 * Copyright (C) 2007 The Regents of the University of California.
4 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
5 * Written by Brian Behlendorf <[email protected]>.
6 * UCRL-CODE-235197
7 *
8 * This file is part of the SPL, Solaris Porting Layer.
9 *
10 * The SPL is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * The SPL is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 * for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with the SPL. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #ifndef _SPL_CRED_H
25 #define _SPL_CRED_H
26
27 #include <linux/module.h>
28 #include <linux/cred.h>
29 #include <linux/sched.h>
30 #include <sys/types.h>
31 #include <sys/vfs.h>
32
33 typedef struct cred cred_t;
34
35 extern struct task_struct init_task;
36
37 #define kcred ((cred_t *)(init_task.cred))
38 #define CRED() ((cred_t *)current_cred())
39
40 /* Linux 4.9 API change, GROUP_AT was removed */
41 #ifndef GROUP_AT
42 #define GROUP_AT(gi, i) ((gi)->gid[i])
43 #endif
44
45 #define KUID_TO_SUID(x) (__kuid_val(x))
46 #define KGID_TO_SGID(x) (__kgid_val(x))
47 #define SUID_TO_KUID(x) (KUIDT_INIT(x))
48 #define SGID_TO_KGID(x) (KGIDT_INIT(x))
49 #define KGIDP_TO_SGIDP(x) (&(x)->val)
50
51 extern zidmap_t *zfs_get_init_idmap(void);
52
53 /* Check if the user ns is the initial one */
54 static inline boolean_t
zfs_is_init_userns(struct user_namespace * user_ns)55 zfs_is_init_userns(struct user_namespace *user_ns)
56 {
57 #if defined(CONFIG_USER_NS)
58 return (user_ns == kcred->user_ns);
59 #else
60 return (B_FALSE);
61 #endif
62 }
63
zfs_i_user_ns(struct inode * inode)64 static inline struct user_namespace *zfs_i_user_ns(struct inode *inode)
65 {
66 #ifdef HAVE_SUPER_USER_NS
67 return (inode->i_sb->s_user_ns);
68 #else
69 return (kcred->user_ns);
70 #endif
71 }
72
zfs_no_idmapping(struct user_namespace * mnt_userns,struct user_namespace * fs_userns)73 static inline boolean_t zfs_no_idmapping(struct user_namespace *mnt_userns,
74 struct user_namespace *fs_userns)
75 {
76 return (zfs_is_init_userns(mnt_userns) ||
77 mnt_userns == fs_userns);
78 }
79
zfs_uid_to_vfsuid(zidmap_t * mnt_userns,struct user_namespace * fs_userns,uid_t uid)80 static inline uid_t zfs_uid_to_vfsuid(zidmap_t *mnt_userns,
81 struct user_namespace *fs_userns, uid_t uid)
82 {
83 struct user_namespace *owner;
84 #ifdef HAVE_IOPS_CREATE_IDMAP
85 if (mnt_userns == zfs_init_idmap)
86 return (uid);
87 #endif
88 #ifdef HAVE_IDMAP_NO_USERNS
89 struct user_namespace ns;
90 ns.uid_map = mnt_userns->uid_map;
91 owner = &ns;
92 #else
93 owner = idmap_owner(mnt_userns);
94 #endif
95 if (zfs_no_idmapping(owner, fs_userns))
96 return (uid);
97 if (!zfs_is_init_userns(fs_userns))
98 uid = from_kuid(fs_userns, KUIDT_INIT(uid));
99 if (uid == (uid_t)-1)
100 return (uid);
101 return (__kuid_val(make_kuid(owner, uid)));
102 }
103
zfs_gid_to_vfsgid(zidmap_t * mnt_userns,struct user_namespace * fs_userns,gid_t gid)104 static inline gid_t zfs_gid_to_vfsgid(zidmap_t *mnt_userns,
105 struct user_namespace *fs_userns, gid_t gid)
106 {
107 struct user_namespace *owner;
108 #ifdef HAVE_IOPS_CREATE_IDMAP
109 if (mnt_userns == zfs_init_idmap)
110 return (gid);
111 #endif
112 #ifdef HAVE_IDMAP_NO_USERNS
113 struct user_namespace ns;
114 ns.gid_map = mnt_userns->gid_map;
115 owner = &ns;
116 #else
117 owner = idmap_owner(mnt_userns);
118 #endif
119 if (zfs_no_idmapping(owner, fs_userns))
120 return (gid);
121 if (!zfs_is_init_userns(fs_userns))
122 gid = from_kgid(fs_userns, KGIDT_INIT(gid));
123 if (gid == (gid_t)-1)
124 return (gid);
125 return (__kgid_val(make_kgid(owner, gid)));
126 }
127
zfs_vfsuid_to_uid(zidmap_t * mnt_userns,struct user_namespace * fs_userns,uid_t uid)128 static inline uid_t zfs_vfsuid_to_uid(zidmap_t *mnt_userns,
129 struct user_namespace *fs_userns, uid_t uid)
130 {
131 struct user_namespace *owner;
132 #ifdef HAVE_IOPS_CREATE_IDMAP
133 if (mnt_userns == zfs_init_idmap)
134 return (uid);
135 #endif
136 #ifdef HAVE_IDMAP_NO_USERNS
137 struct user_namespace ns;
138 ns.uid_map = mnt_userns->uid_map;
139 owner = &ns;
140 #else
141 owner = idmap_owner(mnt_userns);
142 #endif
143 if (zfs_no_idmapping(owner, fs_userns))
144 return (uid);
145 uid = from_kuid(owner, KUIDT_INIT(uid));
146 if (uid == (uid_t)-1)
147 return (uid);
148 if (zfs_is_init_userns(fs_userns))
149 return (uid);
150 return (__kuid_val(make_kuid(fs_userns, uid)));
151 }
152
zfs_vfsgid_to_gid(zidmap_t * mnt_userns,struct user_namespace * fs_userns,gid_t gid)153 static inline gid_t zfs_vfsgid_to_gid(zidmap_t *mnt_userns,
154 struct user_namespace *fs_userns, gid_t gid)
155 {
156 struct user_namespace *owner;
157 #ifdef HAVE_IOPS_CREATE_IDMAP
158 if (mnt_userns == zfs_init_idmap)
159 return (gid);
160 #endif
161 #ifdef HAVE_IDMAP_NO_USERNS
162 struct user_namespace ns;
163 ns.gid_map = mnt_userns->gid_map;
164 owner = &ns;
165 #else
166 owner = idmap_owner(mnt_userns);
167 #endif
168 if (zfs_no_idmapping(owner, fs_userns))
169 return (gid);
170 gid = from_kgid(owner, KGIDT_INIT(gid));
171 if (gid == (gid_t)-1)
172 return (gid);
173 if (zfs_is_init_userns(fs_userns))
174 return (gid);
175 return (__kgid_val(make_kgid(fs_userns, gid)));
176 }
177
178 extern void crhold(cred_t *cr);
179 extern void crfree(cred_t *cr);
180 extern uid_t crgetuid(const cred_t *cr);
181 extern uid_t crgetruid(const cred_t *cr);
182 extern gid_t crgetgid(const cred_t *cr);
183 extern int crgetngroups(const cred_t *cr);
184 extern gid_t *crgetgroups(const cred_t *cr);
185 extern int groupmember(gid_t gid, const cred_t *cr);
186 #endif /* _SPL_CRED_H */
187