diff options
author | jp151216 <none@none> | 2008-01-04 13:09:02 -0800 |
---|---|---|
committer | jp151216 <none@none> | 2008-01-04 13:09:02 -0800 |
commit | bda89588bd7667394a834e8a9a34612cce2ae9c3 (patch) | |
tree | 1226b1cea0d00fb32b21d27ea65b184516cd8c84 | |
parent | 30ac2e7bcba3a0a4c91d060d5ac3d60cd00f7a3a (diff) | |
download | illumos-gate-bda89588bd7667394a834e8a9a34612cce2ae9c3.tar.gz |
6552639 Each zone should have it's own idmapd
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(®, &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(¶ms) != 0) { + if (kidmap_call_door(zs, ¶ms) != 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(®, &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 |