/*
* 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 2011 Nexenta Systems, Inc. All rights reserved.
*/
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <grp.h>
#include <pwd.h>
#include <strings.h>
#include <errno.h>
#include <locale.h>
#include <aclutils.h>
#include <acl_common.h>
#include <idmap.h>
#define ACL_PATH 0
typedef union {
const char *file;
int fd;
} acl_inp;
/*
* Determine whether a file has a trivial ACL
* returns: 0 = trivial
* 1 = nontrivial
* <0 some other system failure, such as ENOENT or EPERM
*/
int
{
int acl_flavor;
int aclcnt;
int cntcmd;
int val = 0;
if (acl_flavor == _ACL_ACE_ENABLED)
else
if (aclcnt > 0) {
if (acl_flavor == _ACL_ACE_ENABLED) {
return (-1);
return (-1);
}
} else if (aclcnt > MIN_ACL_ENTRIES)
val = 1;
}
return (val);
}
static int
{
const char *fname;
int fd;
int ace_acl = 0;
int error;
int save_errno;
int stat_error;
} else {
}
/*
* if acl's aren't supported then
* send it through the old GETACL interface
*/
}
if (ace_acl & _ACL_ACE_ENABLED) {
getcmd = ACE_GETACL;
} else {
}
return (-1);
} else {
}
save_errno = errno;
errno = save_errno;
return (-1);
}
errno = save_errno;
return (0);
}
save_errno = errno;
errno = save_errno;
return (-1);
}
} else {
}
save_errno = errno;
if (error == -1) {
errno = save_errno;
return (-1);
}
if (stat_error == 0) {
} else
case ACLENT_T:
break;
case ACE_T:
break;
default:
return (-1);
}
(get_flag & ACL_NO_TRIVIAL)) {
errno = 0;
return (0);
}
return (0);
}
/*
* return -1 on failure, otherwise the number of acl
* entries is returned
*/
int
{
}
int
{
}
/*
* Set an ACL, translates acl to ace_t when appropriate.
*/
static int
{
int error = 0;
int acl_flavor_target;
int stat_error;
int isdir;
if (stat_error)
return (-1);
} else {
if (stat_error)
return (-1);
}
/*
* If target returns an error or 0 from pathconf call then
* In the case of 0 we will then fail in either acl(2) or
* acl_translate(). We could erroneously get 0 back from
* a file system that is using fs_pathconf() and not answering
* the _PC_ACL_ENABLED question itself.
*/
return (error);
}
} else {
}
return (error);
}
int
{
}
int
{
}
int
{
}
int
{
}
acl_t *
{
return (NULL);
return (NULL);
}
return (newaclp);
}
int
{
}
void *
{
}
/*
* Take an acl array and build an acl_t.
*/
acl_t *
{
return (aclp);
return (aclp);
}
/*
* Remove an ACL from a file and create a trivial ACL based
* are updated to match owner,group arguments
*/
int
{
int error = 0;
int acl_flavor;
int aclcnt;
error = 1;
return (error);
}
/*
* force it through aclent flavor when file system doesn't
* understand question
*/
if (acl_flavor & _ACL_ACLENT_ENABLED) {
aclcnt = 4;
} else if (acl_flavor & _ACL_ACE_ENABLED) {
&min_ace_acl, &aclcnt)) != 0)
return (error);
} else {
error = 1;
}
if (error == 0)
return (error);
}
static int
{
/*
* Need to fixup who field for abstrations for
* accurate comparison, since field is undefined.
*/
}
static int
{
}
/*
* Find acl entries in acl that correspond to removeacl. Search
* is started from slot. The flag argument indicates whether to
* remove all matches or just the first match.
*/
int
{
int i, j;
int match;
void *start;
int found = 0;
return (EACL_NO_ACL_ENTRY);
return (EACL_DIFF_TYPE);
else
j = 0;
for (;;) {
if (match == 0) {
found++;
/* avoid memmove if last entry */
break;
}
if (flag == ACL_REMOVE_FIRST)
break;
/*
* List has changed, just continue so this
* slot gets checked with it's new contents.
*/
continue;
}
break;
}
}
}
return ((found == 0) ? EACL_NO_ACL_ENTRY : 0);
}
/*
* Replace entires entries in acl1 with the corresponding entries
* in newentries. The where argument specifies where to begin
* the replacement. If the where argument is 1 greater than the
* number of acl entries in acl1 then they are appended. If the
* where argument is 2+ greater than the number of acl entries then
* EACL_INVALID_SLOT is returned.
*/
int
{
int slot;
int slots_needed;
int slots_left;
int newsize;
return (EACL_NO_ACL_ENTRY);
return (EACL_INVALID_SLOT);
return (EACL_DIFF_TYPE);
return (-1);
}
/*
* Did ACL grow?
*/
}
return (0);
}
/*
* Add acl2 entries into acl1. The where argument specifies where
* to add the entries.
*/
int
{
int newsize;
int len;
void *start;
void *to;
return (EACL_NO_ACL_ENTRY);
return (EACL_DIFF_TYPE);
/*
* allow where to specify 1 past last slot for an append operation
* but anything greater is an error.
*/
return (EACL_INVALID_SLOT);
return (-1);
/*
* first push down entries where new ones will be inserted
*/
}
/*
* now stick in new entries.
*/
return (0);
}
/*
* return text for an ACL error.
*/
char *
{
switch (errnum) {
case EACL_GRP_ERROR:
return (dgettext(TEXT_DOMAIN,
"There is more than one group or default group entry"));
case EACL_USER_ERROR:
return (dgettext(TEXT_DOMAIN,
"There is more than one user or default user entry"));
case EACL_OTHER_ERROR:
return (dgettext(TEXT_DOMAIN,
"There is more than one other entry"));
case EACL_CLASS_ERROR:
return (dgettext(TEXT_DOMAIN,
"There is more than one mask entry"));
case EACL_DUPLICATE_ERROR:
return (dgettext(TEXT_DOMAIN,
"Duplicate user or group entries"));
case EACL_MISS_ERROR:
return (dgettext(TEXT_DOMAIN,
case EACL_MEM_ERROR:
return (dgettext(TEXT_DOMAIN,
"Memory error"));
case EACL_ENTRY_ERROR:
return (dgettext(TEXT_DOMAIN,
"Unrecognized entry type"));
case EACL_INHERIT_ERROR:
return (dgettext(TEXT_DOMAIN,
"Invalid inheritance flags"));
case EACL_FLAGS_ERROR:
return (dgettext(TEXT_DOMAIN,
"Unrecognized entry flags"));
case EACL_PERM_MASK_ERROR:
return (dgettext(TEXT_DOMAIN,
"Invalid ACL permissions"));
case EACL_COUNT_ERROR:
return (dgettext(TEXT_DOMAIN,
"Invalid ACL count"));
case EACL_INVALID_SLOT:
return (dgettext(TEXT_DOMAIN,
"Invalid ACL entry number specified"));
case EACL_NO_ACL_ENTRY:
return (dgettext(TEXT_DOMAIN,
"ACL entry doesn't exist"));
case EACL_DIFF_TYPE:
return (dgettext(TEXT_DOMAIN,
"Different file system ACL types cannot be merged"));
case EACL_INVALID_USER_GROUP:
case EACL_INVALID_STR:
case EACL_FIELD_NOT_BLANK:
case EACL_INVALID_ACCESS_TYPE:
case EACL_UNKNOWN_DATA:
case EACL_MISSING_FIELDS:
return (dgettext(TEXT_DOMAIN,
"ACL specification missing required fields"));
case EACL_INHERIT_NOTDIR:
return (dgettext(TEXT_DOMAIN,
"Inheritance flags are only allowed on directories"));
case -1:
default:
}
}
extern int yyinteractive;
/* PRINTFLIKE1 */
void
{
if (yyinteractive == 0)
return;
}
int
{
char *end;
char *domain_start;
return (1);
*rid_start++ = '\0';
errno = 0;
if (idmap_get_create(&get_hdl) ==
if (user)
else
if (error == IDMAP_SUCCESS) {
if (error == IDMAP_SUCCESS &&
status != IDMAP_SUCCESS)
error = 1;
else
error = 0;
}
} else {
error = 1;
}
if (get_hdl)
} else {
error = 1;
}
} else {
*domain_start++ = '\0';
if (user)
else
*--domain_start = '@';
}
return (error);
}