1 /* $NetBSD: creds.c,v 1.13 2007/10/18 13:48:04 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.13 2007/10/18 13:48:04 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
);
91 ncopy
= MIN(*ngids
, NGROUPS
);
92 (void)memcpy(rgids
, pkcr
->pkcr_uuc
.cr_groups
, sizeof(gid_t
) * ncopy
);
93 *ngids
= (short)ncopy
;
99 puffs_cred_isuid(const struct puffs_cred
*pcr
, uid_t uid
)
101 PUFFS_MAKEKCRED(pkcr
, pcr
);
103 return UUCCRED(pkcr
) && pkcr
->pkcr_uuc
.cr_uid
== uid
;
107 puffs_cred_hasgroup(const struct puffs_cred
*pcr
, gid_t gid
)
109 PUFFS_MAKEKCRED(pkcr
, pcr
);
115 if (pkcr
->pkcr_uuc
.cr_gid
== gid
)
117 for (i
= 0; i
< pkcr
->pkcr_uuc
.cr_ngroups
; i
++)
118 if (pkcr
->pkcr_uuc
.cr_groups
[i
] == gid
)
125 puffs_cred_isregular(const struct puffs_cred
*pcr
)
127 PUFFS_MAKEKCRED(pkcr
, pcr
);
129 return UUCCRED(pkcr
);
133 puffs_cred_iskernel(const struct puffs_cred
*pcr
)
135 PUFFS_MAKEKCRED(pkcr
, pcr
);
137 return INTCRED(pkcr
) && pkcr
->pkcr_internal
== PUFFCRED_CRED_NOCRED
;
141 puffs_cred_isfs(const struct puffs_cred
*pcr
)
143 PUFFS_MAKEKCRED(pkcr
, pcr
);
145 return INTCRED(pkcr
) && pkcr
->pkcr_internal
== PUFFCRED_CRED_FSCRED
;
149 puffs_cred_isjuggernaut(const struct puffs_cred
*pcr
)
152 return puffs_cred_isuid(pcr
, 0) || puffs_cred_iskernel(pcr
)
153 || puffs_cred_isfs(pcr
);
157 * Generic routine for checking file access rights. Modeled after
158 * vaccess() in the kernel.
161 puffs_access(enum vtype type
, mode_t file_mode
, uid_t uid
, gid_t gid
,
162 mode_t acc_mode
, const struct puffs_cred
*pcr
)
167 if (puffs_cred_iskernel(pcr
) || puffs_cred_isfs(pcr
))
170 /* superuser, allow all except exec if *ALL* exec bits are unset */
171 if (puffs_cred_isuid(pcr
, 0)) {
172 if ((acc_mode
& PUFFS_VEXEC
) && type
!= VDIR
&&
173 (file_mode
& (S_IXUSR
|S_IXGRP
|S_IXOTH
)) == 0)
180 if (puffs_cred_isuid(pcr
, uid
)) {
181 if (acc_mode
& PUFFS_VEXEC
)
183 if (acc_mode
& PUFFS_VREAD
)
185 if (acc_mode
& PUFFS_VWRITE
)
188 } else if (puffs_cred_hasgroup(pcr
, gid
)) {
189 if (acc_mode
& PUFFS_VEXEC
)
191 if (acc_mode
& PUFFS_VREAD
)
193 if (acc_mode
& PUFFS_VWRITE
)
197 if (acc_mode
& PUFFS_VEXEC
)
199 if (acc_mode
& PUFFS_VREAD
)
201 if (acc_mode
& PUFFS_VWRITE
)
205 if ((file_mode
& mask
) == mask
)
212 puffs_access_chown(uid_t owner
, gid_t group
, uid_t newowner
, gid_t newgroup
,
213 const struct puffs_cred
*pcr
)
216 if (newowner
== (uid_t
)PUFFS_VNOVAL
)
218 if (newgroup
== (gid_t
)PUFFS_VNOVAL
)
221 if ((!puffs_cred_isuid(pcr
, owner
) || newowner
!= owner
||
222 ((newgroup
!= group
&& !puffs_cred_hasgroup(pcr
, newgroup
))))
223 && !puffs_cred_isjuggernaut(pcr
))
230 puffs_access_chmod(uid_t owner
, gid_t group
, enum vtype type
, mode_t mode
,
231 const struct puffs_cred
*pcr
)
234 if (!puffs_cred_isuid(pcr
, owner
) && !puffs_cred_isjuggernaut(pcr
))
237 if (!puffs_cred_isjuggernaut(pcr
)) {
238 if (type
!= VDIR
&& (mode
& S_ISTXT
))
240 if (!puffs_cred_hasgroup(pcr
, group
) && (mode
& S_ISGID
))
248 puffs_access_times(uid_t uid
, gid_t gid
, mode_t mode
, int va_utimes_null
,
249 const struct puffs_cred
*pcr
)
252 if (!puffs_cred_isuid(pcr
, uid
) && !puffs_cred_isjuggernaut(pcr
)
253 && (va_utimes_null
== 0
254 || puffs_access(VNON
, mode
, uid
, gid
, PUFFS_VWRITE
, pcr
) != 0))