summaryrefslogtreecommitdiff
path: root/usr/src/lib/libsec
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libsec')
-rw-r--r--usr/src/lib/libsec/Makefile89
-rw-r--r--usr/src/lib/libsec/Makefile.com78
-rw-r--r--usr/src/lib/libsec/amd64/Makefile40
-rw-r--r--usr/src/lib/libsec/common/aclcheck.c278
-rw-r--r--usr/src/lib/libsec/common/aclmode.c128
-rw-r--r--usr/src/lib/libsec/common/aclsort.c194
-rw-r--r--usr/src/lib/libsec/common/acltext.c464
-rw-r--r--usr/src/lib/libsec/common/llib-lsec46
-rw-r--r--usr/src/lib/libsec/i386/Makefile38
-rw-r--r--usr/src/lib/libsec/sparc/Makefile38
-rw-r--r--usr/src/lib/libsec/sparcv9/Makefile41
-rw-r--r--usr/src/lib/libsec/spec/Makefile29
-rw-r--r--usr/src/lib/libsec/spec/Makefile.targ33
-rw-r--r--usr/src/lib/libsec/spec/acl.spec80
-rw-r--r--usr/src/lib/libsec/spec/amd64/Makefile44
-rw-r--r--usr/src/lib/libsec/spec/i386/Makefile44
-rw-r--r--usr/src/lib/libsec/spec/sparc/Makefile44
-rw-r--r--usr/src/lib/libsec/spec/sparcv9/Makefile45
-rw-r--r--usr/src/lib/libsec/spec/versions47
19 files changed, 1800 insertions, 0 deletions
diff --git a/usr/src/lib/libsec/Makefile b/usr/src/lib/libsec/Makefile
new file mode 100644
index 0000000000..a698fe0251
--- /dev/null
+++ b/usr/src/lib/libsec/Makefile
@@ -0,0 +1,89 @@
+#
+# 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
+# or http://www.opensolaris.org/os/licensing.
+# 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 (c) 1993-1999 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libsec/Makefile
+
+include ../../Makefile.master
+include ../Makefile.lib
+
+SUBDIRS= spec .WAIT $(MACH) $(BUILD64) $(MACH64)
+
+all := TARGET= all
+clean := TARGET= clean
+clobber := TARGET= clobber
+delete := TARGET= delete
+install := TARGET= install
+lint := TARGET= lint
+_msg := TARGET= _msg
+package := TARGET= package
+
+LIBRARY= libsec.a
+TEXT_DOMAIN= SUNW_OST_OSLIB
+XGETFLAGS= -a
+POFILE= $(LIBRARY:.a=.po)
+POFILES= generic.po
+
+SED= sed
+GREP= grep
+CP= cp
+
+.KEEP_STATE:
+
+all clean clobber delete install lint package: $(SUBDIRS)
+
+# definitions for install_h target
+HDRS=
+ROOTHDRDIR= $(ROOT)/usr/include
+ROOTHDRS= $(HDRS:%=$(ROOTHDRDIR)/%)
+CHECKHDRS= $(HDRS:%.h=%.check)
+
+# install rule for install_h target
+$(ROOTHDRDIR)/%: common/%
+ $(INS.file)
+
+install_h: $(ROOTHDRS)
+
+check: $(CHECKHDRS)
+
+$(MACH) $(MACH64) spec: FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+_msg: $(MSGDOMAIN) $(POFILE)
+ $(RM) $(MSGDOMAIN)/$(POFILE)
+ $(CP) $(POFILE) $(MSGDOMAIN)
+
+$(POFILE): $(POFILES)
+ $(RM) $@
+ $(CAT) $(POFILES) > $@
+
+$(POFILES):
+ $(RM) messages.po
+ $(XGETTEXT) $(XGETFLAGS) *.[ch]* */*.[ch]*
+ $(SED) -e '/^# msg/d' -e '/^domain/d' messages.po > $@
+ $(RM) messages.po
+
+FRC:
diff --git a/usr/src/lib/libsec/Makefile.com b/usr/src/lib/libsec/Makefile.com
new file mode 100644
index 0000000000..b619caa0b7
--- /dev/null
+++ b/usr/src/lib/libsec/Makefile.com
@@ -0,0 +1,78 @@
+#
+# 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
+# or http://www.opensolaris.org/os/licensing.
+# 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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libsec/Makefile.com
+#
+
+LIBRARY= libsec.a
+VERS= .1
+
+OBJECTS= \
+ aclcheck.o \
+ aclmode.o \
+ aclsort.o \
+ acltext.o
+
+# include library definitions
+include ../../Makefile.lib
+
+# install this library in the root filesystem
+include ../../Makefile.rootfs
+
+MAPFILE= $(MAPDIR)/mapfile
+MAPOPTS= $(MAPFILE:%=-M %)
+SRCS= $(OBJECTS:%.o=../common/%.c)
+
+LIBS = $(DYNLIB) $(LINTLIB)
+
+$(LINTLIB):= SRCS=../common/llib-lsec
+
+LINTSRC= $(LINTLIB:%.ln=%)
+
+CFLAGS += $(CCVERBOSE)
+DYNFLAGS += $(MAPOPTS)
+LDLIBS += -lc
+
+.KEEP_STATE:
+
+lint: lintcheck
+
+$(DYNLIB): $(MAPFILE)
+
+$(MAPFILE):
+ @cd $(MAPDIR); $(MAKE) mapfile
+
+# include library targets
+include ../../Makefile.targ
+
+pics/%.o: ../common/%.c
+ $(COMPILE.c) -o $@ $<
+ $(POST_PROCESS_O)
+
+# install rule for lint library target
+$(ROOTLINTDIR)/%: ../common/%
+ $(INS.file)
diff --git a/usr/src/lib/libsec/amd64/Makefile b/usr/src/lib/libsec/amd64/Makefile
new file mode 100644
index 0000000000..29ebb8f58b
--- /dev/null
+++ b/usr/src/lib/libsec/amd64/Makefile
@@ -0,0 +1,40 @@
+#
+# 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
+# or http://www.opensolaris.org/os/licensing.
+# 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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+MAPDIR= ../spec/amd64
+
+include ../Makefile.com
+include ../../Makefile.lib.64
+
+LIBS= $(DYNLIB) $(LINTLIB)
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64)
diff --git a/usr/src/lib/libsec/common/aclcheck.c b/usr/src/lib/libsec/common/aclcheck.c
new file mode 100644
index 0000000000..75c1a6cf56
--- /dev/null
+++ b/usr/src/lib/libsec/common/aclcheck.c
@@ -0,0 +1,278 @@
+/*
+ * 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
+ * or http://www.opensolaris.org/os/licensing.
+ * 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 (c) 1993-1997 by Sun Microsystems, Inc.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+/*LINTLIBRARY*/
+
+/*
+ * aclcheck(): check validity of an ACL
+ * A valid ACL is defined as follows:
+ * There must be exactly one USER_OBJ, GROUP_OBJ, and OTHER_OBJ entry.
+ * If there are any USER entries, then the user id must be unique.
+ * If there are any GROUP entries, then the group id must be unique.
+ * If there are any GROUP or USER entries, there must be exactly one
+ * CLASS_OBJ entry.
+ * The same rules apply to default ACL entries.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/acl.h>
+
+struct entry {
+ int count;
+ uid_t *id;
+};
+
+struct entry_stat {
+ struct entry user_obj;
+ struct entry user;
+ struct entry group_obj;
+ struct entry group;
+ struct entry other_obj;
+ struct entry class_obj;
+ struct entry def_user_obj;
+ struct entry def_user;
+ struct entry def_group_obj;
+ struct entry def_group;
+ struct entry def_other_obj;
+ struct entry def_class_obj;
+};
+
+static void free_mem(struct entry_stat *);
+static int check_dup(int, uid_t *, uid_t, struct entry_stat *);
+
+int
+aclcheck(aclent_t *aclbufp, int nentries, int *which)
+{
+ struct entry_stat tally;
+ aclent_t *aclentp;
+ uid_t **idp;
+ int cnt;
+
+ *which = -1;
+ memset(&tally, '\0', sizeof (tally));
+
+ for (aclentp = aclbufp; nentries > 0; nentries--, aclentp++) {
+ switch (aclentp->a_type) {
+ case USER_OBJ:
+ /* check uniqueness */
+ if (tally.user_obj.count > 0) {
+ *which = (int) (aclentp - aclbufp);
+ (void) free_mem(&tally);
+ errno = EINVAL;
+ return (USER_ERROR);
+ }
+ tally.user_obj.count = 1;
+ break;
+
+ case GROUP_OBJ:
+ /* check uniqueness */
+ if (tally.group_obj.count > 0) {
+ *which = (int) (aclentp - aclbufp);
+ (void) free_mem(&tally);
+ errno = EINVAL;
+ return (GRP_ERROR);
+ }
+ tally.group_obj.count = 1;
+ break;
+
+ case OTHER_OBJ:
+ /* check uniqueness */
+ if (tally.other_obj.count > 0) {
+ *which = (int) (aclentp - aclbufp);
+ (void) free_mem(&tally);
+ errno = EINVAL;
+ return (OTHER_ERROR);
+ }
+ tally.other_obj.count = 1;
+ break;
+
+ case CLASS_OBJ:
+ /* check uniqueness */
+ if (tally.class_obj.count > 0) {
+ *which = (int) (aclentp - aclbufp);
+ (void) free_mem(&tally);
+ errno = EINVAL;
+ return (CLASS_ERROR);
+ }
+ tally.class_obj.count = 1;
+ break;
+
+ case USER:
+ case GROUP:
+ case DEF_USER:
+ case DEF_GROUP:
+ /* check duplicate */
+ if (aclentp->a_type == DEF_USER) {
+ cnt = (tally.def_user.count)++;
+ idp = &(tally.def_user.id);
+ } else if (aclentp->a_type == DEF_GROUP) {
+ cnt = (tally.def_group.count)++;
+ idp = &(tally.def_group.id);
+ } else if (aclentp->a_type == USER) {
+ cnt = (tally.user.count)++;
+ idp = &(tally.user.id);
+ } else {
+ cnt = (tally.group.count)++;
+ idp = &(tally.group.id);
+ }
+
+ if (cnt == 0) {
+ *idp = calloc(nentries, sizeof (uid_t));
+ if (*idp == NULL)
+ return (MEM_ERROR);
+ } else {
+ if (check_dup(cnt, *idp, aclentp->a_id,
+ &tally) == -1) {
+ *which = (int) (aclentp - aclbufp);
+ return (DUPLICATE_ERROR);
+ }
+ }
+ (*idp)[cnt] = aclentp->a_id;
+ break;
+
+ case DEF_USER_OBJ:
+ /* check uniqueness */
+ if (tally.def_user_obj.count > 0) {
+ *which = (int) (aclentp - aclbufp);
+ (void) free_mem(&tally);
+ errno = EINVAL;
+ return (USER_ERROR);
+ }
+ tally.def_user_obj.count = 1;
+ break;
+
+ case DEF_GROUP_OBJ:
+ /* check uniqueness */
+ if (tally.def_group_obj.count > 0) {
+ *which = (int) (aclentp - aclbufp);
+ (void) free_mem(&tally);
+ errno = EINVAL;
+ return (GRP_ERROR);
+ }
+ tally.def_group_obj.count = 1;
+ break;
+
+ case DEF_OTHER_OBJ:
+ /* check uniqueness */
+ if (tally.def_other_obj.count > 0) {
+ *which = (int) (aclentp - aclbufp);
+ (void) free_mem(&tally);
+ errno = EINVAL;
+ return (OTHER_ERROR);
+ }
+ tally.def_other_obj.count = 1;
+ break;
+
+ case DEF_CLASS_OBJ:
+ /* check uniqueness */
+ if (tally.def_class_obj.count > 0) {
+ *which = (int) (aclentp - aclbufp);
+ (void) free_mem(&tally);
+ errno = EINVAL;
+ return (CLASS_ERROR);
+ }
+ tally.def_class_obj.count = 1;
+ break;
+
+ default:
+ (void) free_mem(&tally);
+ errno = EINVAL;
+ *which = (int) (aclentp - aclbufp);
+ return (ENTRY_ERROR);
+ }
+ }
+ /* If there are group or user entries, there must be one class entry */
+ if (tally.user.count > 0 || tally.group.count > 0)
+ if (tally.class_obj.count != 1) {
+ (void) free_mem(&tally);
+ errno = EINVAL;
+ return (MISS_ERROR);
+ }
+ /* same is true for default entries */
+ if (tally.def_user.count > 0 || tally.def_group.count > 0)
+ if (tally.def_class_obj.count != 1) {
+ (void) free_mem(&tally);
+ errno = EINVAL;
+ return (MISS_ERROR);
+ }
+
+ /* there must be exactly one user_obj, group_obj, and other_obj entry */
+ if (tally.user_obj.count != 1 ||
+ tally.group_obj.count != 1 ||
+ tally.other_obj.count != 1) {
+ (void) free_mem(&tally);
+ errno = EINVAL;
+ return (MISS_ERROR);
+ }
+
+ /* has default? same rules apply to default entries */
+ if (tally.def_user.count > 0 ||
+ tally.def_user_obj.count > 0 ||
+ tally.def_group.count > 0 ||
+ tally.def_group_obj.count > 0 ||
+ tally.def_class_obj.count > 0 ||
+ tally.def_other_obj.count > 0)
+ if (tally.def_user_obj.count != 1 ||
+ tally.def_group_obj.count != 1 ||
+ tally.def_other_obj.count != 1) {
+ (void) free_mem(&tally);
+ errno = EINVAL;
+ return (MISS_ERROR);
+ }
+ (void) free_mem(&tally);
+ return (0);
+}
+
+static void
+free_mem(struct entry_stat *tallyp)
+{
+ if ((tallyp->user).count > 0)
+ free((tallyp->user).id);
+ if ((tallyp->group).count > 0)
+ free((tallyp->group).id);
+ if ((tallyp->def_user).count > 0)
+ free((tallyp->def_user).id);
+ if ((tallyp->def_group).count > 0)
+ free((tallyp->def_group).id);
+}
+
+static int
+check_dup(int count, uid_t *ids, uid_t newid, struct entry_stat *tallyp)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ if (ids[i] == newid) {
+ errno = EINVAL;
+ (void) free_mem(tallyp);
+ return (-1);
+ }
+ }
+ return (0);
+}
diff --git a/usr/src/lib/libsec/common/aclmode.c b/usr/src/lib/libsec/common/aclmode.c
new file mode 100644
index 0000000000..b59f95a725
--- /dev/null
+++ b/usr/src/lib/libsec/common/aclmode.c
@@ -0,0 +1,128 @@
+/*
+ * 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
+ * or http://www.opensolaris.org/os/licensing.
+ * 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 (c) 1993-1997 by Sun Microsystems, Inc.
+ * All rights reserved
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+/* LINTLIBRARY */
+
+/*
+ * Convert ACL to/from permission bits
+ */
+
+#include <errno.h>
+#include <sys/acl.h>
+
+int
+acltomode(aclent_t *aclbufp, int nentries, mode_t *modep)
+{
+ aclent_t *tp;
+ unsigned long mode;
+ unsigned long grpmode;
+ unsigned long mask;
+ int which;
+ int got_mask = 0;
+
+ *modep = 0;
+ if (aclcheck(aclbufp, nentries, &which) != 0) {
+ errno = EINVAL;
+ return (-1); /* errno is set in aclcheck() */
+ }
+ for (tp = aclbufp; nentries--; tp++) {
+ if (tp->a_type == USER_OBJ) {
+ mode = tp->a_perm;
+ if (mode > 07)
+ return (-1);
+ *modep |= (mode << 6);
+ continue;
+ }
+ if (tp->a_type == GROUP_OBJ) {
+ grpmode = tp->a_perm;
+ if (grpmode > 07)
+ return (-1);
+ continue;
+ }
+ if (tp->a_type == CLASS_OBJ) {
+ got_mask = 1;
+ mask = tp->a_perm;
+ if (mask > 07)
+ return (-1);
+ *modep |= (mask << 3);
+ continue;
+ }
+ if (tp->a_type == OTHER_OBJ) {
+ mode = tp->a_perm;
+ if (mode > 07)
+ return (-1);
+ *modep |= mode;
+ continue; /* we may break here if it is sorted */
+ }
+ }
+ if (!got_mask)
+ *modep |= (grpmode << 3);
+ return (0);
+}
+
+
+int
+aclfrommode(aclent_t *aclbufp, int nentries, mode_t *modep)
+{
+ aclent_t *tp;
+ aclent_t *savp;
+ mode_t mode;
+ mode_t grpmode;
+ int which;
+ int got_mask = 0;
+
+ if (aclcheck(aclbufp, nentries, &which) != 0) {
+ errno = EINVAL;
+ return (-1); /* errno is set in aclcheck() */
+ }
+ for (tp = aclbufp; nentries--; tp++) {
+ if (tp->a_type == USER_OBJ) {
+ mode = (*modep & 0700);
+ tp->a_perm = (mode >> 6);
+ continue;
+ }
+ if (tp->a_type == GROUP_OBJ) {
+ grpmode = (*modep & 070);
+ savp = tp;
+ continue;
+ }
+ if (tp->a_type == CLASS_OBJ) {
+ got_mask = 1;
+ mode = (*modep & 070);
+ tp->a_perm = (mode >> 3);
+ continue;
+ }
+ if (tp->a_type == OTHER_OBJ) {
+ mode = (*modep & 07);
+ tp->a_perm = (o_mode_t)mode;
+ continue; /* we may break here if it is sorted */
+ }
+ }
+ if (!got_mask)
+ savp->a_perm = (grpmode >> 3);
+ return (0);
+}
diff --git a/usr/src/lib/libsec/common/aclsort.c b/usr/src/lib/libsec/common/aclsort.c
new file mode 100644
index 0000000000..784ff36c72
--- /dev/null
+++ b/usr/src/lib/libsec/common/aclsort.c
@@ -0,0 +1,194 @@
+/*
+ * 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
+ * or http://www.opensolaris.org/os/licensing.
+ * 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 (c) 1993-1997 by Sun Microsystems, Inc.
+ * All rights reserved
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+/*LINTLIBRARY*/
+
+/*
+ * aclsort():
+ * Sort an ACL by entry type according to the following order:
+ * USER_OBJ, USER, GROUP_OBJ, GROUP, CLASS_OBJ, OTHER_OBJ
+ * DEF_USER_OBJ, DEF_USER, DEF_GROUP_OBJ, DEF_GROUP, DEF_CLASS_OBJ,
+ * DEF_OTHER_OBJ.
+ * For USER, GROUP, DEF_USER, and DEF_GROUP entries, the entries
+ * are further sorted by ids.
+ */
+
+#include <stdlib.h>
+#include <sys/acl.h>
+
+#define TOTAL_ENTRY_TYPES 12
+
+/*
+ * This maps the entry defined value to a value for sorting.
+ * These values may not be the same. It is easier to add an
+ * entry type with this map.
+ *
+ * Because the defines and sorting order are not the same,
+ * the following map_to_sort table is needed.
+ */
+struct map {
+ int sort_order;
+ int entry_type;
+};
+
+static struct map map_to_sort[] = {
+ {0, 0}, /* UNUSED */
+ {1, USER_OBJ},
+ {2, USER},
+ {3, GROUP_OBJ},
+ {4, GROUP},
+ {5, CLASS_OBJ},
+ {6, OTHER_OBJ},
+ {7, DEF_USER_OBJ},
+ {8, DEF_USER},
+ {9, DEF_GROUP_OBJ},
+ {10, DEF_GROUP},
+ {11, DEF_CLASS_OBJ},
+ {12, DEF_OTHER_OBJ},
+};
+
+static int entrycmp(const aclent_t *, const aclent_t *);
+static int idcmp(const aclent_t *, const aclent_t *);
+static void sortid(aclent_t *, int, int);
+
+int
+aclsort(int nentries, int calcmask, aclent_t *aclbufp)
+{
+ aclent_t *tp;
+ unsigned int newmask = 0;
+ int which;
+ int i;
+ int k;
+
+ /* check validity first before sorting */
+ if (aclcheck(aclbufp, nentries, &which) != 0)
+ return (-1);
+
+ /*
+ * Performance enhancement:
+ * We change entry type to sort order in the ACL, do the sorting.
+ * We then change sort order back to entry type.
+ * This makes entrycmp() very "light" and thus improves performance.
+ * Contrast to original implementation that had to find out
+ * the sorting order each time it is called.
+ */
+ for (tp = aclbufp, i = 0; i < nentries; tp++, i++) {
+ for (k = 1; k <= TOTAL_ENTRY_TYPES; k++) {
+ if (tp->a_type == map_to_sort[k].entry_type) {
+ tp->a_type = map_to_sort[k].sort_order;
+ break;
+ }
+ }
+ }
+
+ /* typecast to remove incompatible type warning */
+ qsort(aclbufp, nentries, sizeof (aclent_t),
+ (int (*)(const void *, const void *))entrycmp);
+
+ for (tp = aclbufp, i = 0; i < nentries; tp++, i++) {
+ for (k = 1; k <= TOTAL_ENTRY_TYPES; k++) {
+ if (tp->a_type == map_to_sort[k].sort_order) {
+ tp->a_type = map_to_sort[k].entry_type;
+ break;
+ }
+ }
+ }
+
+ /*
+ * Start sorting id within USER and GROUP
+ * sortid() could return a pointer and entries left
+ * so that we dont have to search from the beginning
+ * every time it calls
+ */
+ sortid(aclbufp, nentries, USER);
+ sortid(aclbufp, nentries, GROUP);
+ sortid(aclbufp, nentries, DEF_USER);
+ sortid(aclbufp, nentries, DEF_GROUP);
+
+ /*
+ * Recalculate mask entry
+ */
+ if (calcmask != 0) {
+ /*
+ * At this point, ACL is valid and sorted. We may find a
+ * CLASS_OBJ entry and stop. Because of the case of minimum ACL,
+ * we still have to check till OTHER_OBJ entry is shown.
+ */
+ for (tp = aclbufp; tp->a_type != OTHER_OBJ; tp++) {
+ if (tp->a_type == USER || tp->a_type == GROUP ||
+ tp->a_type == GROUP_OBJ)
+ newmask |= tp->a_perm;
+ if (tp->a_type == CLASS_OBJ)
+ break;
+ }
+ if (tp->a_type == CLASS_OBJ)
+ tp->a_perm = (unsigned char)newmask;
+ }
+ return (0);
+}
+
+/*
+ * sortid() sorts the ids with the same entry type in increasing order
+ */
+static void
+sortid(aclent_t *ap, int cnt, int type)
+{
+ aclent_t *tp;
+ aclent_t *startp; /* start of the desired entry type */
+ int howmany;
+
+ for (tp = ap; cnt-- > 0; tp++) {
+ if (tp->a_type != type)
+ continue;
+ startp = tp;
+ howmany = 1;
+ for (tp++, cnt--; cnt > 0 && tp->a_type == type; tp++, cnt--)
+ howmany++;
+ /* typecast to remove incompatible type warning */
+ qsort(startp, howmany, sizeof (aclent_t),
+ (int (*)(const void*, const void*))idcmp);
+ }
+}
+
+/*
+ * compare the field a_type
+ */
+static int
+entrycmp(const aclent_t *i, const aclent_t *j)
+{
+ return ((int)(i->a_type) - (int)(j->a_type));
+}
+
+/*
+ * compare the field a_id
+ */
+static int
+idcmp(const aclent_t *i, const aclent_t *j)
+{
+ return ((int)(i->a_id) - (int)(j->a_id));
+}
diff --git a/usr/src/lib/libsec/common/acltext.c b/usr/src/lib/libsec/common/acltext.c
new file mode 100644
index 0000000000..da3195379c
--- /dev/null
+++ b/usr/src/lib/libsec/common/acltext.c
@@ -0,0 +1,464 @@
+/*
+ * 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
+ * or http://www.opensolaris.org/os/licensing.
+ * 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>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/acl.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
+#define ACL_ENTRY_SIZE (ENTRYTYPELEN + LOGNAME_MAX + PERMS)
+
+struct dynaclstr {
+ size_t bufsize; /* current size of aclexport */
+ char *aclexport;
+};
+
+static char *strappend(char *, char *);
+static char *convert_perm(char *, o_mode_t);
+static int increase_length(struct dynaclstr *, size_t);
+
+#define FREE free(aclp);\
+ free(allocp)
+
+/*
+ * 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 *
+acltotext(aclent_t *aclp, int aclcnt)
+{
+ char *aclexport;
+ char *where;
+ struct group *groupp;
+ struct passwd *passwdp;
+ struct dynaclstr *dstr;
+ int i, rtn;
+ size_t excess = 0;
+
+ if (aclp == NULL)
+ return (NULL);
+ if ((dstr = malloc(sizeof (struct dynaclstr))) == NULL)
+ return (NULL);
+ dstr->bufsize = aclcnt * ACL_ENTRY_SIZE;
+ if ((dstr->aclexport = malloc(dstr->bufsize)) == NULL) {
+ free(dstr);
+ return (NULL);
+ }
+ *dstr->aclexport = '\0';
+ where = dstr->aclexport;
+
+ for (i = 0; i < aclcnt; i++, aclp++) {
+ switch (aclp->a_type) {
+ case DEF_USER_OBJ:
+ case USER_OBJ:
+ if (aclp->a_type == USER_OBJ)
+ where = strappend(where, "user::");
+ else
+ where = strappend(where, "defaultuser::");
+ where = convert_perm(where, aclp->a_perm);
+ break;
+ case DEF_USER:
+ case USER:
+ if (aclp->a_type == USER)
+ where = strappend(where, "user:");
+ else
+ where = strappend(where, "defaultuser:");
+ passwdp = getpwuid(aclp->a_id);
+ if (passwdp == (struct passwd *)NULL) {
+ /* put in uid instead */
+ (void) sprintf(where, "%d", aclp->a_id);
+ } else {
+ excess = strlen(passwdp->pw_name) - LOGNAME_MAX;
+ if (excess > 0) {
+ rtn = increase_length(dstr, excess);
+ if (rtn == 1) {
+ /* reset where */
+ where = dstr->aclexport +
+ strlen(dstr->aclexport);
+ } else {
+ free(dstr->aclexport);
+ free(dstr);
+ return (NULL);
+ }
+ }
+ where = strappend(where, passwdp->pw_name);
+ }
+ where = strappend(where, ":");
+ where = convert_perm(where, aclp->a_perm);
+ break;
+ case DEF_GROUP_OBJ:
+ case GROUP_OBJ:
+ if (aclp->a_type == GROUP_OBJ)
+ where = strappend(where, "group::");
+ else
+ where = strappend(where, "defaultgroup::");
+ where = convert_perm(where, aclp->a_perm);
+ break;
+ case DEF_GROUP:
+ case GROUP:
+ if (aclp->a_type == GROUP)
+ where = strappend(where, "group:");
+ else
+ where = strappend(where, "defaultgroup:");
+ groupp = getgrgid(aclp->a_id);
+ if (groupp == (struct group *)NULL) {
+ /* put in gid instead */
+ (void) sprintf(where, "%d", aclp->a_id);
+ } else {
+ excess = strlen(groupp->gr_name) - LOGNAME_MAX;
+ if (excess > 0) {
+ rtn = increase_length(dstr, excess);
+ if (rtn == 1) {
+ /* reset where */
+ where = dstr->aclexport +
+ strlen(dstr->aclexport);
+ } else {
+ free(dstr->aclexport);
+ free(dstr);
+ return (NULL);
+ }
+ }
+ where = strappend(where, groupp->gr_name);
+ }
+ where = strappend(where, ":");
+ where = convert_perm(where, aclp->a_perm);
+ break;
+ case DEF_CLASS_OBJ:
+ case CLASS_OBJ:
+ if (aclp->a_type == CLASS_OBJ)
+ where = strappend(where, "mask:");
+ else
+ where = strappend(where, "defaultmask:");
+ where = convert_perm(where, aclp->a_perm);
+ break;
+ case DEF_OTHER_OBJ:
+ case OTHER_OBJ:
+ if (aclp->a_type == OTHER_OBJ)
+ where = strappend(where, "other:");
+ else
+ where = strappend(where, "defaultother:");
+ where = convert_perm(where, aclp->a_perm);
+ break;
+ default:
+ free(dstr->aclexport);
+ free(dstr);
+ return (NULL);
+
+ }
+ if (i < aclcnt - 1)
+ where = strappend(where, ",");
+ }
+ aclexport = dstr->aclexport;
+ free(dstr);
+ 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 *
+aclfromtext(char *aclstr, int *aclcnt)
+{
+ char *fieldp;
+ char *tp;
+ char *nextp;
+ char *allocp;
+ char *aclimport;
+ int entry_type;
+ int id;
+ int len;
+ o_mode_t perm;
+ aclent_t *tmpaclp;
+ aclent_t *aclp;
+ struct group *groupp;
+ struct passwd *passwdp;
+
+ *aclcnt = 0;
+ aclp = NULL;
+
+ if (! aclstr)
+ return (NULL);
+
+ len = strlen(aclstr);
+
+ if ((aclimport = allocp = strdup(aclstr)) == NULL) {
+ fprintf(stderr, "malloc() failed\n");
+ return (NULL);
+ }
+
+ if (aclimport[len - 1] == ',')
+ aclimport[len - 1] = '\0';
+
+ for (; aclimport; ) {
+ /* look for an ACL entry */
+ tp = strchr(aclimport, ',');
+ if (tp == NULL) {
+ nextp = NULL;
+ } else {
+ *tp = '\0';
+ nextp = tp + 1;
+ }
+
+ *aclcnt += 1;
+
+ /*
+ * get additional memory:
+ * can be more efficient by allocating a bigger block
+ * each time.
+ */
+ if (*aclcnt > 1)
+ tmpaclp = (aclent_t *)realloc(aclp,
+ sizeof (aclent_t) * (*aclcnt));
+ else
+ tmpaclp = (aclent_t *)malloc(sizeof (aclent_t));
+ if (tmpaclp == NULL) {
+ free(allocp);
+ if (aclp)
+ free(aclp);
+ return (NULL);
+ }
+ aclp = tmpaclp;
+ tmpaclp = aclp + (*aclcnt - 1);
+
+ /* look for entry type field */
+ tp = strchr(aclimport, ':');
+ if (tp == NULL) {
+ FREE;
+ return (NULL);
+ } else
+ *tp = '\0';
+ if (strcmp(aclimport, "user") == 0) {
+ if (*(tp+1) == ':')
+ entry_type = USER_OBJ;
+ else
+ entry_type = USER;
+ } else if (strcmp(aclimport, "group") == 0) {
+ if (*(tp+1) == ':')
+ entry_type = GROUP_OBJ;
+ else
+ entry_type = GROUP;
+ } else if (strcmp(aclimport, "other") == 0)
+ entry_type = OTHER_OBJ;
+ else if (strcmp(aclimport, "mask") == 0)
+ entry_type = CLASS_OBJ;
+ else if (strcmp(aclimport, "defaultuser") == 0) {
+ if (*(tp+1) == ':')
+ entry_type = DEF_USER_OBJ;
+ else
+ entry_type = DEF_USER;
+ } else if (strcmp(aclimport, "defaultgroup") == 0) {
+ if (*(tp+1) == ':')
+ entry_type = DEF_GROUP_OBJ;
+ else
+ entry_type = DEF_GROUP;
+ } else if (strcmp(aclimport, "defaultmask") == 0)
+ entry_type = DEF_CLASS_OBJ;
+ else if (strcmp(aclimport, "defaultother") == 0)
+ entry_type = DEF_OTHER_OBJ;
+ else {
+ FREE;
+ return (NULL);
+ }
+
+ /* look for user/group name */
+ if (entry_type != CLASS_OBJ && entry_type != OTHER_OBJ &&
+ entry_type != DEF_CLASS_OBJ &&
+ entry_type != DEF_OTHER_OBJ) {
+ fieldp = tp + 1;
+ tp = strchr(fieldp, ':');
+ if (tp == NULL) {
+ FREE;
+ return (NULL);
+ } else
+ *tp = '\0';
+ if (fieldp != tp) {
+ /*
+ * The second field could be empty. We only care
+ * when the field has user/group name.
+ */
+ if (entry_type == USER ||
+ entry_type == DEF_USER) {
+ /*
+ * The reentrant interface getpwnam_r()
+ * is uncommitted and subject to
+ * change. Use the friendlier interface
+ * getpwnam().
+ */
+ passwdp = getpwnam(fieldp);
+ if (passwdp == NULL) {
+ (void) fprintf(stderr,
+ "user %s not found\n", fieldp);
+ id = UID_NOBODY; /* nobody */
+ }
+ else
+ id = passwdp->pw_uid;
+ } else {
+ if (entry_type == GROUP ||
+ entry_type == DEF_GROUP) {
+ groupp = getgrnam(fieldp);
+ if (groupp == NULL) {
+ (void) fprintf(stderr,
+ "group %s not found\n",
+ fieldp);
+ /* no group? */
+ id = GID_NOBODY;
+ }
+ else
+ id = groupp->gr_gid;
+ } else {
+ (void) fprintf(stderr,
+ "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.
+ */
+ if (*(tp + 1) == ':')
+ *++tp = 0;
+ }
+
+ /* next field: permission */
+ fieldp = tp + 1;
+ if (strlen(fieldp) != 3) {
+ /* not "rwx" format */
+ FREE;
+ return (NULL);
+ } else {
+ char s[] = "rwx";
+ int mask = 0x04;
+ int i;
+ perm = 0;
+
+ for (i = 0; i < 3; i++, mask /= 2) {
+ if (fieldp[i] == s[i])
+ perm |= mask;
+ else if (fieldp[i] != '-') {
+ FREE;
+ return (NULL);
+ }
+ }
+ }
+
+ tmpaclp->a_type = entry_type;
+ tmpaclp->a_id = id;
+ tmpaclp->a_perm = perm;
+ aclimport = nextp;
+ }
+ free(allocp);
+ return (aclp);
+}
+
+static char *
+strappend(char *where, char *newstr)
+{
+ (void) strcat(where, newstr);
+ return (where + strlen(newstr));
+}
+
+static char *
+convert_perm(char *where, o_mode_t perm)
+{
+ if (perm & 04)
+ where = strappend(where, "r");
+ else
+ where = strappend(where, "-");
+ if (perm & 02)
+ where = strappend(where, "w");
+ else
+ where = strappend(where, "-");
+ if (perm & 01)
+ where = strappend(where, "x");
+ else
+ where = strappend(where, "-");
+ /* 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
+increase_length(struct dynaclstr *dacl, size_t increase)
+{
+ char *tptr;
+ size_t newsize;
+
+ newsize = dacl->bufsize + increase;
+ tptr = realloc(dacl->aclexport, newsize);
+ if (tptr != NULL) {
+ dacl->aclexport = tptr;
+ dacl->bufsize = newsize;
+ return (1);
+ } else
+ return (0);
+}
diff --git a/usr/src/lib/libsec/common/llib-lsec b/usr/src/lib/libsec/common/llib-lsec
new file mode 100644
index 0000000000..8db1f3875f
--- /dev/null
+++ b/usr/src/lib/libsec/common/llib-lsec
@@ -0,0 +1,46 @@
+/*
+ * 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
+ * or http://www.opensolaris.org/os/licensing.
+ * 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
+ */
+/* LINTLIBRARY */
+/* PROTOLIB1 */
+
+/*
+ * Copyright (c) 1997 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <grp.h>
+#include <pwd.h>
+#include <limits.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/acl.h>
+
+int aclcheck(aclent_t *aclbufp, int nentries, int *which);
+int aclfrommode(aclent_t *aclbufp, int nentries, mode_t *modep);
+aclent_t *aclfromtext(char *aclimport, int *aclcnt);
+int aclsort(int nentries, int calcmask, aclent_t *aclbufp);
+int acltomode(aclent_t *aclbufp, int nentries, mode_t *modep);
+char *acltotext(aclent_t *aclp, int aclcnt);
diff --git a/usr/src/lib/libsec/i386/Makefile b/usr/src/lib/libsec/i386/Makefile
new file mode 100644
index 0000000000..765e97be50
--- /dev/null
+++ b/usr/src/lib/libsec/i386/Makefile
@@ -0,0 +1,38 @@
+#
+# 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
+# or http://www.opensolaris.org/os/licensing.
+# 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 (c) 1997-1999 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libsec/i386/Makefile
+
+MAPDIR= ../spec/i386
+
+include ../Makefile.com
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
diff --git a/usr/src/lib/libsec/sparc/Makefile b/usr/src/lib/libsec/sparc/Makefile
new file mode 100644
index 0000000000..2a9a1e2be2
--- /dev/null
+++ b/usr/src/lib/libsec/sparc/Makefile
@@ -0,0 +1,38 @@
+#
+# 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
+# or http://www.opensolaris.org/os/licensing.
+# 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 (c) 1997-1999 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libsec/sparc/Makefile
+
+MAPDIR= ../spec/sparc
+
+include ../Makefile.com
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
diff --git a/usr/src/lib/libsec/sparcv9/Makefile b/usr/src/lib/libsec/sparcv9/Makefile
new file mode 100644
index 0000000000..9234baa89e
--- /dev/null
+++ b/usr/src/lib/libsec/sparcv9/Makefile
@@ -0,0 +1,41 @@
+#
+# 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
+# or http://www.opensolaris.org/os/licensing.
+# 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 (c) 1997-1999 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libsec/sparcv9/Makefile
+
+MAPDIR= ../spec/sparcv9
+
+include ../Makefile.com
+include ../../Makefile.lib.64
+
+LIBS= $(DYNLIB) $(LINTLIB)
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64)
diff --git a/usr/src/lib/libsec/spec/Makefile b/usr/src/lib/libsec/spec/Makefile
new file mode 100644
index 0000000000..04d1851ff8
--- /dev/null
+++ b/usr/src/lib/libsec/spec/Makefile
@@ -0,0 +1,29 @@
+#
+# 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
+# or http://www.opensolaris.org/os/licensing.
+# 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
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright (c) 1998-1999 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+# lib/libsec/spec/Makefile
+
+include $(SRC)/lib/Makefile.spec.arch
diff --git a/usr/src/lib/libsec/spec/Makefile.targ b/usr/src/lib/libsec/spec/Makefile.targ
new file mode 100644
index 0000000000..dca847f7c0
--- /dev/null
+++ b/usr/src/lib/libsec/spec/Makefile.targ
@@ -0,0 +1,33 @@
+#
+# 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
+# or http://www.opensolaris.org/os/licensing.
+# 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
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright (c) 1998-1999 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+# lib/libsec/spec/Makefile.targ
+
+LIBRARY = libsec.a
+VERS = .1
+
+OBJECTS = acl.o
+
diff --git a/usr/src/lib/libsec/spec/acl.spec b/usr/src/lib/libsec/spec/acl.spec
new file mode 100644
index 0000000000..b69d7109e1
--- /dev/null
+++ b/usr/src/lib/libsec/spec/acl.spec
@@ -0,0 +1,80 @@
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# 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
+# or http://www.opensolaris.org/os/licensing.
+# 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
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libsec/spec/acl.spec
+
+function aclcheck
+include <sys/acl.h>
+declaration int aclcheck(aclent_t *aclbufp, int nentries, int *which)
+version SUNW_0.9
+errno EINVAL
+exception ($return == GRP_ERROR || \
+ $return == USER_ERROR || \
+ $return == CLASS_ERROR || \
+ $return == OTHER_ERROR || \
+ $return == DUPLICATE_ERROR || \
+ $return == ENTRY_ERROR || \
+ $return == MISS_ERROR || \
+ $return == MEM_ERROR)
+end
+
+function aclsort
+include <sys/acl.h>
+declaration int aclsort(int nentries, int calclass, aclent_t *aclbufp)
+version SUNW_0.9
+exception $return == -1
+end
+
+function acltomode
+include <sys/types.h>, <sys/acl.h>
+declaration int acltomode(aclent_t *aclbufp, int nentries, mode_t *modep)
+version SUNW_0.9
+errno EINVAL
+exception $return == -1
+end
+
+function aclfrommode
+include <sys/types.h>, <sys/acl.h>
+declaration int aclfrommode(aclent_t *aclbufp, int nentries, mode_t *modep)
+version SUNW_0.9
+errno EINVAL
+exception $return == -1
+end
+
+function acltotext
+include <sys/acl.h>
+declaration char *acltotext(aclent_t *aclbufp, int aclcnt)
+version SUNW_0.9
+exception $return == 0
+end
+
+function aclfromtext
+include <sys/acl.h>
+declaration aclent_t *aclfromtext(char *acltextp, int *aclcnt)
+version SUNW_0.9
+exception $return == 0
+end
+
diff --git a/usr/src/lib/libsec/spec/amd64/Makefile b/usr/src/lib/libsec/spec/amd64/Makefile
new file mode 100644
index 0000000000..453c0ea671
--- /dev/null
+++ b/usr/src/lib/libsec/spec/amd64/Makefile
@@ -0,0 +1,44 @@
+#
+# 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
+# or http://www.opensolaris.org/os/licensing.
+# 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 2004 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+
+# Add arch specific objects here
+OBJECTS +=
+
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+
+# Uncomment the following if the linker complains
+#amd64_C_PICFLAGS = -K PIC
+
+include $(SRC)/lib/Makefile.spec
+
+install: $(ROOTABILIB64)
diff --git a/usr/src/lib/libsec/spec/i386/Makefile b/usr/src/lib/libsec/spec/i386/Makefile
new file mode 100644
index 0000000000..c5b9831e2f
--- /dev/null
+++ b/usr/src/lib/libsec/spec/i386/Makefile
@@ -0,0 +1,44 @@
+#
+# 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
+# or http://www.opensolaris.org/os/licensing.
+# 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
+#
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright (c) 1998-1999 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+# lib/libsec/spec/i386/Makefile
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+
+# Add arch specific objects here
+OBJECTS +=
+
+include $(SRC)/lib/Makefile.lib
+
+# Uncomment the following if the linker complains
+#i386_C_PICFLAGS = -K PIC
+
+include $(SRC)/lib/Makefile.spec
+
+install: $(ROOTABILIB)
diff --git a/usr/src/lib/libsec/spec/sparc/Makefile b/usr/src/lib/libsec/spec/sparc/Makefile
new file mode 100644
index 0000000000..696a94a08a
--- /dev/null
+++ b/usr/src/lib/libsec/spec/sparc/Makefile
@@ -0,0 +1,44 @@
+#
+# 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
+# or http://www.opensolaris.org/os/licensing.
+# 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
+#
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright (c) 1998-1999 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+# lib/libsec/spec/sparc/Makefile
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+
+# Add arch specific objects here
+OBJECTS +=
+
+include $(SRC)/lib/Makefile.lib
+
+# Uncomment the following if the linker complains
+#sparc_C_PICFLAGS = -K PIC
+
+include $(SRC)/lib/Makefile.spec
+
+install: $(ROOTABILIB)
diff --git a/usr/src/lib/libsec/spec/sparcv9/Makefile b/usr/src/lib/libsec/spec/sparcv9/Makefile
new file mode 100644
index 0000000000..44a835c629
--- /dev/null
+++ b/usr/src/lib/libsec/spec/sparcv9/Makefile
@@ -0,0 +1,45 @@
+#
+# 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
+# or http://www.opensolaris.org/os/licensing.
+# 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
+#
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright (c) 1998-1999 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+# lib/libsec/spec/sparcv9/Makefile
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+
+# Add arch specific objects here
+OBJECTS +=
+
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+
+# Uncomment the following if the linker complains
+#sparcv9_C_PICFLAGS = -K PIC
+
+include $(SRC)/lib/Makefile.spec
+
+install: $(ROOTABILIB64)
diff --git a/usr/src/lib/libsec/spec/versions b/usr/src/lib/libsec/spec/versions
new file mode 100644
index 0000000000..710b438c72
--- /dev/null
+++ b/usr/src/lib/libsec/spec/versions
@@ -0,0 +1,47 @@
+#
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# 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
+# or http://www.opensolaris.org/os/licensing.
+# 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
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# Note: Even though the SUNW_1.1 version now contains no symbols
+# beyond what was present at Solaris 2.5, the SUNW_1.1 version MUST be
+# present. This is because applications built on 2.6 Beta
+# (when it did contain symbols explicitly) may depend on it.
+#
+i386 {
+ SUNW_1.1: {SUNW_0.9};
+ SUNW_0.9;
+}
+sparcv9 {
+ SUNW_1.1: {SUNW_0.9};
+ SUNW_0.9;
+}
+sparc {
+ SUNW_1.1: {SUNW_0.9};
+ SUNW_0.9;
+}
+amd64 {
+ SUNW_1.1: {SUNW_0.9};
+ SUNW_0.9;
+}