acl_conv.c revision 9c9af2590af49bb395bc8d2eace0f2d4ea16d165
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* ACL support for smbfs
*
* and compile with the smbfs kmod too, once we
* implement VOP_GETSECATTR, VOP_SETSECATTR.
*/
#include <sys/byteorder.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <umem.h>
#include <idmap.h>
#include <netsmb/smbfs_acl.h>
#include <netsmb/smbfs_isec.h>
#include "private.h"
#ifdef _KERNEL
#else /* _KERNEL */
#ifndef lint
#else /* lint */
/* ARGSUSED */
static void
{
free(p);
}
#endif /* lint */
#endif /* _KERNEL */
/*
* Security IDentifier (SID)
*/
static void
{
return;
}
static int
{
int error, i;
return (error);
return (error);
return (ENOMEM);
for (i = 0; i < subauthcount; i++) {
subauthp++;
}
/* Success! */
return (0);
return (error);
}
static int
{
int error, i;
return (EINVAL);
for (i = 0; i < sid->sid_subauthcount; i++) {
subauthp++;
}
/* Success! */
return (0);
return (error);
}
/*
* Access Control Entry (ACE)
*/
static void
{
return;
}
static int
{
int error;
return (ENOMEM);
/*
* The ACE is realy variable length,
* with format determined by the type.
* XXX: This only decodes types 0-7
*
* There may also be padding after it, so
* decode the using a copy of the mbdata,
* and then consume the specified length.
*/
/* Fixed-size header */
/* Variable-size body */
/* Now actually consume ace_len */
/* Success! */
return (0);
return (error);
}
static int
{
return (EINVAL);
/* Success! */
return (0);
return (error);
}
/*
* Access Control List (ACL)
*/
/* Not an OTW structure, so size can be at our convenience. */
static void
{
int i;
return;
for (i = 0; i < acl->acl_acecount; i++) {
acep++;
}
}
static int
{
int i, error;
return (error);
return (error);
return (error);
return (error);
return (error);
return (ENOMEM);
for (i = 0; i < acl->acl_acecount; i++) {
acep++;
}
/*
* There may be more data here, but
* the caller takes care of that.
*/
/* Success! */
return (0);
return (error);
}
static int
{
for (i = 0; i < acl->acl_acecount; i++) {
acep++;
}
/* Fill in acl_len_p */
/* Success! */
return (0);
return (error);
}
/*
* Security Descriptor
*/
void
{
return;
}
/*
* Import a raw SD (mb chain) into "internal" form.
* (like "absolute" form per. NT docs)
* Returns allocated data in sdp
*
* Note: does NOT consume all the mbp data, so the
* caller has to take care of that if necessary.
*/
int
{
int error;
return (ENOMEM);
/*
* Offsets below are relative to this point,
* so save the mbp state for use below.
*/
/*
* For each section make a temporary copy of the
* top_mb state, advance to the given offset, and
* pass that to the lower mb_get_xxx functions.
* These could be marshalled in any order, but
* are normally found in the order shown here.
*/
if (sacloff) {
}
if (dacloff) {
}
if (owneroff) {
}
if (groupoff) {
}
/* Success! */
return (0);
return (error);
}
/*
* Export an "internal" SD into an raw SD (mb chain).
* (a.k.a "self-relative" form per. NT docs)
* Returns allocated mbchain in mbp.
*/
int
{
/*
* These could be marshalled in any order, but
* are normally found in the order shown here.
*/
}
}
}
}
/* Fill in the offsets */
/* Success! */
return (0);
return (error);
}
/*
* Helper functions for conversion between ZFS-style ACLs
* and Windows Security Descriptors.
*/
/*
* Convert an NT SID to a string. Optionally return the
* last sub-authority (or "relative ID" -- RID) in *ridp
* and truncate the output string after the domain part.
* If ridp==NULL, the output string is the whole SID,
* including both the domain and RID.
*
* Return length written, or -1 on error.
*/
int
{
char *s = obuf;
uint_t i, n;
if (n > osz)
return (-1);
s += n; osz -= n;
for (i = 0; i < 6; i++)
if (n > osz)
return (-1);
s += n; osz -= n;
return (-1);
if (ridp)
subs--;
if (n > osz)
return (-1);
s += n; osz -= n;
}
if (ridp)
return (s - obuf);
}
/*
* Our interface to the idmap service.
*/
#ifdef _KERNEL
#define I_GetMappings kidmap_get_mappings
#else /* _KERNEL */
#define I_GetPidBySid idmap_get_pidbysid
#define I_GetMappings idmap_get_mappings
#endif /* _KERNEL */
struct mapinfo {
int mi_isuser;
};
/*
* A special value for mi_isuser (above) to indicate
* that the SID is the well-known "Everyone" (S-1-1-0).
* The idmap library only uses -1, 0, 1, so this value
* is arbitrary but must not overlap w/ idmap values.
* XXX: Could use a way for idmap to tell us when
* it recognizes this well-known SID.
*/
#define IS_WKSID_EVERYONE 11
/*
* Build an idmap request. Cleanup is
* handled by the caller (error or not)
*/
static int
{
char sid_prefix[256];
return (EINVAL);
/*
* Give the "Everyone" group special treatment.
*/
/* This is "Everyone" */
return (0);
}
if (idms != IDMAP_SUCCESS)
return (EINVAL);
return (0);
}
static void
{
/*
* Translate NT ACE flags to ZFS ACE flags.
* The low four bits are the same, but not
* others: INHERITED_ACE_FLAG, etc.
*/
zflags = 0;
if (ntflags & OBJECT_INHERIT_ACE_FLAG)
if (ntflags & INHERIT_ONLY_ACE_FLAG)
if (ntflags & INHERITED_ACE_FLAG)
if (ntflags & FAILED_ACCESS_ACE_FLAG)
/*
* Add the "ID type" flags to the ZFS ace flags.
* Would be nice if the idmap header defined some
* manifest constants for these "isuser" values.
*/
case IS_WKSID_EVERYONE:
zflags |= ACE_EVERYONE;
break;
case 0: /* it's a GID */
break;
default:
case 1: /* it's a UID */
break;
}
/*
* The access mask bits are the same, but
* mask off any bits we don't expect.
* Should not see any GENERIC_xxx flags,
* as those are only valid in requested
* access masks, not ACLs. But if we do,
* get those, silently clear them here.
*/
/*
* Verify that it's a known ACE type.
* Only handle the types that appear in
* V2, V3, V4 ACLs for now. Avoid failing
* the whole conversion if we get unknown
* ace types, but convert them to something
* that will have no effect on access.
*/
if (zatype > SYSTEM_ALARM_OBJECT_ACE_TYPE) {
zamask = 0; /* harmless */
}
/*
* Fill in the ZFS-style ACE
*/
}
/*
* Convert an internal SD to a ZFS-style ACL.
*/
int
#ifdef _KERNEL
#else /* _KERNEL */
#endif /* _KERNEL */
{
#ifndef _KERNEL
#endif /* _KERNEL */
/*
* sanity checks
*/
#ifndef _KERNEL
if (acl_info) {
return (EINVAL);
}
#endif /* _KERNEL */
/*
* First, get all the SID mappings.
* How many?
*/
mapcnt = 0;
mapcnt++;
mapcnt++;
if (mapcnt == 0)
return (EINVAL);
goto errout;
}
/*
* Build our request to the idmap deamon.
*/
#ifdef _KERNEL
#else /* _KERNEL */
if (idms != IDMAP_SUCCESS) {
error = ENOTACTIVE;
goto errout;
}
if (idms != IDMAP_SUCCESS) {
error = ENOTACTIVE;
goto errout;
}
#endif /* _KERNEL */
if (error)
goto errout;
mip++;
}
if (error)
goto errout;
mip++;
}
for (i = 0; i < ntacl->acl_acecount; i++) {
if (error)
goto errout;
ntacep++;
mip++;
}
}
for (i = 0; i < ntacl->acl_acecount; i++) {
if (error)
goto errout;
ntacep++;
mip++;
}
}
if (idms != IDMAP_SUCCESS) {
#ifdef DEBUG
#endif
/* creative error choice */
goto errout;
}
/*
* for every Windows SID in the security descriptor.
* The remaining work is just format conversion.
*/
if (uidp) {
else
}
mip++;
} else {
if (uidp)
}
if (gidp) {
else
}
mip++;
} else {
if (gidp)
}
goto ok_out;
}
/*
* Build the ZFS-style ACL
*/
zacecnt = 0;
#ifdef _KERNEL
#else /* _KERNEL */
goto errout;
}
#endif /* _KERNEL */
for (i = 0; i < ntacl->acl_acecount; i++) {
zacep++;
ntacep++;
mip++;
}
}
for (i = 0; i < ntacl->acl_acecount; i++) {
zacep++;
ntacep++;
mip++;
}
}
error = 0;
if (mapinfo)
return (error);
}
/*
* Convert an internal SD to a ZFS-style ACL.
*/
int smbfs_acl_zfs2sd(
#ifdef _KERNEL
#else /* _KERNEL */
#endif /* _KERNEL */
{
/* XXX - todo */
return (ENOSYS);
}