acltext.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*LINTLIBRARY*/
#include <grp.h>
#include <pwd.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
/*
* acltotext() converts each ACL entry to look like this:
*
* entry_type:uid^gid^name:perms
*
* The maximum length of entry_type is 14 ("defaultgroup::" and
* "defaultother::") hence ENTRYTYPELEN is set to 14.
*
* The max length of a uid^gid^name entry (in theory) is 8, hence we use
* LOGNAME_MAX.
*
* The length of a perms entry is 4 to allow for the comma appended to each
* to each acl entry. Hence PERMS is set to 4.
*/
#define ENTRYTYPELEN 14
#define PERMS 4
struct dynaclstr {
char *aclexport;
};
static char *strappend(char *, char *);
static char *convert_perm(char *, o_mode_t);
/*
* Convert internal acl representation to external representation.
*
* The length of a non-owning user name or non-owning group name ie entries
* of type DEF_USER, USER, DEF_GROUP or GROUP, can exceed LOGNAME_MAX. We
* thus check the length of these entries, and if greater than LOGNAME_MAX,
* we realloc() via increase_length().
*
* The LOGNAME_MAX, ENTRYTYPELEN and PERMS limits are otherwise always
* adhered to.
*/
char *
{
char *aclexport;
char *where;
int i, rtn;
return (NULL);
return (NULL);
return (NULL);
}
case DEF_USER_OBJ:
case USER_OBJ:
else
break;
case DEF_USER:
case USER:
else
/* put in uid instead */
} else {
if (excess > 0) {
if (rtn == 1) {
/* reset where */
} else {
return (NULL);
}
}
}
break;
case DEF_GROUP_OBJ:
case GROUP_OBJ:
else
break;
case DEF_GROUP:
case GROUP:
else
/* put in gid instead */
} else {
if (excess > 0) {
if (rtn == 1) {
/* reset where */
} else {
return (NULL);
}
}
}
break;
case DEF_CLASS_OBJ:
case CLASS_OBJ:
else
break;
case DEF_OTHER_OBJ:
case OTHER_OBJ:
else
break;
default:
return (NULL);
}
if (i < aclcnt - 1)
}
return (aclexport);
}
/*
* Convert external acl representation to internal representation.
* The accepted syntax is: <acl_entry>[,<acl_entry>]*[,]
* The comma at the end is not prescribed by the man pages.
* But it is needed not to break the old programs.
*/
aclent_t *
{
char *fieldp;
char *tp;
char *nextp;
char *allocp;
char *aclimport;
int entry_type;
int id;
int len;
*aclcnt = 0;
if (! aclstr)
return (NULL);
return (NULL);
}
for (; aclimport; ) {
/* look for an ACL entry */
} else {
*tp = '\0';
}
*aclcnt += 1;
/*
* get additional memory:
* can be more efficient by allocating a bigger block
* each time.
*/
if (*aclcnt > 1)
else
if (aclp)
return (NULL);
}
/* look for entry type field */
FREE;
return (NULL);
} else
*tp = '\0';
else
entry_type = USER;
else
entry_type = GROUP;
else
else
else {
FREE;
return (NULL);
}
entry_type != DEF_CLASS_OBJ &&
entry_type != DEF_OTHER_OBJ) {
FREE;
return (NULL);
} else
*tp = '\0';
/*
* The second field could be empty. We only care
*/
if (entry_type == USER ||
entry_type == DEF_USER) {
/*
* The reentrant interface getpwnam_r()
* is uncommitted and subject to
* change. Use the friendlier interface
* getpwnam().
*/
"user %s not found\n", fieldp);
}
else
} else {
if (entry_type == GROUP ||
entry_type == DEF_GROUP) {
"group %s not found\n",
fieldp);
/* no group? */
id = GID_NOBODY;
}
else
} else {
"acl import errors\n");
FREE;
return (NULL);
}
}
} else {
/*
* The second field is empty.
* Treat it as undefined (-1)
*/
id = -1;
}
} else {
/*
* Let's not break the old applications
* that use mask::rwx, other::rwx format,
* though they violate the man pages.
*/
*++tp = 0;
}
/* next field: permission */
/* not "rwx" format */
FREE;
return (NULL);
} else {
char s[] = "rwx";
int mask = 0x04;
int i;
perm = 0;
if (fieldp[i] == s[i])
else if (fieldp[i] != '-') {
FREE;
return (NULL);
}
}
}
}
return (aclp);
}
static char *
{
}
static char *
{
if (perm & 04)
else
if (perm & 02)
else
if (perm & 01)
else
/* perm is the last field */
return (where);
}
/*
* Callers should check the return code as this routine may change the string
* pointer in dynaclstr.
*/
static int
{
char *tptr;
return (1);
} else
return (0);
}