1 /* $NetBSD: creds.c,v 1.14 2007/12/08 19:57:02 pooka Exp $ */
4 * Copyright (c) 2006 Antti Kantee. All Rights Reserved.
6 * Development of this software was supported by the Ulla Tuominen Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: creds.c,v 1.14 2007/12/08 19:57:02 pooka Exp $");
36 * Interface for dealing with credits.
39 #include <sys/types.h>
40 #include <sys/param.h>
47 #include "puffs_priv.h"
49 #define UUCCRED(a) (a->pkcr_type == PUFFCRED_TYPE_UUC)
50 #define INTCRED(a) (a->pkcr_type == PUFFCRED_TYPE_INTERNAL)
53 puffs_cred_getuid(const struct puffs_cred
*pcr
, uid_t
*ruid
)
55 PUFFS_MAKEKCRED(pkcr
, pcr
);
61 *ruid
= pkcr
->pkcr_uuc
.cr_uid
;
67 puffs_cred_getgid(const struct puffs_cred
*pcr
, gid_t
*rgid
)
69 PUFFS_MAKEKCRED(pkcr
, pcr
);
75 *rgid
= pkcr
->pkcr_uuc
.cr_gid
;
81 puffs_cred_getgroups(const struct puffs_cred
*pcr
, gid_t
*rgids
, short *ngids
)
83 PUFFS_MAKEKCRED(pkcr
, pcr
);
92 ncopy
= MIN(*ngids
, pkcr
->pkcr_uuc
.cr_ngroups
);
93 (void)memcpy(rgids
, pkcr
->pkcr_uuc
.cr_groups
, sizeof(gid_t
) * ncopy
);
94 *ngids
= (short)ncopy
;
100 puffs_cred_isuid(const struct puffs_cred
*pcr
, uid_t uid
)
102 PUFFS_MAKEKCRED(pkcr
, pcr
);
104 return UUCCRED(pkcr
) && pkcr
->pkcr_uuc
.cr_uid
== uid
;
108 puffs_cred_hasgroup(const struct puffs_cred
*pcr
, gid_t gid
)
110 PUFFS_MAKEKCRED(pkcr
, pcr
);
116 if (pkcr
->pkcr_uuc
.cr_gid
== gid
)
118 for (i
= 0; i
< pkcr
->pkcr_uuc
.cr_ngroups
; i
++)
119 if (pkcr
->pkcr_uuc
.cr_groups
[i
] == gid
)
126 puffs_cred_isregular(const struct puffs_cred
*pcr
)
128 PUFFS_MAKEKCRED(pkcr
, pcr
);
130 return UUCCRED(pkcr
);
134 puffs_cred_iskernel(const struct puffs_cred
*pcr
)
136 PUFFS_MAKEKCRED(pkcr
, pcr
);
138 return INTCRED(pkcr
) && pkcr
->pkcr_internal
== PUFFCRED_CRED_NOCRED
;
142 puffs_cred_isfs(const struct puffs_cred
*pcr
)
144 PUFFS_MAKEKCRED(pkcr
, pcr
);
146 return INTCRED(pkcr
) && pkcr
->pkcr_internal
== PUFFCRED_CRED_FSCRED
;
150 puffs_cred_isjuggernaut(const struct puffs_cred
*pcr
)
153 return puffs_cred_isuid(pcr
, 0) || puffs_cred_iskernel(pcr
)
154 || puffs_cred_isfs(pcr
);
158 * Generic routine for checking file access rights. Modeled after
159 * vaccess() in the kernel.
162 puffs_access(enum vtype type
, mode_t file_mode
, uid_t uid
, gid_t gid
,
163 mode_t acc_mode
, const struct puffs_cred
*pcr
)
168 if (puffs_cred_iskernel(pcr
) || puffs_cred_isfs(pcr
))
171 /* superuser, allow all except exec if *ALL* exec bits are unset */
172 if (puffs_cred_isuid(pcr
, 0)) {
173 if ((acc_mode
& PUFFS_VEXEC
) && type
!= VDIR
&&
174 (file_mode
& (S_IXUSR
|S_IXGRP
|S_IXOTH
)) == 0)
181 if (puffs_cred_isuid(pcr
, uid
)) {
182 if (acc_mode
& PUFFS_VEXEC
)
184 if (acc_mode
& PUFFS_VREAD
)
186 if (acc_mode
& PUFFS_VWRITE
)
189 } else if (puffs_cred_hasgroup(pcr
, gid
)) {
190 if (acc_mode
& PUFFS_VEXEC
)
192 if (acc_mode
& PUFFS_VREAD
)
194 if (acc_mode
& PUFFS_VWRITE
)
198 if (acc_mode
& PUFFS_VEXEC
)
200 if (acc_mode
& PUFFS_VREAD
)
202 if (acc_mode
& PUFFS_VWRITE
)
206 if ((file_mode
& mask
) == mask
)
213 puffs_access_chown(uid_t owner
, gid_t group
, uid_t newowner
, gid_t newgroup
,
214 const struct puffs_cred
*pcr
)
217 if (newowner
== (uid_t
)PUFFS_VNOVAL
)
219 if (newgroup
== (gid_t
)PUFFS_VNOVAL
)
222 if ((!puffs_cred_isuid(pcr
, owner
) || newowner
!= owner
||
223 ((newgroup
!= group
&& !puffs_cred_hasgroup(pcr
, newgroup
))))
224 && !puffs_cred_isjuggernaut(pcr
))
231 puffs_access_chmod(uid_t owner
, gid_t group
, enum vtype type
, mode_t mode
,
232 const struct puffs_cred
*pcr
)
235 if (!puffs_cred_isuid(pcr
, owner
) && !puffs_cred_isjuggernaut(pcr
))
238 if (!puffs_cred_isjuggernaut(pcr
)) {
239 if (type
!= VDIR
&& (mode
& S_ISTXT
))
241 if (!puffs_cred_hasgroup(pcr
, group
) && (mode
& S_ISGID
))
249 puffs_access_times(uid_t uid
, gid_t gid
, mode_t mode
, int va_utimes_null
,
250 const struct puffs_cred
*pcr
)
253 if (!puffs_cred_isuid(pcr
, uid
) && !puffs_cred_isjuggernaut(pcr
)
254 && (va_utimes_null
== 0
255 || puffs_access(VNON
, mode
, uid
, gid
, PUFFS_VWRITE
, pcr
) != 0))