1 /* $NetBSD: creds.c,v 1.15 2009/11/20 14:23:54 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
31 * Interface for dealing with credits.
34 #include <sys/types.h>
35 #include <sys/param.h>
42 #include "puffs_priv.h"
44 #define UUCCRED(a) (a->pkcr_type == PUFFCRED_TYPE_UUC)
45 #define INTCRED(a) (a->pkcr_type == PUFFCRED_TYPE_INTERNAL)
48 puffs_cred_getuid(const struct puffs_cred
*pcr
, uid_t
*ruid
)
50 PUFFS_MAKEKCRED(pkcr
, pcr
);
56 *ruid
= pkcr
->pkcr_uuc
.cr_uid
;
62 puffs_cred_getgid(const struct puffs_cred
*pcr
, gid_t
*rgid
)
64 PUFFS_MAKEKCRED(pkcr
, pcr
);
70 *rgid
= pkcr
->pkcr_uuc
.cr_gid
;
76 puffs_cred_getgroups(const struct puffs_cred
*pcr
, gid_t
*rgids
, short *ngids
)
78 PUFFS_MAKEKCRED(pkcr
, pcr
);
87 ncopy
= MIN(*ngids
, pkcr
->pkcr_uuc
.cr_ngroups
);
88 (void)memcpy(rgids
, pkcr
->pkcr_uuc
.cr_groups
, sizeof(gid_t
) * ncopy
);
89 *ngids
= (short)ncopy
;
95 puffs_cred_isuid(const struct puffs_cred
*pcr
, uid_t uid
)
97 PUFFS_MAKEKCRED(pkcr
, pcr
);
99 return UUCCRED(pkcr
) && pkcr
->pkcr_uuc
.cr_uid
== uid
;
103 puffs_cred_hasgroup(const struct puffs_cred
*pcr
, gid_t gid
)
105 PUFFS_MAKEKCRED(pkcr
, pcr
);
111 if (pkcr
->pkcr_uuc
.cr_gid
== gid
)
113 for (i
= 0; i
< pkcr
->pkcr_uuc
.cr_ngroups
; i
++)
114 if (pkcr
->pkcr_uuc
.cr_groups
[i
] == gid
)
121 puffs_cred_isregular(const struct puffs_cred
*pcr
)
123 PUFFS_MAKEKCRED(pkcr
, pcr
);
125 return UUCCRED(pkcr
);
129 puffs_cred_iskernel(const struct puffs_cred
*pcr
)
131 PUFFS_MAKEKCRED(pkcr
, pcr
);
133 return INTCRED(pkcr
) && pkcr
->pkcr_internal
== PUFFCRED_CRED_NOCRED
;
137 puffs_cred_isfs(const struct puffs_cred
*pcr
)
139 PUFFS_MAKEKCRED(pkcr
, pcr
);
141 return INTCRED(pkcr
) && pkcr
->pkcr_internal
== PUFFCRED_CRED_FSCRED
;
145 puffs_cred_isjuggernaut(const struct puffs_cred
*pcr
)
148 return puffs_cred_isuid(pcr
, 0) || puffs_cred_iskernel(pcr
)
149 || puffs_cred_isfs(pcr
);
153 * Generic routine for checking file access rights. Modeled after
154 * vaccess() in the kernel.
157 puffs_access(enum vtype type
, mode_t file_mode
, uid_t uid
, gid_t gid
,
158 mode_t acc_mode
, const struct puffs_cred
*pcr
)
163 if (puffs_cred_iskernel(pcr
) || puffs_cred_isfs(pcr
))
166 /* superuser, allow all except exec if *ALL* exec bits are unset */
167 if (puffs_cred_isuid(pcr
, 0)) {
168 if ((acc_mode
& PUFFS_VEXEC
) && type
!= VDIR
&&
169 (file_mode
& (S_IXUSR
|S_IXGRP
|S_IXOTH
)) == 0)
176 if (puffs_cred_isuid(pcr
, uid
)) {
177 if (acc_mode
& PUFFS_VEXEC
)
179 if (acc_mode
& PUFFS_VREAD
)
181 if (acc_mode
& PUFFS_VWRITE
)
184 } else if (puffs_cred_hasgroup(pcr
, gid
)) {
185 if (acc_mode
& PUFFS_VEXEC
)
187 if (acc_mode
& PUFFS_VREAD
)
189 if (acc_mode
& PUFFS_VWRITE
)
193 if (acc_mode
& PUFFS_VEXEC
)
195 if (acc_mode
& PUFFS_VREAD
)
197 if (acc_mode
& PUFFS_VWRITE
)
201 if ((file_mode
& mask
) == mask
)
208 puffs_access_chown(uid_t owner
, gid_t group
, uid_t newowner
, gid_t newgroup
,
209 const struct puffs_cred
*pcr
)
212 if (newowner
== (uid_t
)PUFFS_VNOVAL
)
214 if (newgroup
== (gid_t
)PUFFS_VNOVAL
)
217 if ((!puffs_cred_isuid(pcr
, owner
) || newowner
!= owner
||
218 ((newgroup
!= group
&& !puffs_cred_hasgroup(pcr
, newgroup
))))
219 && !puffs_cred_isjuggernaut(pcr
))
226 puffs_access_chmod(uid_t owner
, gid_t group
, enum vtype type
, mode_t mode
,
227 const struct puffs_cred
*pcr
)
230 if (!puffs_cred_isuid(pcr
, owner
) && !puffs_cred_isjuggernaut(pcr
))
233 if (!puffs_cred_isjuggernaut(pcr
)) {
234 if (type
!= VDIR
&& (mode
& S_ISTXT
))
236 if (!puffs_cred_hasgroup(pcr
, group
) && (mode
& S_ISGID
))
244 puffs_access_times(uid_t uid
, gid_t gid
, mode_t mode
, int va_utimes_null
,
245 const struct puffs_cred
*pcr
)
248 if (!puffs_cred_isuid(pcr
, uid
) && !puffs_cred_isjuggernaut(pcr
)
249 && (va_utimes_null
== 0
250 || puffs_access(VNON
, mode
, uid
, gid
, PUFFS_VWRITE
, pcr
) != 0))