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