xref: /freebsd/sys/contrib/openzfs/include/os/linux/spl/sys/cred.h (revision 61145dc2b94f12f6a47344fb9aac702321880e43)
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 <sys/types.h>
32 #include <sys/vfs.h>
33 
34 typedef struct cred cred_t;
35 
36 extern struct task_struct init_task;
37 
38 #define	kcred		((cred_t *)(init_task.cred))
39 #define	CRED()		((cred_t *)current_cred())
40 
41 /* Linux 4.9 API change, GROUP_AT was removed */
42 #ifndef GROUP_AT
43 #define	GROUP_AT(gi, i)	((gi)->gid[i])
44 #endif
45 
46 #define	KUID_TO_SUID(x)		(__kuid_val(x))
47 #define	KGID_TO_SGID(x)		(__kgid_val(x))
48 #define	SUID_TO_KUID(x)		(KUIDT_INIT(x))
49 #define	SGID_TO_KGID(x)		(KGIDT_INIT(x))
50 #define	KGIDP_TO_SGIDP(x)	(&(x)->val)
51 
52 extern zidmap_t *zfs_get_init_idmap(void);
53 
54 /* Check if the user ns is the initial one */
55 static inline boolean_t
zfs_is_init_userns(struct user_namespace * user_ns)56 zfs_is_init_userns(struct user_namespace *user_ns)
57 {
58 #if defined(CONFIG_USER_NS)
59 	return (user_ns == kcred->user_ns);
60 #else
61 	return (B_FALSE);
62 #endif
63 }
64 
zfs_i_user_ns(struct inode * inode)65 static inline struct user_namespace *zfs_i_user_ns(struct inode *inode)
66 {
67 	return (inode->i_sb->s_user_ns);
68 }
69 
zfs_no_idmapping(struct user_namespace * mnt_userns,struct user_namespace * fs_userns)70 static inline boolean_t zfs_no_idmapping(struct user_namespace *mnt_userns,
71     struct user_namespace *fs_userns)
72 {
73 	return (zfs_is_init_userns(mnt_userns) ||
74 	    mnt_userns == fs_userns);
75 }
76 
zfs_uid_to_vfsuid(zidmap_t * mnt_userns,struct user_namespace * fs_userns,uid_t uid)77 static inline uid_t zfs_uid_to_vfsuid(zidmap_t *mnt_userns,
78     struct user_namespace *fs_userns, uid_t uid)
79 {
80 	struct user_namespace *owner;
81 #ifdef HAVE_IOPS_CREATE_IDMAP
82 	if (mnt_userns == zfs_init_idmap)
83 		return (uid);
84 #endif
85 #ifdef HAVE_IDMAP_NO_USERNS
86 	struct user_namespace ns;
87 	ns.uid_map = mnt_userns->uid_map;
88 	owner = &ns;
89 #else
90 	owner = idmap_owner(mnt_userns);
91 #endif
92 	if (zfs_no_idmapping(owner, fs_userns))
93 		return (uid);
94 	if (!zfs_is_init_userns(fs_userns))
95 		uid = from_kuid(fs_userns, KUIDT_INIT(uid));
96 	if (uid == (uid_t)-1)
97 		return (uid);
98 	return (__kuid_val(make_kuid(owner, uid)));
99 }
100 
zfs_gid_to_vfsgid(zidmap_t * mnt_userns,struct user_namespace * fs_userns,gid_t gid)101 static inline gid_t zfs_gid_to_vfsgid(zidmap_t *mnt_userns,
102     struct user_namespace *fs_userns, gid_t gid)
103 {
104 	struct user_namespace *owner;
105 #ifdef HAVE_IOPS_CREATE_IDMAP
106 	if (mnt_userns == zfs_init_idmap)
107 		return (gid);
108 #endif
109 #ifdef HAVE_IDMAP_NO_USERNS
110 	struct user_namespace ns;
111 	ns.gid_map = mnt_userns->gid_map;
112 	owner = &ns;
113 #else
114 	owner = idmap_owner(mnt_userns);
115 #endif
116 	if (zfs_no_idmapping(owner, fs_userns))
117 		return (gid);
118 	if (!zfs_is_init_userns(fs_userns))
119 		gid = from_kgid(fs_userns, KGIDT_INIT(gid));
120 	if (gid == (gid_t)-1)
121 		return (gid);
122 	return (__kgid_val(make_kgid(owner, gid)));
123 }
124 
zfs_vfsuid_to_uid(zidmap_t * mnt_userns,struct user_namespace * fs_userns,uid_t uid)125 static inline uid_t zfs_vfsuid_to_uid(zidmap_t *mnt_userns,
126     struct user_namespace *fs_userns, uid_t uid)
127 {
128 	struct user_namespace *owner;
129 #ifdef HAVE_IOPS_CREATE_IDMAP
130 	if (mnt_userns == zfs_init_idmap)
131 		return (uid);
132 #endif
133 #ifdef HAVE_IDMAP_NO_USERNS
134 	struct user_namespace ns;
135 	ns.uid_map = mnt_userns->uid_map;
136 	owner = &ns;
137 #else
138 	owner = idmap_owner(mnt_userns);
139 #endif
140 	if (zfs_no_idmapping(owner, fs_userns))
141 		return (uid);
142 	uid = from_kuid(owner, KUIDT_INIT(uid));
143 	if (uid == (uid_t)-1)
144 		return (uid);
145 	if (zfs_is_init_userns(fs_userns))
146 		return (uid);
147 	return (__kuid_val(make_kuid(fs_userns, uid)));
148 }
149 
zfs_vfsgid_to_gid(zidmap_t * mnt_userns,struct user_namespace * fs_userns,gid_t gid)150 static inline gid_t zfs_vfsgid_to_gid(zidmap_t *mnt_userns,
151     struct user_namespace *fs_userns, gid_t gid)
152 {
153 	struct user_namespace *owner;
154 #ifdef HAVE_IOPS_CREATE_IDMAP
155 	if (mnt_userns == zfs_init_idmap)
156 		return (gid);
157 #endif
158 #ifdef HAVE_IDMAP_NO_USERNS
159 	struct user_namespace ns;
160 	ns.gid_map = mnt_userns->gid_map;
161 	owner = &ns;
162 #else
163 	owner = idmap_owner(mnt_userns);
164 #endif
165 	if (zfs_no_idmapping(owner, fs_userns))
166 		return (gid);
167 	gid = from_kgid(owner, KGIDT_INIT(gid));
168 	if (gid == (gid_t)-1)
169 		return (gid);
170 	if (zfs_is_init_userns(fs_userns))
171 		return (gid);
172 	return (__kgid_val(make_kgid(fs_userns, gid)));
173 }
174 
175 extern void crhold(cred_t *cr);
176 extern void crfree(cred_t *cr);
177 extern uid_t crgetuid(const cred_t *cr);
178 extern uid_t crgetruid(const cred_t *cr);
179 extern gid_t crgetgid(const cred_t *cr);
180 extern int crgetngroups(const cred_t *cr);
181 extern gid_t *crgetgroups(const cred_t *cr);
182 extern int groupmember(gid_t gid, const cred_t *cr);
183 #endif  /* _SPL_CRED_H */
184