acl_api.c revision 02d09e03eb27f3a2dc299de704e45dae5173f43f
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy/*
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * CDDL HEADER START
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy *
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * The contents of this file are subject to the terms of the
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * Common Development and Distribution License (the "License").
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * You may not use this file except in compliance with the License.
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy *
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * or http://www.opensolaris.org/os/licensing.
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * See the License for the specific language governing permissions
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * and limitations under the License.
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy *
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * When distributing Covered Code, include this CDDL HEADER in each
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * If applicable, add the following below this CDDL HEADER, with the
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * fields enclosed by brackets "[]" replaced with your own identifying
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * information: Portions Copyright [yyyy] [name of copyright owner]
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy *
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * CDDL HEADER END
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy/*
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * Use is subject to license terms.
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy/*
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * ACL API for smbfs
1d32ba663e202c24a5a1f2e5aef83fffb447cb7fJohn Wren Kennedy */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <sys/types.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <sys/errno.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <sys/cred.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <sys/cmn_err.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <sys/kmem.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <sys/sunddi.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <sys/acl.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <sys/vnode.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <sys/vfs.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <sys/byteorder.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <errno.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <stdio.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <strings.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <unistd.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <umem.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <idmap.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <sys/fs/smbfs_ioctl.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <netsmb/smb.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <netsmb/smb_lib.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include <netsmb/smbfs_acl.h>
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include "smbfs_ntacl.h"
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#include "private.h"
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy/* Sanity check SD sizes */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy#define MAX_RAW_SD_SIZE 32768
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
1d32ba663e202c24a5a1f2e5aef83fffb447cb7fJohn Wren Kennedy/* XXX: acl_common.h */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedyacl_t *acl_alloc(enum acl_type);
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedyvoid acl_free(acl_t *);
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy/*
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * Get/set a Windows security descriptor (SD)
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * using the (private) smbfs ioctl mechanism.
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * Note: Get allocates mbp->mb_top
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy/* ARGSUSED */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedyint
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedysmbfs_acl_iocget(int fd, uint32_t selector, mbdata_t *mbp)
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy{
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy ioc_sdbuf_t iocb;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy struct mbuf *m;
447b1e1fca22e4de5e04623965fbb1460857930cJohn Wren Kennedy int error;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy error = mb_init_sz(mbp, MAX_RAW_SD_SIZE);
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy if (error)
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy return (error);
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy m = mbp->mb_top;
9498083eeaed1aacdde41369b7fa6f3b84870791Yuri Pankov iocb.addr = mtod(m, uintptr_t);
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy iocb.alloc = m->m_maxlen;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy iocb.used = 0;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy iocb.selector = selector;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy /*
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy * This does the OTW Get.
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy if (ioctl(fd, SMBFSIO_GETSD, &iocb) < 0) {
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy error = errno;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy goto errout;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy }
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy m->m_len = iocb.used;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy return (0);
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedyerrout:
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy mb_done(mbp);
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy return (error);
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy}
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy/* ARGSUSED */
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedyint
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedysmbfs_acl_iocset(int fd, uint32_t selector, mbdata_t *mbp)
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy{
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy ioc_sdbuf_t iocb;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy struct mbuf *m;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy int error;
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy
f38cb554a534c6df738be3f4d23327e69888e634John Wren Kennedy /* Make the data contiguous. */
error = m_lineup(mbp->mb_top, &m);
if (error)
return (error);
if (mbp->mb_top != m)
mb_initm(mbp, m);
iocb.addr = mtod(m, uintptr_t);
iocb.alloc = m->m_maxlen;
iocb.used = m->m_len;
iocb.selector = selector;
/*
* This does the OTW Set.
*/
if (ioctl(fd, SMBFSIO_SETSD, &iocb) < 0)
error = errno;
return (error);
}
/*
* Get an NT SD from the open file via ioctl.
*/
int
smbfs_acl_getsd(int fd, uint32_t selector, i_ntsd_t **sdp)
{
mbdata_t *mbp, mb_store;
int error;
mbp = &mb_store;
bzero(mbp, sizeof (*mbp));
/*
* Get the raw Windows SD via ioctl.
* Returns allocated mbchain in mbp.
*/
error = smbfs_acl_iocget(fd, selector, mbp);
if (error == 0) {
/*
* Import the raw SD into "internal" form.
* (like "absolute" form per. NT docs)
* Returns allocated data in sdp
*/
error = md_get_ntsd(mbp, sdp);
}
mb_done(mbp);
return (error);
}
/*
* Set an NT SD onto the open file via ioctl.
*/
int
smbfs_acl_setsd(int fd, uint32_t selector, i_ntsd_t *sd)
{
mbdata_t *mbp, mb_store;
int error;
mbp = &mb_store;
error = mb_init_sz(mbp, MAX_RAW_SD_SIZE);
if (error)
return (error);
/*
* Export the "internal" SD into an mb chain.
* (a.k.a "self-relative" form per. NT docs)
* Returns allocated mbchain in mbp.
*/
error = mb_put_ntsd(mbp, sd);
if (error == 0) {
/*
* Set the raw Windows SD via ioctl.
*/
error = smbfs_acl_iocset(fd, selector, mbp);
}
mb_done(mbp);
return (error);
}
/*
* Convenience function to Get security using a
* ZFS-style ACL (libsec acl, type=ACE_T)
* Intentionally similar to: facl_get(3SEC)
*/
int
smbfs_acl_get(int fd, acl_t **aclp, uid_t *uidp, gid_t *gidp)
{
i_ntsd_t *sd = NULL;
acl_t *acl = NULL;
uint32_t selector;
int error;
/*
* Which parts of the SD are being requested?
* XXX: Should we request the SACL too? If so,
* might that cause this access to be denied?
* Or maybe: if we get access denied, try the
* open/fetch again without the SACL bit.
*/
selector = 0;
if (aclp)
selector |= DACL_SECURITY_INFORMATION;
if (uidp)
selector |= OWNER_SECURITY_INFORMATION;
if (gidp)
selector |= GROUP_SECURITY_INFORMATION;
if (selector == 0)
return (0);
/*
* Get the Windows SD via ioctl, in
* "internal" (absolute) form.
*/
error = smbfs_acl_getsd(fd, selector, &sd);
if (error)
return (error);
/* Note: sd now holds allocated data. */
/*
* Convert the internal SD to a ZFS ACL.
* Get uid/gid too if pointers != NULL.
*/
if (aclp) {
acl = acl_alloc(ACE_T);
if (acl == NULL) {
error = ENOMEM;
goto out;
}
}
error = smbfs_acl_sd2zfs(sd, acl, uidp, gidp);
if (error)
goto out;
/* Success! */
if (aclp) {
*aclp = acl;
acl = NULL;
}
out:
if (acl)
acl_free(acl);
smbfs_acl_free_sd(sd);
return (error);
}
/*
* Convenience function to Set security using a
* ZFS-style ACL (libsec acl, type=ACE_T)
* Intentionally similar to: facl_set(3SEC)
*/
int
smbfs_acl_set(int fd, acl_t *acl, uid_t uid, gid_t gid)
{
i_ntsd_t *sd = NULL;
uint32_t selector;
int error;
/*
* Which parts of the SD are being modified?
* XXX: Ditto comments above re. SACL.
*/
selector = 0;
if (acl)
selector |= DACL_SECURITY_INFORMATION;
if (uid != (uid_t)-1)
selector |= OWNER_SECURITY_INFORMATION;
if (gid != (gid_t)-1)
selector |= GROUP_SECURITY_INFORMATION;
if (selector == 0)
return (0);
if (acl && acl->acl_type != ACE_T)
return (EINVAL);
/*
* Convert the ZFS ACL to an internal SD.
* Returns allocated data in sd
*/
error = smbfs_acl_zfs2sd(acl, uid, gid, &sd);
if (error == 0)
error = smbfs_acl_setsd(fd, selector, sd);
smbfs_acl_free_sd(sd);
return (error);
}