diff --git a/lib/libpuffs/creds.c b/lib/libpuffs/creds.c index 560030092c6d..41f29578e434 100644 --- a/lib/libpuffs/creds.c +++ b/lib/libpuffs/creds.c @@ -1,4 +1,4 @@ -/* $NetBSD: creds.c,v 1.4 2007/03/20 18:28:08 pooka Exp $ */ +/* $NetBSD: creds.c,v 1.5 2007/03/21 19:55:55 pooka Exp $ */ /* * Copyright (c) 2006 Antti Kantee. All Rights Reserved. @@ -32,7 +32,7 @@ #include #if !defined(lint) -__RCSID("$NetBSD: creds.c,v 1.4 2007/03/20 18:28:08 pooka Exp $"); +__RCSID("$NetBSD: creds.c,v 1.5 2007/03/21 19:55:55 pooka Exp $"); #endif /* !lint */ /* @@ -186,3 +186,52 @@ puffs_access(enum vtype type, mode_t file_mode, uid_t uid, gid_t gid, else return EACCES; } + +int +puffs_access_chown(const struct puffs_cred *pcr, uid_t owner, gid_t group, + uid_t newowner, gid_t newgroup) +{ + + if (newowner == (uid_t)PUFFS_VNOVAL) + newowner = owner; + if (newgroup == (gid_t)PUFFS_VNOVAL) + newgroup = group; + + if ((!puffs_cred_isuid(pcr, owner) || newowner != owner || + ((newgroup != group && !puffs_cred_hasgroup(pcr, newgroup)))) + && !puffs_cred_isjuggernaut(pcr)) + return EPERM; + + return 0; +} + +int +puffs_access_chmod(const struct puffs_cred *pcr, uid_t owner, gid_t group, + enum vtype type, mode_t mode) +{ + + if (!puffs_cred_isuid(pcr, owner) && !puffs_cred_isuid(pcr, 0)) + return EPERM; + + if (!puffs_cred_isuid(pcr, 0)) { + if (type != VDIR && (mode & S_ISTXT)) + return EFTYPE; + if (!puffs_cred_hasgroup(pcr, group) && (mode & S_ISGID)) + return EPERM; + } + + return 0; +} + +int +puffs_access_times(const struct puffs_cred *pcr, uid_t uid, gid_t gid, + mode_t mode, int va_utimes_null) +{ + + if (!puffs_cred_isuid(pcr, uid) && !puffs_cred_isuid(pcr, 0) + && (va_utimes_null == 0 + || puffs_access(VNON, mode, uid, gid, PUFFS_VWRITE, pcr) != 0)) + return EPERM; + + return 0; +} diff --git a/lib/libpuffs/puffs.h b/lib/libpuffs/puffs.h index fe10ad85273b..efed45bcf90d 100644 --- a/lib/libpuffs/puffs.h +++ b/lib/libpuffs/puffs.h @@ -1,4 +1,4 @@ -/* $NetBSD: puffs.h,v 1.34 2007/03/20 18:28:08 pooka Exp $ */ +/* $NetBSD: puffs.h,v 1.35 2007/03/21 19:55:55 pooka Exp $ */ /* * Copyright (c) 2005, 2006 Antti Kantee. All Rights Reserved. @@ -279,26 +279,6 @@ enum { #define DENT_ADJ(a) ((a)-2) /* nth request means dir's n-2th */ -/* - * Operation credentials - */ - -/* Credential fetch */ -int puffs_cred_getuid(const struct puffs_cred *pcr, uid_t *); -int puffs_cred_getgid(const struct puffs_cred *pcr, gid_t *); -int puffs_cred_getgroups(const struct puffs_cred *pcr, gid_t *, short *); - -/* Credential check */ -int puffs_cred_isuid(const struct puffs_cred *pcr, uid_t); -int puffs_cred_hasgroup(const struct puffs_cred *pcr, gid_t); -/* kernel internal NOCRED */ -int puffs_cred_iskernel(const struct puffs_cred *pcr); -/* kernel internal FSCRED */ -int puffs_cred_isfs(const struct puffs_cred *pcr); -/* root || NOCRED || FSCRED */ -int puffs_cred_isjuggernaut(const struct puffs_cred *pcr); - - /* * protos */ @@ -454,8 +434,37 @@ int puffs_vtype2dt(enum vtype); enum vtype puffs_mode2vt(mode_t); void puffs_stat2vattr(struct vattr *va, const struct stat *); mode_t puffs_addvtype2mode(mode_t, enum vtype); -int puffs_access(enum vtype, mode_t, uid_t, gid_t, mode_t, - const struct puffs_cred *); + + +/* + * credentials & permissions + */ + +/* Credential fetch */ +int puffs_cred_getuid(const struct puffs_cred *pcr, uid_t *); +int puffs_cred_getgid(const struct puffs_cred *pcr, gid_t *); +int puffs_cred_getgroups(const struct puffs_cred *pcr, gid_t *, short *); + +/* Credential check */ +int puffs_cred_isuid(const struct puffs_cred *pcr, uid_t); +int puffs_cred_hasgroup(const struct puffs_cred *pcr, gid_t); +/* kernel internal NOCRED */ +int puffs_cred_iskernel(const struct puffs_cred *pcr); +/* kernel internal FSCRED */ +int puffs_cred_isfs(const struct puffs_cred *pcr); +/* root || NOCRED || FSCRED */ +int puffs_cred_isjuggernaut(const struct puffs_cred *pcr); + +/* misc */ +int puffs_access(enum vtype, mode_t, uid_t, gid_t, mode_t, + const struct puffs_cred *); +int puffs_access_chown(const struct puffs_cred *, uid_t, gid_t, + uid_t, gid_t); +int puffs_access_chmod(const struct puffs_cred *, uid_t, gid_t, + enum vtype, mode_t); +int puffs_access_times(const struct puffs_cred *, uid_t, gid_t, + mode_t, int); + /* * Requests