summaryrefslogtreecommitdiff
path: root/usr/src/uts/common
diff options
context:
space:
mode:
authorcasper <none@none>2007-05-25 05:43:42 -0700
committercasper <none@none>2007-05-25 05:43:42 -0700
commitf48205be61a214698b763ff550ab9e657525104c (patch)
treebc63168b8468284765bb770eb48473b7a0bf980e /usr/src/uts/common
parent7387092aa96cd872b317dfab3fee34a96c681f3e (diff)
downloadillumos-joyent-f48205be61a214698b763ff550ab9e657525104c.tar.gz
PSARC 2007/064 Unified POSIX and Windows Credentials for Solaris
4994017 data structure sharing between rpcbind and libnsl leads to accidents 6549510 Need the ability to store SIDs in the Solaris cred_t 6549515 PSARC 2007/064: uid_t and gid_t to become unsigned
Diffstat (limited to 'usr/src/uts/common')
-rw-r--r--usr/src/uts/common/Makefile.files2
-rw-r--r--usr/src/uts/common/brand/lx/procfs/lx_prvnops.c18
-rw-r--r--usr/src/uts/common/c2/audit.h2
-rw-r--r--usr/src/uts/common/c2/audit_event.c2
-rw-r--r--usr/src/uts/common/fs/cachefs/cachefs_log.c33
-rw-r--r--usr/src/uts/common/fs/dev/sdev_ptsops.c4
-rw-r--r--usr/src/uts/common/fs/fs_subr.c6
-rw-r--r--usr/src/uts/common/fs/nfs/nfs_acl_xdr.c2
-rw-r--r--usr/src/uts/common/fs/proc/prcontrol.c16
-rw-r--r--usr/src/uts/common/fs/proc/prvfsops.c2
-rw-r--r--usr/src/uts/common/fs/ufs/quota.c17
-rw-r--r--usr/src/uts/common/fs/vfs.c3
-rw-r--r--usr/src/uts/common/fs/vnode.c83
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_acl.c6
-rw-r--r--usr/src/uts/common/io/ptm.c3
-rw-r--r--usr/src/uts/common/io/ptms_conf.c6
-rw-r--r--usr/src/uts/common/ipp/flowacct/flowacct.c2
-rw-r--r--usr/src/uts/common/ipp/ipgpc/classifier.c4
-rw-r--r--usr/src/uts/common/ipp/ipgpc/filters.c13
-rw-r--r--usr/src/uts/common/os/core.c4
-rw-r--r--usr/src/uts/common/os/cred.c200
-rw-r--r--usr/src/uts/common/os/ipc.c5
-rw-r--r--usr/src/uts/common/os/modctl.c6
-rw-r--r--usr/src/uts/common/os/policy.c12
-rw-r--r--usr/src/uts/common/os/sid.c395
-rw-r--r--usr/src/uts/common/os/sysent.c6
-rw-r--r--usr/src/uts/common/rpc/auth.h9
-rw-r--r--usr/src/uts/common/rpc/sec/key_call.c9
-rw-r--r--usr/src/uts/common/rpc/sec/svcauthdes.c9
-rw-r--r--usr/src/uts/common/rpc/sec_gss/rpcsec_gss.c9
-rw-r--r--usr/src/uts/common/sys/Makefile1
-rw-r--r--usr/src/uts/common/sys/cred.h27
-rw-r--r--usr/src/uts/common/sys/cred_impl.h4
-rw-r--r--usr/src/uts/common/sys/param.h5
-rw-r--r--usr/src/uts/common/sys/policy.h1
-rw-r--r--usr/src/uts/common/sys/priv.h3
-rw-r--r--usr/src/uts/common/sys/sid.h150
-rw-r--r--usr/src/uts/common/sys/syscall.h9
-rw-r--r--usr/src/uts/common/sys/sysconfig.h9
-rw-r--r--usr/src/uts/common/sys/types.h6
-rw-r--r--usr/src/uts/common/sys/types32.h13
-rw-r--r--usr/src/uts/common/sys/unistd.h8
-rw-r--r--usr/src/uts/common/sys/vfs.h2
-rw-r--r--usr/src/uts/common/syscall/chown.c11
-rw-r--r--usr/src/uts/common/syscall/gid.c72
-rw-r--r--usr/src/uts/common/syscall/groups.c26
-rw-r--r--usr/src/uts/common/syscall/ppriv.c5
-rw-r--r--usr/src/uts/common/syscall/sidsys.c299
-rw-r--r--usr/src/uts/common/syscall/sysconfig.c5
-rw-r--r--usr/src/uts/common/syscall/uid.c71
50 files changed, 1428 insertions, 187 deletions
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files
index fd75841cbf..f5593ec93a 100644
--- a/usr/src/uts/common/Makefile.files
+++ b/usr/src/uts/common/Makefile.files
@@ -251,6 +251,8 @@ GENUNIX_OBJS += \
rw.o \
rwstlock.o \
sad_conf.o \
+ sid.o \
+ sidsys.o \
sched.o \
schedctl.o \
seg_dev.o \
diff --git a/usr/src/uts/common/brand/lx/procfs/lx_prvnops.c b/usr/src/uts/common/brand/lx/procfs/lx_prvnops.c
index bc1de2eefd..3105ac16a6 100644
--- a/usr/src/uts/common/brand/lx/procfs/lx_prvnops.c
+++ b/usr/src/uts/common/brand/lx/procfs/lx_prvnops.c
@@ -865,8 +865,8 @@ lxpr_read_pid_status(lxpr_node_t *lxpnp, lxpr_uiobuf_t *uiobuf)
"Pid:\t%d\n"
"PPid:\t%d\n"
"TracerPid:\t%d\n"
- "Uid:\t%d\t%d\t%d\t%d\n"
- "Gid:\t%d\t%d\t%d\t%d\n"
+ "Uid:\t%u\t%u\t%u\t%u\n"
+ "Gid:\t%u\t%u\t%u\t%u\n"
"FDSize:\t%d\n"
"Groups:\t",
up->u_comm,
@@ -883,7 +883,7 @@ lxpr_read_pid_status(lxpr_node_t *lxpnp, lxpr_uiobuf_t *uiobuf)
groups = crgetgroups(cr);
for (i = 0; i < ngroups; i++) {
lxpr_uiobuf_printf(uiobuf,
- "%d ",
+ "%u ",
groups[i]);
}
crfree(cr);
@@ -987,12 +987,12 @@ lxpr_read_pid_stat(lxpr_node_t *lxpnp, lxpr_uiobuf_t *uiobuf)
* Set Linux defaults if we're the zone's init process
*/
if (pid == curproc->p_zone->zone_proc_initpid) {
- pid = 1; /* PID for init */
- ppid = 0; /* parent PID for init is 0 */
- pgpid = 0; /* process group for init is 0 */
- psgid = -1; /* credential GID for init is -1 */
- spid = 0; /* session id for init is 0 */
- psdev = 0; /* session device for init is 0 */
+ pid = 1; /* PID for init */
+ ppid = 0; /* parent PID for init is 0 */
+ pgpid = 0; /* process group for init is 0 */
+ psgid = (gid_t)-1; /* credential GID for init is -1 */
+ spid = 0; /* session id for init is 0 */
+ psdev = 0; /* session device for init is 0 */
} else {
/*
* Make sure not to reference parent PIDs that reside outside
diff --git a/usr/src/uts/common/c2/audit.h b/usr/src/uts/common/c2/audit.h
index 29ef7efc38..765374d848 100644
--- a/usr/src/uts/common/c2/audit.h
+++ b/usr/src/uts/common/c2/audit.h
@@ -62,7 +62,7 @@ extern "C" {
* The user id -2 is never audited - in fact, a setauid(AU_NOAUDITID)
* will turn off auditing.
*/
-#define AU_NOAUDITID -2
+#define AU_NOAUDITID ((au_id_t)-2)
/*
* success/failure bits for asynchronous events
diff --git a/usr/src/uts/common/c2/audit_event.c b/usr/src/uts/common/c2/audit_event.c
index 8dd5e62bfa..bdf5e1cb1c 100644
--- a/usr/src/uts/common/c2/audit_event.c
+++ b/usr/src/uts/common/c2/audit_event.c
@@ -351,7 +351,7 @@ aui_null, AUE_NULL, aus_null, /* 73 (loadable) was notused */
auf_null, 0,
aui_null, AUE_NULL, aus_null, /* 74 (loadable) was notused */
auf_null, 0,
-aui_null, AUE_NULL, aus_null, /* 75 issetugid */
+aui_null, AUE_NULL, aus_null, /* 75 sidsys */
/* was sigret (SunOS) */
auf_null, 0,
aui_fsat, AUE_FSAT, aus_fsat, /* 76 fsat */
diff --git a/usr/src/uts/common/fs/cachefs/cachefs_log.c b/usr/src/uts/common/fs/cachefs/cachefs_log.c
index 0fe25933d0..8d0103cd39 100644
--- a/usr/src/uts/common/fs/cachefs/cachefs_log.c
+++ b/usr/src/uts/common/fs/cachefs/cachefs_log.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -866,7 +865,7 @@ cachefs_xdr_getpage(XDR *xdrs, struct cachefs_log_getpage_record *rec)
(! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
(! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
(! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_int(xdrs, &rec->uid)) ||
+ (! xdr_u_int(xdrs, &rec->uid)) ||
(! xdr_u_longlong_t(xdrs, &rec->offset)) ||
(! xdr_u_int(xdrs, &rec->len)))
return (FALSE);
@@ -914,7 +913,7 @@ cachefs_xdr_readdir(XDR *xdrs, struct cachefs_log_readdir_record *rec)
(! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
(! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
(! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_int(xdrs, &rec->uid)) ||
+ (! xdr_u_int(xdrs, &rec->uid)) ||
(! xdr_u_longlong_t(xdrs, (u_longlong_t *)&rec->offset)) ||
(! xdr_int(xdrs, &rec->eof)))
return (FALSE);
@@ -961,7 +960,7 @@ cachefs_xdr_readlink(XDR *xdrs, struct cachefs_log_readlink_record *rec)
(! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
(! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
(! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_int(xdrs, &rec->uid)) ||
+ (! xdr_u_int(xdrs, &rec->uid)) ||
(! xdr_u_int(xdrs, &rec->length)))
return (FALSE);
@@ -1006,7 +1005,7 @@ cachefs_xdr_remove(XDR *xdrs, struct cachefs_log_remove_record *rec)
(! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
(! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
(! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_int(xdrs, &rec->uid)))
+ (! xdr_u_int(xdrs, &rec->uid)))
return (FALSE);
return (TRUE);
@@ -1050,7 +1049,7 @@ cachefs_xdr_rmdir(XDR *xdrs, struct cachefs_log_rmdir_record *rec)
(! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
(! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
(! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_int(xdrs, &rec->uid)))
+ (! xdr_u_int(xdrs, &rec->uid)))
return (FALSE);
return (TRUE);
@@ -1095,7 +1094,7 @@ cachefs_xdr_truncate(XDR *xdrs, struct cachefs_log_truncate_record *rec)
(! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
(! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
(! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_int(xdrs, &rec->uid)) ||
+ (! xdr_u_int(xdrs, &rec->uid)) ||
(! xdr_u_longlong_t(xdrs, &rec->size)))
return (FALSE);
@@ -1142,7 +1141,7 @@ cachefs_xdr_putpage(XDR *xdrs, struct cachefs_log_putpage_record *rec)
(! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
(! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
(! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_int(xdrs, &rec->uid)) ||
+ (! xdr_u_int(xdrs, &rec->uid)) ||
(! xdr_u_longlong_t(xdrs, (u_longlong_t *)&rec->offset)) ||
(! xdr_u_int(xdrs, &rec->len)))
return (FALSE);
@@ -1188,7 +1187,7 @@ cachefs_xdr_create(XDR *xdrs, struct cachefs_log_create_record *rec)
(! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
(! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
(! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_int(xdrs, &rec->uid)))
+ (! xdr_u_int(xdrs, &rec->uid)))
return (FALSE);
return (TRUE);
@@ -1234,7 +1233,7 @@ cachefs_xdr_mkdir(XDR *xdrs, struct cachefs_log_mkdir_record *rec)
(! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
(! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
(! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_int(xdrs, &rec->uid)))
+ (! xdr_u_int(xdrs, &rec->uid)))
return (FALSE);
return (TRUE);
@@ -1279,7 +1278,7 @@ cachefs_xdr_rename(XDR *xdrs, struct cachefs_log_rename_record *rec)
(! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
(! xdr_opaque(xdrs, (caddr_t)&rec->gone, sizeof (rec->gone))) ||
(! xdr_int(xdrs, &rec->removed)) ||
- (! xdr_int(xdrs, &rec->uid)))
+ (! xdr_u_int(xdrs, &rec->uid)))
return (FALSE);
return (TRUE);
@@ -1325,7 +1324,7 @@ cachefs_xdr_symlink(XDR *xdrs, struct cachefs_log_symlink_record *rec)
(! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
(! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
(! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_int(xdrs, &rec->uid)) ||
+ (! xdr_u_int(xdrs, &rec->uid)) ||
(! xdr_u_int(xdrs, &rec->size)))
return (FALSE);
@@ -1550,7 +1549,7 @@ cachefs_xdr_gpfront(XDR *xdrs, struct cachefs_log_gpfront_record *rec)
(! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
(! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
(! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_int(xdrs, &rec->uid)) ||
+ (! xdr_u_int(xdrs, &rec->uid)) ||
(! xdr_u_longlong_t(xdrs, (u_longlong_t *)&rec->off)) ||
(! xdr_u_int(xdrs, &rec->len)))
return (FALSE);
@@ -1596,7 +1595,7 @@ cachefs_xdr_rfdir(XDR *xdrs, struct cachefs_log_rfdir_record *rec)
(! xdr_opaque(xdrs, (caddr_t)&rec->vfsp, sizeof (rec->vfsp))) ||
(! xdr_opaque(xdrs, (caddr_t)&rec->fid, sizeof (rec->fid))) ||
(! xdr_ino64(xdrs, &rec->fileno)) ||
- (! xdr_int(xdrs, &rec->uid)))
+ (! xdr_u_int(xdrs, &rec->uid)))
return (FALSE);
return (TRUE);
diff --git a/usr/src/uts/common/fs/dev/sdev_ptsops.c b/usr/src/uts/common/fs/dev/sdev_ptsops.c
index 64493f6402..4ee3a52857 100644
--- a/usr/src/uts/common/fs/dev/sdev_ptsops.c
+++ b/usr/src/uts/common/fs/dev/sdev_ptsops.c
@@ -146,8 +146,6 @@ devpts_validate(struct sdev_node *dv)
ASSERT(dv->sdev_attr);
if (dv->sdev_attr->va_uid != uid || dv->sdev_attr->va_gid != gid) {
- ASSERT(uid >= 0);
- ASSERT(gid >= 0);
dv->sdev_attr->va_uid = uid;
dv->sdev_attr->va_gid = gid;
gethrestime(&now);
@@ -208,8 +206,6 @@ devpts_create_rvp(struct sdev_node *ddv, char *nm,
*/
*vap = devpts_vattr;
vap->va_rdev = makedevice(maj, min);
- ASSERT(uid >= 0);
- ASSERT(gid >= 0);
vap->va_uid = uid;
vap->va_gid = gid;
gethrestime(&now);
diff --git a/usr/src/uts/common/fs/fs_subr.c b/usr/src/uts/common/fs/fs_subr.c
index e52ecd4182..0fe058556d 100644
--- a/usr/src/uts/common/fs/fs_subr.c
+++ b/usr/src/uts/common/fs/fs_subr.c
@@ -23,7 +23,7 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -543,12 +543,12 @@ cred_t *cr;
aclentp->a_type = OTHER_OBJ; /* Other */
aclentp->a_perm = vattr.va_mode & 0007;
- aclentp->a_id = -1; /* Really undefined */
+ aclentp->a_id = (gid_t)-1; /* Really undefined */
aclentp++;
aclentp->a_type = CLASS_OBJ; /* Class */
aclentp->a_perm = (ushort_t)(0007);
- aclentp->a_id = -1; /* Really undefined */
+ aclentp->a_id = (gid_t)-1; /* Really undefined */
} else if (vsecattr->vsa_mask & (VSA_ACECNT | VSA_ACE)) {
vsecattr->vsa_aclcnt = 6;
vsecattr->vsa_aclentp = kmem_zalloc(6 * sizeof (ace_t),
diff --git a/usr/src/uts/common/fs/nfs/nfs_acl_xdr.c b/usr/src/uts/common/fs/nfs/nfs_acl_xdr.c
index eb70bb78e9..5044c86b22 100644
--- a/usr/src/uts/common/fs/nfs/nfs_acl_xdr.c
+++ b/usr/src/uts/common/fs/nfs/nfs_acl_xdr.c
@@ -56,7 +56,7 @@
bool_t
xdr_uid(XDR *xdrs, uid32_t *objp)
{
- if (!xdr_int(xdrs, objp))
+ if (!xdr_u_int(xdrs, objp))
return (FALSE);
return (TRUE);
}
diff --git a/usr/src/uts/common/fs/proc/prcontrol.c b/usr/src/uts/common/fs/proc/prcontrol.c
index 19e5f4b604..9bbf929b5f 100644
--- a/usr/src/uts/common/fs/proc/prcontrol.c
+++ b/usr/src/uts/common/fs/proc/prcontrol.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -2137,12 +2137,12 @@ pr_scred(proc_t *p, prcred_t *prcred, cred_t *cr, boolean_t dogrps)
uid_t oldruid;
int error;
- if ((uint_t)prcred->pr_euid > MAXUID ||
- (uint_t)prcred->pr_ruid > MAXUID ||
- (uint_t)prcred->pr_suid > MAXUID ||
- (uint_t)prcred->pr_egid > MAXUID ||
- (uint_t)prcred->pr_rgid > MAXUID ||
- (uint_t)prcred->pr_sgid > MAXUID)
+ if (!VALID_UID(prcred->pr_euid) ||
+ !VALID_UID(prcred->pr_ruid) ||
+ !VALID_UID(prcred->pr_suid) ||
+ !VALID_GID(prcred->pr_egid) ||
+ !VALID_GID(prcred->pr_rgid) ||
+ !VALID_GID(prcred->pr_sgid))
return (EINVAL);
if (dogrps) {
@@ -2153,7 +2153,7 @@ pr_scred(proc_t *p, prcred_t *prcred, cred_t *cr, boolean_t dogrps)
return (EINVAL);
for (i = 0; i < ngrp; i++) {
- if ((uint_t)prcred->pr_groups[i] > MAXUID)
+ if (!VALID_GID(prcred->pr_groups[i]))
return (EINVAL);
}
}
diff --git a/usr/src/uts/common/fs/proc/prvfsops.c b/usr/src/uts/common/fs/proc/prvfsops.c
index 35d829facd..1ff5993983 100644
--- a/usr/src/uts/common/fs/proc/prvfsops.c
+++ b/usr/src/uts/common/fs/proc/prvfsops.c
@@ -72,7 +72,7 @@ static vfsdef_t vfw = {
VFSDEF_VERSION,
"proc",
prinit,
- VSW_HASPROTO|VSW_STATS,
+ VSW_HASPROTO|VSW_STATS|VSW_XID,
&proc_mntopts
};
diff --git a/usr/src/uts/common/fs/ufs/quota.c b/usr/src/uts/common/fs/ufs/quota.c
index 0dbaecc0b8..674635fda6 100644
--- a/usr/src/uts/common/fs/ufs/quota.c
+++ b/usr/src/uts/common/fs/ufs/quota.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -259,15 +258,7 @@ loop:
* Large Files: i_size need to be accessed atomically now.
*/
rw_enter(&qip->i_contents, RW_READER);
- if (uid >= 0 && dqoff(uid) >= 0 && dqoff(uid) < qip->i_size) {
- /*
- * This could almost be a static comparison with UID_MAX,
- * but we keep the ASSERT here to document the restriction
- * inherent in this simplistic database.
- */
- ASSERT((u_offset_t)uid <
- UFS_MAXOFFSET_T / sizeof (struct dqblk));
-
+ if (uid <= MAXUID && dqoff(uid) >= 0 && dqoff(uid) < qip->i_size) {
/*
* Read quota info off disk.
*/
diff --git a/usr/src/uts/common/fs/vfs.c b/usr/src/uts/common/fs/vfs.c
index eeba3e23e2..c00879da35 100644
--- a/usr/src/uts/common/fs/vfs.c
+++ b/usr/src/uts/common/fs/vfs.c
@@ -1570,6 +1570,9 @@ domount(char *fsname, struct mounta *uap, vnode_t *vp, struct cred *credp,
vfsp->vfs_fstypevsp = get_fstype_vopstats(vfsp, vswp);
}
+ if (vswp->vsw_flag & VSW_XID)
+ vfsp->vfs_flag |= VFS_XID;
+
vfs_unlock(vfsp);
}
mount_completed();
diff --git a/usr/src/uts/common/fs/vnode.c b/usr/src/uts/common/fs/vnode.c
index 5b796d6f8a..7129cfead9 100644
--- a/usr/src/uts/common/fs/vnode.c
+++ b/usr/src/uts/common/fs/vnode.c
@@ -150,6 +150,16 @@ int vopstats_enabled = 1;
}
/*
+ * If the filesystem does not support XIDs map credential
+ * If the vfsp is NULL, perhaps we should also map?
+ */
+#define VOPXID_MAP_CR(vp, cr) { \
+ vfs_t *vfsp = (vp)->v_vfsp; \
+ if (vfsp != NULL && (vfsp->vfs_flag & VFS_XID) == 0) \
+ cr = crgetmapped(cr); \
+ }
+
+/*
* Convert stat(2) formats to vnode types and vice versa. (Knows about
* numerical order of S_IFMT and vnode types.)
*/
@@ -670,6 +680,8 @@ vn_rdwr(
if (len < 0)
return (EIO);
+ VOPXID_MAP_CR(vp, cr);
+
iov.iov_base = base;
iov.iov_len = len;
uio.uio_iov = &iov;
@@ -2718,6 +2730,8 @@ fop_open(
atomic_add_32(&((*vpp)->v_wrcnt), 1);
}
+ VOPXID_MAP_CR(vp, cr);
+
ret = (*(*(vpp))->v_op->vop_open)(vpp, mode, cr);
if (ret) {
@@ -2766,6 +2780,8 @@ fop_close(
{
int err;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_close)(vp, flag, count, offset, cr);
VOPSTATS_UPDATE(vp, close);
/*
@@ -2796,6 +2812,8 @@ fop_read(
int err;
ssize_t resid_start = uiop->uio_resid;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_read)(vp, uiop, ioflag, cr, ct);
VOPSTATS_UPDATE_IO(vp, read,
read_bytes, (resid_start - uiop->uio_resid));
@@ -2813,6 +2831,8 @@ fop_write(
int err;
ssize_t resid_start = uiop->uio_resid;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_write)(vp, uiop, ioflag, cr, ct);
VOPSTATS_UPDATE_IO(vp, write,
write_bytes, (resid_start - uiop->uio_resid));
@@ -2830,6 +2850,8 @@ fop_ioctl(
{
int err;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_ioctl)(vp, cmd, arg, flag, cr, rvalp);
VOPSTATS_UPDATE(vp, ioctl);
return (err);
@@ -2844,6 +2866,8 @@ fop_setfl(
{
int err;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_setfl)(vp, oflags, nflags, cr);
VOPSTATS_UPDATE(vp, setfl);
return (err);
@@ -2858,6 +2882,8 @@ fop_getattr(
{
int err;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_getattr)(vp, vap, flags, cr);
VOPSTATS_UPDATE(vp, getattr);
return (err);
@@ -2873,6 +2899,8 @@ fop_setattr(
{
int err;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_setattr)(vp, vap, flags, cr, ct);
VOPSTATS_UPDATE(vp, setattr);
return (err);
@@ -2887,6 +2915,8 @@ fop_access(
{
int err;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_access)(vp, mode, flags, cr);
VOPSTATS_UPDATE(vp, access);
return (err);
@@ -2904,6 +2934,8 @@ fop_lookup(
{
int ret;
+ VOPXID_MAP_CR(dvp, cr);
+
ret = (*(dvp)->v_op->vop_lookup)(dvp, nm, vpp, pnp, flags, rdir, cr);
if (ret == 0 && *vpp) {
VOPSTATS_UPDATE(*vpp, lookup);
@@ -2928,6 +2960,8 @@ fop_create(
{
int ret;
+ VOPXID_MAP_CR(dvp, cr);
+
ret = (*(dvp)->v_op->vop_create)
(dvp, name, vap, excl, mode, vpp, cr, flag);
if (ret == 0 && *vpp) {
@@ -2948,6 +2982,8 @@ fop_remove(
{
int err;
+ VOPXID_MAP_CR(dvp, cr);
+
err = (*(dvp)->v_op->vop_remove)(dvp, nm, cr);
VOPSTATS_UPDATE(dvp, remove);
return (err);
@@ -2962,6 +2998,8 @@ fop_link(
{
int err;
+ VOPXID_MAP_CR(tdvp, cr);
+
err = (*(tdvp)->v_op->vop_link)(tdvp, svp, tnm, cr);
VOPSTATS_UPDATE(tdvp, link);
return (err);
@@ -2977,6 +3015,8 @@ fop_rename(
{
int err;
+ VOPXID_MAP_CR(tdvp, cr);
+
err = (*(sdvp)->v_op->vop_rename)(sdvp, snm, tdvp, tnm, cr);
VOPSTATS_UPDATE(sdvp, rename);
return (err);
@@ -2992,6 +3032,8 @@ fop_mkdir(
{
int ret;
+ VOPXID_MAP_CR(dvp, cr);
+
ret = (*(dvp)->v_op->vop_mkdir)(dvp, dirname, vap, vpp, cr);
if (ret == 0 && *vpp) {
VOPSTATS_UPDATE(*vpp, mkdir);
@@ -3013,6 +3055,8 @@ fop_rmdir(
{
int err;
+ VOPXID_MAP_CR(dvp, cr);
+
err = (*(dvp)->v_op->vop_rmdir)(dvp, nm, cdir, cr);
VOPSTATS_UPDATE(dvp, rmdir);
return (err);
@@ -3028,6 +3072,8 @@ fop_readdir(
int err;
ssize_t resid_start = uiop->uio_resid;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_readdir)(vp, uiop, cr, eofp);
VOPSTATS_UPDATE_IO(vp, readdir,
readdir_bytes, (resid_start - uiop->uio_resid));
@@ -3044,6 +3090,8 @@ fop_symlink(
{
int err;
+ VOPXID_MAP_CR(dvp, cr);
+
err = (*(dvp)->v_op->vop_symlink) (dvp, linkname, vap, target, cr);
VOPSTATS_UPDATE(dvp, symlink);
return (err);
@@ -3057,6 +3105,8 @@ fop_readlink(
{
int err;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_readlink)(vp, uiop, cr);
VOPSTATS_UPDATE(vp, readlink);
return (err);
@@ -3070,6 +3120,8 @@ fop_fsync(
{
int err;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_fsync)(vp, syncflag, cr);
VOPSTATS_UPDATE(vp, fsync);
return (err);
@@ -3082,6 +3134,9 @@ fop_inactive(
{
/* Need to update stats before vop call since we may lose the vnode */
VOPSTATS_UPDATE(vp, inactive);
+
+ VOPXID_MAP_CR(vp, cr);
+
(*(vp)->v_op->vop_inactive)(vp, cr);
}
@@ -3157,6 +3212,8 @@ fop_frlock(
{
int err;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_frlock)
(vp, cmd, bfp, flag, offset, flk_cbp, cr);
VOPSTATS_UPDATE(vp, frlock);
@@ -3175,6 +3232,8 @@ fop_space(
{
int err;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_space)(vp, cmd, bfp, flag, offset, cr, ct);
VOPSTATS_UPDATE(vp, space);
return (err);
@@ -3207,6 +3266,8 @@ fop_getpage(
{
int err;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_getpage)
(vp, off, len, protp, plarr, plsz, seg, addr, rw, cr);
VOPSTATS_UPDATE(vp, getpage);
@@ -3223,6 +3284,8 @@ fop_putpage(
{
int err;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_putpage)(vp, off, len, flags, cr);
VOPSTATS_UPDATE(vp, putpage);
return (err);
@@ -3242,6 +3305,8 @@ fop_map(
{
int err;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_map)
(vp, off, as, addrp, len, prot, maxprot, flags, cr);
VOPSTATS_UPDATE(vp, map);
@@ -3263,6 +3328,8 @@ fop_addmap(
int error;
u_longlong_t delta;
+ VOPXID_MAP_CR(vp, cr);
+
error = (*(vp)->v_op->vop_addmap)
(vp, off, as, addr, len, prot, maxprot, flags, cr);
@@ -3309,6 +3376,9 @@ fop_delmap(
{
int error;
u_longlong_t delta;
+
+ VOPXID_MAP_CR(vp, cr);
+
error = (*(vp)->v_op->vop_delmap)
(vp, off, as, addr, len, prot, maxprot, flags, cr);
@@ -3385,6 +3455,8 @@ fop_pathconf(
{
int err;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_pathconf)(vp, cmd, valp, cr);
VOPSTATS_UPDATE(vp, pathconf);
return (err);
@@ -3401,6 +3473,8 @@ fop_pageio(
{
int err;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_pageio)(vp, pp, io_off, io_len, flags, cr);
VOPSTATS_UPDATE(vp, pageio);
return (err);
@@ -3428,6 +3502,9 @@ fop_dispose(
{
/* Must do stats first since it's possible to lose the vnode */
VOPSTATS_UPDATE(vp, dispose);
+
+ VOPXID_MAP_CR(vp, cr);
+
(*(vp)->v_op->vop_dispose)(vp, pp, flag, dn, cr);
}
@@ -3440,6 +3517,8 @@ fop_setsecattr(
{
int err;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_setsecattr) (vp, vsap, flag, cr);
VOPSTATS_UPDATE(vp, setsecattr);
return (err);
@@ -3454,6 +3533,8 @@ fop_getsecattr(
{
int err;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_getsecattr) (vp, vsap, flag, cr);
VOPSTATS_UPDATE(vp, getsecattr);
return (err);
@@ -3469,6 +3550,8 @@ fop_shrlock(
{
int err;
+ VOPXID_MAP_CR(vp, cr);
+
err = (*(vp)->v_op->vop_shrlock)(vp, cmd, shr, flag, cr);
VOPSTATS_UPDATE(vp, shrlock);
return (err);
diff --git a/usr/src/uts/common/fs/zfs/zfs_acl.c b/usr/src/uts/common/fs/zfs/zfs_acl.c
index 89eec4e0aa..5eeed0bb88 100644
--- a/usr/src/uts/common/fs/zfs/zfs_acl.c
+++ b/usr/src/uts/common/fs/zfs/zfs_acl.c
@@ -343,16 +343,16 @@ zfs_acl_valid(znode_t *zp, ace_t *uace, int aclcnt, int *inherit)
switch (acep->a_flags & ACE_TYPE_FLAGS) {
case ACE_OWNER:
- acep->a_who = -1;
+ acep->a_who = (uid_t)-1;
break;
case (ACE_IDENTIFIER_GROUP | ACE_GROUP):
case ACE_IDENTIFIER_GROUP:
if (acep->a_flags & ACE_GROUP) {
- acep->a_who = -1;
+ acep->a_who = (uid_t)-1;
}
break;
case ACE_EVERYONE:
- acep->a_who = -1;
+ acep->a_who = (uid_t)-1;
break;
}
diff --git a/usr/src/uts/common/io/ptm.c b/usr/src/uts/common/io/ptm.c
index aaa4886069..8909fb516a 100644
--- a/usr/src/uts/common/io/ptm.c
+++ b/usr/src/uts/common/io/ptm.c
@@ -572,7 +572,8 @@ ptmwput(queue_t *qp, mblk_t *mp)
ptop = (pt_own_t *)mp->b_cont->b_rptr;
- if (ptop->pto_ruid < 0 || ptop->pto_rgid < 0) {
+ if (!VALID_UID(ptop->pto_ruid) ||
+ !VALID_GID(ptop->pto_rgid)) {
miocnak(qp, mp, 0, EINVAL);
break;
}
diff --git a/usr/src/uts/common/io/ptms_conf.c b/usr/src/uts/common/io/ptms_conf.c
index b1b48f748b..841826860f 100644
--- a/usr/src/uts/common/io/ptms_conf.c
+++ b/usr/src/uts/common/io/ptms_conf.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -463,8 +463,8 @@ ptms_minor_valid(minor_t dminor, uid_t *ruid, gid_t *rgid)
ASSERT(ruid);
ASSERT(rgid);
- *ruid = -1;
- *rgid = -1;
+ *ruid = (uid_t)-1;
+ *rgid = (gid_t)-1;
/*
* /dev/pts/0 is not used, but some applications may check it, so create
diff --git a/usr/src/uts/common/ipp/flowacct/flowacct.c b/usr/src/uts/common/ipp/flowacct/flowacct.c
index c319a746d9..dfffdb05e9 100644
--- a/usr/src/uts/common/ipp/flowacct/flowacct.c
+++ b/usr/src/uts/common/ipp/flowacct/flowacct.c
@@ -219,7 +219,7 @@ flowacct_find_ids(mblk_t *mp, header_t *header)
header->uid = crgetuid(cr);
header->projid = crgetprojid(cr);
} else {
- header->uid = -1;
+ header->uid = (uid_t)-1;
header->projid = -1;
}
}
diff --git a/usr/src/uts/common/ipp/ipgpc/classifier.c b/usr/src/uts/common/ipp/ipgpc/classifier.c
index a0d011968c..4f329c9d1b 100644
--- a/usr/src/uts/common/ipp/ipgpc/classifier.c
+++ b/usr/src/uts/common/ipp/ipgpc/classifier.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -614,7 +614,7 @@ find_ids(ipgpc_packet_t *packet, mblk_t *mp)
packet->uid = crgetuid(cr);
packet->projid = crgetprojid(cr);
} else {
- packet->uid = -1;
+ packet->uid = (uid_t)-1;
packet->projid = -1;
}
}
diff --git a/usr/src/uts/common/ipp/ipgpc/filters.c b/usr/src/uts/common/ipp/ipgpc/filters.c
index 7103817bcd..2add8eba6a 100644
--- a/usr/src/uts/common/ipp/ipgpc/filters.c
+++ b/usr/src/uts/common/ipp/ipgpc/filters.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -632,8 +631,8 @@ ipgpc_parse_filter(ipgpc_filter_t *filter, nvlist_t *nvlp)
}
/* parse uid */
- if (nvlist_lookup_int32(nvlp, IPGPC_UID, &filter->uid) != 0) {
- filter->uid = IPGPC_WILDCARD;
+ if (nvlist_lookup_uint32(nvlp, IPGPC_UID, &filter->uid) != 0) {
+ filter->uid = (uid_t)IPGPC_WILDCARD;
}
/* parse projid */
@@ -2337,7 +2336,7 @@ build_filter_nvlist(nvlist_t **nvlpp, ipgpc_filter_t *in_filter,
/* add uid */
if (in_filter->uid != IPGPC_WILDCARD) {
- if ((rc = nvlist_add_int32(nvlp, IPGPC_UID, in_filter->uid))
+ if ((rc = nvlist_add_uint32(nvlp, IPGPC_UID, in_filter->uid))
!= 0) {
return (rc);
}
diff --git a/usr/src/uts/common/os/core.c b/usr/src/uts/common/os/core.c
index e833022e2b..8faf69db54 100644
--- a/usr/src/uts/common/os/core.c
+++ b/usr/src/uts/common/os/core.c
@@ -490,10 +490,10 @@ expand_string(const char *pat, char *fp, int size, cred_t *cr)
(void) sprintf((s = buf), "%d", p->p_pid);
break;
case 'u': /* effective uid */
- (void) sprintf((s = buf), "%d", crgetuid(p->p_cred));
+ (void) sprintf((s = buf), "%u", crgetuid(p->p_cred));
break;
case 'g': /* effective gid */
- (void) sprintf((s = buf), "%d", crgetgid(p->p_cred));
+ (void) sprintf((s = buf), "%u", crgetgid(p->p_cred));
break;
case 'f': /* exec'd filename */
s = PTOU(p)->u_comm;
diff --git a/usr/src/uts/common/os/cred.c b/usr/src/uts/common/os/cred.c
index e6452fe4f2..4ebda51792 100644
--- a/usr/src/uts/common/os/cred.c
+++ b/usr/src/uts/common/os/cred.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -55,9 +55,18 @@
#include <sys/ucred.h>
#include <sys/prsystm.h>
#include <sys/modctl.h>
+#include <sys/avl.h>
#include <c2/audit.h>
#include <sys/zone.h>
#include <sys/tsol/label.h>
+#include <sys/sid.h>
+
+typedef struct ephidmap_data {
+ uid_t min_uid, last_uid;
+ gid_t min_gid, last_gid;
+ cred_t *nobody;
+ kmutex_t eph_lock;
+} ephidmap_data_t;
static struct kmem_cache *cred_cache;
static size_t crsize = 0;
@@ -76,6 +85,16 @@ static int get_c2audit_load(void);
#define REMOTE_PEER_CRED(c) ((c)->cr_gid == -1)
/*
+ * XXX: should be per-zone.
+ * Start with an invalid value for atomic increments.
+ */
+static ephidmap_data_t ephemeral_data = {
+ MAXUID, MAXUID, MAXUID, MAXUID
+};
+
+static boolean_t hasephids = B_FALSE;
+
+/*
* Initialize credentials data structures.
*/
@@ -111,12 +130,13 @@ cred_init(void)
dummycr = cralloc();
bzero(dummycr, crsize);
dummycr->cr_ref = 1;
- dummycr->cr_uid = -1;
- dummycr->cr_gid = -1;
- dummycr->cr_ruid = -1;
- dummycr->cr_rgid = -1;
- dummycr->cr_suid = -1;
- dummycr->cr_sgid = -1;
+ dummycr->cr_uid = (uid_t)-1;
+ dummycr->cr_gid = (gid_t)-1;
+ dummycr->cr_ruid = (uid_t)-1;
+ dummycr->cr_rgid = (gid_t)-1;
+ dummycr->cr_suid = (uid_t)-1;
+ dummycr->cr_sgid = (gid_t)-1;
+
/*
* kcred is used by anything that needs all privileges; it's
@@ -152,6 +172,13 @@ cred_init(void)
ttoproc(curthread)->p_cred = kcred;
curthread->t_cred = kcred;
+ /*
+ * nobody is used to map SID containing CRs.
+ */
+ ephemeral_data.nobody = crdup(kcred);
+ (void) crsetugid(ephemeral_data.nobody, UID_NOBODY, GID_NOBODY);
+ CR_FLAGS(kcred) = 0;
+
ucredsize = UCRED_SIZE;
}
@@ -165,6 +192,19 @@ cralloc(void)
cr->cr_ref = 1; /* So we can crfree() */
cr->cr_zone = NULL;
cr->cr_label = NULL;
+ cr->cr_ksid = NULL;
+ return (cr);
+}
+
+/*
+ * As cralloc but prepared for ksid change (if appropriate).
+ */
+cred_t *
+cralloc_ksid(void)
+{
+ cred_t *cr = cralloc();
+ if (hasephids)
+ cr->cr_ksid = kcrsid_alloc();
return (cr);
}
@@ -248,6 +288,8 @@ crfree(cred_t *cr)
label_rele(cr->cr_label);
if (cr->cr_zone)
zone_cred_rele(cr->cr_zone);
+ if (cr->cr_ksid)
+ kcrsid_rele(cr->cr_ksid);
kmem_cache_free(cred_cache, cr);
}
}
@@ -268,6 +310,8 @@ crcopy(cred_t *cr)
zone_cred_hold(newcr->cr_zone);
if (newcr->cr_label)
label_hold(cr->cr_label);
+ if (newcr->cr_ksid)
+ kcrsid_hold(cr->cr_ksid);
crfree(cr);
newcr->cr_ref = 2; /* caller gets two references */
return (newcr);
@@ -283,11 +327,18 @@ crcopy(cred_t *cr)
void
crcopy_to(cred_t *oldcr, cred_t *newcr)
{
+ credsid_t *nkcr = newcr->cr_ksid;
+
bcopy(oldcr, newcr, crsize);
if (newcr->cr_zone)
zone_cred_hold(newcr->cr_zone);
if (newcr->cr_label)
label_hold(newcr->cr_label);
+ if (nkcr) {
+ newcr->cr_ksid = nkcr;
+ kcrsidcopy_to(oldcr->cr_ksid, newcr->cr_ksid);
+ } else if (newcr->cr_ksid)
+ kcrsid_hold(newcr->cr_ksid);
crfree(oldcr);
newcr->cr_ref = 2; /* caller gets two references */
}
@@ -307,6 +358,8 @@ crdup(cred_t *cr)
zone_cred_hold(newcr->cr_zone);
if (newcr->cr_label)
label_hold(newcr->cr_label);
+ if (newcr->cr_ksid)
+ kcrsid_hold(newcr->cr_ksid);
newcr->cr_ref = 1;
return (newcr);
}
@@ -320,11 +373,18 @@ crdup(cred_t *cr)
void
crdup_to(cred_t *oldcr, cred_t *newcr)
{
+ credsid_t *nkcr = newcr->cr_ksid;
+
bcopy(oldcr, newcr, crsize);
if (newcr->cr_zone)
zone_cred_hold(newcr->cr_zone);
if (newcr->cr_label)
label_hold(newcr->cr_label);
+ if (nkcr) {
+ newcr->cr_ksid = nkcr;
+ kcrsidcopy_to(oldcr->cr_ksid, newcr->cr_ksid);
+ } else if (newcr->cr_ksid)
+ kcrsid_hold(newcr->cr_ksid);
newcr->cr_ref = 1;
}
@@ -559,14 +619,15 @@ crisremote(const cred_t *cr)
return (REMOTE_PEER_CRED(cr));
}
-#define BADID(x) ((x) != -1 && (unsigned int)(x) > MAXUID)
+#define BADUID(x) ((x) != -1 && !VALID_UID(x))
+#define BADGID(x) ((x) != -1 && !VALID_GID(x))
int
crsetresuid(cred_t *cr, uid_t r, uid_t e, uid_t s)
{
ASSERT(cr->cr_ref <= 2);
- if (BADID(r) || BADID(e) || BADID(s))
+ if (BADUID(r) || BADUID(e) || BADUID(s))
return (-1);
if (r != -1)
@@ -584,7 +645,7 @@ crsetresgid(cred_t *cr, gid_t r, gid_t e, gid_t s)
{
ASSERT(cr->cr_ref <= 2);
- if (BADID(r) || BADID(e) || BADID(s))
+ if (BADGID(r) || BADGID(e) || BADGID(s))
return (-1);
if (r != -1)
@@ -602,7 +663,7 @@ crsetugid(cred_t *cr, uid_t uid, gid_t gid)
{
ASSERT(cr->cr_ref <= 2);
- if (uid < 0 || uid > MAXUID || gid < 0 || gid > MAXUID)
+ if (!VALID_UID(uid) || !VALID_GID(gid))
return (-1);
cr->cr_uid = cr->cr_ruid = cr->cr_suid = uid;
@@ -904,3 +965,120 @@ zone_kcred(void)
else
return (kcred);
}
+
+boolean_t
+valid_ephemeral_uid(uid_t id)
+{
+ membar_consumer();
+ return (id > ephemeral_data.min_uid && id <= ephemeral_data.last_uid);
+}
+
+boolean_t
+valid_ephemeral_gid(gid_t id)
+{
+ membar_consumer();
+ return (id > ephemeral_data.min_gid && id <= ephemeral_data.last_gid);
+}
+
+int
+eph_uid_alloc(int flags, uid_t *start, int count)
+{
+ mutex_enter(&ephemeral_data.eph_lock);
+
+ /* Test for unsigned integer wrap around */
+ if (ephemeral_data.last_uid + count < ephemeral_data.last_uid) {
+ mutex_exit(&ephemeral_data.eph_lock);
+ return (-1);
+ }
+
+ /* first call or idmap crashed and state corrupted */
+ if (flags != 0)
+ ephemeral_data.min_uid = ephemeral_data.last_uid;
+
+ hasephids = B_TRUE;
+ *start = ephemeral_data.last_uid + 1;
+ atomic_add_32(&ephemeral_data.last_uid, count);
+ mutex_exit(&ephemeral_data.eph_lock);
+ return (0);
+}
+
+int
+eph_gid_alloc(int flags, gid_t *start, int count)
+{
+ mutex_enter(&ephemeral_data.eph_lock);
+
+ /* Test for unsigned integer wrap around */
+ if (ephemeral_data.last_gid + count < ephemeral_data.last_gid) {
+ mutex_exit(&ephemeral_data.eph_lock);
+ return (-1);
+ }
+
+ /* first call or idmap crashed and state corrupted */
+ if (flags != 0)
+ ephemeral_data.min_gid = ephemeral_data.last_gid;
+
+ hasephids = B_TRUE;
+ *start = ephemeral_data.last_gid + 1;
+ atomic_add_32(&ephemeral_data.last_gid, count);
+ mutex_exit(&ephemeral_data.eph_lock);
+ return (0);
+}
+
+/*
+ * If the credential contains any ephemeral IDs, map the credential
+ * to nobody.
+ */
+cred_t *
+crgetmapped(const cred_t *cr)
+{
+ if (cr->cr_ksid != NULL) {
+ int i;
+
+ for (i = 0; i < KSID_COUNT; i++)
+ if (cr->cr_ksid->kr_sidx[i].ks_id > MAXUID)
+ return (ephemeral_data.nobody);
+ if (cr->cr_ksid->kr_sidlist != NULL &&
+ cr->cr_ksid->kr_sidlist->ksl_neid > 0) {
+ return (ephemeral_data.nobody);
+ }
+ }
+
+ return ((cred_t *)cr);
+}
+
+/* index should be in range for a ksidindex_t */
+void
+crsetsid(cred_t *cr, ksid_t *ksp, int index)
+{
+ ASSERT(cr->cr_ref <= 2);
+ ASSERT(index >= 0 && index < KSID_COUNT);
+ if (cr->cr_ksid == NULL && ksp == NULL)
+ return;
+ cr->cr_ksid = kcrsid_setsid(cr->cr_ksid, ksp, index);
+}
+
+void
+crsetsidlist(cred_t *cr, ksidlist_t *ksl)
+{
+ ASSERT(cr->cr_ref <= 2);
+ if (cr->cr_ksid == NULL && ksl == NULL)
+ return;
+ cr->cr_ksid = kcrsid_setsidlist(cr->cr_ksid, ksl);
+}
+
+ksid_t *
+crgetsid(const cred_t *cr, int i)
+{
+ ASSERT(i >= 0 && i < KSID_COUNT);
+ if (cr->cr_ksid != NULL && cr->cr_ksid->kr_sidx[i].ks_domain)
+ return ((ksid_t *)&cr->cr_ksid->kr_sidx[i]);
+ return (NULL);
+}
+
+ksidlist_t *
+crgetsidlist(const cred_t *cr)
+{
+ if (cr->cr_ksid != NULL && cr->cr_ksid->kr_sidlist != NULL)
+ return ((ksidlist_t *)&cr->cr_ksid->kr_sidlist);
+ return (NULL);
+}
diff --git a/usr/src/uts/common/os/ipc.c b/usr/src/uts/common/os/ipc.c
index 0094652f15..367089e686 100644
--- a/usr/src/uts/common/os/ipc.c
+++ b/usr/src/uts/common/os/ipc.c
@@ -529,7 +529,7 @@ ipcperm_set(ipc_service_t *service, struct cred *cr,
if (secpolicy_ipc_owner(cr, kperm) != 0)
return (EPERM);
- if ((uid < 0) || (uid > MAXUID) || (gid < 0) || (gid > MAXUID))
+ if (!VALID_UID(uid) || !VALID_GID(gid))
return (EINVAL);
kperm->ipc_uid = uid;
@@ -568,8 +568,7 @@ ipcperm_set64(ipc_service_t *service, struct cred *cr,
if (secpolicy_ipc_owner(cr, kperm) != 0)
return (EPERM);
- if ((perm64->ipcx_uid < 0) || (perm64->ipcx_uid > MAXUID) ||
- (perm64->ipcx_gid < 0) || (perm64->ipcx_gid > MAXUID))
+ if (!VALID_UID(perm64->ipcx_uid) || !VALID_GID(perm64->ipcx_gid))
return (EINVAL);
kperm->ipc_uid = perm64->ipcx_uid;
diff --git a/usr/src/uts/common/os/modctl.c b/usr/src/uts/common/os/modctl.c
index 4acbaae74f..31108c215b 100644
--- a/usr/src/uts/common/os/modctl.c
+++ b/usr/src/uts/common/os/modctl.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1537,12 +1537,12 @@ process_minorperm(int cmd, nvlist_t *nvl)
nvp = nvlist_next_nvpair(nvl, nvp);
ASSERT(strcmp(nvpair_name(nvp), "uid") == 0);
if (mp)
- (void) nvpair_value_int32(nvp, &mp->mp_uid);
+ (void) nvpair_value_uint32(nvp, &mp->mp_uid);
/* gid */
nvp = nvlist_next_nvpair(nvl, nvp);
ASSERT(strcmp(nvpair_name(nvp), "gid") == 0);
if (mp) {
- (void) nvpair_value_int32(nvp, &mp->mp_gid);
+ (void) nvpair_value_uint32(nvp, &mp->mp_gid);
if (cmd == MODREMMINORPERM) {
rem_minorperm(major, name, mp, is_clone);
diff --git a/usr/src/uts/common/os/policy.c b/usr/src/uts/common/os/policy.c
index 5800e1e96f..7025453518 100644
--- a/usr/src/uts/common/os/policy.c
+++ b/usr/src/uts/common/os/policy.c
@@ -1885,3 +1885,15 @@ secpolicy_zfs(const cred_t *cr)
{
return (PRIV_POLICY(cr, PRIV_SYS_MOUNT, B_FALSE, EPERM, NULL));
}
+
+/*
+ * secpolicy_idmap
+ *
+ * Determine if the calling process has permissions to register an SID
+ * mapping daemon and allocate ephemeral IDs.
+ */
+int
+secpolicy_idmap(const cred_t *cr)
+{
+ return (PRIV_POLICY(cr, PRIV_ALL, B_FALSE, EPERM, NULL));
+}
diff --git a/usr/src/uts/common/os/sid.c b/usr/src/uts/common/os/sid.c
new file mode 100644
index 0000000000..d5bef7def5
--- /dev/null
+++ b/usr/src/uts/common/os/sid.c
@@ -0,0 +1,395 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Sid manipulation (stubs).
+ */
+
+#include <sys/atomic.h>
+#include <sys/avl.h>
+#include <sys/cmn_err.h>
+#include <sys/kmem.h>
+#include <sys/mutex.h>
+#include <sys/sid.h>
+#include <sys/sysmacros.h>
+#include <sys/systm.h>
+
+static kmutex_t sid_lock;
+static avl_tree_t sid_tree;
+static boolean_t sid_inited = B_FALSE;
+
+static ksiddomain_t
+*ksid_enterdomain(const char *dom)
+{
+ size_t len = strlen(dom) + 1;
+ ksiddomain_t *res;
+
+ ASSERT(MUTEX_HELD(&sid_lock));
+ res = kmem_alloc(sizeof (ksiddomain_t), KM_SLEEP);
+ res->kd_len = (uint_t)len;
+ res->kd_name = kmem_alloc(len, KM_SLEEP);
+ bcopy(dom, res->kd_name, len);
+
+ res->kd_ref = 1;
+
+ avl_add(&sid_tree, res);
+
+ return (res);
+}
+
+void
+ksid_hold(ksid_t *ks)
+{
+ if (ks->ks_domain != NULL)
+ ksiddomain_hold(ks->ks_domain);
+}
+
+void
+ksid_rele(ksid_t *ks)
+{
+ if (ks->ks_domain != NULL)
+ ksiddomain_rele(ks->ks_domain);
+}
+
+void
+ksiddomain_hold(ksiddomain_t *kd)
+{
+ atomic_add_32(&kd->kd_ref, 1);
+}
+
+void
+ksiddomain_rele(ksiddomain_t *kd)
+{
+ if (atomic_add_32_nv(&kd->kd_ref, -1) == 0) {
+ /*
+ * The kd reference can only be incremented from 0 when
+ * the sid_lock is held; so we lock and then check need to
+ * check for 0 again.
+ */
+ mutex_enter(&sid_lock);
+ if (kd->kd_ref == 0) {
+ avl_remove(&sid_tree, kd);
+ kmem_free(kd->kd_name, kd->kd_len);
+ kmem_free(kd, sizeof (*kd));
+ }
+ mutex_exit(&sid_lock);
+ }
+}
+
+void
+ksidlist_hold(ksidlist_t *ksl)
+{
+ atomic_add_32(&ksl->ksl_ref, 1);
+}
+
+void
+ksidlist_rele(ksidlist_t *ksl)
+{
+ if (atomic_add_32_nv(&ksl->ksl_ref, -1) == 0) {
+ int i;
+
+ for (i = 0; i < ksl->ksl_nsid; i++)
+ ksid_rele(&ksl->ksl_sids[i]);
+
+ kmem_free(ksl, KSIDLIST_MEM(ksl->ksl_nsid));
+ }
+}
+
+static int
+ksid_cmp(const void *a, const void *b)
+{
+ const ksiddomain_t *ap = a;
+ const ksiddomain_t *bp = b;
+ int res;
+
+ res = strcmp(ap->kd_name, bp->kd_name);
+ if (res > 0)
+ return (1);
+ if (res != 0)
+ return (-1);
+ return (0);
+}
+
+/*
+ * Lookup the named domain in the AVL tree.
+ * If no entry is found, add the domain to the AVL tree.
+ * The domain is returned held and needs to be released
+ * when done.
+ */
+ksiddomain_t
+*ksid_lookupdomain(const char *dom)
+{
+ ksiddomain_t *res;
+ ksiddomain_t tmpl;
+
+ mutex_enter(&sid_lock);
+
+ if (!sid_inited) {
+ avl_create(&sid_tree, ksid_cmp, sizeof (ksiddomain_t),
+ offsetof(ksiddomain_t, kd_link));
+
+ res = ksid_enterdomain(dom);
+ sid_inited = B_TRUE;
+ mutex_exit(&sid_lock);
+ return (res);
+ }
+
+ tmpl.kd_name = (char *)dom;
+
+ res = avl_find(&sid_tree, &tmpl, NULL);
+ if (res == NULL) {
+ res = ksid_enterdomain(dom);
+ } else {
+ ksiddomain_hold(res);
+ }
+
+ mutex_exit(&sid_lock);
+ return (res);
+}
+
+const char *
+ksid_getdomain(ksid_t *ks)
+{
+ return (ks->ks_domain->kd_name);
+}
+
+uint_t
+ksid_getrid(ksid_t *ks)
+{
+ return (ks->ks_rid);
+}
+
+int
+ksid_lookup(uid_t id, ksid_t *res)
+{
+ uid_t tmp;
+
+ if (idmap_call_byid(id, res) == -1)
+ return (-1);
+
+ tmp = idmap_call_bysid(res);
+ if (tmp != id)
+ cmn_err(CE_WARN, "The idmapper has gone bonkers");
+ res->ks_id = id;
+
+ return (0);
+}
+
+credsid_t *
+kcrsid_alloc(void)
+{
+ credsid_t *kcr = kmem_zalloc(sizeof (*kcr), KM_SLEEP);
+ kcr->kr_ref = 1;
+ return (kcr);
+}
+
+/*
+ * Returns a credsid_t with a refcount of 1.
+ */
+static credsid_t *
+kcrsid_dup(credsid_t *org)
+{
+ credsid_t *new;
+ ksid_index_t ki;
+
+ if (org == NULL)
+ return (kcrsid_alloc());
+ if (org->kr_ref == 1)
+ return (org);
+ new = kcrsid_alloc();
+
+ /* Copy, then update reference counts */
+ *new = *org;
+ new->kr_ref = 1;
+ for (ki = 0; ki < KSID_COUNT; ki++)
+ ksid_hold(&new->kr_sidx[ki]);
+
+ if (new->kr_sidlist != NULL)
+ ksidlist_hold(new->kr_sidlist);
+
+ kcrsid_rele(org);
+ return (new);
+}
+
+void
+kcrsid_hold(credsid_t *kcr)
+{
+ atomic_add_32(&kcr->kr_ref, 1);
+}
+
+void
+kcrsid_rele(credsid_t *kcr)
+{
+ if (atomic_add_32_nv(&kcr->kr_ref, -1) == 0) {
+ ksid_index_t i;
+
+ for (i = 0; i < KSID_COUNT; i++)
+ ksid_rele(&kcr->kr_sidx[i]);
+
+ if (kcr->kr_sidlist != NULL)
+ ksidlist_rele(kcr->kr_sidlist);
+
+ kmem_free(kcr, sizeof (*kcr));
+ }
+}
+
+/*
+ * Copy the SID credential into a previously allocated piece of memory.
+ */
+void
+kcrsidcopy_to(const credsid_t *okcr, credsid_t *nkcr)
+{
+ int i;
+
+ ASSERT(nkcr->kr_ref == 1);
+
+ if (okcr == NULL)
+ return;
+ *nkcr = *okcr;
+ for (i = 0; i < KSID_COUNT; i++)
+ ksid_hold(&nkcr->kr_sidx[i]);
+ if (nkcr->kr_sidlist != NULL)
+ ksidlist_hold(nkcr->kr_sidlist);
+ nkcr->kr_ref = 1;
+}
+
+static int
+kcrsid_sidcount(const credsid_t *kcr)
+{
+ int cnt = 0;
+ int i;
+
+ if (kcr == NULL)
+ return (0);
+
+ for (i = 0; i < KSID_COUNT; i++)
+ if (kcr->kr_sidx[i].ks_domain != NULL)
+ cnt++;
+
+ if (kcr->kr_sidlist != NULL)
+ cnt += kcr->kr_sidlist->ksl_nsid;
+ return (cnt);
+}
+
+/*
+ * Argument needs to be a ksid_t with a properly held ks_domain reference.
+ */
+credsid_t *
+kcrsid_setsid(credsid_t *okcr, ksid_t *ksp, ksid_index_t i)
+{
+ int ocnt = kcrsid_sidcount(okcr);
+ credsid_t *nkcr;
+
+ /*
+ * Unset the particular ksid; if there are no other SIDs or if this
+ * is the last SID, remove the auxilary data structure.
+ */
+ if (ksp == NULL) {
+ if (ocnt == 0 ||
+ (ocnt == 1 && okcr->kr_sidx[i].ks_domain != NULL)) {
+ if (okcr != NULL)
+ kcrsid_rele(okcr);
+ return (NULL);
+ }
+ }
+ nkcr = kcrsid_dup(okcr);
+ ksid_rele(&nkcr->kr_sidx[i]);
+ if (ksp == NULL)
+ bzero(&nkcr->kr_sidx[i], sizeof (ksid_t));
+ else
+ nkcr->kr_sidx[i] = *ksp;
+
+ return (nkcr);
+}
+
+/*
+ * Argument needs to be a ksidlist_t with properly held ks_domain references
+ * and a reference count taking the new reference into account.
+ */
+credsid_t *
+kcrsid_setsidlist(credsid_t *okcr, ksidlist_t *ksl)
+{
+ int ocnt = kcrsid_sidcount(okcr);
+ credsid_t *nkcr;
+
+ /*
+ * Unset the sidlist; if there are no further SIDs, remove the
+ * auxilary data structure.
+ */
+ if (ksl == NULL) {
+ if (ocnt == 0 || (okcr->kr_sidlist != NULL &&
+ ocnt == okcr->kr_sidlist->ksl_nsid)) {
+ if (okcr != NULL)
+ kcrsid_rele(okcr);
+ return (NULL);
+ }
+ }
+ nkcr = kcrsid_dup(okcr);
+ if (nkcr->kr_sidlist != NULL)
+ ksidlist_rele(nkcr->kr_sidlist);
+
+ nkcr->kr_sidlist = ksl;
+ return (nkcr);
+}
+
+ksidlist_t *
+kcrsid_gidstosids(int ngrp, gid_t *grp)
+{
+ int i;
+ ksidlist_t *list;
+ int cnt;
+
+ if (ngrp == 0)
+ return (NULL);
+
+ cnt = 0;
+ list = kmem_zalloc(KSIDLIST_MEM(ngrp), KM_SLEEP);
+
+ list->ksl_nsid = ngrp;
+ list->ksl_ref = 1;
+
+ for (i = 0; i < ngrp; i++) {
+ if (grp[i] > MAXUID) {
+ list->ksl_neid++;
+ if (ksid_lookup(grp[i], &list->ksl_sids[i]) != 0) {
+ while (--i >= 0)
+ ksid_rele(&list->ksl_sids[i]);
+ cnt = 0;
+ break;
+ }
+ cnt++;
+ } else {
+ list->ksl_sids[i].ks_id = grp[i];
+ }
+ }
+ if (cnt == 0) {
+ kmem_free(list, KSIDLIST_MEM(ngrp));
+ return (NULL);
+ }
+ return (list);
+}
diff --git a/usr/src/uts/common/os/sysent.c b/usr/src/uts/common/os/sysent.c
index 233de3b873..7b767297f3 100644
--- a/usr/src/uts/common/os/sysent.c
+++ b/usr/src/uts/common/os/sysent.c
@@ -84,7 +84,6 @@ int gtty();
int hrtsys();
#endif /* __i386 || __amd64 */
int ioctl();
-int issetugid();
int kill();
int labelsys();
int link();
@@ -110,6 +109,7 @@ int setgid();
int setpgrp();
int setuid();
uintptr_t shmsys();
+uint64_t sidsys();
int ssig();
int sigprocmask();
int sigsuspend();
@@ -521,7 +521,7 @@ struct sysent sysent[NSYSCALL] =
/* 72 */ SYSENT_LOADABLE(), /* exacct */
/* 73 */ SYSENT_CI("getpagesizes", getpagesizes, 2),
/* 74 */ SYSENT_CI("rctlsys", rctlsys, 6),
- /* 75 */ SYSENT_CI("issetugid", issetugid, 0),
+ /* 75 */ SYSENT_2CI("sidsys", sidsys, 4),
/* 76 */ IF_LP64(
SYSENT_CI("fsat", fsat64, 6),
SYSENT_CI("fsat", fsat32, 6)),
@@ -922,7 +922,7 @@ struct sysent sysent32[NSYSCALL] =
/* 72 */ SYSENT_LOADABLE32(), /* exacct */
/* 73 */ SYSENT_CI("getpagesizes", getpagesizes32, 2),
/* 74 */ SYSENT_CI("rctlsys", rctlsys, 6),
- /* 75 */ SYSENT_CI("issetugid", issetugid, 0),
+ /* 75 */ SYSENT_2CI("sidsys", sidsys, 4),
/* 76 */ SYSENT_CI("fsat", fsat32, 6),
/* 77 */ SYSENT_CI("lwp_park", syslwp_park, 3),
/* 78 */ SYSENT_CI("sendfilev", sendfilev, 5),
diff --git a/usr/src/uts/common/rpc/auth.h b/usr/src/uts/common/rpc/auth.h
index 3e11b15819..ab82e7799f 100644
--- a/usr/src/uts/common/rpc/auth.h
+++ b/usr/src/uts/common/rpc/auth.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@@ -365,7 +364,7 @@ extern AUTH *authdes_seccreate();
*/
#ifdef _KERNEL
-extern enum clnt_stat netname2user(char *, uid_t *, gid_t *, int *, int *);
+extern enum clnt_stat netname2user(char *, uid_t *, gid_t *, int *, gid_t *);
#endif
#ifdef __STDC__
extern int getnetname(char *);
diff --git a/usr/src/uts/common/rpc/sec/key_call.c b/usr/src/uts/common/rpc/sec/key_call.c
index 88866edbb0..382924bffe 100644
--- a/usr/src/uts/common/rpc/sec/key_call.c
+++ b/usr/src/uts/common/rpc/sec/key_call.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -199,7 +198,7 @@ key_getnetname(netname, cr)
}
enum clnt_stat
-netname2user(char *name, uid_t *uid, gid_t *gid, int *len, int *groups)
+netname2user(char *name, uid_t *uid, gid_t *gid, int *len, gid_t *groups)
{
struct getcredres res;
enum clnt_stat stat;
diff --git a/usr/src/uts/common/rpc/sec/svcauthdes.c b/usr/src/uts/common/rpc/sec/svcauthdes.c
index 4c8b23a3f4..67cd471c4b 100644
--- a/usr/src/uts/common/rpc/sec/svcauthdes.c
+++ b/usr/src/uts/common/rpc/sec/svcauthdes.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -417,7 +416,7 @@ struct bsdcred {
gid_t gid; /* cached gid */
short valid; /* valid creds */
short grouplen; /* length of cached groups */
- int groups[NGROUPS_UMAX]; /* cached groups */
+ gid_t groups[NGROUPS_UMAX]; /* cached groups */
};
/*
diff --git a/usr/src/uts/common/rpc/sec_gss/rpcsec_gss.c b/usr/src/uts/common/rpc/sec_gss/rpcsec_gss.c
index 9b93b5b505..e9495d7137 100644
--- a/usr/src/uts/common/rpc/sec_gss/rpcsec_gss.c
+++ b/usr/src/uts/common/rpc/sec_gss/rpcsec_gss.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -109,7 +108,7 @@ typedef struct _rpc_gss_data {
/* The table size must be a power of two. */
#define GSSAUTH_TABLESIZE 16
#define HASH(keynum, uid_num) \
- ((((intptr_t)(keynum)) ^ (uid_num)) & (GSSAUTH_TABLESIZE - 1))
+ ((((intptr_t)(keynum)) ^ ((int)uid_num)) & (GSSAUTH_TABLESIZE - 1))
/*
* gss auth cache entry.
diff --git a/usr/src/uts/common/sys/Makefile b/usr/src/uts/common/sys/Makefile
index c6a74fea30..184473fe4d 100644
--- a/usr/src/uts/common/sys/Makefile
+++ b/usr/src/uts/common/sys/Makefile
@@ -438,6 +438,7 @@ CHKHDRS= \
share.h \
shm.h \
shm_impl.h \
+ sid.h \
siginfo.h \
signal.h \
sleepq.h \
diff --git a/usr/src/uts/common/sys/cred.h b/usr/src/uts/common/sys/cred.h
index c1400b83d7..29e9a6ddeb 100644
--- a/usr/src/uts/common/sys/cred.h
+++ b/usr/src/uts/common/sys/cred.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -55,6 +55,8 @@ typedef struct cred cred_t;
struct proc; /* cred.h is included in proc.h */
struct prcred;
+struct ksid;
+struct ksidlist;
struct auditinfo_addr; /* cred.h is included in audit.h */
@@ -68,6 +70,7 @@ extern void cred_init(void);
extern void crhold(cred_t *);
extern void crfree(cred_t *);
extern cred_t *cralloc(void); /* all but ref uninitialized */
+extern cred_t *cralloc_ksid(void); /* cralloc() + ksid alloc'ed */
extern cred_t *crget(void); /* initialized */
extern cred_t *crcopy(cred_t *);
extern void crcopy_to(cred_t *, cred_t *);
@@ -91,6 +94,8 @@ extern gid_t crgetsgid(const cred_t *);
extern zoneid_t crgetzoneid(const cred_t *);
extern projid_t crgetprojid(const cred_t *);
+extern cred_t *crgetmapped(const cred_t *);
+
extern const struct auditinfo_addr *crgetauinfo(const cred_t *);
extern struct auditinfo_addr *crgetauinfo_modifiable(cred_t *);
@@ -145,6 +150,26 @@ struct ts_label_s;
extern struct ts_label_s *crgetlabel(const cred_t *);
extern boolean_t crisremote(const cred_t *);
+/*
+ * Private interfaces for ephemeral uids.
+ */
+#define VALID_UID(id) \
+ ((id) <= MAXUID || valid_ephemeral_uid((id)))
+#define VALID_GID(id) \
+ ((id) <= MAXUID || valid_ephemeral_gid((id)))
+
+extern boolean_t valid_ephemeral_uid(uid_t);
+extern boolean_t valid_ephemeral_gid(gid_t);
+
+extern int eph_uid_alloc(int, uid_t *, int);
+extern int eph_gid_alloc(int, gid_t *, int);
+
+extern void crsetsid(cred_t *, struct ksid *, int);
+extern void crsetsidlist(cred_t *, struct ksidlist *);
+
+extern struct ksid *crgetsid(const cred_t *, int);
+extern struct ksidlist *crgetsidlist(const cred_t *);
+
#endif /* _KERNEL */
#ifdef __cplusplus
diff --git a/usr/src/uts/common/sys/cred_impl.h b/usr/src/uts/common/sys/cred_impl.h
index ef31b60922..c2272de9a5 100644
--- a/usr/src/uts/common/sys/cred_impl.h
+++ b/usr/src/uts/common/sys/cred_impl.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,6 +31,7 @@
#include <sys/types.h>
#include <sys/cred.h>
#include <sys/priv_impl.h>
+#include <sys/sid.h>
#ifdef __cplusplus
extern "C" {
@@ -78,6 +79,7 @@ struct cred {
projid_t cr_projid; /* project */
struct zone *cr_zone; /* pointer to per-zone structure */
struct ts_label_s *cr_label; /* pointer to the effective label */
+ credsid_t *cr_ksid; /* pointer to SIDs */
gid_t cr_groups[1]; /* cr_groups size not fixed */
/* audit info is defined dynamically */
/* and valid only when audit enabled */
diff --git a/usr/src/uts/common/sys/param.h b/usr/src/uts/common/sys/param.h
index cb7ab43c2f..d73d4cf8be 100644
--- a/usr/src/uts/common/sys/param.h
+++ b/usr/src/uts/common/sys/param.h
@@ -87,6 +87,7 @@ extern "C" {
#ifdef _KERNEL
#define MAX_TASKID 999999
#define MAX_MAXPID 999999
+#define MAXEPHUID 0xfffffffcu /* max ephemeral user id */
#endif
#ifdef DEBUG
@@ -99,9 +100,12 @@ extern "C" {
#endif
#define MAXUID 2147483647 /* max user id */
+
#define MAXPROJID MAXUID /* max project id */
#define MAXLINK 32767 /* max links */
+#define MINEPHUID 0x80000000u /* min ephemeral user id */
+
#define NMOUNT 40 /* est. of # mountable fs for quota calc */
#define CANBSIZ 256 /* max size of typewriter line */
@@ -464,6 +468,7 @@ extern long _sysconf(int); /* System Private interface to sysconf() */
#define PAGEOFFSET (PAGESIZE - 1)
#define PAGEMASK (~PAGEOFFSET)
#define MAXPID ((pid_t)_sysconf(_SC_MAXPID))
+#define MAXEPHUID ((uid_t)_sysconf(_SC_EPHID_MAX))
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/sys/policy.h b/usr/src/uts/common/sys/policy.h
index 89636cf86d..4bea4a5c0c 100644
--- a/usr/src/uts/common/sys/policy.h
+++ b/usr/src/uts/common/sys/policy.h
@@ -95,6 +95,7 @@ int secpolicy_fs_config(const cred_t *, const struct vfs *);
int secpolicy_fs_linkdir(const cred_t *, const struct vfs *);
int secpolicy_fs_minfree(const cred_t *, const struct vfs *);
int secpolicy_fs_quota(const cred_t *, const struct vfs *);
+int secpolicy_idmap(const cred_t *);
int secpolicy_ip(const cred_t *, int, boolean_t);
int secpolicy_ip_config(const cred_t *, boolean_t);
int secpolicy_ipc_access(const cred_t *, const struct kipc_perm *, mode_t);
diff --git a/usr/src/uts/common/sys/priv.h b/usr/src/uts/common/sys/priv.h
index ffab3a7648..08c58ef679 100644
--- a/usr/src/uts/common/sys/priv.h
+++ b/usr/src/uts/common/sys/priv.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -81,6 +81,7 @@ typedef enum priv_op {
#define PRIVSYS_GETIMPLINFO 2
#define PRIVSYS_SETPFLAGS 3
#define PRIVSYS_GETPFLAGS 4
+#define PRIVSYS_ISSETUGID 5
/*
* Maximum length of a user defined privilege name.
diff --git a/usr/src/uts/common/sys/sid.h b/usr/src/uts/common/sys/sid.h
new file mode 100644
index 0000000000..8a2605f484
--- /dev/null
+++ b/usr/src/uts/common/sys/sid.h
@@ -0,0 +1,150 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SYS_SID_H
+#define _SYS_SID_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/avl.h>
+
+/*
+ * Kernel SID data structure and functions.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* sidsys subcodes */
+#define SIDSYS_ALLOC_IDS 0
+/* Flags for ALLOC_IDS */
+#define SID_EXTEND_RANGE 0
+#define SID_NEW_RANGE 1
+
+#define SIDSYS_IDMAP_REG 1
+#define SIDSYS_IDMAP_UNREG 2
+
+#define SIDSYS_SID2ID 0
+#define SIDSYS_ID2SID 1
+
+typedef struct domsid {
+ uint_t ds_rid;
+ char ds_dom[1];
+} domsid_t;
+
+typedef struct sidmap_call {
+ int sc_type;
+ union sc_val_u {
+ uid_t sc_id;
+ domsid_t sc_sid;
+ } sc_val;
+} sidmap_call_t;
+
+
+#ifdef _KERNEL
+/* Domains are stored in AVL trees so we can share them among SIDs */
+typedef struct ksiddomain {
+ uint_t kd_ref;
+ uint_t kd_len;
+ char *kd_name; /* Domain part of SID */
+ avl_node_t kd_link;
+} ksiddomain_t;
+
+typedef struct ksid {
+ uid_t ks_id; /* Cache of (ephemeral) uid */
+ uint32_t ks_rid; /* Rid part of the name */
+ uint32_t ks_attr; /* Attribute */
+ ksiddomain_t *ks_domain; /* Domain descsriptor */
+} ksid_t;
+
+typedef enum ksid_index {
+ KSID_USER,
+ KSID_GROUP,
+ KSID_OWNER,
+ KSID_COUNT /* Must be last */
+} ksid_index_t;
+
+/*
+ * As no memory may be allocated for credentials while holding p_crlock,
+ * all sub data structures need to be ref counted.
+ */
+
+typedef struct ksidlist {
+ uint_t ksl_ref;
+ uint_t ksl_nsid;
+ uint_t ksl_neid; /* Number of ids which are ephemeral */
+ ksid_t ksl_sids[1]; /* Allocate ksl_nsid times */
+} ksidlist_t;
+
+#define KSIDLIST_MEM(n) (sizeof (ksidlist_t) + ((n) - 1) * sizeof (ksid_t))
+
+typedef struct credsid {
+ uint_t kr_ref; /* Reference count */
+ ksid_t kr_sidx[KSID_COUNT]; /* User, group, default owner */
+ ksidlist_t *kr_sidlist; /* List of SIDS */
+} credsid_t;
+
+const char *ksid_getdomain(ksid_t *);
+uint_t ksid_getrid(ksid_t *);
+
+int ksid_lookup(uid_t, ksid_t *);
+void ksid_rele(ksid_t *);
+
+credsid_t *kcrsid_alloc(void);
+
+credsid_t *kcrsid_setsid(credsid_t *, ksid_t *, ksid_index_t);
+credsid_t *kcrsid_setsidlist(credsid_t *, ksidlist_t *);
+
+void kcrsid_rele(credsid_t *);
+void kcrsid_hold(credsid_t *);
+void kcrsidcopy_to(const credsid_t *okcr, credsid_t *nkcr);
+
+void ksiddomain_rele(ksiddomain_t *);
+void ksiddomain_hold(ksiddomain_t *);
+void ksidlist_rele(ksidlist_t *);
+void ksidlist_hold(ksidlist_t *);
+
+ksiddomain_t *ksid_lookupdomain(const char *);
+
+ksidlist_t *kcrsid_gidstosids(int, gid_t *);
+
+int idmap_call_byid(uid_t, ksid_t *);
+uid_t idmap_call_bysid(ksid_t *);
+
+#else
+
+int allocids(int, int, uid_t *, int, gid_t *);
+int idmap_reg(int);
+int idmap_unreg(int);
+
+#endif /* _KERNEL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_SID_H */
diff --git a/usr/src/uts/common/sys/syscall.h b/usr/src/uts/common/sys/syscall.h
index 55a6760b1e..4feaf1998e 100644
--- a/usr/src/uts/common/sys/syscall.h
+++ b/usr/src/uts/common/sys/syscall.h
@@ -203,7 +203,13 @@ extern "C" {
* rctllist(...) :: rctlsys(2, ...)
* rctlctl(...) :: rctlsys(3, ...)
*/
-#define SYS_issetugid 75
+#define SYS_sidsys 75
+ /*
+ * subcodes:
+ * allocids(...) :: sidsys(0, ...)
+ * idmap_reg(...) :: sidsys(1, ...)
+ * idmap_unreg(...) :: sidsys(2, ...)
+ */
#define SYS_fsat 76
/*
* subcodes:
@@ -240,6 +246,7 @@ extern "C" {
* getimplinfo(...) :: privsys(2, ...)
* setpflags(...) :: privsys(3, ...)
* getpflags(...) :: privsys(4, ...)
+ * issetugid(); :: privsys(5)
*/
#define SYS_ucredsys 83
/*
diff --git a/usr/src/uts/common/sys/sysconfig.h b/usr/src/uts/common/sys/sysconfig.h
index 56524eb5f6..1bbcdcfe98 100644
--- a/usr/src/uts/common/sys/sysconfig.h
+++ b/usr/src/uts/common/sys/sysconfig.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -24,7 +23,7 @@
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -102,6 +101,8 @@ extern int mach_sysconfig(int);
/* UNIX 03 names */
#define _CONFIG_SYMLOOP_MAX 46 /* maximum # of symlinks in pathname */
+#define _CONFIG_EPHID_MAX 47 /* maximum ephemeral uid */
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/common/sys/types.h b/usr/src/uts/common/sys/types.h
index ac5de5d5c0..3ff5497cef 100644
--- a/usr/src/uts/common/sys/types.h
+++ b/usr/src/uts/common/sys/types.h
@@ -365,11 +365,7 @@ typedef ulong_t mode_t; /* (historical version) */
#ifndef _UID_T
#define _UID_T
-#if defined(_LP64) || defined(_I32LPx)
-typedef int uid_t; /* UID type */
-#else
-typedef long uid_t; /* (historical version) */
-#endif
+typedef unsigned int uid_t; /* UID type */
#endif /* _UID_T */
typedef uid_t gid_t; /* GID type */
diff --git a/usr/src/uts/common/sys/types32.h b/usr/src/uts/common/sys/types32.h
index 527e5a7938..daa27eaf76 100644
--- a/usr/src/uts/common/sys/types32.h
+++ b/usr/src/uts/common/sys/types32.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1997-1998 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#ifndef _SYS_TYPES32_H
@@ -58,8 +57,8 @@ typedef uint32_t major32_t;
typedef uint32_t minor32_t;
typedef int32_t key32_t;
typedef uint32_t mode32_t;
-typedef int32_t uid32_t;
-typedef int32_t gid32_t;
+typedef uint32_t uid32_t;
+typedef uint32_t gid32_t;
typedef uint32_t nlink32_t;
typedef uint32_t dev32_t;
typedef int32_t pid32_t;
diff --git a/usr/src/uts/common/sys/unistd.h b/usr/src/uts/common/sys/unistd.h
index fa770b803e..92d0798426 100644
--- a/usr/src/uts/common/sys/unistd.h
+++ b/usr/src/uts/common/sys/unistd.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -26,7 +25,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -211,6 +210,7 @@ extern "C" {
#define _SC_STACK_PROT 515 /* default stack protection */
#define _SC_NPROCESSORS_MAX 516 /* maximum # of processors */
#define _SC_CPUID_MAX 517 /* maximum CPU id */
+#define _SC_EPHID_MAX 518 /* maximum ephemeral id */
/*
* POSIX.1c (pthreads) names. These values are defined above
diff --git a/usr/src/uts/common/sys/vfs.h b/usr/src/uts/common/sys/vfs.h
index 0834cf1f84..114ce97811 100644
--- a/usr/src/uts/common/sys/vfs.h
+++ b/usr/src/uts/common/sys/vfs.h
@@ -269,6 +269,7 @@ typedef struct vfs {
#define VFS_NODEVICES 0x800 /* device-special files disallowed */
#define VFS_NOEXEC 0x1000 /* executables disallowed */
#define VFS_STATS 0x2000 /* file system can collect stats */
+#define VFS_XID 0x4000 /* file system supports extended ids */
#define VFS_NORESOURCE "unspecified_resource"
#define VFS_NOMNTPT "unspecified_mountpoint"
@@ -405,6 +406,7 @@ enum {
#define VSW_NOTZONESAFE 0x08 /* zone_enter(2) should fail for these files */
#define VSW_VOLATILEDEV 0x10 /* vfs_dev can change each time fs is mounted */
#define VSW_STATS 0x20 /* file system can collect stats */
+#define VSW_XID 0x40 /* file system supports extended ids */
#define VSW_INSTALLED 0x8000 /* this vsw is associated with a file system */
diff --git a/usr/src/uts/common/syscall/chown.c b/usr/src/uts/common/syscall/chown.c
index 7dc7fc663e..d32e16b5c5 100644
--- a/usr/src/uts/common/syscall/chown.c
+++ b/usr/src/uts/common/syscall/chown.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -71,8 +70,10 @@ cfchownat(int fd, char *name, int nmflag, uid_t uid, gid_t gid, int flags)
int error = 0;
char startchar;
- if (uid < -1 || uid > MAXUID || gid < -1 || gid > MAXUID)
+ if (uid != (uid_t)-1 && !VALID_UID(uid) ||
+ gid != (gid_t)-1 && !VALID_GID(gid)) {
return (set_errno(EINVAL));
+ }
vattr.va_uid = uid;
vattr.va_gid = gid;
vattr.va_mask = 0;
diff --git a/usr/src/uts/common/syscall/gid.c b/usr/src/uts/common/syscall/gid.c
index 1cd5a4fd24..388225b600 100644
--- a/usr/src/uts/common/syscall/gid.c
+++ b/usr/src/uts/common/syscall/gid.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 1994,2001-2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -44,19 +43,28 @@
int
setgid(gid_t gid)
{
- register proc_t *p;
+ proc_t *p;
int error;
int do_nocd = 0;
cred_t *cr, *newcr;
+ ksid_t ksid, *ksp;
- if (gid < 0 || gid > MAXUID)
+ if (!VALID_GID(gid))
return (set_errno(EINVAL));
+ if (gid > MAXUID) {
+ if (ksid_lookup(gid, &ksid) != 0)
+ return (set_errno(EINVAL));
+ ksp = &ksid;
+ } else {
+ ksp = NULL;
+ }
+
/*
* Need to pre-allocate the new cred structure before grabbing
* the p_crlock mutex.
*/
- newcr = cralloc();
+ newcr = cralloc_ksid();
p = ttoproc(curthread);
mutex_enter(&p->p_crlock);
cr = p->p_cred;
@@ -67,6 +75,7 @@ setgid(gid_t gid)
crcopy_to(cr, newcr);
p->p_cred = newcr;
newcr->cr_gid = gid;
+ crsetsid(newcr, ksp, KSID_GROUP);
} else if ((error = secpolicy_allow_setid(cr, -1, B_FALSE)) == 0) {
/*
* A privileged process that makes itself look like a
@@ -81,8 +90,13 @@ setgid(gid_t gid)
newcr->cr_gid = gid;
newcr->cr_rgid = gid;
newcr->cr_sgid = gid;
- } else
+ crsetsid(newcr, ksp, KSID_GROUP);
+ } else {
crfree(newcr);
+ if (ksp != NULL)
+ ksid_rele(ksp);
+
+ }
mutex_exit(&p->p_crlock);
@@ -113,19 +127,27 @@ getgid(void)
int
setegid(gid_t gid)
{
- register proc_t *p;
- register cred_t *cr, *newcr;
+ proc_t *p;
+ cred_t *cr, *newcr;
int error = EPERM;
int do_nocd = 0;
+ ksid_t ksid, *ksp;
- if (gid < 0 || gid > MAXUID)
+ if (!VALID_GID(gid))
return (set_errno(EINVAL));
+ if (gid > MAXUID) {
+ if (ksid_lookup(gid, &ksid) != 0)
+ return (set_errno(EINVAL));
+ ksp = &ksid;
+ } else {
+ ksp = NULL;
+ }
/*
* Need to pre-allocate the new cred structure before grabbing
* the p_crlock mutex.
*/
- newcr = cralloc();
+ newcr = cralloc_ksid();
p = ttoproc(curthread);
mutex_enter(&p->p_crlock);
cr = p->p_cred;
@@ -141,8 +163,12 @@ setegid(gid_t gid)
crcopy_to(cr, newcr);
p->p_cred = newcr;
newcr->cr_gid = gid;
- } else
+ crsetsid(newcr, ksp, KSID_GROUP);
+ } else {
crfree(newcr);
+ if (ksp != NULL)
+ ksid_rele(ksp);
+ }
mutex_exit(&p->p_crlock);
@@ -172,16 +198,24 @@ setregid(gid_t rgid, gid_t egid)
int error = EPERM;
int do_nocd = 0;
cred_t *cr, *newcr;
+ ksid_t ksid, *ksp;
- if ((rgid != -1 && (rgid < 0 || rgid > MAXUID)) ||
- (egid != -1 && (egid < 0 || egid > MAXUID)))
+ if ((rgid != -1 && !VALID_GID(rgid)) ||
+ (egid != -1 && !VALID_GID(egid)))
return (set_errno(EINVAL));
+ if (egid != -1 && egid > MAXUID) {
+ if (ksid_lookup(egid, &ksid) != 0)
+ return (set_errno(EINVAL));
+ ksp = &ksid;
+ } else {
+ ksp = NULL;
+ }
/*
* Need to pre-allocate the new cred structure before grabbing
* the p_crlock mutex.
*/
- newcr = cralloc();
+ newcr = cralloc_ksid();
p = ttoproc(curthread);
mutex_enter(&p->p_crlock);
@@ -196,8 +230,10 @@ setregid(gid_t rgid, gid_t egid)
crcopy_to(cr, newcr);
p->p_cred = newcr;
- if (egid != -1)
+ if (egid != -1) {
newcr->cr_gid = egid;
+ crsetsid(newcr, ksp, KSID_GROUP);
+ }
if (rgid != -1)
newcr->cr_rgid = rgid;
/*
@@ -231,5 +267,7 @@ setregid(gid_t rgid, gid_t egid)
return (0);
}
crfree(newcr);
+ if (ksp != NULL)
+ ksid_rele(ksp);
return (set_errno(error));
}
diff --git a/usr/src/uts/common/syscall/groups.c b/usr/src/uts/common/syscall/groups.c
index 88e3777afd..b9a6c23441 100644
--- a/usr/src/uts/common/syscall/groups.c
+++ b/usr/src/uts/common/syscall/groups.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
- * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -48,6 +47,8 @@ setgroups(int gidsetsize, gid_t *gidset)
int n = gidsetsize;
gid_t *groups = NULL;
int error;
+ int scnt = 0;
+ ksidlist_t *ksl = NULL;
/* Perform the cheapest tests before grabbing p_crlock */
if (n > ngroups_max || n < 0)
@@ -62,18 +63,28 @@ setgroups(int gidsetsize, gid_t *gidset)
}
for (i = 0; i < n; i++) {
- if (groups[i] < 0 || groups[i] > MAXUID) {
+ if (!VALID_GID(groups[i])) {
+ kmem_free(groups, n * sizeof (gid_t));
+ return (set_errno(EINVAL));
+ }
+ if (groups[i] > MAXUID)
+ scnt++;
+ }
+ if (scnt > 0) {
+ ksl = kcrsid_gidstosids(n, groups);
+ if (ksl == NULL) {
kmem_free(groups, n * sizeof (gid_t));
return (set_errno(EINVAL));
}
}
}
+
/*
* Need to pre-allocate the new cred structure before acquiring
* the p_crlock mutex.
*/
- newcr = cralloc();
+ newcr = cralloc_ksid();
p = ttoproc(curthread);
mutex_enter(&p->p_crlock);
cr = p->p_cred;
@@ -82,11 +93,14 @@ setgroups(int gidsetsize, gid_t *gidset)
mutex_exit(&p->p_crlock);
if (groups != NULL)
kmem_free(groups, n * sizeof (gid_t));
+ if (ksl != NULL)
+ ksidlist_rele(ksl);
crfree(newcr);
return (set_errno(error));
}
crdup_to(cr, newcr);
+ crsetsidlist(newcr, ksl);
if (n != 0) {
bcopy(groups, newcr->cr_groups, n * sizeof (gid_t));
diff --git a/usr/src/uts/common/syscall/ppriv.c b/usr/src/uts/common/syscall/ppriv.c
index a817bcaec1..e4e04b32a4 100644
--- a/usr/src/uts/common/syscall/ppriv.c
+++ b/usr/src/uts/common/syscall/ppriv.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -336,6 +336,7 @@ int
privsys(int code, priv_op_t op, priv_ptype_t type, void *buf, size_t bufsize)
{
int retv;
+ extern int issetugid(void);
switch (code) {
case PRIVSYS_SETPPRIV:
@@ -354,6 +355,8 @@ privsys(int code, priv_op_t op, priv_ptype_t type, void *buf, size_t bufsize)
case PRIVSYS_GETPFLAGS:
retv = (int)getpflags((uint_t)op, CRED());
return (retv == -1 ? set_errno(EINVAL) : retv);
+ case PRIVSYS_ISSETUGID:
+ return (issetugid());
}
return (set_errno(EINVAL));
}
diff --git a/usr/src/uts/common/syscall/sidsys.c b/usr/src/uts/common/syscall/sidsys.c
new file mode 100644
index 0000000000..bcb749cadc
--- /dev/null
+++ b/usr/src/uts/common/syscall/sidsys.c
@@ -0,0 +1,299 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * SID system call.
+ */
+
+#include <sys/sid.h>
+#include <sys/cred.h>
+#include <sys/errno.h>
+#include <sys/systm.h>
+#include <sys/policy.h>
+#include <sys/door.h>
+
+static kmutex_t idmap_mutex;
+
+typedef struct idmap_reg {
+ door_handle_t idmap_door;
+ int idmap_flags;
+ int idmap_ref;
+} idmap_reg_t;
+
+static idmap_reg_t *idmap_ptr;
+
+static int idmap_unreg_dh(door_handle_t);
+
+static void
+idmap_freeone(idmap_reg_t *p)
+{
+ ASSERT(p->idmap_ref == 0);
+ ASSERT(MUTEX_HELD(&idmap_mutex));
+
+ door_ki_rele(p->idmap_door);
+ if (idmap_ptr == p)
+ idmap_ptr = NULL;
+
+ kmem_free(p, sizeof (*p));
+}
+
+static int
+idmap_do_call(sidmap_call_t *callp, size_t callsz, void **resp, size_t *respsz)
+{
+ door_arg_t da;
+ idmap_reg_t *p;
+ int ret;
+ int dres;
+
+ mutex_enter(&idmap_mutex);
+ p = idmap_ptr;
+ if (p != NULL) {
+ p->idmap_ref++;
+ } else {
+ mutex_exit(&idmap_mutex);
+ return (-1);
+ }
+ mutex_exit(&idmap_mutex);
+
+ da.data_ptr = (char *)callp;
+ da.data_size = callsz;
+ da.desc_ptr = NULL;
+ da.desc_num = 0;
+ da.rbuf = *resp;
+ da.rsize = *respsz;
+
+ while ((dres = door_ki_upcall(p->idmap_door, &da)) != 0) {
+ switch (dres) {
+ case EINTR:
+ case EAGAIN:
+ delay(1);
+ continue;
+ case EINVAL:
+ case EBADF:
+ (void) idmap_unreg_dh(p->idmap_door);
+ /* FALLTHROUGH */
+ default:
+ ret = -1;
+ goto out;
+ }
+ }
+ *resp = da.rbuf;
+ *respsz = da.rsize;
+ ret = 0;
+out:
+ mutex_enter(&idmap_mutex);
+ if (--p->idmap_ref == 0)
+ idmap_freeone(p);
+ mutex_exit(&idmap_mutex);
+ return (ret);
+}
+
+/*
+ * Current code only attempts to map ids to sids.
+ */
+int
+idmap_call_byid(uid_t id, ksid_t *ksid)
+{
+ sidmap_call_t call;
+ domsid_t res, *resp = &res;
+ size_t respsz = sizeof (res);
+
+ call.sc_type = SIDSYS_ID2SID;
+ call.sc_val.sc_id = id;
+
+ if (idmap_do_call(&call, sizeof (call), (void **)&resp, &respsz) != 0)
+ return (-1);
+
+ ksid->ks_domain = ksid_lookupdomain(resp->ds_dom);
+ ksid->ks_rid = resp->ds_rid;
+
+ /* Larger SID return value; this usually happens */
+ if (resp != &res)
+ kmem_free(resp, respsz);
+
+ return (0);
+}
+
+uid_t
+idmap_call_bysid(ksid_t *ksid)
+{
+ ksiddomain_t *domp = ksid->ks_domain;
+ sidmap_call_t *callp;
+ uid_t res = (uid_t)-1;
+ uid_t *resp = &res;
+ size_t callsz;
+ size_t respsz = sizeof (res);
+
+ callsz = sizeof (sidmap_call_t) + domp->kd_len;
+
+ callp = kmem_alloc(callsz, KM_SLEEP);
+ callp->sc_type = SIDSYS_SID2ID;
+ bcopy(domp->kd_name, callp->sc_val.sc_sid.ds_dom, domp->kd_len);
+ callp->sc_val.sc_sid.ds_rid = ksid->ks_rid;
+
+ if (idmap_do_call(callp, callsz, (void **)&resp, &respsz) != 0)
+ goto out;
+
+ /* Should never happen; the original buffer should be large enough */
+ if (resp != &res) {
+ kmem_free(resp, respsz);
+ goto out;
+ }
+
+ if (respsz != sizeof (uid_t))
+ res = (uid_t)-1;
+
+out:
+ kmem_free(callp, callsz);
+ return (res);
+}
+
+static int
+idmap_reg(int did)
+{
+ door_handle_t dh;
+ idmap_reg_t *idmp;
+ int err;
+
+ if ((err = secpolicy_idmap(CRED())) != 0)
+ return (set_errno(err));
+
+ dh = door_ki_lookup(did);
+
+ if (dh == NULL)
+ return (set_errno(EBADF));
+
+ idmp = kmem_alloc(sizeof (*idmp), KM_SLEEP);
+
+ idmp->idmap_door = dh;
+ mutex_enter(&idmap_mutex);
+ if (idmap_ptr != NULL) {
+ if (--idmap_ptr->idmap_ref == 0)
+ idmap_freeone(idmap_ptr);
+ }
+ idmp->idmap_flags = 0;
+ idmp->idmap_ref = 1;
+ idmap_ptr = idmp;
+ mutex_exit(&idmap_mutex);
+ return (0);
+}
+
+static int
+idmap_unreg_dh(door_handle_t dh)
+{
+ mutex_enter(&idmap_mutex);
+ if (idmap_ptr == NULL || idmap_ptr->idmap_door != dh) {
+ mutex_exit(&idmap_mutex);
+ return (EINVAL);
+ }
+
+ if (idmap_ptr->idmap_flags != 0) {
+ mutex_exit(&idmap_mutex);
+ return (EAGAIN);
+ }
+ idmap_ptr->idmap_flags = 1;
+ if (--idmap_ptr->idmap_ref == 0)
+ idmap_freeone(idmap_ptr);
+ mutex_exit(&idmap_mutex);
+ return (0);
+}
+
+static int
+idmap_unreg(int did)
+{
+ door_handle_t dh = door_ki_lookup(did);
+ int res;
+
+ if (dh == NULL)
+ return (set_errno(EINVAL));
+
+ res = idmap_unreg_dh(dh);
+ door_ki_rele(dh);
+
+ if (res != 0)
+ return (set_errno(res));
+ return (0);
+}
+
+static boolean_t
+its_my_door(void)
+{
+ mutex_enter(&idmap_mutex);
+ if (idmap_ptr != NULL) {
+ struct door_info info;
+ int err = door_ki_info(idmap_ptr->idmap_door, &info);
+ if (err == 0 && info.di_target == curproc->p_pid) {
+ mutex_exit(&idmap_mutex);
+ return (B_TRUE);
+ }
+ }
+ mutex_exit(&idmap_mutex);
+ return (B_FALSE);
+}
+
+static uint64_t
+allocids(int flag, int nuids, int ngids)
+{
+ rval_t r;
+ uid_t su = 0;
+ gid_t sg = 0;
+ int err;
+
+ if (!its_my_door())
+ return (set_errno(EPERM));
+
+ if (nuids < 0 || ngids < 0)
+ return (set_errno(EINVAL));
+
+ if (flag != 0 || nuids > 0)
+ err = eph_uid_alloc(flag, &su, nuids);
+ if (err == 0 && (flag != 0 || ngids > 0))
+ err = eph_gid_alloc(flag, &sg, ngids);
+
+ if (err != 0)
+ return (set_errno(EOVERFLOW));
+
+ r.r_val1 = su;
+ r.r_val2 = sg;
+ return (r.r_vals);
+}
+
+uint64_t
+sidsys(int op, int flag, int nuids, int ngids)
+{
+ switch (op) {
+ case SIDSYS_ALLOC_IDS:
+ return (allocids(flag, nuids, ngids));
+ case SIDSYS_IDMAP_REG:
+ return (idmap_reg(flag));
+ case SIDSYS_IDMAP_UNREG:
+ return (idmap_unreg(flag));
+ default:
+ return (set_errno(EINVAL));
+ }
+}
diff --git a/usr/src/uts/common/syscall/sysconfig.c b/usr/src/uts/common/syscall/sysconfig.c
index 02c756dcb6..5db23fee7b 100644
--- a/usr/src/uts/common/syscall/sysconfig.c
+++ b/usr/src/uts/common/syscall/sysconfig.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -164,6 +164,9 @@ sysconfig(int which)
case _CONFIG_CPUID_MAX:
return (max_cpuid);
+ case _CONFIG_EPHID_MAX:
+ return (MAXEPHUID);
+
case _CONFIG_SYMLOOP_MAX:
return (MAXSYMLINKS);
}
diff --git a/usr/src/uts/common/syscall/uid.c b/usr/src/uts/common/syscall/uid.c
index 65bcabcaf0..24e1e92f82 100644
--- a/usr/src/uts/common/syscall/uid.c
+++ b/usr/src/uts/common/syscall/uid.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -42,26 +41,35 @@
#include <sys/debug.h>
#include <sys/policy.h>
#include <sys/zone.h>
+#include <sys/sid.h>
int
setuid(uid_t uid)
{
- register proc_t *p;
+ proc_t *p;
int error;
int do_nocd = 0;
int uidchge = 0;
cred_t *cr, *newcr;
uid_t oldruid = uid;
zoneid_t zoneid = getzoneid();
+ ksid_t ksid, *ksp;
- if (uid < 0 || uid > MAXUID)
+ if (!VALID_UID(uid))
return (set_errno(EINVAL));
+ if (uid > MAXUID) {
+ if (ksid_lookup(uid, &ksid) != 0)
+ return (set_errno(EINVAL));
+ ksp = &ksid;
+ } else {
+ ksp = NULL;
+ }
/*
* Need to pre-allocate the new cred structure before grabbing
* the p_crlock mutex.
*/
- newcr = cralloc();
+ newcr = cralloc_ksid();
p = ttoproc(curthread);
@@ -75,6 +83,7 @@ retry:
crcopy_to(cr, newcr);
p->p_cred = newcr;
newcr->cr_uid = uid;
+ crsetsid(newcr, ksp, KSID_USER);
} else if ((error = secpolicy_allow_setid(cr, uid, B_FALSE)) == 0) {
if (!uidchge && uid != cr->cr_ruid) {
/*
@@ -111,9 +120,13 @@ retry:
newcr->cr_ruid = uid;
newcr->cr_suid = uid;
newcr->cr_uid = uid;
+ crsetsid(newcr, ksp, KSID_USER);
ASSERT(uid != oldruid ? uidchge : 1);
- } else
+ } else {
crfree(newcr);
+ if (ksp != NULL)
+ ksid_rele(ksp);
+ }
mutex_exit(&p->p_crlock);
@@ -155,19 +168,28 @@ getuid(void)
int
seteuid(uid_t uid)
{
- register proc_t *p;
+ proc_t *p;
int error = EPERM;
int do_nocd = 0;
cred_t *cr, *newcr;
+ ksid_t ksid, *ksp;
- if (uid < 0 || uid > MAXUID)
+ if (!VALID_UID(uid))
return (set_errno(EINVAL));
+ if (uid > MAXUID) {
+ if (ksid_lookup(uid, &ksid) != 0)
+ return (set_errno(EINVAL));
+ ksp = &ksid;
+ } else {
+ ksp = NULL;
+ }
+
/*
* Need to pre-allocate the new cred structure before grabbing
* the p_crlock mutex.
*/
- newcr = cralloc();
+ newcr = cralloc_ksid();
p = ttoproc(curthread);
mutex_enter(&p->p_crlock);
cr = p->p_cred;
@@ -185,8 +207,12 @@ seteuid(uid_t uid)
crcopy_to(cr, newcr);
p->p_cred = newcr;
newcr->cr_uid = uid;
- } else
+ crsetsid(newcr, ksp, KSID_USER);
+ } else {
crfree(newcr);
+ if (ksp != NULL)
+ ksid_rele(ksp);
+ }
mutex_exit(&p->p_crlock);
@@ -219,16 +245,25 @@ setreuid(uid_t ruid, uid_t euid)
uid_t oldruid = ruid;
cred_t *cr, *newcr;
zoneid_t zoneid = getzoneid();
+ ksid_t ksid, *ksp;
- if ((ruid != -1 && (ruid < 0 || ruid > MAXUID)) ||
- (euid != -1 && (euid < 0 || euid > MAXUID)))
+ if ((ruid != -1 && !VALID_UID(ruid)) ||
+ (euid != -1 && !VALID_UID(euid)))
return (set_errno(EINVAL));
+ if (euid != -1 && euid > MAXUID) {
+ if (ksid_lookup(euid, &ksid) != 0)
+ return (set_errno(EINVAL));
+ ksp = &ksid;
+ } else {
+ ksp = NULL;
+ }
+
/*
* Need to pre-allocate the new cred structure before grabbing
* the p_crlock mutex.
*/
- newcr = cralloc();
+ newcr = cralloc_ksid();
p = ttoproc(curthread);
@@ -269,8 +304,10 @@ retry:
crcopy_to(cr, newcr);
p->p_cred = newcr;
- if (euid != -1)
+ if (euid != -1) {
newcr->cr_uid = euid;
+ crsetsid(newcr, ksp, KSID_USER);
+ }
if (ruid != -1) {
oldruid = newcr->cr_ruid;
newcr->cr_ruid = ruid;
@@ -319,5 +356,7 @@ retry:
return (0);
}
crfree(newcr);
+ if (ksp != NULL)
+ ksid_rele(ksp);
return (set_errno(error));
}