xref: /freebsd/sys/contrib/openzfs/include/os/linux/spl/sys/cred.h (revision 22649d4dba730d46244fd2dff4fd174903c8379f)
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