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 <behlendorf1@llnl.gov>.
8 * This file is part of the SPL, Solaris Porting Layer.
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.
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
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/>.
27 #include <linux/module.h>
28 #include <linux/cred.h>
29 #include <linux/sched.h>
30 #include <sys/types.h>
33 typedef struct cred cred_t
;
35 extern struct task_struct init_task
;
37 #define kcred ((cred_t *)(init_task.cred))
38 #define CRED() ((cred_t *)current_cred())
40 /* Linux 4.9 API change, GROUP_AT was removed */
42 #define GROUP_AT(gi, i) ((gi)->gid[i])
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)
51 extern zidmap_t
*zfs_get_init_idmap(void);
53 /* Check if the user ns is the initial one */
54 static inline boolean_t
55 zfs_is_init_userns(struct user_namespace
*user_ns
)
57 #if defined(CONFIG_USER_NS)
58 return (user_ns
== kcred
->user_ns
);
64 static inline struct user_namespace
*zfs_i_user_ns(struct inode
*inode
)
66 return (inode
->i_sb
->s_user_ns
);
69 static inline boolean_t
zfs_no_idmapping(struct user_namespace
*mnt_userns
,
70 struct user_namespace
*fs_userns
)
72 return (zfs_is_init_userns(mnt_userns
) ||
73 mnt_userns
== fs_userns
);
76 static inline uid_t
zfs_uid_to_vfsuid(zidmap_t
*mnt_userns
,
77 struct user_namespace
*fs_userns
, uid_t uid
)
79 struct user_namespace
*owner
;
80 #ifdef HAVE_IOPS_CREATE_IDMAP
81 if (mnt_userns
== zfs_init_idmap
)
84 #ifdef HAVE_IDMAP_NO_USERNS
85 struct user_namespace ns
;
86 ns
.uid_map
= mnt_userns
->uid_map
;
89 owner
= idmap_owner(mnt_userns
);
91 if (zfs_no_idmapping(owner
, fs_userns
))
93 if (!zfs_is_init_userns(fs_userns
))
94 uid
= from_kuid(fs_userns
, KUIDT_INIT(uid
));
97 return (__kuid_val(make_kuid(owner
, uid
)));
100 static inline gid_t
zfs_gid_to_vfsgid(zidmap_t
*mnt_userns
,
101 struct user_namespace
*fs_userns
, gid_t gid
)
103 struct user_namespace
*owner
;
104 #ifdef HAVE_IOPS_CREATE_IDMAP
105 if (mnt_userns
== zfs_init_idmap
)
108 #ifdef HAVE_IDMAP_NO_USERNS
109 struct user_namespace ns
;
110 ns
.gid_map
= mnt_userns
->gid_map
;
113 owner
= idmap_owner(mnt_userns
);
115 if (zfs_no_idmapping(owner
, fs_userns
))
117 if (!zfs_is_init_userns(fs_userns
))
118 gid
= from_kgid(fs_userns
, KGIDT_INIT(gid
));
119 if (gid
== (gid_t
)-1)
121 return (__kgid_val(make_kgid(owner
, gid
)));
124 static inline uid_t
zfs_vfsuid_to_uid(zidmap_t
*mnt_userns
,
125 struct user_namespace
*fs_userns
, uid_t uid
)
127 struct user_namespace
*owner
;
128 #ifdef HAVE_IOPS_CREATE_IDMAP
129 if (mnt_userns
== zfs_init_idmap
)
132 #ifdef HAVE_IDMAP_NO_USERNS
133 struct user_namespace ns
;
134 ns
.uid_map
= mnt_userns
->uid_map
;
137 owner
= idmap_owner(mnt_userns
);
139 if (zfs_no_idmapping(owner
, fs_userns
))
141 uid
= from_kuid(owner
, KUIDT_INIT(uid
));
142 if (uid
== (uid_t
)-1)
144 if (zfs_is_init_userns(fs_userns
))
146 return (__kuid_val(make_kuid(fs_userns
, uid
)));
149 static inline gid_t
zfs_vfsgid_to_gid(zidmap_t
*mnt_userns
,
150 struct user_namespace
*fs_userns
, gid_t gid
)
152 struct user_namespace
*owner
;
153 #ifdef HAVE_IOPS_CREATE_IDMAP
154 if (mnt_userns
== zfs_init_idmap
)
157 #ifdef HAVE_IDMAP_NO_USERNS
158 struct user_namespace ns
;
159 ns
.gid_map
= mnt_userns
->gid_map
;
162 owner
= idmap_owner(mnt_userns
);
164 if (zfs_no_idmapping(owner
, fs_userns
))
166 gid
= from_kgid(owner
, KGIDT_INIT(gid
));
167 if (gid
== (gid_t
)-1)
169 if (zfs_is_init_userns(fs_userns
))
171 return (__kgid_val(make_kgid(fs_userns
, gid
)));
174 extern void crhold(cred_t
*cr
);
175 extern void crfree(cred_t
*cr
);
176 extern uid_t
crgetuid(const cred_t
*cr
);
177 extern uid_t
crgetruid(const cred_t
*cr
);
178 extern gid_t
crgetgid(const cred_t
*cr
);
179 extern int crgetngroups(const cred_t
*cr
);
180 extern gid_t
*crgetgroups(const cred_t
*cr
);
181 extern int groupmember(gid_t gid
, const cred_t
*cr
);
182 #endif /* _SPL_CRED_H */