summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjp151216 <none@none>2008-01-04 13:09:02 -0800
committerjp151216 <none@none>2008-01-04 13:09:02 -0800
commitbda89588bd7667394a834e8a9a34612cce2ae9c3 (patch)
tree1226b1cea0d00fb32b21d27ea65b184516cd8c84
parent30ac2e7bcba3a0a4c91d060d5ac3d60cd00f7a3a (diff)
downloadillumos-gate-bda89588bd7667394a834e8a9a34612cce2ae9c3.tar.gz
6552639 Each zone should have it's own idmapd
-rw-r--r--usr/src/cmd/idmap/idmapd/idmapd.c11
-rw-r--r--usr/src/uts/common/fs/proc/prcontrol.c197
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_util.c20
-rw-r--r--usr/src/uts/common/fs/xattr.c12
-rw-r--r--usr/src/uts/common/fs/zfs/sys/zfs_acl.h4
-rw-r--r--usr/src/uts/common/fs/zfs/sys/zfs_fuid.h12
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_acl.c45
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_dir.c8
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_fuid.c30
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_vnops.c18
-rw-r--r--usr/src/uts/common/idmap/idmap_kapi.c437
-rw-r--r--usr/src/uts/common/idmap/idmap_mod.c3
-rw-r--r--usr/src/uts/common/io/ptm.c11
-rw-r--r--usr/src/uts/common/os/cred.c234
-rw-r--r--usr/src/uts/common/os/ipc.c12
-rw-r--r--usr/src/uts/common/os/policy.c4
-rw-r--r--usr/src/uts/common/os/sid.c17
-rw-r--r--usr/src/uts/common/sys/cred.h19
-rw-r--r--usr/src/uts/common/sys/kidmap.h37
-rw-r--r--usr/src/uts/common/sys/sid.h15
-rw-r--r--usr/src/uts/common/syscall/chown.c7
-rw-r--r--usr/src/uts/common/syscall/gid.c20
-rw-r--r--usr/src/uts/common/syscall/groups.c8
-rw-r--r--usr/src/uts/common/syscall/sidsys.c33
-rw-r--r--usr/src/uts/common/syscall/uid.c19
-rw-r--r--usr/src/uts/intel/ia32/ml/modstubs.s36
-rw-r--r--usr/src/uts/sparc/ml/modstubs.s36
27 files changed, 773 insertions, 532 deletions
diff --git a/usr/src/cmd/idmap/idmapd/idmapd.c b/usr/src/cmd/idmap/idmapd/idmapd.c
index d43b0e7b86..b27c333fdb 100644
--- a/usr/src/cmd/idmap/idmapd/idmapd.c
+++ b/usr/src/cmd/idmap/idmapd/idmapd.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -213,9 +213,10 @@ main(int argc, char **argv)
(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);
- if (getzoneid() != GLOBAL_ZONEID) {
+ if (is_system_labeled() && getzoneid() != GLOBAL_ZONEID) {
(void) idmapdlog(LOG_ERR,
- "idmapd: idmapd runs only in the global zone");
+ "idmapd: with Trusted Extensions idmapd runs only in the "
+ "global zone");
exit(1);
}
@@ -313,7 +314,7 @@ init_idmapd() {
}
if ((error = idmap_reg(dfd)) != 0) {
idmapdlog(LOG_ERR, "idmapd: unable to register door (%s)",
- strerror(error));
+ strerror(errno));
goto errout;
}
@@ -321,7 +322,7 @@ init_idmapd() {
8192, &_idmapdstate.next_uid,
8192, &_idmapdstate.next_gid)) != 0) {
idmapdlog(LOG_ERR, "idmapd: unable to allocate ephemeral IDs "
- "(%s)", strerror(error));
+ "(%s)", strerror(errno));
_idmapdstate.next_uid = _idmapdstate.limit_uid = SENTINEL_PID;
_idmapdstate.next_gid = _idmapdstate.limit_gid = SENTINEL_PID;
} else {
diff --git a/usr/src/uts/common/fs/proc/prcontrol.c b/usr/src/uts/common/fs/proc/prcontrol.c
index f4b20a4045..227b732fc3 100644
--- a/usr/src/uts/common/fs/proc/prcontrol.c
+++ b/usr/src/uts/common/fs/proc/prcontrol.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -309,40 +309,41 @@ pr_control(long cmd, arg_t *argp, prnode_t *pnp, cred_t *cr)
case PCDSTOP: /* direct process or lwp to stop, don't wait */
case PCWSTOP: /* wait for process or lwp to stop */
case PCTWSTOP: /* wait for process or lwp to stop, with timeout */
- {
- time_t timeo;
+ {
+ time_t timeo;
- /*
- * Can't apply to a system process.
- */
- if ((p->p_flag & SSYS) || p->p_as == &kas) {
- error = EBUSY;
- break;
- }
+ /*
+ * Can't apply to a system process.
+ */
+ if ((p->p_flag & SSYS) || p->p_as == &kas) {
+ error = EBUSY;
+ break;
+ }
- if (cmd == PCSTOP || cmd == PCDSTOP)
- pr_stop(pnp);
+ if (cmd == PCSTOP || cmd == PCDSTOP)
+ pr_stop(pnp);
- if (cmd == PCDSTOP)
- break;
+ if (cmd == PCDSTOP)
+ break;
- /*
- * If an lwp is waiting for itself or its process, don't wait.
- * The stopped lwp would never see the fact that it is stopped.
- */
- if ((pcp->prc_flags & PRC_LWP)?
- (pcp->prc_thread == curthread) : (p == curproc)) {
- if (cmd == PCWSTOP || cmd == PCTWSTOP)
- error = EBUSY;
- break;
- }
+ /*
+ * If an lwp is waiting for itself or its process,
+ * don't wait. The stopped lwp would never see the
+ * fact that it is stopped.
+ */
+ if ((pcp->prc_flags & PRC_LWP)?
+ (pcp->prc_thread == curthread) : (p == curproc)) {
+ if (cmd == PCWSTOP || cmd == PCTWSTOP)
+ error = EBUSY;
+ break;
+ }
timeo = (cmd == PCTWSTOP)? (time_t)argp->timeo : 0;
if ((error = pr_wait_stop(pnp, timeo)) != 0)
return (error);
break;
- }
+ }
case PCRUN: /* make lwp or process runnable */
error = pr_setrun(pnp, argp->flags);
@@ -392,20 +393,20 @@ pr_control(long cmd, arg_t *argp, prnode_t *pnp, cred_t *cr)
break;
case PCSREG: /* set general registers */
- {
- kthread_t *t = pr_thread(pnp);
+ {
+ kthread_t *t = pr_thread(pnp);
- if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) {
- thread_unlock(t);
- error = EBUSY;
- } else {
- thread_unlock(t);
- mutex_exit(&p->p_lock);
- prsetprregs(ttolwp(t), argp->prgregset, 0);
- mutex_enter(&p->p_lock);
+ if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) {
+ thread_unlock(t);
+ error = EBUSY;
+ } else {
+ thread_unlock(t);
+ mutex_exit(&p->p_lock);
+ prsetprregs(ttolwp(t), argp->prgregset, 0);
+ mutex_enter(&p->p_lock);
+ }
+ break;
}
- break;
- }
case PCSFPREG: /* set floating-point registers */
error = pr_setfpregs(pnp, &argp->prfpregset);
@@ -732,40 +733,41 @@ pr_control32(int32_t cmd, arg32_t *argp, prnode_t *pnp, cred_t *cr)
case PCDSTOP: /* direct process or lwp to stop, don't wait */
case PCWSTOP: /* wait for process or lwp to stop */
case PCTWSTOP: /* wait for process or lwp to stop, with timeout */
- {
- time_t timeo;
+ {
+ time_t timeo;
- /*
- * Can't apply to a system process.
- */
- if ((p->p_flag & SSYS) || p->p_as == &kas) {
- error = EBUSY;
- break;
- }
+ /*
+ * Can't apply to a system process.
+ */
+ if ((p->p_flag & SSYS) || p->p_as == &kas) {
+ error = EBUSY;
+ break;
+ }
- if (cmd == PCSTOP || cmd == PCDSTOP)
- pr_stop(pnp);
+ if (cmd == PCSTOP || cmd == PCDSTOP)
+ pr_stop(pnp);
- if (cmd == PCDSTOP)
- break;
+ if (cmd == PCDSTOP)
+ break;
- /*
- * If an lwp is waiting for itself or its process, don't wait.
- * The lwp will never see the fact that itself is stopped.
- */
- if ((pcp->prc_flags & PRC_LWP)?
- (pcp->prc_thread == curthread) : (p == curproc)) {
- if (cmd == PCWSTOP || cmd == PCTWSTOP)
- error = EBUSY;
- break;
- }
+ /*
+ * If an lwp is waiting for itself or its process,
+ * don't wait. The lwp will never see the fact that
+ * itself is stopped.
+ */
+ if ((pcp->prc_flags & PRC_LWP)?
+ (pcp->prc_thread == curthread) : (p == curproc)) {
+ if (cmd == PCWSTOP || cmd == PCTWSTOP)
+ error = EBUSY;
+ break;
+ }
- timeo = (cmd == PCTWSTOP)? (time_t)argp->timeo : 0;
- if ((error = pr_wait_stop(pnp, timeo)) != 0)
- return (error);
+ timeo = (cmd == PCTWSTOP)? (time_t)argp->timeo : 0;
+ if ((error = pr_wait_stop(pnp, timeo)) != 0)
+ return (error);
- break;
- }
+ break;
+ }
case PCRUN: /* make lwp or process runnable */
error = pr_setrun(pnp, (ulong_t)argp->flags);
@@ -839,7 +841,7 @@ pr_control32(int32_t cmd, arg32_t *argp, prnode_t *pnp, cred_t *cr)
thread_unlock(t);
mutex_exit(&p->p_lock);
prgregset_32ton(lwp, argp->prgregset,
- prgregset);
+ prgregset);
prsetprregs(lwp, prgregset, 0);
mutex_enter(&p->p_lock);
}
@@ -933,38 +935,39 @@ pr_control32(int32_t cmd, arg32_t *argp, prnode_t *pnp, cred_t *cr)
(void *)(uintptr_t)argp->priovec.pio_base;
priovec.pio_len = (size_t)argp->priovec.pio_len;
priovec.pio_offset = (off_t)
- (uint32_t)argp->priovec.pio_offset;
+ (uint32_t)argp->priovec.pio_offset;
error = pr_rdwr(p, rw, &priovec);
}
break;
case PCSCRED: /* set the process credentials */
case PCSCREDX:
- {
- /*
- * All the fields in these structures are exactly the same
- * and so the structures are compatible. In case this
- * ever changes, we catch this with the ASSERT below.
- */
- prcred_t *prcred = (prcred_t *)&argp->prcred;
+ {
+ /*
+ * All the fields in these structures are exactly the
+ * same and so the structures are compatible. In case
+ * this ever changes, we catch this with the ASSERT
+ * below.
+ */
+ prcred_t *prcred = (prcred_t *)&argp->prcred;
#ifndef __lint
- ASSERT(sizeof (prcred_t) == sizeof (prcred32_t));
+ ASSERT(sizeof (prcred_t) == sizeof (prcred32_t));
#endif
- error = pr_scred(p, prcred, cr, cmd == PCSCREDX);
- break;
- }
+ error = pr_scred(p, prcred, cr, cmd == PCSCREDX);
+ break;
+ }
case PCSPRIV: /* set the process privileges */
- {
- error = pr_spriv(p, &argp->prpriv, cr);
- break;
- }
+ {
+ error = pr_spriv(p, &argp->prpriv, cr);
+ break;
+ }
case PCSZONE: /* set the process's zoneid */
- error = pr_szoneid(p, (zoneid_t)argp->przoneid, cr);
- break;
+ error = pr_szoneid(p, (zoneid_t)argp->przoneid, cr);
+ break;
}
if (error)
@@ -1922,9 +1925,8 @@ pr_watch(prnode_t *pnp, prwatch_t *pwp, int *unlocked)
pwa->wa_eaddr = (caddr_t)vaddr + size;
pwa->wa_flags = (ulong_t)wflags;
- error = ((pwa->wa_flags & ~WA_TRAPAFTER) == 0)?
- clear_watched_area(p, pwa) :
- set_watched_area(p, pwa);
+ error = ((pwa->wa_flags & ~WA_TRAPAFTER) == 0) ?
+ clear_watched_area(p, pwa) : set_watched_area(p, pwa);
if (p == curproc) {
setallwatch();
@@ -2136,13 +2138,14 @@ pr_scred(proc_t *p, prcred_t *prcred, cred_t *cr, boolean_t dogrps)
cred_t *newcred;
uid_t oldruid;
int error;
-
- 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))
+ zone_t *zone = crgetzone(cr);
+
+ if (!VALID_UID(prcred->pr_euid, zone) ||
+ !VALID_UID(prcred->pr_ruid, zone) ||
+ !VALID_UID(prcred->pr_suid, zone) ||
+ !VALID_GID(prcred->pr_egid, zone) ||
+ !VALID_GID(prcred->pr_rgid, zone) ||
+ !VALID_GID(prcred->pr_sgid, zone))
return (EINVAL);
if (dogrps) {
@@ -2153,7 +2156,7 @@ pr_scred(proc_t *p, prcred_t *prcred, cred_t *cr, boolean_t dogrps)
return (EINVAL);
for (i = 0; i < ngrp; i++) {
- if (!VALID_GID(prcred->pr_groups[i]))
+ if (!VALID_GID(prcred->pr_groups[i], zone))
return (EINVAL);
}
}
@@ -2182,9 +2185,9 @@ pr_scred(proc_t *p, prcred_t *prcred, cred_t *cr, boolean_t dogrps)
/* Error checking done above */
(void) crsetresuid(newcred, prcred->pr_ruid, prcred->pr_euid,
- prcred->pr_suid);
+ prcred->pr_suid);
(void) crsetresgid(newcred, prcred->pr_rgid, prcred->pr_egid,
- prcred->pr_sgid);
+ prcred->pr_sgid);
if (dogrps) {
(void) crsetgroups(newcred, prcred->pr_ngroups,
diff --git a/usr/src/uts/common/fs/smbsrv/smb_util.c b/usr/src/uts/common/fs/smbsrv/smb_util.c
index beb39a6e51..55c056141c 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_util.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_util.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1251,6 +1251,10 @@ smb_rwx_rwwait(
* with binary SIDs understandable by CIFS clients. A layer of SMB ID
* mapping functions are implemeted to hide the SID conversion details
* and also hide the handling of array of batch mapping requests.
+ *
+ * IMPORTANT NOTE The Winchester API requires a zone. Because CIFS server
+ * currently only runs in the global zone the global zone is specified.
+ * This needs to be fixed when the CIFS server supports zones.
*/
static int smb_idmap_batch_binsid(smb_idmap_batch_t *sib);
@@ -1275,17 +1279,17 @@ smb_idmap_getid(nt_sid_t *sid, uid_t *id, int *idtype)
switch (*idtype) {
case SMB_IDMAP_USER:
- sim.sim_stat = kidmap_getuidbysid(sim.sim_domsid,
+ sim.sim_stat = kidmap_getuidbysid(global_zone, sim.sim_domsid,
sim.sim_rid, sim.sim_id);
break;
case SMB_IDMAP_GROUP:
- sim.sim_stat = kidmap_getgidbysid(sim.sim_domsid,
+ sim.sim_stat = kidmap_getgidbysid(global_zone, sim.sim_domsid,
sim.sim_rid, sim.sim_id);
break;
case SMB_IDMAP_UNKNOWN:
- sim.sim_stat = kidmap_getpidbysid(sim.sim_domsid,
+ sim.sim_stat = kidmap_getpidbysid(global_zone, sim.sim_domsid,
sim.sim_rid, sim.sim_id, &sim.sim_idtype);
break;
@@ -1313,12 +1317,12 @@ smb_idmap_getsid(uid_t id, int idtype, nt_sid_t **sid)
switch (idtype) {
case SMB_IDMAP_USER:
- sim.sim_stat = kidmap_getsidbyuid(id,
+ sim.sim_stat = kidmap_getsidbyuid(global_zone, id,
(const char **)&sim.sim_domsid, &sim.sim_rid);
break;
case SMB_IDMAP_GROUP:
- sim.sim_stat = kidmap_getsidbygid(id,
+ sim.sim_stat = kidmap_getsidbygid(global_zone, id,
(const char **)&sim.sim_domsid, &sim.sim_rid);
break;
@@ -1366,9 +1370,7 @@ smb_idmap_batch_create(smb_idmap_batch_t *sib, uint16_t nmap, int flags)
bzero(sib, sizeof (smb_idmap_batch_t));
- sib->sib_idmaph = kidmap_get_create();
- if (sib->sib_idmaph == NULL)
- return (IDMAP_ERR_INTERNAL);
+ sib->sib_idmaph = kidmap_get_create(global_zone);
sib->sib_flags = flags;
sib->sib_nmap = nmap;
diff --git a/usr/src/uts/common/fs/xattr.c b/usr/src/uts/common/fs/xattr.c
index 9c28d9a5c9..418d598cc9 100644
--- a/usr/src/uts/common/fs/xattr.c
+++ b/usr/src/uts/common/fs/xattr.c
@@ -307,7 +307,7 @@ xattr_fill_nvlist(vnode_t *vp, xattr_view_t xattr_view, nvlist_t *nvlp,
if (nvlist_alloc(&nvl_sid, NV_UNIQUE_NAME, KM_SLEEP))
return (ENOMEM);
- if (kidmap_getsidbyuid(xvattr.xva_vattr.va_uid,
+ if (kidmap_getsidbyuid(crgetzone(cr), xvattr.xva_vattr.va_uid,
&domain, &rid) == 0) {
VERIFY(nvlist_add_string(nvl_sid,
SID_DOMAIN, domain) == 0);
@@ -323,7 +323,7 @@ xattr_fill_nvlist(vnode_t *vp, xattr_view_t xattr_view, nvlist_t *nvlp,
if (nvlist_alloc(&nvl_sid, NV_UNIQUE_NAME, KM_SLEEP))
return (ENOMEM);
- if (kidmap_getsidbygid(xvattr.xva_vattr.va_gid,
+ if (kidmap_getsidbygid(crgetzone(cr), xvattr.xva_vattr.va_gid,
&domain, &rid) == 0) {
VERIFY(nvlist_add_string(nvl_sid,
SID_DOMAIN, domain) == 0);
@@ -647,12 +647,12 @@ xattr_file_write(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr,
*/
if (attr == F_OWNERSID) {
- (void) kidmap_getuidbysid(domain, rid,
- &xvattr.xva_vattr.va_uid);
+ (void) kidmap_getuidbysid(crgetzone(cr), domain,
+ rid, &xvattr.xva_vattr.va_uid);
xvattr.xva_vattr.va_mask |= AT_UID;
} else {
- (void) kidmap_getgidbysid(domain, rid,
- &xvattr.xva_vattr.va_gid);
+ (void) kidmap_getgidbysid(crgetzone(cr), domain,
+ rid, &xvattr.xva_vattr.va_gid);
xvattr.xva_vattr.va_mask |= AT_GID;
}
break;
diff --git a/usr/src/uts/common/fs/zfs/sys/zfs_acl.h b/usr/src/uts/common/fs/zfs/sys/zfs_acl.h
index 6a7724cee4..1e6656612a 100644
--- a/usr/src/uts/common/fs/zfs/sys/zfs_acl.h
+++ b/usr/src/uts/common/fs/zfs/sys/zfs_acl.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -198,7 +198,7 @@ extern int zfs_zaccess(struct znode *, int, int, boolean_t, cred_t *);
extern int zfs_zaccess_rwx(struct znode *, mode_t, int, cred_t *);
extern int zfs_zaccess_unix(struct znode *, mode_t, cred_t *);
extern int zfs_acl_access(struct znode *, int, cred_t *);
-int zfs_acl_chmod_setattr(struct znode *, uint64_t, dmu_tx_t *);
+int zfs_acl_chmod_setattr(struct znode *, uint64_t, dmu_tx_t *, cred_t *);
int zfs_zaccess_delete(struct znode *, struct znode *, cred_t *);
int zfs_zaccess_rename(struct znode *, struct znode *,
struct znode *, struct znode *, cred_t *cr);
diff --git a/usr/src/uts/common/fs/zfs/sys/zfs_fuid.h b/usr/src/uts/common/fs/zfs/sys/zfs_fuid.h
index 3f46ff7e3e..56f1073607 100644
--- a/usr/src/uts/common/fs/zfs/sys/zfs_fuid.h
+++ b/usr/src/uts/common/fs/zfs/sys/zfs_fuid.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -102,15 +102,17 @@ typedef struct zfs_fuid_info {
#ifdef _KERNEL
struct znode;
-extern void zfs_fuid_map_id(zfsvfs_t *, uint64_t, zfs_fuid_type_t, uid_t *);
+extern void zfs_fuid_map_id(zfsvfs_t *, uint64_t, cred_t *, zfs_fuid_type_t,
+ uid_t *);
extern void zfs_fuid_destroy(zfsvfs_t *);
extern uint64_t zfs_fuid_create_cred(zfsvfs_t *, uint64_t, zfs_fuid_type_t,
dmu_tx_t *, cred_t *, zfs_fuid_info_t **);
-extern uint64_t zfs_fuid_create(zfsvfs_t *, uint64_t, zfs_fuid_type_t,
+extern uint64_t zfs_fuid_create(zfsvfs_t *, uint64_t, cred_t *, zfs_fuid_type_t,
dmu_tx_t *, zfs_fuid_info_t **);
extern void zfs_fuid_queue_map_id(zfsvfs_t *zfsvfs, zfs_fuid_hdl_t *,
- uint64_t, zfs_fuid_type_t, uid_t *);
-extern void zfs_fuid_map_ids(struct znode *zp, uid_t *uid, uid_t *gid);
+ uint64_t, cred_t *, zfs_fuid_type_t, uid_t *);
+extern void zfs_fuid_map_ids(struct znode *zp, cred_t *cr, uid_t *uid,
+ uid_t *gid);
extern void zfs_fuid_get_mappings(zfs_fuid_hdl_t *);
extern char *zfs_fuid_find_by_idx(zfsvfs_t *, uint64_t);
int zfs_fuid_find_by_domain(zfsvfs_t *, const char *, char **, dmu_tx_t *);
diff --git a/usr/src/uts/common/fs/zfs/zfs_acl.c b/usr/src/uts/common/fs/zfs/zfs_acl.c
index 7846d4050e..482c53bd96 100644
--- a/usr/src/uts/common/fs/zfs/zfs_acl.c
+++ b/usr/src/uts/common/fs/zfs/zfs_acl.c
@@ -584,7 +584,8 @@ zfs_copy_ace_2_fuid(vtype_t obj_type, zfs_acl_t *aclp, void *datap,
* Copy ZFS ACEs to fixed size ace_t layout
*/
static void
-zfs_copy_fuid_2_ace(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, void *datap, int filter)
+zfs_copy_fuid_2_ace(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, cred_t *cr,
+ void *datap, int filter)
{
uint64_t who;
uint32_t access_mask;
@@ -627,7 +628,7 @@ zfs_copy_fuid_2_ace(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, void *datap, int filter)
if ((entry_type != ACE_OWNER &&
entry_type != (ACE_GROUP | ACE_IDENTIFIER_GROUP) &&
entry_type != ACE_EVERYONE))
- zfs_fuid_queue_map_id(zfsvfs, &hdl, who,
+ zfs_fuid_queue_map_id(zfsvfs, &hdl, who, cr,
(entry_type & ACE_IDENTIFIER_GROUP) ?
ZFS_ACE_GROUP : ZFS_ACE_USER, &acep->a_who);
else
@@ -755,8 +756,8 @@ zfs_set_ace(zfs_acl_t *aclp, void *acep, uint32_t access_mask,
* Also, create FUIDs for any User/Group ACEs
*/
static uint64_t
-zfs_mode_fuid_compute(znode_t *zp, zfs_acl_t *aclp, zfs_fuid_info_t **fuidp,
- dmu_tx_t *tx)
+zfs_mode_fuid_compute(znode_t *zp, zfs_acl_t *aclp, cred_t *cr,
+ zfs_fuid_info_t **fuidp, dmu_tx_t *tx)
{
int entry_type;
mode_t mode;
@@ -890,7 +891,7 @@ zfs_mode_fuid_compute(znode_t *zp, zfs_acl_t *aclp, zfs_fuid_info_t **fuidp,
*/
if (entry_type == 0 || entry_type == ACE_IDENTIFIER_GROUP) {
aclp->z_ops.ace_who_set(acep,
- zfs_fuid_create(zp->z_zfsvfs, who,
+ zfs_fuid_create(zp->z_zfsvfs, who, cr,
entry_type == 0 ? ZFS_ACE_USER : ZFS_ACE_GROUP, tx,
fuidp));
}
@@ -991,8 +992,8 @@ zfs_acl_node_read(znode_t *zp, zfs_acl_t **aclpp, boolean_t will_modify)
* already checked the acl and knows whether to inherit.
*/
int
-zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, zfs_fuid_info_t **fuidp,
- dmu_tx_t *tx)
+zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr,
+ zfs_fuid_info_t **fuidp, dmu_tx_t *tx)
{
int error;
znode_phys_t *zphys = zp->z_phys;
@@ -1008,7 +1009,7 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, zfs_fuid_info_t **fuidp,
dmu_buf_will_dirty(zp->z_dbuf, tx);
- zphys->zp_mode = zfs_mode_fuid_compute(zp, aclp, fuidp, tx);
+ zphys->zp_mode = zfs_mode_fuid_compute(zp, aclp, cr, fuidp, tx);
/*
* Decide which opbject type to use. If we are forced to
@@ -1451,7 +1452,7 @@ zfs_fixup_group_entries(zfs_acl_t *aclp, void *acep, void *prevacep,
*/
static int
zfs_acl_chmod(znode_t *zp, uint64_t mode, zfs_acl_t *aclp,
- dmu_tx_t *tx)
+ dmu_tx_t *tx, cred_t *cr)
{
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
void *acep = NULL, *prevacep = NULL;
@@ -1592,12 +1593,12 @@ nextace:
zfs_acl_fixup_canonical_six(aclp, mode);
zp->z_phys->zp_mode = mode;
- error = zfs_aclset_common(zp, aclp, NULL, tx);
+ error = zfs_aclset_common(zp, aclp, cr, NULL, tx);
return (error);
}
int
-zfs_acl_chmod_setattr(znode_t *zp, uint64_t mode, dmu_tx_t *tx)
+zfs_acl_chmod_setattr(znode_t *zp, uint64_t mode, dmu_tx_t *tx, cred_t *cr)
{
zfs_acl_t *aclp = NULL;
int error;
@@ -1606,7 +1607,7 @@ zfs_acl_chmod_setattr(znode_t *zp, uint64_t mode, dmu_tx_t *tx)
mutex_enter(&zp->z_acl_lock);
error = zfs_acl_node_read(zp, &aclp, B_TRUE);
if (error == 0)
- error = zfs_acl_chmod(zp, mode, aclp, tx);
+ error = zfs_acl_chmod(zp, mode, aclp, tx, cr);
mutex_exit(&zp->z_acl_lock);
if (aclp)
zfs_acl_free(aclp);
@@ -1786,9 +1787,9 @@ zfs_perm_init(znode_t *zp, znode_t *parent, int flag,
*/
if ((flag & (IS_ROOT_NODE | IS_REPLAY)) ||
((flag & IS_XATTR) && (vap->va_type == VDIR))) {
- uid = zfs_fuid_create(zfsvfs, vap->va_uid,
+ uid = zfs_fuid_create(zfsvfs, vap->va_uid, cr,
ZFS_OWNER, tx, fuidp);
- gid = zfs_fuid_create(zfsvfs, vap->va_gid,
+ gid = zfs_fuid_create(zfsvfs, vap->va_gid, cr,
ZFS_GROUP, tx, fuidp);
} else {
uid = zfs_fuid_create_cred(zfsvfs, crgetuid(cr),
@@ -1841,7 +1842,7 @@ zfs_perm_init(znode_t *zp, znode_t *parent, int flag,
mutex_exit(&parent->z_lock);
mutex_enter(&zp->z_lock);
mutex_enter(&zp->z_acl_lock);
- error = zfs_acl_chmod(zp, mode, aclp, tx);
+ error = zfs_acl_chmod(zp, mode, aclp, tx, cr);
} else {
mutex_enter(&zp->z_lock);
mutex_enter(&zp->z_acl_lock);
@@ -1851,7 +1852,7 @@ zfs_perm_init(znode_t *zp, znode_t *parent, int flag,
if (vap->va_type == VDIR)
aclp->z_hints |= ZFS_ACL_AUTO_INHERIT;
- error = zfs_aclset_common(zp, aclp, fuidp, tx);
+ error = zfs_aclset_common(zp, aclp, cr, fuidp, tx);
/* Set optional attributes if any */
if (vap->va_mask & AT_XVATTR)
@@ -1938,7 +1939,7 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
vsecp->vsa_aclentsz = aclsz;
if (aclp->z_version == ZFS_ACL_VERSION_FUID)
- zfs_copy_fuid_2_ace(zp->z_zfsvfs, aclp,
+ zfs_copy_fuid_2_ace(zp->z_zfsvfs, aclp, cr,
vsecp->vsa_aclentp, !(mask & VSA_ACE_ALLTYPES));
else {
bcopy(aclnode->z_acldata, vsecp->vsa_aclentp,
@@ -2107,7 +2108,7 @@ top:
return (error);
}
- error = zfs_aclset_common(zp, aclp, &fuidp, tx);
+ error = zfs_aclset_common(zp, aclp, cr, &fuidp, tx);
ASSERT(error == 0);
zfs_log_acl(zilog, tx, zp, vsecp, fuidp);
@@ -2200,7 +2201,7 @@ zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
return (0);
}
- zfs_fuid_map_ids(zp, &fowner, &gowner);
+ zfs_fuid_map_ids(zp, cr, &fowner, &gowner);
mutex_enter(&zp->z_acl_lock);
@@ -2240,7 +2241,7 @@ zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
if (entry_type == 0) {
uid_t newid;
- zfs_fuid_map_id(zfsvfs, who,
+ zfs_fuid_map_id(zfsvfs, who, cr,
ZFS_ACE_USER, &newid);
if (newid != IDMAP_WK_CREATOR_OWNER_UID &&
uid == newid)
@@ -2353,7 +2354,7 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
uid_t owner;
mode_t checkmode = 0;
- zfs_fuid_map_id(zfsvfs, check_zp->z_phys->zp_uid,
+ zfs_fuid_map_id(zfsvfs, check_zp->z_phys->zp_uid, cr,
ZFS_OWNER, &owner);
/*
@@ -2438,7 +2439,7 @@ zfs_delete_final_check(znode_t *zp, znode_t *dzp, cred_t *cr)
uid_t downer;
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
- zfs_fuid_map_id(zfsvfs, dzp->z_phys->zp_uid, ZFS_OWNER, &downer);
+ zfs_fuid_map_id(zfsvfs, dzp->z_phys->zp_uid, cr, ZFS_OWNER, &downer);
error = secpolicy_vnode_access(cr, ZTOV(zp), downer, S_IWRITE|S_IEXEC);
diff --git a/usr/src/uts/common/fs/zfs/zfs_dir.c b/usr/src/uts/common/fs/zfs/zfs_dir.c
index 0170fffb31..5488b25fd1 100644
--- a/usr/src/uts/common/fs/zfs/zfs_dir.c
+++ b/usr/src/uts/common/fs/zfs/zfs_dir.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -905,7 +905,7 @@ top:
va.va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID;
va.va_type = VDIR;
va.va_mode = S_IFDIR | S_ISVTX | 0777;
- zfs_fuid_map_ids(zp, &va.va_uid, &va.va_gid);
+ zfs_fuid_map_ids(zp, cr, &va.va_uid, &va.va_gid);
error = zfs_make_xattrdir(zp, &va, xvpp, cr);
zfs_dirent_unlock(dl);
@@ -945,8 +945,8 @@ zfs_sticky_remove_access(znode_t *zdp, znode_t *zp, cred_t *cr)
if ((zdp->z_phys->zp_mode & S_ISVTX) == 0)
return (0);
- zfs_fuid_map_id(zfsvfs, zdp->z_phys->zp_uid, ZFS_OWNER, &downer);
- zfs_fuid_map_id(zfsvfs, zp->z_phys->zp_uid, ZFS_OWNER, &fowner);
+ zfs_fuid_map_id(zfsvfs, zdp->z_phys->zp_uid, cr, ZFS_OWNER, &downer);
+ zfs_fuid_map_id(zfsvfs, zp->z_phys->zp_uid, cr, ZFS_OWNER, &fowner);
if ((uid = crgetuid(cr)) == downer || uid == fowner ||
(ZTOV(zp)->v_type == VREG &&
diff --git a/usr/src/uts/common/fs/zfs/zfs_fuid.c b/usr/src/uts/common/fs/zfs/zfs_fuid.c
index d2d6377a29..3ac3f8ee32 100644
--- a/usr/src/uts/common/fs/zfs/zfs_fuid.c
+++ b/usr/src/uts/common/fs/zfs/zfs_fuid.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -351,7 +351,7 @@ zfs_fuid_get_mappings(zfs_fuid_hdl_t *hdl)
void
zfs_fuid_queue_map_id(zfsvfs_t *zfsvfs, zfs_fuid_hdl_t *hdl,
- uint64_t fuid, zfs_fuid_type_t type, uid_t *id)
+ uint64_t fuid, cred_t *cr, zfs_fuid_type_t type, uid_t *id)
{
uint32_t index = FUID_INDEX(fuid);
char *domain;
@@ -365,7 +365,7 @@ zfs_fuid_queue_map_id(zfsvfs_t *zfsvfs, zfs_fuid_hdl_t *hdl,
}
if (hdl->z_hdl == NULL) {
- hdl->z_hdl = kidmap_get_create();
+ hdl->z_hdl = kidmap_get_create(crgetzone(cr));
hdl->z_map_needed = B_TRUE;
}
@@ -382,7 +382,7 @@ zfs_fuid_queue_map_id(zfsvfs_t *zfsvfs, zfs_fuid_hdl_t *hdl,
}
void
-zfs_fuid_map_ids(znode_t *zp, uid_t *uid, uid_t *gid)
+zfs_fuid_map_ids(znode_t *zp, cred_t *cr, uid_t *uid, uid_t *gid)
{
uint32_t uid_index = FUID_INDEX(zp->z_phys->zp_uid);
uint32_t gid_index = FUID_INDEX(zp->z_phys->zp_gid);
@@ -396,10 +396,10 @@ zfs_fuid_map_ids(znode_t *zp, uid_t *uid, uid_t *gid)
zfs_fuid_hdl_t hdl = { 0 };
zfs_fuid_queue_map_id(zp->z_zfsvfs, &hdl,
- zp->z_phys->zp_uid, ZFS_OWNER, uid);
+ zp->z_phys->zp_uid, cr, ZFS_OWNER, uid);
zfs_fuid_queue_map_id(zp->z_zfsvfs, &hdl,
- zp->z_phys->zp_gid, ZFS_GROUP, gid);
+ zp->z_phys->zp_gid, cr, ZFS_GROUP, gid);
zfs_fuid_get_mappings(&hdl);
}
@@ -407,7 +407,7 @@ zfs_fuid_map_ids(znode_t *zp, uid_t *uid, uid_t *gid)
void
zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid,
- zfs_fuid_type_t type, uid_t *id)
+ cred_t *cr, zfs_fuid_type_t type, uid_t *id)
{
uint32_t index = FUID_INDEX(fuid);
char *domain;
@@ -421,9 +421,11 @@ zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid,
ASSERT(domain != NULL);
if (type == ZFS_OWNER || type == ZFS_ACE_USER)
- (void) kidmap_getuidbysid(domain, FUID_RID(fuid), id);
+ (void) kidmap_getuidbysid(crgetzone(cr), domain,
+ FUID_RID(fuid), id);
else
- (void) kidmap_getgidbysid(domain, FUID_RID(fuid), id);
+ (void) kidmap_getgidbysid(crgetzone(cr), domain,
+ FUID_RID(fuid), id);
}
/*
@@ -535,7 +537,7 @@ zfs_fuid_create_cred(zfsvfs_t *zfsvfs, uint64_t id,
* attached to the zfsvfs of the file system.
*/
uint64_t
-zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id,
+zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
zfs_fuid_type_t type, dmu_tx_t *tx, zfs_fuid_info_t **fuidpp)
{
const char *domain;
@@ -586,9 +588,11 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id,
domain = fuidp->z_domain_table[idx -1];
} else {
if (type == ZFS_OWNER || type == ZFS_ACE_USER)
- status = kidmap_getsidbyuid(id, &domain, &rid);
+ status = kidmap_getsidbyuid(crgetzone(cr), id,
+ &domain, &rid);
else
- status = kidmap_getsidbygid(id, &domain, &rid);
+ status = kidmap_getsidbygid(crgetzone(cr), id,
+ &domain, &rid);
if (status != 0) {
/*
@@ -733,6 +737,6 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
/*
* Not found in ksidlist, check posix groups
*/
- zfs_fuid_map_id(zfsvfs, id, ZFS_GROUP, &gid);
+ zfs_fuid_map_id(zfsvfs, id, cr, ZFS_GROUP, &gid);
return (groupmember(gid, cr));
}
diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c
index f2a07e74ac..edf2e85200 100644
--- a/usr/src/uts/common/fs/zfs/zfs_vnops.c
+++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -2165,7 +2165,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
vap->va_type = vp->v_type;
vap->va_mode = pzp->zp_mode & MODEMASK;
- zfs_fuid_map_ids(zp, &vap->va_uid, &vap->va_gid);
+ zfs_fuid_map_ids(zp, cr, &vap->va_uid, &vap->va_gid);
vap->va_fsid = zp->z_zfsvfs->z_vfs->vfs_dev;
vap->va_nodeid = zp->z_id;
if ((vp->v_flag & VROOT) && zfs_show_ctldir(zp))
@@ -2489,7 +2489,7 @@ top:
mutex_enter(&zp->z_lock);
oldva.va_mode = pzp->zp_mode;
- zfs_fuid_map_ids(zp, &oldva.va_uid, &oldva.va_gid);
+ zfs_fuid_map_ids(zp, cr, &oldva.va_uid, &oldva.va_gid);
if (mask & AT_XVATTR) {
if ((need_policy == FALSE) &&
(XVA_ISSET_REQ(xvap, XAT_APPENDONLY) &&
@@ -2639,7 +2639,7 @@ top:
mutex_enter(&zp->z_lock);
if (mask & AT_MODE) {
- err = zfs_acl_chmod_setattr(zp, new_mode, tx);
+ err = zfs_acl_chmod_setattr(zp, new_mode, tx, cr);
ASSERT3U(err, ==, 0);
}
@@ -2648,19 +2648,19 @@ top:
if (mask & AT_UID) {
pzp->zp_uid = zfs_fuid_create(zfsvfs,
- vap->va_uid, ZFS_OWNER, tx, &fuidp);
+ vap->va_uid, cr, ZFS_OWNER, tx, &fuidp);
if (attrzp) {
attrzp->z_phys->zp_uid = zfs_fuid_create(zfsvfs,
- vap->va_uid, ZFS_OWNER, tx, &fuidp);
+ vap->va_uid, cr, ZFS_OWNER, tx, &fuidp);
}
}
if (mask & AT_GID) {
pzp->zp_gid = zfs_fuid_create(zfsvfs, vap->va_gid,
- ZFS_GROUP, tx, &fuidp);
+ cr, ZFS_GROUP, tx, &fuidp);
if (attrzp)
attrzp->z_phys->zp_gid = zfs_fuid_create(zfsvfs,
- vap->va_gid, ZFS_GROUP, tx, &fuidp);
+ vap->va_gid, cr, ZFS_GROUP, tx, &fuidp);
}
if (attrzp)
@@ -3383,7 +3383,7 @@ top:
return (EPERM);
}
- zfs_fuid_map_id(zfsvfs, szp->z_phys->zp_uid, ZFS_OWNER, &owner);
+ zfs_fuid_map_id(zfsvfs, szp->z_phys->zp_uid, cr, ZFS_OWNER, &owner);
if (owner != crgetuid(cr) &&
secpolicy_basic_link(cr) != 0) {
ZFS_EXIT(zfsvfs);
diff --git a/usr/src/uts/common/idmap/idmap_kapi.c b/usr/src/uts/common/idmap/idmap_kapi.c
index ea53f9a7be..018cd1bc9e 100644
--- a/usr/src/uts/common/idmap/idmap_kapi.c
+++ b/usr/src/uts/common/idmap/idmap_kapi.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -49,19 +49,20 @@
#include <sys/sysmacros.h>
#include <sys/disp.h>
#include <sys/kidmap.h>
+#include <sys/zone.h>
#include "idmap_prot.h"
#include "kidmap_priv.h"
-static kmutex_t idmap_lock;
-static idmap_cache_t idmap_cache;
-
/*
- * Used to hold RPC header, in particular the XID (not that XID matters
- * in doors RPC)
+ * Defined types
*/
-static struct rpc_msg call_msg;
+
+/*
+ * This structure holds pointers for the
+ * batch mapping results.
+ */
typedef struct idmap_get_res {
idmap_id_type idtype;
uid_t *uid;
@@ -75,169 +76,123 @@ typedef struct idmap_get_res {
/* Batch mapping handle structure */
struct idmap_get_handle {
- idmap_cache_t *cache;
+ struct idmap_zone_specific *zs;
int mapping_num;
int mapping_size;
idmap_mapping *mapping;
idmap_get_res *result;
};
-static kmutex_t idmap_mutex;
-static int idmap_stopped = 0;
-
-struct idmap_reg {
- door_handle_t idmap_door;
- int idmap_invalid;
- int idmap_invalidated;
- int idmap_ref;
-};
-
-static idmap_reg_t *idmap_ptr;
+/* Zone specific data */
+typedef struct idmap_zone_specific {
+ kmutex_t zone_mutex;
+ idmap_cache_t cache;
+ door_handle_t door_handle;
+ int door_valid;
+ uint32_t message_id;
+} idmap_zone_specific_t;
-static int
-kidmap_rpc_call(uint32_t op, xdrproc_t xdr_args, caddr_t args,
- xdrproc_t xdr_res, caddr_t res);
-
-static int kidmap_call_door(door_arg_t *arg);
-
-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));
-}
+/*
+ * Module global data
+ */
-void
-idmap_get_door(idmap_reg_t **state, door_handle_t *dh)
-{
- idmap_reg_t *idmp;
+static kmutex_t idmap_zone_mutex;
+static zone_key_t idmap_zone_key;
- *state = NULL;
- if (dh != NULL)
- *dh = NULL;
- mutex_enter(&idmap_mutex);
- if ((idmp = idmap_ptr) == NULL || idmp->idmap_invalid) {
- mutex_exit(&idmap_mutex);
- return;
- }
+/*
+ * Local function definitions
+ */
- idmap_ptr->idmap_ref++;
- mutex_exit(&idmap_mutex);
+static int
+kidmap_rpc_call(idmap_zone_specific_t *zs, uint32_t op,
+ xdrproc_t xdr_args, caddr_t args,
+ xdrproc_t xdr_res, caddr_t res);
- *state = idmp;
- if (dh != NULL)
- *dh = idmp->idmap_door;
-}
+static int
+kidmap_call_door(idmap_zone_specific_t *zs, door_arg_t *arg);
-void
-idmap_release_door(idmap_reg_t *idmp)
-{
- mutex_enter(&idmap_mutex);
-
- /*
- * Note we may decrement idmap_ref twice; if we do it's because
- * we had EBADF, and rather than decrement the ref count where
- * that happens we do it here to make sure that we do both
- * decrements while holding idmap_mutex.
- */
- if (idmp->idmap_invalid && !idmp->idmap_invalidated) {
- idmp->idmap_invalidated = 1;
- if (--idmp->idmap_ref == 0) {
- idmap_freeone(idmap_ptr);
- mutex_exit(&idmap_mutex);
- return;
- }
- }
+static idmap_zone_specific_t *
+idmap_get_zone_specific(zone_t *zone);
- if (--idmp->idmap_ref == 0)
- idmap_freeone(idmap_ptr);
- mutex_exit(&idmap_mutex);
-}
int
-idmap_reg_dh(door_handle_t dh)
+idmap_reg_dh(zone_t *zone, door_handle_t dh)
{
- idmap_reg_t *idmp;
+ idmap_zone_specific_t *zs;
- idmp = kmem_alloc(sizeof (*idmp), KM_SLEEP);
+ zs = idmap_get_zone_specific(zone);
- idmp->idmap_door = dh;
- mutex_enter(&idmap_mutex);
+ mutex_enter(&zs->zone_mutex);
+ if (zs->door_valid)
+ door_ki_rele(zs->door_handle);
- if (idmap_stopped) {
- mutex_exit(&idmap_mutex);
- /*
- * We're unloading the module. Calling idmap_reg(2)
- * again once we're done unloading should cause the
- * module to be loaded again, so we return EAGAIN.
- */
- return (EAGAIN);
- }
-
- if (idmap_ptr != NULL) {
- if (--idmap_ptr->idmap_ref == 0)
- idmap_freeone(idmap_ptr);
- }
- idmp->idmap_invalid = 0;
- idmp->idmap_invalidated = 0;
- idmp->idmap_ref = 1;
- idmap_ptr = idmp;
-
- call_msg.rm_xid = 1;
- call_msg.rm_call.cb_prog = IDMAP_PROG;
- call_msg.rm_call.cb_vers = IDMAP_V1;
+ zs->door_handle = dh;
+ zs->door_valid = 1;
- mutex_exit(&idmap_mutex);
+ mutex_exit(&zs->zone_mutex);
return (0);
}
+/*
+ * idmap_unreg_dh
+ *
+ * This routine is called by system call idmap_unreg().
+ * idmap_unreg() calls door_ki_rele() on the supplied
+ * door handle after this routine returns. We only
+ * need to perform one door release on zs->door_handle
+ */
int
-idmap_unreg_dh(door_handle_t dh)
+idmap_unreg_dh(zone_t *zone, door_handle_t dh)
{
- kidmap_cache_purge(&idmap_cache);
+ idmap_zone_specific_t *zs;
+
+ zs = idmap_get_zone_specific(zone);
- mutex_enter(&idmap_mutex);
- if (idmap_ptr == NULL || idmap_ptr->idmap_door != dh) {
- mutex_exit(&idmap_mutex);
+ kidmap_cache_purge(&zs->cache);
+
+ mutex_enter(&zs->zone_mutex);
+
+ if (!zs->door_valid) {
+ mutex_exit(&zs->zone_mutex);
return (EINVAL);
}
- if (idmap_ptr->idmap_invalid) {
- mutex_exit(&idmap_mutex);
+ if (zs->door_handle != dh) {
+ mutex_exit(&zs->zone_mutex);
return (EINVAL);
}
- idmap_ptr->idmap_invalid = 1;
- idmap_ptr->idmap_invalidated = 1;
- if (--idmap_ptr->idmap_ref == 0)
- idmap_freeone(idmap_ptr);
- mutex_exit(&idmap_mutex);
+
+ door_ki_rele(zs->door_handle);
+
+ zs->door_valid = 0;
+ mutex_exit(&zs->zone_mutex);
+
return (0);
}
static int
-kidmap_call_door(door_arg_t *arg)
+kidmap_call_door(idmap_zone_specific_t *zs, door_arg_t *arg)
{
+ door_handle_t dh;
int status = 0;
- door_handle_t dh;
- idmap_reg_t *reg;
- idmap_get_door(&reg, &dh);
- if (reg == NULL || dh == NULL) {
+ mutex_enter(&zs->zone_mutex);
+ if (!zs->door_valid) {
+ mutex_exit(&zs->zone_mutex);
return (-1);
}
+ dh = zs->door_handle;
+ door_ki_hold(dh);
+ mutex_exit(&zs->zone_mutex);
status = door_ki_upcall(dh, arg);
@@ -246,24 +201,74 @@ kidmap_call_door(door_arg_t *arg)
cmn_err(CE_WARN, "idmap: Door call failed %d\n", status);
#endif /* DEBUG */
+ door_ki_rele(dh);
+
if (status == EBADF) {
- reg->idmap_invalid = 1;
+ /*
+ * If we get EBADF we will most likely not get an
+ * idmap_unreg_dh().
+ */
+ mutex_enter(&zs->zone_mutex);
+ if (zs->door_valid) {
+ zs->door_valid = 0;
+ door_ki_rele(zs->door_handle);
+ }
+ mutex_exit(&zs->zone_mutex);
}
- idmap_release_door(reg);
-
return (status);
}
+static idmap_zone_specific_t *
+idmap_get_zone_specific(zone_t *zone)
+{
+ idmap_zone_specific_t *zs;
+
+ ASSERT(zone != NULL);
+
+ zs = zone_getspecific(idmap_zone_key, zone);
+ if (zs != NULL)
+ return (zs);
+
+ mutex_enter(&idmap_zone_mutex);
+ zs = zone_getspecific(idmap_zone_key, zone);
+ if (zs == NULL) {
+ zs = kmem_zalloc(sizeof (idmap_zone_specific_t), KM_SLEEP);
+ mutex_init(&zs->zone_mutex, NULL, MUTEX_DEFAULT, NULL);
+ kidmap_cache_create(&zs->cache);
+ (void) zone_setspecific(idmap_zone_key, zone, zs);
+ mutex_exit(&idmap_zone_mutex);
+ return (zs);
+ }
+ mutex_exit(&idmap_zone_mutex);
+
+ return (zs);
+}
+
+
+static void
+/* ARGSUSED */
+idmap_zone_destroy(zoneid_t zone_id, void *arg)
+{
+ idmap_zone_specific_t *zs = arg;
+ if (zs != NULL) {
+ kidmap_cache_delete(&zs->cache);
+ if (zs->door_valid) {
+ door_ki_rele(zs->door_handle);
+ }
+ mutex_destroy(&zs->zone_mutex);
+ kmem_free(zs, sizeof (idmap_zone_specific_t));
+ }
+}
+
+
int
kidmap_start(void)
{
- mutex_init(&idmap_lock, NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&idmap_zone_mutex, NULL, MUTEX_DEFAULT, NULL);
+ zone_key_create(&idmap_zone_key, NULL, NULL, idmap_zone_destroy);
kidmap_sid_prefix_store_init();
- kidmap_cache_create(&idmap_cache);
-
- idmap_stopped = 0;
return (0);
}
@@ -272,24 +277,53 @@ kidmap_start(void)
int
kidmap_stop(void)
{
- mutex_enter(&idmap_mutex);
+ return (EBUSY);
+}
+
- if (idmap_ptr != NULL) {
- mutex_exit(&idmap_mutex);
- return (EBUSY);
+/*
+ * idmap_get_door
+ *
+ * This is called by the system call allocids() to get the door for the
+ * given zone.
+ */
+door_handle_t
+idmap_get_door(zone_t *zone)
+{
+ door_handle_t dh = NULL;
+ idmap_zone_specific_t *zs;
+
+ zs = idmap_get_zone_specific(zone);
+
+ mutex_enter(&zs->zone_mutex);
+ if (zs->door_valid) {
+ dh = zs->door_handle;
+ door_ki_hold(dh);
}
+ mutex_exit(&zs->zone_mutex);
+ return (dh);
+}
- idmap_stopped = 1;
- mutex_exit(&idmap_mutex);
+/*
+ * idmap_purge_cache
+ *
+ * This is called by the system call allocids() to purge the cache for the
+ * given zone.
+ */
+void
+idmap_purge_cache(zone_t *zone)
+{
+ idmap_zone_specific_t *zs;
- kidmap_cache_delete(&idmap_cache);
- mutex_destroy(&idmap_lock);
+ zs = idmap_get_zone_specific(zone);
- return (0);
+ kidmap_cache_purge(&zs->cache);
}
+
+
/*
* Given Domain SID and RID, get UID
*
@@ -304,8 +338,10 @@ kidmap_stop(void)
* Success return IDMAP_SUCCESS else IDMAP error
*/
idmap_stat
-kidmap_getuidbysid(const char *sid_prefix, uint32_t rid, uid_t *uid)
+kidmap_getuidbysid(zone_t *zone, const char *sid_prefix, uint32_t rid,
+ uid_t *uid)
{
+ idmap_zone_specific_t *zs;
idmap_mapping_batch args;
idmap_mapping mapping;
idmap_ids_res results;
@@ -316,7 +352,9 @@ kidmap_getuidbysid(const char *sid_prefix, uint32_t rid, uid_t *uid)
if (sid_prefix == NULL || uid == NULL)
return (IDMAP_ERR_ARG);
- if (kidmap_cache_lookup_uidbysid(&idmap_cache, sid_prefix, rid, uid)
+ zs = idmap_get_zone_specific(zone);
+
+ if (kidmap_cache_lookup_uidbysid(&zs->cache, sid_prefix, rid, uid)
== IDMAP_SUCCESS)
return (IDMAP_SUCCESS);
@@ -331,7 +369,7 @@ kidmap_getuidbysid(const char *sid_prefix, uint32_t rid, uid_t *uid)
args.idmap_mapping_batch_len = 1;
args.idmap_mapping_batch_val = &mapping;
- if (kidmap_rpc_call(op, xdr_idmap_mapping_batch,
+ if (kidmap_rpc_call(zs, op, xdr_idmap_mapping_batch,
(caddr_t)&args, xdr_idmap_ids_res,
(caddr_t)&results) == 0) {
/* Door call succeded */
@@ -342,7 +380,7 @@ kidmap_getuidbysid(const char *sid_prefix, uint32_t rid, uid_t *uid)
if (status == IDMAP_SUCCESS) {
new_sid_prefix = kidmap_find_sid_prefix(
sid_prefix);
- kidmap_cache_add_uidbysid(&idmap_cache,
+ kidmap_cache_add_uidbysid(&zs->cache,
new_sid_prefix, rid, *uid);
}
} else {
@@ -373,8 +411,10 @@ kidmap_getuidbysid(const char *sid_prefix, uint32_t rid, uid_t *uid)
* Success return IDMAP_SUCCESS else IDMAP error
*/
idmap_stat
-kidmap_getgidbysid(const char *sid_prefix, uint32_t rid, gid_t *gid)
+kidmap_getgidbysid(zone_t *zone, const char *sid_prefix, uint32_t rid,
+ gid_t *gid)
{
+ idmap_zone_specific_t *zs;
idmap_mapping_batch args;
idmap_mapping mapping;
idmap_ids_res results;
@@ -385,10 +425,11 @@ kidmap_getgidbysid(const char *sid_prefix, uint32_t rid, gid_t *gid)
if (sid_prefix == NULL || gid == NULL)
return (IDMAP_ERR_ARG);
- if (kidmap_cache_lookup_gidbysid(&idmap_cache, sid_prefix, rid, gid)
- == IDMAP_SUCCESS) {
+ zs = idmap_get_zone_specific(zone);
+
+ if (kidmap_cache_lookup_gidbysid(&zs->cache, sid_prefix, rid, gid)
+ == IDMAP_SUCCESS)
return (IDMAP_SUCCESS);
- }
bzero(&mapping, sizeof (idmap_mapping));
mapping.id1.idtype = IDMAP_SID;
@@ -401,7 +442,7 @@ kidmap_getgidbysid(const char *sid_prefix, uint32_t rid, gid_t *gid)
args.idmap_mapping_batch_len = 1;
args.idmap_mapping_batch_val = &mapping;
- if (kidmap_rpc_call(op, xdr_idmap_mapping_batch,
+ if (kidmap_rpc_call(zs, op, xdr_idmap_mapping_batch,
(caddr_t)&args, xdr_idmap_ids_res,
(caddr_t)&results) == 0) {
/* Door call succeded */
@@ -412,7 +453,7 @@ kidmap_getgidbysid(const char *sid_prefix, uint32_t rid, gid_t *gid)
if (status == IDMAP_SUCCESS) {
new_sid_prefix = kidmap_find_sid_prefix(
sid_prefix);
- kidmap_cache_add_gidbysid(&idmap_cache,
+ kidmap_cache_add_gidbysid(&zs->cache,
new_sid_prefix, rid, *gid);
}
} else {
@@ -443,9 +484,10 @@ kidmap_getgidbysid(const char *sid_prefix, uint32_t rid, gid_t *gid)
* Success return IDMAP_SUCCESS else IDMAP error
*/
idmap_stat
-kidmap_getpidbysid(const char *sid_prefix, uint32_t rid, uid_t *pid,
- int *is_user)
+kidmap_getpidbysid(zone_t *zone, const char *sid_prefix, uint32_t rid,
+ uid_t *pid, int *is_user)
{
+ idmap_zone_specific_t *zs;
idmap_mapping_batch args;
idmap_mapping mapping;
idmap_ids_res results;
@@ -456,10 +498,11 @@ kidmap_getpidbysid(const char *sid_prefix, uint32_t rid, uid_t *pid,
if (sid_prefix == NULL || pid == NULL || is_user == NULL)
return (IDMAP_ERR_ARG);
- if (kidmap_cache_lookup_pidbysid(&idmap_cache, sid_prefix, rid, pid,
- is_user) == IDMAP_SUCCESS) {
+ zs = idmap_get_zone_specific(zone);
+
+ if (kidmap_cache_lookup_pidbysid(&zs->cache, sid_prefix, rid, pid,
+ is_user) == IDMAP_SUCCESS)
return (IDMAP_SUCCESS);
- }
bzero(&mapping, sizeof (idmap_mapping));
mapping.id1.idtype = IDMAP_SID;
@@ -472,7 +515,7 @@ kidmap_getpidbysid(const char *sid_prefix, uint32_t rid, uid_t *pid,
args.idmap_mapping_batch_len = 1;
args.idmap_mapping_batch_val = &mapping;
- if (kidmap_rpc_call(op, xdr_idmap_mapping_batch,
+ if (kidmap_rpc_call(zs, op, xdr_idmap_mapping_batch,
(caddr_t)&args, xdr_idmap_ids_res,
(caddr_t)&results) == 0) {
/* Door call succeded */
@@ -490,7 +533,7 @@ kidmap_getpidbysid(const char *sid_prefix, uint32_t rid, uid_t *pid,
if (status == IDMAP_SUCCESS) {
new_sid_prefix = kidmap_find_sid_prefix(
sid_prefix);
- kidmap_cache_add_pidbysid(&idmap_cache,
+ kidmap_cache_add_pidbysid(&zs->cache,
new_sid_prefix, rid, *pid,
*is_user);
}
@@ -524,8 +567,10 @@ kidmap_getpidbysid(const char *sid_prefix, uint32_t rid, uid_t *pid,
* Success return IDMAP_SUCCESS else IDMAP error
*/
idmap_stat
-kidmap_getsidbyuid(uid_t uid, const char **sid_prefix, uint32_t *rid)
+kidmap_getsidbyuid(zone_t *zone, uid_t uid, const char **sid_prefix,
+ uint32_t *rid)
{
+ idmap_zone_specific_t *zs;
idmap_mapping_batch args;
idmap_mapping mapping;
idmap_ids_res results;
@@ -537,7 +582,9 @@ kidmap_getsidbyuid(uid_t uid, const char **sid_prefix, uint32_t *rid)
if (sid_prefix == NULL || rid == NULL)
return (IDMAP_ERR_ARG);
- if (kidmap_cache_lookup_sidbyuid(&idmap_cache, sid_prefix, rid, uid)
+ zs = idmap_get_zone_specific(zone);
+
+ if (kidmap_cache_lookup_sidbyuid(&zs->cache, sid_prefix, rid, uid)
== IDMAP_SUCCESS) {
return (IDMAP_SUCCESS);
}
@@ -552,7 +599,7 @@ kidmap_getsidbyuid(uid_t uid, const char **sid_prefix, uint32_t *rid)
args.idmap_mapping_batch_len = 1;
args.idmap_mapping_batch_val = &mapping;
- if (kidmap_rpc_call(op, xdr_idmap_mapping_batch,
+ if (kidmap_rpc_call(zs, op, xdr_idmap_mapping_batch,
(caddr_t)&args, xdr_idmap_ids_res,
(caddr_t)&results) == 0) {
/* Door call succeded */
@@ -566,7 +613,7 @@ kidmap_getsidbyuid(uid_t uid, const char **sid_prefix, uint32_t *rid)
id->idmap_id_u.sid.prefix);
*rid = id->idmap_id_u.sid.rid;
if (status == IDMAP_SUCCESS) {
- kidmap_cache_add_sidbyuid(&idmap_cache,
+ kidmap_cache_add_sidbyuid(&zs->cache,
*sid_prefix, *rid, uid);
}
} else {
@@ -599,8 +646,10 @@ kidmap_getsidbyuid(uid_t uid, const char **sid_prefix, uint32_t *rid)
* Success return IDMAP_SUCCESS else IDMAP error
*/
idmap_stat
-kidmap_getsidbygid(gid_t gid, const char **sid_prefix, uint32_t *rid)
+kidmap_getsidbygid(zone_t *zone, gid_t gid, const char **sid_prefix,
+ uint32_t *rid)
{
+ idmap_zone_specific_t *zs;
idmap_mapping_batch args;
idmap_mapping mapping;
idmap_ids_res results;
@@ -611,7 +660,9 @@ kidmap_getsidbygid(gid_t gid, const char **sid_prefix, uint32_t *rid)
if (sid_prefix == NULL || rid == NULL)
return (IDMAP_ERR_ARG);
- if (kidmap_cache_lookup_sidbygid(&idmap_cache, sid_prefix, rid, gid)
+ zs = idmap_get_zone_specific(zone);
+
+ if (kidmap_cache_lookup_sidbygid(&zs->cache, sid_prefix, rid, gid)
== IDMAP_SUCCESS) {
return (IDMAP_SUCCESS);
}
@@ -626,7 +677,7 @@ kidmap_getsidbygid(gid_t gid, const char **sid_prefix, uint32_t *rid)
args.idmap_mapping_batch_len = 1;
args.idmap_mapping_batch_val = &mapping;
- if (kidmap_rpc_call(op, xdr_idmap_mapping_batch,
+ if (kidmap_rpc_call(zs, op, xdr_idmap_mapping_batch,
(caddr_t)&args, xdr_idmap_ids_res,
(caddr_t)&results) == 0) {
/* Door call succeded */
@@ -640,7 +691,7 @@ kidmap_getsidbygid(gid_t gid, const char **sid_prefix, uint32_t *rid)
id->idmap_id_u.sid.prefix);
*rid = id->idmap_id_u.sid.rid;
if (status == IDMAP_SUCCESS) {
- kidmap_cache_add_sidbygid(&idmap_cache,
+ kidmap_cache_add_sidbygid(&zs->cache,
*sid_prefix, *rid, gid);
}
} else {
@@ -668,10 +719,13 @@ kidmap_getsidbygid(gid_t gid, const char **sid_prefix, uint32_t *rid)
*
*/
idmap_get_handle_t *
-kidmap_get_create(void)
+kidmap_get_create(zone_t *zone)
{
- idmap_get_handle_t *handle;
-#define INIT_MAPPING_SIZE 6
+ idmap_zone_specific_t *zs;
+ idmap_get_handle_t *handle;
+#define INIT_MAPPING_SIZE 32
+
+ zs = idmap_get_zone_specific(zone);
handle = kmem_zalloc(sizeof (idmap_get_handle_t), KM_SLEEP);
@@ -681,7 +735,7 @@ kidmap_get_create(void)
handle->result = kmem_zalloc((sizeof (idmap_get_res)) *
INIT_MAPPING_SIZE, KM_SLEEP);
handle->mapping_size = INIT_MAPPING_SIZE;
- handle->cache = &idmap_cache;
+ handle->zs = zs;
return (handle);
}
@@ -742,7 +796,7 @@ kidmap_batch_getuidbysid(idmap_get_handle_t *get_handle, const char *sid_prefix,
uid == NULL || stat == NULL)
return (IDMAP_ERR_ARG);
- if (kidmap_cache_lookup_uidbysid(get_handle->cache, sid_prefix,
+ if (kidmap_cache_lookup_uidbysid(&get_handle->zs->cache, sid_prefix,
rid, uid) == IDMAP_SUCCESS) {
*stat = IDMAP_SUCCESS;
return (IDMAP_SUCCESS);
@@ -798,7 +852,7 @@ kidmap_batch_getgidbysid(idmap_get_handle_t *get_handle, const char *sid_prefix,
gid == NULL || stat == NULL)
return (IDMAP_ERR_ARG);
- if (kidmap_cache_lookup_gidbysid(get_handle->cache, sid_prefix,
+ if (kidmap_cache_lookup_gidbysid(&get_handle->zs->cache, sid_prefix,
rid, gid) == IDMAP_SUCCESS) {
*stat = IDMAP_SUCCESS;
return (IDMAP_SUCCESS);
@@ -856,7 +910,7 @@ kidmap_batch_getpidbysid(idmap_get_handle_t *get_handle, const char *sid_prefix,
is_user == NULL || stat == NULL)
return (IDMAP_ERR_ARG);
- if (kidmap_cache_lookup_pidbysid(get_handle->cache, sid_prefix,
+ if (kidmap_cache_lookup_pidbysid(&get_handle->zs->cache, sid_prefix,
rid, pid, is_user) == IDMAP_SUCCESS) {
*stat = IDMAP_SUCCESS;
return (IDMAP_SUCCESS);
@@ -913,8 +967,8 @@ kidmap_batch_getsidbyuid(idmap_get_handle_t *get_handle, uid_t uid,
rid == NULL || stat == NULL)
return (IDMAP_ERR_ARG);
- if (kidmap_cache_lookup_sidbyuid(get_handle->cache, sid_prefix,
- rid, uid) == IDMAP_SUCCESS) {
+ if (kidmap_cache_lookup_sidbyuid(&get_handle->zs->cache,
+ sid_prefix, rid, uid) == IDMAP_SUCCESS) {
*stat = IDMAP_SUCCESS;
return (IDMAP_SUCCESS);
}
@@ -968,8 +1022,8 @@ kidmap_batch_getsidbygid(idmap_get_handle_t *get_handle, gid_t gid,
rid == NULL || stat == NULL)
return (IDMAP_ERR_ARG);
- if (kidmap_cache_lookup_sidbygid(get_handle->cache, sid_prefix,
- rid, gid) == IDMAP_SUCCESS) {
+ if (kidmap_cache_lookup_sidbygid(&get_handle->zs->cache,
+ sid_prefix, rid, gid) == IDMAP_SUCCESS) {
*stat = IDMAP_SUCCESS;
return (IDMAP_SUCCESS);
}
@@ -1021,19 +1075,21 @@ kidmap_get_mappings(idmap_get_handle_t *get_handle)
int i;
const char *sid_prefix;
int is_user;
+ idmap_cache_t *cache;
if (get_handle == NULL)
return (IDMAP_ERR_ARG);
if (get_handle->mapping_num == 0)
return (IDMAP_SUCCESS);
+ cache = &get_handle->zs->cache;
bzero(&results, sizeof (idmap_ids_res));
args.idmap_mapping_batch_len = get_handle->mapping_num;
args.idmap_mapping_batch_val = get_handle->mapping;
- if (kidmap_rpc_call(op, xdr_idmap_mapping_batch,
+ if (kidmap_rpc_call(get_handle->zs, op, xdr_idmap_mapping_batch,
(caddr_t)&args, xdr_idmap_ids_res,
(caddr_t)&results) == 0) {
/* Door call succeded */
@@ -1074,17 +1130,17 @@ kidmap_get_mappings(idmap_get_handle_t *get_handle)
if (*result->stat == IDMAP_SUCCESS &&
result->uid)
kidmap_cache_add_uidbysid(
- get_handle->cache,
+ cache,
sid_prefix,
mapping->id1.idmap_id_u.sid.rid,
id->idmap_id_u.uid);
else if (*result->stat == IDMAP_SUCCESS &&
result->pid)
- kidmap_cache_add_pidbysid(
- get_handle->cache,
+ kidmap_cache_add_uidbysid(
+ cache,
sid_prefix,
mapping->id1.idmap_id_u.sid.rid,
- id->idmap_id_u.uid, 1);
+ id->idmap_id_u.uid);
break;
case IDMAP_GID:
@@ -1099,17 +1155,17 @@ kidmap_get_mappings(idmap_get_handle_t *get_handle)
if (*result->stat == IDMAP_SUCCESS &&
result->gid)
kidmap_cache_add_gidbysid(
- get_handle->cache,
+ cache,
sid_prefix,
mapping->id1.idmap_id_u.sid.rid,
id->idmap_id_u.gid);
else if (*result->stat == IDMAP_SUCCESS &&
result->pid)
- kidmap_cache_add_pidbysid(
- get_handle->cache,
+ kidmap_cache_add_gidbysid(
+ cache,
sid_prefix,
mapping->id1.idmap_id_u.sid.rid,
- id->idmap_id_u.gid, 0);
+ id->idmap_id_u.gid);
break;
case IDMAP_SID:
@@ -1124,14 +1180,14 @@ kidmap_get_mappings(idmap_get_handle_t *get_handle)
if (*result->stat == IDMAP_SUCCESS &&
mapping->id1.idtype == IDMAP_UID)
kidmap_cache_add_sidbyuid(
- get_handle->cache,
+ cache,
sid_prefix,
id->idmap_id_u.sid.rid,
mapping->id1.idmap_id_u.uid);
else if (*result->stat == IDMAP_SUCCESS &&
mapping->id1.idtype == IDMAP_GID)
kidmap_cache_add_sidbygid(
- get_handle->cache,
+ cache,
sid_prefix,
id->idmap_id_u.sid.rid,
mapping->id1.idmap_id_u.gid);
@@ -1205,8 +1261,8 @@ kidmap_get_destroy(idmap_get_handle_t *get_handle)
static int
-kidmap_rpc_call(uint32_t op, xdrproc_t xdr_args, caddr_t args,
- xdrproc_t xdr_res, caddr_t res)
+kidmap_rpc_call(idmap_zone_specific_t *zs, uint32_t op, xdrproc_t xdr_args,
+ caddr_t args, xdrproc_t xdr_res, caddr_t res)
{
XDR xdr_ctx;
struct rpc_msg reply_msg;
@@ -1218,6 +1274,7 @@ kidmap_rpc_call(uint32_t op, xdrproc_t xdr_args, caddr_t args,
int status = 0;
door_arg_t params;
int retry = 0;
+ struct rpc_msg call_msg;
params.rbuf = NULL;
params.rsize = 0;
@@ -1227,7 +1284,11 @@ retry:
outbuf_ptr = kmem_alloc(outbuf_size, KM_SLEEP);
xdrmem_create(&xdr_ctx, inbuf_ptr, inbuf_size, XDR_ENCODE);
- atomic_inc_32(&call_msg.rm_xid);
+
+ call_msg.rm_call.cb_prog = IDMAP_PROG;
+ call_msg.rm_call.cb_vers = IDMAP_V1;
+ call_msg.rm_xid = atomic_inc_32_nv(&zs->message_id);
+
if (!xdr_callhdr(&xdr_ctx, &call_msg)) {
#ifdef DEBUG
cmn_err(CE_WARN, "idmap: xdr encoding header error");
@@ -1277,7 +1338,7 @@ retry:
params.rbuf = outbuf_ptr;
params.rsize = outbuf_size;
- if (kidmap_call_door(&params) != 0) {
+ if (kidmap_call_door(zs, &params) != 0) {
status = -1;
goto exit;
}
diff --git a/usr/src/uts/common/idmap/idmap_mod.c b/usr/src/uts/common/idmap/idmap_mod.c
index 0fff9642f0..0c5542b9b1 100644
--- a/usr/src/uts/common/idmap/idmap_mod.c
+++ b/usr/src/uts/common/idmap/idmap_mod.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -86,7 +86,6 @@ int
_fini()
{
int i;
- idmap_reg_t *reg;
if ((i = kidmap_stop()) != 0) {
return (i);
diff --git a/usr/src/uts/common/io/ptm.c b/usr/src/uts/common/io/ptm.c
index 8909fb516a..83b6b162a7 100644
--- a/usr/src/uts/common/io/ptm.c
+++ b/usr/src/uts/common/io/ptm.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
@@ -564,20 +564,23 @@ ptmwput(queue_t *qp, mblk_t *mp)
{
pt_own_t *ptop;
int error;
+ zone_t *zone;
if ((error = miocpullup(mp, sizeof (pt_own_t))) != 0) {
miocnak(qp, mp, 0, error);
break;
}
+ zone = zone_find_by_id(ptmp->pt_zoneid);
ptop = (pt_own_t *)mp->b_cont->b_rptr;
- if (!VALID_UID(ptop->pto_ruid) ||
- !VALID_GID(ptop->pto_rgid)) {
+ if (!VALID_UID(ptop->pto_ruid, zone) ||
+ !VALID_GID(ptop->pto_rgid, zone)) {
+ zone_rele(zone);
miocnak(qp, mp, 0, EINVAL);
break;
}
-
+ zone_rele(zone);
mutex_enter(&ptmp->pt_lock);
ptmp->pt_ruid = ptop->pto_ruid;
ptmp->pt_rgid = ptop->pto_rgid;
diff --git a/usr/src/uts/common/os/cred.c b/usr/src/uts/common/os/cred.c
index c6a1f1fabb..9102e0b627 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -64,19 +64,27 @@
#include <sys/idmap.h>
#include <sys/varargs.h>
-typedef struct ephidmap_data {
- uid_t min_uid, last_uid;
- gid_t min_gid, last_gid;
- cred_t *nobody;
+
+/* Ephemeral IDs Zones specific data */
+typedef struct ephemeral_zsd {
+ uid_t min_uid;
+ uid_t last_uid;
+ gid_t min_gid;
+ gid_t last_gid;
kmutex_t eph_lock;
-} ephidmap_data_t;
+ cred_t *eph_nobody;
+} ephemeral_zsd_t;
+
+
+static kmutex_t ephemeral_zone_mutex;
+static zone_key_t ephemeral_zone_key;
static struct kmem_cache *cred_cache;
-static size_t crsize = 0;
-static int audoff = 0;
-uint32_t ucredsize;
-cred_t *kcred;
-static cred_t *dummycr;
+static size_t crsize = 0;
+static int audoff = 0;
+uint32_t ucredsize;
+cred_t *kcred;
+static cred_t *dummycr;
int rstlink; /* link(2) restricted to files owned by user? */
@@ -87,15 +95,59 @@ static int get_c2audit_load(void);
#define REMOTE_PEER_CRED(c) ((c)->cr_gid == -1)
+
+static boolean_t hasephids = B_FALSE;
+
+static ephemeral_zsd_t *
+get_ephemeral_zsd(zone_t *zone)
+{
+ ephemeral_zsd_t *eph_zsd;
+
+ eph_zsd = zone_getspecific(ephemeral_zone_key, zone);
+ if (eph_zsd != NULL) {
+ return (eph_zsd);
+ }
+
+ mutex_enter(&ephemeral_zone_mutex);
+ eph_zsd = zone_getspecific(ephemeral_zone_key, zone);
+ if (eph_zsd == NULL) {
+ eph_zsd = kmem_zalloc(sizeof (ephemeral_zsd_t), KM_SLEEP);
+ eph_zsd->min_uid = MAXUID;
+ eph_zsd->last_uid = IDMAP_WK__MAX_UID;
+ eph_zsd->min_gid = MAXUID;
+ eph_zsd->last_gid = IDMAP_WK__MAX_GID;
+ mutex_init(&eph_zsd->eph_lock, NULL, MUTEX_DEFAULT, NULL);
+
+ /*
+ * nobody is used to map SID containing CRs.
+ */
+ eph_zsd->eph_nobody = crdup(zone->zone_kcred);
+ (void) crsetugid(eph_zsd->eph_nobody, UID_NOBODY, GID_NOBODY);
+ CR_FLAGS(eph_zsd->eph_nobody) = 0;
+ eph_zsd->eph_nobody->cr_zone = zone;
+
+ (void) zone_setspecific(ephemeral_zone_key, zone, eph_zsd);
+ }
+ mutex_exit(&ephemeral_zone_mutex);
+ return (eph_zsd);
+}
+
/*
- * XXX: should be per-zone.
- * Start with an invalid value for atomic increments.
+ * This function is called when a zone is destroyed
*/
-static ephidmap_data_t ephemeral_data = {
- MAXUID, IDMAP_WK__MAX_UID, MAXUID, IDMAP_WK__MAX_GID
-};
+static void
+/* ARGSUSED */
+destroy_ephemeral_zsd(zoneid_t zone_id, void *arg)
+{
+ ephemeral_zsd_t *eph_zsd = arg;
+ if (eph_zsd != NULL) {
+ mutex_destroy(&eph_zsd->eph_lock);
+ crfree(eph_zsd->eph_nobody);
+ kmem_free(eph_zsd, sizeof (ephemeral_zsd_t));
+ }
+}
+
-static boolean_t hasephids = B_FALSE;
/*
* Initialize credentials data structures.
@@ -175,14 +227,10 @@ 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(ephemeral_data.nobody) = 0;
-
ucredsize = UCRED_SIZE;
+
+ mutex_init(&ephemeral_zone_mutex, NULL, MUTEX_DEFAULT, NULL);
+ zone_key_create(&ephemeral_zone_key, NULL, NULL, destroy_ephemeral_zsd);
}
/*
@@ -622,15 +670,17 @@ crisremote(const cred_t *cr)
return (REMOTE_PEER_CRED(cr));
}
-#define BADUID(x) ((x) != -1 && !VALID_UID(x))
-#define BADGID(x) ((x) != -1 && !VALID_GID(x))
+#define BADUID(x, zn) ((x) != -1 && !VALID_UID((x), (zn)))
+#define BADGID(x, zn) ((x) != -1 && !VALID_GID((x), (zn)))
int
crsetresuid(cred_t *cr, uid_t r, uid_t e, uid_t s)
{
+ zone_t *zone = crgetzone(cr);
+
ASSERT(cr->cr_ref <= 2);
- if (BADUID(r) || BADUID(e) || BADUID(s))
+ if (BADUID(r, zone) || BADUID(e, zone) || BADUID(s, zone))
return (-1);
if (r != -1)
@@ -646,9 +696,11 @@ crsetresuid(cred_t *cr, uid_t r, uid_t e, uid_t s)
int
crsetresgid(cred_t *cr, gid_t r, gid_t e, gid_t s)
{
+ zone_t *zone = crgetzone(cr);
+
ASSERT(cr->cr_ref <= 2);
- if (BADGID(r) || BADGID(e) || BADGID(s))
+ if (BADGID(r, zone) || BADGID(e, zone) || BADGID(s, zone))
return (-1);
if (r != -1)
@@ -664,9 +716,11 @@ crsetresgid(cred_t *cr, gid_t r, gid_t e, gid_t s)
int
crsetugid(cred_t *cr, uid_t uid, gid_t gid)
{
+ zone_t *zone = crgetzone(cr);
+
ASSERT(cr->cr_ref <= 2);
- if (!VALID_UID(uid) || !VALID_GID(gid))
+ if (!VALID_UID(uid, zone) || !VALID_GID(gid, zone))
return (-1);
cr->cr_uid = cr->cr_ruid = cr->cr_suid = uid;
@@ -970,72 +1024,138 @@ zone_kcred(void)
}
boolean_t
-valid_ephemeral_uid(uid_t id)
+valid_ephemeral_uid(zone_t *zone, uid_t id)
{
+ ephemeral_zsd_t *eph_zsd;
+ if (id < IDMAP_WK__MAX_UID)
+ return (B_TRUE);
+
+ eph_zsd = get_ephemeral_zsd(zone);
+ ASSERT(eph_zsd != NULL);
membar_consumer();
- return (id < IDMAP_WK__MAX_UID ||
- (id > ephemeral_data.min_uid && id <= ephemeral_data.last_uid));
+ return (id > eph_zsd->min_uid && id <= eph_zsd->last_uid);
}
boolean_t
-valid_ephemeral_gid(gid_t id)
+valid_ephemeral_gid(zone_t *zone, gid_t id)
{
+ ephemeral_zsd_t *eph_zsd;
+ if (id < IDMAP_WK__MAX_GID)
+ return (B_TRUE);
+
+ eph_zsd = get_ephemeral_zsd(zone);
+ ASSERT(eph_zsd != NULL);
membar_consumer();
- return (id < IDMAP_WK__MAX_GID ||
- (id > ephemeral_data.min_gid && id <= ephemeral_data.last_gid));
+ return (id > eph_zsd->min_gid && id <= eph_zsd->last_gid);
}
int
-eph_uid_alloc(int flags, uid_t *start, int count)
+eph_uid_alloc(zone_t *zone, int flags, uid_t *start, int count)
{
- mutex_enter(&ephemeral_data.eph_lock);
+ ephemeral_zsd_t *eph_zsd = get_ephemeral_zsd(zone);
+
+ ASSERT(eph_zsd != NULL);
+
+ mutex_enter(&eph_zsd->eph_lock);
/* Test for unsigned integer wrap around */
- if (ephemeral_data.last_uid + count < ephemeral_data.last_uid) {
- mutex_exit(&ephemeral_data.eph_lock);
+ if (eph_zsd->last_uid + count < eph_zsd->last_uid) {
+ mutex_exit(&eph_zsd->eph_lock);
return (-1);
}
/* first call or idmap crashed and state corrupted */
if (flags != 0)
- ephemeral_data.min_uid = ephemeral_data.last_uid;
+ eph_zsd->min_uid = eph_zsd->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);
+ *start = eph_zsd->last_uid + 1;
+ atomic_add_32(&eph_zsd->last_uid, count);
+ mutex_exit(&eph_zsd->eph_lock);
return (0);
}
int
-eph_gid_alloc(int flags, gid_t *start, int count)
+eph_gid_alloc(zone_t *zone, int flags, gid_t *start, int count)
{
- mutex_enter(&ephemeral_data.eph_lock);
+ ephemeral_zsd_t *eph_zsd = get_ephemeral_zsd(zone);
+
+ ASSERT(eph_zsd != NULL);
+
+ mutex_enter(&eph_zsd->eph_lock);
/* Test for unsigned integer wrap around */
- if (ephemeral_data.last_gid + count < ephemeral_data.last_gid) {
- mutex_exit(&ephemeral_data.eph_lock);
+ if (eph_zsd->last_gid + count < eph_zsd->last_gid) {
+ mutex_exit(&eph_zsd->eph_lock);
return (-1);
}
/* first call or idmap crashed and state corrupted */
if (flags != 0)
- ephemeral_data.min_gid = ephemeral_data.last_gid;
+ eph_zsd->min_gid = eph_zsd->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);
+ *start = eph_zsd->last_gid + 1;
+ atomic_add_32(&eph_zsd->last_gid, count);
+ mutex_exit(&eph_zsd->eph_lock);
return (0);
}
/*
+ * IMPORTANT.The two functions get_ephemeral_data() and set_ephemeral_data()
+ * are project private functions that are for use of the test system only and
+ * are not to be used for other purposes.
+ */
+
+void
+get_ephemeral_data(zone_t *zone, uid_t *min_uid, uid_t *last_uid,
+ gid_t *min_gid, gid_t *last_gid)
+{
+ ephemeral_zsd_t *eph_zsd = get_ephemeral_zsd(zone);
+
+ ASSERT(eph_zsd != NULL);
+
+ mutex_enter(&eph_zsd->eph_lock);
+
+ *min_uid = eph_zsd->min_uid;
+ *last_uid = eph_zsd->last_uid;
+ *min_gid = eph_zsd->min_gid;
+ *last_gid = eph_zsd->last_gid;
+
+ mutex_exit(&eph_zsd->eph_lock);
+}
+
+
+void
+set_ephemeral_data(zone_t *zone, uid_t min_uid, uid_t last_uid,
+ gid_t min_gid, gid_t last_gid)
+{
+ ephemeral_zsd_t *eph_zsd = get_ephemeral_zsd(zone);
+
+ ASSERT(eph_zsd != NULL);
+
+ mutex_enter(&eph_zsd->eph_lock);
+
+ if (min_uid != 0)
+ eph_zsd->min_uid = min_uid;
+ if (last_uid != 0)
+ eph_zsd->last_uid = last_uid;
+ if (min_gid != 0)
+ eph_zsd->min_gid = min_gid;
+ if (last_gid != 0)
+ eph_zsd->last_gid = last_gid;
+
+ mutex_exit(&eph_zsd->eph_lock);
+}
+
+/*
* If the credential user SID or group SID is mapped to an ephemeral
* ID, map the credential to nobody.
*/
cred_t *
crgetmapped(const cred_t *cr)
{
+ ephemeral_zsd_t *eph_zsd;
/*
* Someone incorrectly passed a NULL cred to a vnode operation
* either on purpose or by calling CRED() in interrupt context.
@@ -1044,11 +1164,15 @@ crgetmapped(const cred_t *cr)
return (NULL);
if (cr->cr_ksid != NULL) {
- if (cr->cr_ksid->kr_sidx[KSID_USER].ks_id > MAXUID)
- return (ephemeral_data.nobody);
+ if (cr->cr_ksid->kr_sidx[KSID_USER].ks_id > MAXUID) {
+ eph_zsd = get_ephemeral_zsd(crgetzone(cr));
+ return (eph_zsd->eph_nobody);
+ }
- if (cr->cr_ksid->kr_sidx[KSID_GROUP].ks_id > MAXUID)
- return (ephemeral_data.nobody);
+ if (cr->cr_ksid->kr_sidx[KSID_GROUP].ks_id > MAXUID) {
+ eph_zsd = get_ephemeral_zsd(crgetzone(cr));
+ return (eph_zsd->eph_nobody);
+ }
}
return ((cred_t *)cr);
diff --git a/usr/src/uts/common/os/ipc.c b/usr/src/uts/common/os/ipc.c
index 3e3a5b79cb..06324b140a 100644
--- a/usr/src/uts/common/os/ipc.c
+++ b/usr/src/uts/common/os/ipc.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -518,6 +518,7 @@ ipcperm_set(ipc_service_t *service, struct cred *cr,
uid_t uid;
gid_t gid;
mode_t mode;
+ zone_t *zone;
ASSERT(IPC_LOCKED(service, kperm));
@@ -529,7 +530,8 @@ ipcperm_set(ipc_service_t *service, struct cred *cr,
if (secpolicy_ipc_owner(cr, kperm) != 0)
return (EPERM);
- if (!VALID_UID(uid) || !VALID_GID(gid))
+ zone = crgetzone(cr);
+ if (!VALID_UID(uid, zone) || !VALID_GID(gid, zone))
return (EINVAL);
kperm->ipc_uid = uid;
@@ -561,12 +563,16 @@ int
ipcperm_set64(ipc_service_t *service, struct cred *cr,
kipc_perm_t *kperm, ipc_perm64_t *perm64)
{
+ zone_t *zone;
+
ASSERT(IPC_LOCKED(service, kperm));
if (secpolicy_ipc_owner(cr, kperm) != 0)
return (EPERM);
- if (!VALID_UID(perm64->ipcx_uid) || !VALID_GID(perm64->ipcx_gid))
+ zone = crgetzone(cr);
+ if (!VALID_UID(perm64->ipcx_uid, zone) ||
+ !VALID_GID(perm64->ipcx_gid, zone))
return (EINVAL);
kperm->ipc_uid = perm64->ipcx_uid;
diff --git a/usr/src/uts/common/os/policy.c b/usr/src/uts/common/os/policy.c
index 33602dc660..d5e83e8e6a 100644
--- a/usr/src/uts/common/os/policy.c
+++ b/usr/src/uts/common/os/policy.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -2016,7 +2016,7 @@ secpolicy_zfs(const cred_t *cr)
int
secpolicy_idmap(const cred_t *cr)
{
- return (PRIV_POLICY(cr, PRIV_ALL, B_FALSE, EPERM, NULL));
+ return (PRIV_POLICY(cr, PRIV_FILE_SETID, B_TRUE, EPERM, NULL));
}
/*
diff --git a/usr/src/uts/common/os/sid.c b/usr/src/uts/common/os/sid.c
index 2ed5ad2989..9073e645b5 100644
--- a/usr/src/uts/common/os/sid.c
+++ b/usr/src/uts/common/os/sid.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -187,11 +187,12 @@ ksid_getrid(ksid_t *ks)
}
int
-ksid_lookupbyuid(uid_t id, ksid_t *res)
+ksid_lookupbyuid(zone_t *zone, uid_t id, ksid_t *res)
{
const char *sid_prefix;
- if (kidmap_getsidbyuid(id, &sid_prefix, &res->ks_rid) != IDMAP_SUCCESS)
+ if (kidmap_getsidbyuid(zone, id, &sid_prefix, &res->ks_rid)
+ != IDMAP_SUCCESS)
return (-1);
res->ks_domain = ksid_lookupdomain(sid_prefix);
@@ -202,11 +203,12 @@ ksid_lookupbyuid(uid_t id, ksid_t *res)
}
int
-ksid_lookupbygid(gid_t id, ksid_t *res)
+ksid_lookupbygid(zone_t *zone, gid_t id, ksid_t *res)
{
const char *sid_prefix;
- if (kidmap_getsidbygid(id, &sid_prefix, &res->ks_rid) != IDMAP_SUCCESS)
+ if (kidmap_getsidbygid(zone, id, &sid_prefix, &res->ks_rid)
+ != IDMAP_SUCCESS)
return (-1);
res->ks_domain = ksid_lookupdomain(sid_prefix);
@@ -374,7 +376,7 @@ kcrsid_setsidlist(credsid_t *okcr, ksidlist_t *ksl)
}
ksidlist_t *
-kcrsid_gidstosids(int ngrp, gid_t *grp)
+kcrsid_gidstosids(zone_t *zone, int ngrp, gid_t *grp)
{
int i;
ksidlist_t *list;
@@ -392,7 +394,8 @@ kcrsid_gidstosids(int ngrp, gid_t *grp)
for (i = 0; i < ngrp; i++) {
if (grp[i] > MAXUID) {
list->ksl_neid++;
- if (ksid_lookupbygid(grp[i], &list->ksl_sids[i]) != 0) {
+ if (ksid_lookupbygid(zone,
+ grp[i], &list->ksl_sids[i]) != 0) {
while (--i >= 0)
ksid_rele(&list->ksl_sids[i]);
cnt = 0;
diff --git a/usr/src/uts/common/sys/cred.h b/usr/src/uts/common/sys/cred.h
index 41f2827f78..35785d3c1d 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -153,16 +153,17 @@ 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)))
+#define VALID_UID(id, zn) \
+ ((id) <= MAXUID || valid_ephemeral_uid((zn), (id)))
-extern boolean_t valid_ephemeral_uid(uid_t);
-extern boolean_t valid_ephemeral_gid(gid_t);
+#define VALID_GID(id, zn) \
+ ((id) <= MAXUID || valid_ephemeral_gid((zn), (id)))
-extern int eph_uid_alloc(int, uid_t *, int);
-extern int eph_gid_alloc(int, gid_t *, int);
+extern boolean_t valid_ephemeral_uid(struct zone *, uid_t);
+extern boolean_t valid_ephemeral_gid(struct zone *, gid_t);
+
+extern int eph_uid_alloc(struct zone *, int, uid_t *, int);
+extern int eph_gid_alloc(struct zone *, int, gid_t *, int);
extern void crsetsid(cred_t *, struct ksid *, int);
extern void crsetsidlist(cred_t *, struct ksidlist *);
diff --git a/usr/src/uts/common/sys/kidmap.h b/usr/src/uts/common/sys/kidmap.h
index 36fb0e8143..00db50eb63 100644
--- a/usr/src/uts/common/sys/kidmap.h
+++ b/usr/src/uts/common/sys/kidmap.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,6 +37,7 @@
#include <sys/idmap.h>
#include <sys/door.h>
+#include <sys/zone.h>
#ifdef __cplusplus
extern "C" {
@@ -67,20 +68,24 @@ typedef int32_t idmap_stat;
idmap_stat
-kidmap_getuidbysid(const char *sid_prefix, uint32_t rid, uid_t *uid);
+kidmap_getuidbysid(zone_t *zone, const char *sid_prefix, uint32_t rid,
+ uid_t *uid);
idmap_stat
-kidmap_getgidbysid(const char *sid_prefix, uint32_t rid, gid_t *gid);
+kidmap_getgidbysid(zone_t *zone, const char *sid_prefix, uint32_t rid,
+ gid_t *gid);
idmap_stat
-kidmap_getpidbysid(const char *sid_prefix, uint32_t rid, uid_t *pid,
- int *is_user);
+kidmap_getpidbysid(zone_t *zone, const char *sid_prefix, uint32_t rid,
+ uid_t *pid, int *is_user);
idmap_stat
-kidmap_getsidbyuid(uid_t uid, const char **sid_prefix, uint32_t *rid);
+kidmap_getsidbyuid(zone_t *zone, uid_t uid, const char **sid_prefix,
+ uint32_t *rid);
idmap_stat
-kidmap_getsidbygid(gid_t gid, const char **sid_prefix, uint32_t *rid);
+kidmap_getsidbygid(zone_t *zone, gid_t gid, const char **sid_prefix,
+ uint32_t *rid);
@@ -92,7 +97,7 @@ kidmap_getsidbygid(gid_t gid, const char **sid_prefix, uint32_t *rid);
* Create a batch "get mapping" handle for batch mappings.
*/
idmap_get_handle_t *
-kidmap_get_create(void);
+kidmap_get_create(zone_t *zone);
/*
* These routines queue the request to the "get mapping" handle
@@ -139,17 +144,21 @@ kidmap_get_destroy(idmap_get_handle_t *get_handle);
* Functions that do the hard part of door registration/unregistration
* for the idmap_reg()/idmap_unreg() syscalls
*/
-int idmap_reg_dh(door_handle_t dh);
-int idmap_unreg_dh(door_handle_t dh);
+int idmap_reg_dh(zone_t *zone, door_handle_t dh);
+int idmap_unreg_dh(zone_t *zone, door_handle_t dh);
/*
- * Functions needed by allocids() to ensure only the daemon that owns
+ * Function needed by allocids() to ensure only the daemon that owns
* the door gets ephemeral IDS
*/
-typedef struct idmap_reg idmap_reg_t;
+door_handle_t idmap_get_door(zone_t *zone);
+
+/*
+ * Function used by system call allocids() to purge the
+ * ID mapping cache
+ */
+void idmap_purge_cache(zone_t *zone);
-void idmap_get_door(idmap_reg_t **state, door_handle_t *dh);
-void idmap_release_door(idmap_reg_t *idmp);
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/sys/sid.h b/usr/src/uts/common/sys/sid.h
index 96b9f5a0b8..68f01379c0 100644
--- a/usr/src/uts/common/sys/sid.h
+++ b/usr/src/uts/common/sys/sid.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,6 +31,9 @@
#include <sys/types.h>
#include <sys/avl.h>
+#ifdef _KERNEL
+#include <sys/zone.h>
+#endif
/*
* Kernel SID data structure and functions.
@@ -42,8 +45,8 @@ extern "C" {
/* sidsys subcodes */
#define SIDSYS_ALLOC_IDS 0
/* Flags for ALLOC_IDS */
-#define SID_EXTEND_RANGE 0
-#define SID_NEW_RANGE 1
+#define SID_EXTEND_RANGE 0
+#define SID_NEW_RANGE 1
#define SIDSYS_IDMAP_REG 1
#define SIDSYS_IDMAP_UNREG 2
@@ -97,8 +100,8 @@ typedef struct credsid {
const char *ksid_getdomain(ksid_t *);
uint_t ksid_getrid(ksid_t *);
-int ksid_lookupbyuid(uid_t, ksid_t *);
-int ksid_lookupbygid(gid_t, ksid_t *);
+int ksid_lookupbyuid(zone_t *, uid_t, ksid_t *);
+int ksid_lookupbygid(zone_t *, gid_t, ksid_t *);
void ksid_rele(ksid_t *);
credsid_t *kcrsid_alloc(void);
@@ -117,7 +120,7 @@ void ksidlist_hold(ksidlist_t *);
ksiddomain_t *ksid_lookupdomain(const char *);
-ksidlist_t *kcrsid_gidstosids(int, gid_t *);
+ksidlist_t *kcrsid_gidstosids(zone_t *, int, gid_t *);
#else
diff --git a/usr/src/uts/common/syscall/chown.c b/usr/src/uts/common/syscall/chown.c
index f21a2a1e1f..706b3b4f71 100644
--- a/usr/src/uts/common/syscall/chown.c
+++ b/usr/src/uts/common/syscall/chown.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -69,9 +69,10 @@ cfchownat(int fd, char *name, int nmflag, uid_t uid, gid_t gid, int flags)
struct vattr vattr;
int error = 0;
char startchar;
+ struct zone *zone = crgetzone(CRED());
- if (uid != (uid_t)-1 && !VALID_UID(uid) ||
- gid != (gid_t)-1 && !VALID_GID(gid)) {
+ if (uid != (uid_t)-1 && !VALID_UID(uid, zone) ||
+ gid != (gid_t)-1 && !VALID_GID(gid, zone)) {
return (set_errno(EINVAL));
}
vattr.va_uid = uid;
diff --git a/usr/src/uts/common/syscall/gid.c b/usr/src/uts/common/syscall/gid.c
index 4ea9660cc3..fbf90d3d3e 100644
--- a/usr/src/uts/common/syscall/gid.c
+++ b/usr/src/uts/common/syscall/gid.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -48,12 +48,14 @@ setgid(gid_t gid)
int do_nocd = 0;
cred_t *cr, *newcr;
ksid_t ksid, *ksp;
+ zone_t *zone = crgetzone(CRED());
- if (!VALID_GID(gid))
+
+ if (!VALID_GID(gid, zone))
return (set_errno(EINVAL));
if (gid > MAXUID) {
- if (ksid_lookupbygid(gid, &ksid) != 0)
+ if (ksid_lookupbygid(zone, gid, &ksid) != 0)
return (set_errno(EINVAL));
ksp = &ksid;
} else {
@@ -132,12 +134,13 @@ setegid(gid_t gid)
int error = EPERM;
int do_nocd = 0;
ksid_t ksid, *ksp;
+ zone_t *zone = crgetzone(CRED());
- if (!VALID_GID(gid))
+ if (!VALID_GID(gid, zone))
return (set_errno(EINVAL));
if (gid > MAXUID) {
- if (ksid_lookupbygid(gid, &ksid) != 0)
+ if (ksid_lookupbygid(zone, gid, &ksid) != 0)
return (set_errno(EINVAL));
ksp = &ksid;
} else {
@@ -199,13 +202,14 @@ setregid(gid_t rgid, gid_t egid)
int do_nocd = 0;
cred_t *cr, *newcr;
ksid_t ksid, *ksp;
+ zone_t *zone = crgetzone(CRED());
- if ((rgid != -1 && !VALID_GID(rgid)) ||
- (egid != -1 && !VALID_GID(egid)))
+ if ((rgid != -1 && !VALID_GID(rgid, zone)) ||
+ (egid != -1 && !VALID_GID(egid, zone)))
return (set_errno(EINVAL));
if (egid != -1 && egid > MAXUID) {
- if (ksid_lookupbygid(egid, &ksid) != 0)
+ if (ksid_lookupbygid(zone, egid, &ksid) != 0)
return (set_errno(EINVAL));
ksp = &ksid;
} else {
diff --git a/usr/src/uts/common/syscall/groups.c b/usr/src/uts/common/syscall/groups.c
index b9a6c23441..8273171d0c 100644
--- a/usr/src/uts/common/syscall/groups.c
+++ b/usr/src/uts/common/syscall/groups.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -49,11 +49,13 @@ setgroups(int gidsetsize, gid_t *gidset)
int error;
int scnt = 0;
ksidlist_t *ksl = NULL;
+ zone_t *zone;
/* Perform the cheapest tests before grabbing p_crlock */
if (n > ngroups_max || n < 0)
return (set_errno(EINVAL));
+ zone = crgetzone(CRED());
if (n != 0) {
groups = kmem_alloc(n * sizeof (gid_t), KM_SLEEP);
@@ -63,7 +65,7 @@ setgroups(int gidsetsize, gid_t *gidset)
}
for (i = 0; i < n; i++) {
- if (!VALID_GID(groups[i])) {
+ if (!VALID_GID(groups[i], zone)) {
kmem_free(groups, n * sizeof (gid_t));
return (set_errno(EINVAL));
}
@@ -71,7 +73,7 @@ setgroups(int gidsetsize, gid_t *gidset)
scnt++;
}
if (scnt > 0) {
- ksl = kcrsid_gidstosids(n, groups);
+ ksl = kcrsid_gidstosids(zone, n, groups);
if (ksl == NULL) {
kmem_free(groups, n * sizeof (gid_t));
return (set_errno(EINVAL));
diff --git a/usr/src/uts/common/syscall/sidsys.c b/usr/src/uts/common/syscall/sidsys.c
index 9e51fe170c..046326bd60 100644
--- a/usr/src/uts/common/syscall/sidsys.c
+++ b/usr/src/uts/common/syscall/sidsys.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -47,29 +47,34 @@ allocids(int flag, int nuids, int ngids)
gid_t sg = 0;
struct door_info di;
door_handle_t dh;
- idmap_reg_t *reg;
int err;
+ zone_t *zone = crgetzone(CRED());
- idmap_get_door(&reg, &dh);
+ dh = idmap_get_door(zone);
- if (reg == NULL || dh == NULL)
+ if (dh == NULL)
return (set_errno(EPERM));
- if ((err = door_ki_info(dh, &di)) != 0)
+ if ((err = door_ki_info(dh, &di)) != 0) {
+ door_ki_rele(dh);
return (set_errno(err));
+ }
+
+ door_ki_rele(dh);
if (curproc->p_pid != di.di_target)
return (set_errno(EPERM));
- idmap_release_door(reg);
+ if (flag)
+ idmap_purge_cache(zone);
if (nuids < 0 || ngids < 0)
return (set_errno(EINVAL));
if (flag != 0 || nuids > 0)
- err = eph_uid_alloc(flag, &su, nuids);
+ err = eph_uid_alloc(zone, flag, &su, nuids);
if (err == 0 && (flag != 0 || ngids > 0))
- err = eph_gid_alloc(flag, &sg, ngids);
+ err = eph_gid_alloc(zone, flag, &sg, ngids);
if (err != 0)
return (set_errno(EOVERFLOW));
@@ -84,8 +89,9 @@ idmap_reg(int did)
{
door_handle_t dh;
int err;
+ cred_t *cr = CRED();
- if ((err = secpolicy_idmap(CRED())) != 0)
+ if ((err = secpolicy_idmap(cr)) != 0)
return (set_errno(err));
dh = door_ki_lookup(did);
@@ -93,9 +99,10 @@ idmap_reg(int did)
if (dh == NULL)
return (set_errno(EBADF));
- err = idmap_reg_dh(dh);
+ if ((err = idmap_reg_dh(crgetzone(cr), dh)) != 0)
+ return (set_errno(err));
- return (err);
+ return (0);
}
static int
@@ -103,11 +110,13 @@ idmap_unreg(int did)
{
door_handle_t dh = door_ki_lookup(did);
int res;
+ zone_t *zone;
if (dh == NULL)
return (set_errno(EINVAL));
- res = idmap_unreg_dh(dh);
+ zone = crgetzone(CRED());
+ res = idmap_unreg_dh(zone, dh);
door_ki_rele(dh);
if (res != 0)
diff --git a/usr/src/uts/common/syscall/uid.c b/usr/src/uts/common/syscall/uid.c
index ef96933ba3..9973b17e43 100644
--- a/usr/src/uts/common/syscall/uid.c
+++ b/usr/src/uts/common/syscall/uid.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -54,12 +54,13 @@ setuid(uid_t uid)
uid_t oldruid = uid;
zoneid_t zoneid = getzoneid();
ksid_t ksid, *ksp;
+ zone_t *zone = crgetzone(CRED());
- if (!VALID_UID(uid))
+ if (!VALID_UID(uid, zone))
return (set_errno(EINVAL));
if (uid > MAXUID) {
- if (ksid_lookupbyuid(uid, &ksid) != 0)
+ if (ksid_lookupbyuid(zone, uid, &ksid) != 0)
return (set_errno(EINVAL));
ksp = &ksid;
} else {
@@ -173,12 +174,13 @@ seteuid(uid_t uid)
int do_nocd = 0;
cred_t *cr, *newcr;
ksid_t ksid, *ksp;
+ zone_t *zone = crgetzone(CRED());
- if (!VALID_UID(uid))
+ if (!VALID_UID(uid, zone))
return (set_errno(EINVAL));
if (uid > MAXUID) {
- if (ksid_lookupbyuid(uid, &ksid) != 0)
+ if (ksid_lookupbyuid(zone, uid, &ksid) != 0)
return (set_errno(EINVAL));
ksp = &ksid;
} else {
@@ -246,13 +248,14 @@ setreuid(uid_t ruid, uid_t euid)
cred_t *cr, *newcr;
zoneid_t zoneid = getzoneid();
ksid_t ksid, *ksp;
+ zone_t *zone = crgetzone(CRED());
- if ((ruid != -1 && !VALID_UID(ruid)) ||
- (euid != -1 && !VALID_UID(euid)))
+ if ((ruid != -1 && !VALID_UID(ruid, zone)) ||
+ (euid != -1 && !VALID_UID(euid, zone)))
return (set_errno(EINVAL));
if (euid != -1 && euid > MAXUID) {
- if (ksid_lookupbyuid(euid, &ksid) != 0)
+ if (ksid_lookupbyuid(zone, euid, &ksid) != 0)
return (set_errno(EINVAL));
ksp = &ksid;
} else {
diff --git a/usr/src/uts/intel/ia32/ml/modstubs.s b/usr/src/uts/intel/ia32/ml/modstubs.s
index 7cee20312e..8641ff6a77 100644
--- a/usr/src/uts/intel/ia32/ml/modstubs.s
+++ b/usr/src/uts/intel/ia32/ml/modstubs.s
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -896,23 +896,23 @@ fcnname/**/_info: \
*/
#ifndef IDMAP_MODULE
MODULE(idmap,misc);
- STUB(idmap,kidmap_batch_getgidbysid,nomod_zero);
- STUB(idmap,kidmap_batch_getpidbysid,nomod_zero);
- STUB(idmap,kidmap_batch_getsidbygid,nomod_zero);
- STUB(idmap,kidmap_batch_getsidbyuid,nomod_zero);
- STUB(idmap,kidmap_batch_getuidbysid,nomod_zero);
- STUB(idmap,kidmap_get_create,nomod_zero);
- STUB(idmap,kidmap_get_destroy,nomod_zero);
- STUB(idmap,kidmap_get_mappings,nomod_zero);
- STUB(idmap,kidmap_getgidbysid,nomod_zero);
- STUB(idmap,kidmap_getpidbysid,nomod_zero);
- STUB(idmap,kidmap_getsidbygid,nomod_zero);
- STUB(idmap,kidmap_getsidbyuid,nomod_zero);
- STUB(idmap,kidmap_getuidbysid,nomod_zero);
- STUB(idmap,idmap_get_door,nomod_einval);
- STUB(idmap,idmap_unreg_dh,nomod_einval);
- STUB(idmap,idmap_reg_dh,nomod_einval);
- STUB(idmap,idmap_release_door,nomod_einval);
+ STUB(idmap, kidmap_batch_getgidbysid, nomod_zero);
+ STUB(idmap, kidmap_batch_getpidbysid, nomod_zero);
+ STUB(idmap, kidmap_batch_getsidbygid, nomod_zero);
+ STUB(idmap, kidmap_batch_getsidbyuid, nomod_zero);
+ STUB(idmap, kidmap_batch_getuidbysid, nomod_zero);
+ STUB(idmap, kidmap_get_create, nomod_zero);
+ STUB(idmap, kidmap_get_destroy, nomod_zero);
+ STUB(idmap, kidmap_get_mappings, nomod_zero);
+ STUB(idmap, kidmap_getgidbysid, nomod_zero);
+ STUB(idmap, kidmap_getpidbysid, nomod_zero);
+ STUB(idmap, kidmap_getsidbygid, nomod_zero);
+ STUB(idmap, kidmap_getsidbyuid, nomod_zero);
+ STUB(idmap, kidmap_getuidbysid, nomod_zero);
+ STUB(idmap, idmap_get_door, nomod_einval);
+ STUB(idmap, idmap_unreg_dh, nomod_einval);
+ STUB(idmap, idmap_reg_dh, nomod_einval);
+ STUB(idmap, idmap_purge_cache, nomod_einval);
END_MODULE(idmap);
#endif
diff --git a/usr/src/uts/sparc/ml/modstubs.s b/usr/src/uts/sparc/ml/modstubs.s
index db9f9d954f..4ca51c3015 100644
--- a/usr/src/uts/sparc/ml/modstubs.s
+++ b/usr/src/uts/sparc/ml/modstubs.s
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -817,23 +817,23 @@ stubs_base:
*/
#ifndef IDMAP_MODULE
MODULE(idmap,misc);
- STUB(idmap,kidmap_batch_getgidbysid,nomod_zero);
- STUB(idmap,kidmap_batch_getpidbysid,nomod_zero);
- STUB(idmap,kidmap_batch_getsidbygid,nomod_zero);
- STUB(idmap,kidmap_batch_getsidbyuid,nomod_zero);
- STUB(idmap,kidmap_batch_getuidbysid,nomod_zero);
- STUB(idmap,kidmap_get_create,nomod_zero);
- STUB(idmap,kidmap_get_destroy,nomod_zero);
- STUB(idmap,kidmap_get_mappings,nomod_zero);
- STUB(idmap,kidmap_getgidbysid,nomod_zero);
- STUB(idmap,kidmap_getpidbysid,nomod_zero);
- STUB(idmap,kidmap_getsidbygid,nomod_zero);
- STUB(idmap,kidmap_getsidbyuid,nomod_zero);
- STUB(idmap,kidmap_getuidbysid,nomod_zero);
- STUB(idmap,idmap_get_door,nomod_einval);
- STUB(idmap,idmap_unreg_dh,nomod_einval);
- STUB(idmap,idmap_reg_dh,nomod_einval);
- STUB(idmap,idmap_release_door,nomod_einval);
+ STUB(idmap, kidmap_batch_getgidbysid, nomod_zero);
+ STUB(idmap, kidmap_batch_getpidbysid, nomod_zero);
+ STUB(idmap, kidmap_batch_getsidbygid, nomod_zero);
+ STUB(idmap, kidmap_batch_getsidbyuid, nomod_zero);
+ STUB(idmap, kidmap_batch_getuidbysid, nomod_zero);
+ STUB(idmap, kidmap_get_create, nomod_zero);
+ STUB(idmap, kidmap_get_destroy, nomod_zero);
+ STUB(idmap, kidmap_get_mappings, nomod_zero);
+ STUB(idmap, kidmap_getgidbysid, nomod_zero);
+ STUB(idmap, kidmap_getpidbysid, nomod_zero);
+ STUB(idmap, kidmap_getsidbygid, nomod_zero);
+ STUB(idmap, kidmap_getsidbyuid, nomod_zero);
+ STUB(idmap, kidmap_getuidbysid, nomod_zero);
+ STUB(idmap, idmap_get_door, nomod_einval);
+ STUB(idmap, idmap_unreg_dh, nomod_einval);
+ STUB(idmap, idmap_reg_dh, nomod_einval);
+ STUB(idmap, idmap_purge_cache, nomod_einval);
END_MODULE(idmap);
#endif