summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib')
-rw-r--r--usr/src/lib/Makefile10
-rw-r--r--usr/src/lib/auditd_plugins/syslog/systoken.c67
-rw-r--r--usr/src/lib/auditd_plugins/syslog/systoken.h9
-rw-r--r--usr/src/lib/common/inc/c_synonyms.h1
-rw-r--r--usr/src/lib/libbsm/Makefile77
-rw-r--r--usr/src/lib/libbsm/Makefile.com10
-rw-r--r--usr/src/lib/libbsm/audit_class.txt30
-rw-r--r--usr/src/lib/libbsm/audit_event.txt142
-rw-r--r--usr/src/lib/libbsm/common/adt_token.c11
-rw-r--r--usr/src/lib/libbsm/common/au_to.c54
-rw-r--r--usr/src/lib/libbsm/common/audit_allocate.c10
-rw-r--r--usr/src/lib/libbsm/common/audit_ftpd.c14
-rw-r--r--usr/src/lib/libbsm/common/audit_rexd.c12
-rw-r--r--usr/src/lib/libbsm/common/audit_rexecd.c12
-rw-r--r--usr/src/lib/libbsm/common/audit_rshd.c10
-rw-r--r--usr/src/lib/libbsm/common/devalloc.c1723
-rw-r--r--usr/src/lib/libbsm/common/devalloc.h185
-rw-r--r--usr/src/lib/libbsm/common/devices.h78
-rw-r--r--usr/src/lib/libbsm/common/generic.c11
-rw-r--r--usr/src/lib/libbsm/common/getdadefs.c234
-rw-r--r--usr/src/lib/libbsm/common/getdaent.c728
-rw-r--r--usr/src/lib/libbsm/common/getdevicerange.c109
-rw-r--r--usr/src/lib/libbsm/common/getdment.c701
-rw-r--r--usr/src/lib/libbsm/common/llib-lbsm8
-rw-r--r--usr/src/lib/libbsm/mkhdr.sh44
-rw-r--r--usr/src/lib/libbsm/spec/Makefile.targ12
-rw-r--r--usr/src/lib/libbsm/spec/devalloc.spec220
-rw-r--r--usr/src/lib/libbsm/spec/private.spec126
-rw-r--r--usr/src/lib/libc/amd64/Makefile1
-rw-r--r--usr/src/lib/libc/i386/Makefile.com1
-rw-r--r--usr/src/lib/libc/inc/synonyms.h2
-rw-r--r--usr/src/lib/libc/port/gen/ucred.c23
-rw-r--r--usr/src/lib/libc/port/llib-lc3
-rw-r--r--usr/src/lib/libc/port/sys/label.c54
-rw-r--r--usr/src/lib/libc/port/sys/zone.c15
-rw-r--r--usr/src/lib/libc/sparc/Makefile1
-rw-r--r--usr/src/lib/libc/sparcv9/Makefile1
-rw-r--r--usr/src/lib/libc/spec/gen.spec11
-rw-r--r--usr/src/lib/libc/spec/sys.spec25
-rw-r--r--usr/src/lib/libc/spec/versions11
-rw-r--r--usr/src/lib/libipsecutil/common/ipsec_util.h9
-rw-r--r--usr/src/lib/libldap5/Makefile.com24
-rw-r--r--usr/src/lib/libnsl/Makefile20
-rw-r--r--usr/src/lib/libnsl/Makefile.com10
-rw-r--r--usr/src/lib/libnsl/nss/nss.h15
-rw-r--r--usr/src/lib/libnsl/rpc/clnt_bcast.c10
-rw-r--r--usr/src/lib/libnsl/rpc/clnt_generic.c8
-rw-r--r--usr/src/lib/libnsl/rpc/rpc_mt.h8
-rw-r--r--usr/src/lib/libnsl/rpc/svc_dg.c45
-rw-r--r--usr/src/lib/libnsl/rpc/svc_generic.c62
-rw-r--r--usr/src/lib/libnsl/rpc/ti_opts.c41
-rw-r--r--usr/src/lib/libsldap/common/ns_common.c9
-rw-r--r--usr/src/lib/libsldap/common/ns_sldap.h9
-rw-r--r--usr/src/lib/libsldap/common/ns_writes.c132
-rw-r--r--usr/src/lib/libtsnet/Makefile67
-rw-r--r--usr/src/lib/libtsnet/Makefile.com63
-rw-r--r--usr/src/lib/libtsnet/amd64/Makefile31
-rw-r--r--usr/src/lib/libtsnet/common/libtsnet.h148
-rw-r--r--usr/src/lib/libtsnet/common/llib-ltsnet32
-rw-r--r--usr/src/lib/libtsnet/common/misc.c359
-rw-r--r--usr/src/lib/libtsnet/common/synonyms.h52
-rw-r--r--usr/src/lib/libtsnet/common/tnmlp.c49
-rw-r--r--usr/src/lib/libtsnet/common/tnrh.c48
-rw-r--r--usr/src/lib/libtsnet/common/tnrhtp.c49
-rw-r--r--usr/src/lib/libtsnet/common/tsol_getrhent.c257
-rw-r--r--usr/src/lib/libtsnet/common/tsol_gettpent.c195
-rw-r--r--usr/src/lib/libtsnet/common/tsol_getzcent.c141
-rw-r--r--usr/src/lib/libtsnet/common/tsol_sgetrhent.c272
-rw-r--r--usr/src/lib/libtsnet/common/tsol_sgettpent.c301
-rw-r--r--usr/src/lib/libtsnet/common/tsol_sgetzcent.c285
-rw-r--r--usr/src/lib/libtsnet/i386/Makefile35
-rw-r--r--usr/src/lib/libtsnet/sparc/Makefile32
-rw-r--r--usr/src/lib/libtsnet/sparcv9/Makefile31
-rw-r--r--usr/src/lib/libtsnet/spec/Makefile30
-rw-r--r--usr/src/lib/libtsnet/spec/Makefile.targ35
-rw-r--r--usr/src/lib/libtsnet/spec/amd64/Makefile33
-rw-r--r--usr/src/lib/libtsnet/spec/i386/Makefile34
-rw-r--r--usr/src/lib/libtsnet/spec/sparc/Makefile34
-rw-r--r--usr/src/lib/libtsnet/spec/sparcv9/Makefile33
-rw-r--r--usr/src/lib/libtsnet/spec/tsnet.spec206
-rw-r--r--usr/src/lib/libtsnet/spec/versions35
-rw-r--r--usr/src/lib/libtsol/Makefile73
-rw-r--r--usr/src/lib/libtsol/Makefile.com74
-rw-r--r--usr/src/lib/libtsol/amd64/Makefile31
-rw-r--r--usr/src/lib/libtsol/common/btohex.c200
-rw-r--r--usr/src/lib/libtsol/common/btos.c485
-rw-r--r--usr/src/lib/libtsol/common/call_labeld.c308
-rw-r--r--usr/src/lib/libtsol/common/clnt.h49
-rw-r--r--usr/src/lib/libtsol/common/getlabel.c66
-rw-r--r--usr/src/lib/libtsol/common/getpathbylabel.c503
-rw-r--r--usr/src/lib/libtsol/common/getplabel.c59
-rw-r--r--usr/src/lib/libtsol/common/hextob.c97
-rw-r--r--usr/src/lib/libtsol/common/label.h242
-rw-r--r--usr/src/lib/libtsol/common/labeld.h473
-rw-r--r--usr/src/lib/libtsol/common/llib-ltsol35
-rw-r--r--usr/src/lib/libtsol/common/ltos.c283
-rw-r--r--usr/src/lib/libtsol/common/misc.c476
-rw-r--r--usr/src/lib/libtsol/common/private.c660
-rw-r--r--usr/src/lib/libtsol/common/privlib.c179
-rw-r--r--usr/src/lib/libtsol/common/setflabel.c309
-rw-r--r--usr/src/lib/libtsol/common/stob.c312
-rw-r--r--usr/src/lib/libtsol/common/stol.c394
-rw-r--r--usr/src/lib/libtsol/common/zone.c272
-rw-r--r--usr/src/lib/libtsol/i386/Makefile30
-rw-r--r--usr/src/lib/libtsol/sparc/Makefile30
-rw-r--r--usr/src/lib/libtsol/sparcv9/Makefile31
-rw-r--r--usr/src/lib/libtsol/spec/Makefile28
-rw-r--r--usr/src/lib/libtsol/spec/Makefile.targ33
-rw-r--r--usr/src/lib/libtsol/spec/amd64/Makefile33
-rw-r--r--usr/src/lib/libtsol/spec/i386/Makefile32
-rw-r--r--usr/src/lib/libtsol/spec/obsolete.spec122
-rw-r--r--usr/src/lib/libtsol/spec/private.spec239
-rw-r--r--usr/src/lib/libtsol/spec/sparc/Makefile32
-rw-r--r--usr/src/lib/libtsol/spec/sparcv9/Makefile33
-rw-r--r--usr/src/lib/libtsol/spec/tsol.spec143
-rw-r--r--usr/src/lib/libtsol/spec/versions45
-rw-r--r--usr/src/lib/libzonecfg/common/libzonecfg.c12
-rw-r--r--usr/src/lib/nsswitch/files/Makefile.com11
-rw-r--r--usr/src/lib/nsswitch/files/common/mapfile-vers9
-rw-r--r--usr/src/lib/nsswitch/files/common/tsol_getrhent.c73
-rw-r--r--usr/src/lib/nsswitch/files/common/tsol_gettpent.c75
-rw-r--r--usr/src/lib/nsswitch/ldap/Makefile.com13
-rw-r--r--usr/src/lib/nsswitch/ldap/common/ldap_common.c12
-rw-r--r--usr/src/lib/nsswitch/ldap/common/ldap_common.h9
-rw-r--r--usr/src/lib/nsswitch/ldap/common/mapfile-vers9
-rw-r--r--usr/src/lib/nsswitch/ldap/common/tsol_getrhent.c183
-rw-r--r--usr/src/lib/nsswitch/ldap/common/tsol_gettpent.c182
127 files changed, 13970 insertions, 1114 deletions
diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile
index 892a841235..c7d90d71de 100644
--- a/usr/src/lib/Makefile
+++ b/usr/src/lib/Makefile
@@ -184,6 +184,8 @@ SUBDIRS += \
libxnet \
libzonecfg \
libzoneinfo \
+ libtsnet \
+ libtsol \
gss_mechs/mech_spnego \
gss_mechs/mech_dummy \
gss_mechs/mech_dh \
@@ -268,6 +270,7 @@ MSGSUBDIRS= \
libsldap \
libslp \
libsmedia \
+ libtsol \
libuutil \
libwanboot \
libwanbootutil \
@@ -327,6 +330,7 @@ HDRSUBDIRS= libaio \
libmail \
libmtmalloc \
libnvpair \
+ libnsl \
libpam \
libpctx \
libpicl \
@@ -349,6 +353,8 @@ HDRSUBDIRS= libaio \
libtnf \
libtnfctl \
libtnfprobe \
+ libtsnet \
+ libtsol \
libvolmgt \
libumem \
libuutil \
@@ -425,6 +431,7 @@ auditd_plugins: libbsm libnsl libsecdb
gss_mechs/mech_krb5: libgss libnsl libsocket libresolv pkcs11
libadt_jni: libbsm
$(CLOSED_BUILD)libc: $(CLOSED)/lib/libc_i18n
+libbsm: libtsol
libcmdutils: libavl
libcontract: libnvpair
libdevid: libdevinfo
@@ -450,9 +457,10 @@ sasl_plugins: pkcs11 libgss libsocket libsasl
libsctp: libsocket
libsocket: libnsl
libldap5: libsasl libsocket libnsl libmd5
-libsldap: libldap5
+libsldap: libldap5 libtsol
libpool: libnvpair libexacct
libproject: libpool libproc libsecdb
+libtsnet: libnsl libtsol libsecdb
libwrap: libnsl libsocket
libwanboot: libnvpair libresolv libnsl libsocket libdevinfo libinetutil \
libdhcputil openssl
diff --git a/usr/src/lib/auditd_plugins/syslog/systoken.c b/usr/src/lib/auditd_plugins/syslog/systoken.c
index 7ccc79d3c9..ae251a67bd 100644
--- a/usr/src/lib/auditd_plugins/syslog/systoken.c
+++ b/usr/src/lib/auditd_plugins/syslog/systoken.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -46,6 +45,7 @@
#include <string.h>
#include <sys/types.h>
#include <bsm/libbsm.h>
+#include <sys/tsol/label.h>
#include "toktable.h" /* ../praudit */
#include "sysplugin.h"
#include "systoken.h"
@@ -1381,46 +1381,6 @@ xclient_token(parse_context_t *ctx)
return (0);
}
-/*
- * Format of clearance token:
- * clearance adr_char*(sizeof (bclear_t))
- *
- * ifdef TSOL because of bclear_t
- */
-#ifndef TSOL
-/* ARGSUSED */
-#endif /* !TSOL */
-int
-clearance_token(parse_context_t *ctx)
-{
-#ifdef TSOL
-
- ctx->adr.adr_now += sizeof (bclear_t);
-
- return (0);
-#else /* !TSOL */
- return (-1);
-#endif /* TSOL */
-}
-/*
- * Format of ilabel token:
- * ilabel adr_char*(sizeof (bilabel_t))
- */
-#ifndef TSOL
-/* ARGSUSED */
-#endif /* !TSOL */
-int
-ilabel_token(parse_context_t *ctx)
-{
-#ifdef TSOL
-
- ctx->adr.adr_now += sizeof (bilabel_t);
-
- return (0);
-#else /* !TSOL */
- return (-1);
-#endif /* TSOL */
-}
/*
* -----------------------------------------------------------------------
@@ -1445,22 +1405,23 @@ privilege_token(parse_context_t *ctx)
/*
* Format of slabel token:
- * slabel adr_char*(sizeof (bslabel_t))
+ * label ID 1 byte
+ * compartment length 1 byte
+ * classification 2 bytes
+ * compartment words <compartment length> * 4 bytes
*/
-#ifndef TSOL
-/* ARGSUSED */
-#endif /* !TSOL */
int
slabel_token(parse_context_t *ctx)
{
-#ifdef TSOL
+ char c;
- ctx->adr.adr_now += sizeof (bslabel_t);
+ ctx->adr.adr_now += sizeof (char); /* label ID */
+ adrm_char(&(ctx->adr), &c, 1);
+
+ ctx->adr.adr_now += sizeof (ushort_t); /* classification */
+ ctx->adr.adr_now += 4 * c; /* compartments */
return (0);
-#else /* !TSOL */
- return (-1);
-#endif /* TSOL */
}
/*
diff --git a/usr/src/lib/auditd_plugins/syslog/systoken.h b/usr/src/lib/auditd_plugins/syslog/systoken.h
index db60ae43aa..af6517845a 100644
--- a/usr/src/lib/auditd_plugins/syslog/systoken.h
+++ b/usr/src/lib/auditd_plugins/syslog/systoken.h
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -97,9 +96,7 @@ extern void acl_token(adr_t *, parse_context_t *);
extern void attribute_token(adr_t *, parse_context_t *);
extern void s5_IPC_perm_token(adr_t *, parse_context_t *);
extern void group_token();
-extern void ilabel_token(adr_t *, parse_context_t *);
extern void slabel_token(adr_t *, parse_context_t *);
-extern void clearance_token(adr_t *, parse_context_t *);
extern void privilege_token(adr_t *, parse_context_t *);
extern void useofpriv_token(adr_t *, parse_context_t *);
extern void zonename_token(adr_t *, parse_context_t *);
diff --git a/usr/src/lib/common/inc/c_synonyms.h b/usr/src/lib/common/inc/c_synonyms.h
index 06fa420471..2143bb8d06 100644
--- a/usr/src/lib/common/inc/c_synonyms.h
+++ b/usr/src/lib/common/inc/c_synonyms.h
@@ -414,6 +414,7 @@ extern "C" {
#define isastream _isastream
#define isatty _isatty
#define issetugid _issetugid
+#define is_system_labeled _is_system_labeled
#define jrand48 _jrand48
#define kaio _kaio
#define kill _kill
diff --git a/usr/src/lib/libbsm/Makefile b/usr/src/lib/libbsm/Makefile
index 55ccf943e2..4cc23687a8 100644
--- a/usr/src/lib/libbsm/Makefile
+++ b/usr/src/lib/libbsm/Makefile
@@ -18,6 +18,7 @@
#
# CDDL HEADER END
#
+
#
# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
@@ -27,7 +28,6 @@
# lib/libbsm/Makefile
#
-include ../../Makefile.master
include ../Makefile.lib
SUBDIRS= spec .WAIT $(MACH) $(BUILD64) $(MACH64)
@@ -46,54 +46,13 @@ package := TARGET= package
all clean clobber delete install lint package: $(SUBDIRS)
-OBJECTS= adr.o \
- adrf.o \
- adrm.o \
- adt.o \
- adt_token.o \
- adt_xlate.o \
- au_open.o \
- au_preselect.o \
- au_to.o \
- au_usermask.o \
- audit_allocate.o \
- audit_class.o \
- audit_cron.o \
- audit_crontab.o \
- audit_at.o \
- audit_event.o \
- audit_ftpd.o \
- audit_halt.o \
- audit_inetd.o \
- audit_kadmind.o \
- audit_krb5kdc.o \
- audit_mountd.o \
- audit_newgrp.o \
- audit_plugin.o \
- audit_reboot.o \
- audit_rexd.o \
- audit_rexecd.o \
- audit_rshd.o \
- audit_settid.o \
- audit_shutdown.o \
- audit_uadmin.o \
- audit_user.o \
- bsm.o \
- generic.o \
- getacinfo.o \
- getacval.o \
- getauditflags.o \
- getdaent.o \
- getdment.o \
- getfaudflgs.o
-
COMMONDIR = common
#
# Macros for libbsm header files. These define user-level only interfaces.
#
GENHDRS = audit_uevents.h
-HDRS = libbsm.h devices.h adt.h adt_event.h audit_private.h
+HDRS = libbsm.h devices.h devalloc.h adt.h adt_event.h audit_private.h
COMMONHDRS = $(HDRS:%=$(COMMONDIR)/%)
ROOTHDRDIR = $(ROOT)/usr/include/bsm
ROOTCHDRS = $(HDRS:%=$(ROOTHDRDIR)/%)
@@ -154,10 +113,8 @@ ARSYMLNK=$(RESAL)/files
#
# message catalogue file
#
-TEXT_DOMAIN= SUNW_OST_OSLIB
-POFILE= libbsm.po
-CATALOG=libbsm.po
-POFILES= $(OBJECTS:%.o=%.po)
+MSGFILES = `$(GREP) -l gettext $(COMMONDIR)/*.c`
+POFILE = libbsm.po
#
# Definitions for XML (DTD AND XSL)
@@ -241,24 +198,9 @@ $(ROOTETCSECURITY):
$(ROOTETCSECURITY)/%: %.txt
$(INS.rename)
-%.po: $(COMMONDIR)/%.c
- $(COMPILE.cpp) $< > $<.i
- $(BUILD.po)
-
-_msg: $(MSGDOMAIN) $(POFILE)
- $(RM) $(MSGDOMAIN)/$(CATALOG)
- $(CP) $(POFILE) $(MSGDOMAIN)
+$(POFILE): pofile_MSGFILES
-catalog: _msg
-
-po_clean:
- $(RM) $(POFILES) $(POFILE)
-
-clobber: po_clean
-
-$(POFILE): .WAIT $(POFILES)
- $(RM) $@
- $(CAT) $(POFILES) > $@
+_msg: $(MSGDOMAINPOFILE)
# has strings but doesn't use gettext
adt_xlate.po: $(COMMONDIR)/adt_xlate.c
@@ -267,11 +209,10 @@ adt_xlate.po: $(COMMONDIR)/adt_xlate.c
$(SED) "/^domain/d" < messages.po > adt_xlate.po
$(RM) messages.po
-$(MSGDOMAIN):
- $(INS.dir)
-
-
spec $(MACH) $(MACH64) : FRC
@cd $@; pwd; $(MAKE) $(TARGET)
FRC:
+
+include ../Makefile.targ
+include ../../Makefile.msg.targ
diff --git a/usr/src/lib/libbsm/Makefile.com b/usr/src/lib/libbsm/Makefile.com
index 3a7318aa72..52871561fc 100644
--- a/usr/src/lib/libbsm/Makefile.com
+++ b/usr/src/lib/libbsm/Makefile.com
@@ -24,7 +24,7 @@
#
# ident "%Z%%M% %I% %E% SMI"
#
-# lib/libbsm/Makefile
+# lib/libbsm/Makefile.com
#
LIBRARY = libbsm.a
@@ -67,7 +67,10 @@ OBJECTS= adr.o \
getacval.o \
getauditflags.o \
getdaent.o \
+ getdevicerange.o \
getdment.o \
+ getdadefs.o \
+ devalloc.o \
getfaudflgs.o
#
@@ -94,7 +97,10 @@ CLOBBERFILES += $(MAPFILE)
CFLAGS += $(CCVERBOSE)
DYNFLAGS += -M$(MAPFILE)
-LDLIBS += -lsocket -lnsl -lmd5 -lc -lsecdb
+
+LAZYLIBS = $(ZLAZYLOAD) -ltsol $(ZNOLAZYLOAD)
+LDLIBS += -lsocket -lnsl -lmd5 -lc -lsecdb $(LAZYLIBS)
+lint := LAZYLIBS = -ltsol
COMDIR= ../common
diff --git a/usr/src/lib/libbsm/audit_class.txt b/usr/src/lib/libbsm/audit_class.txt
index 5d0b8c7e03..69b06f2b80 100644
--- a/usr/src/lib/libbsm/audit_class.txt
+++ b/usr/src/lib/libbsm/audit_class.txt
@@ -1,13 +1,12 @@
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 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.
+# 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
# or http://www.opensolaris.org/os/licensing.
@@ -62,6 +61,29 @@
0x00100000:ps:process start/stop
0x00200000:pm:process modify
0x00300000:pc:process (meta-class)
+#
+# The following four masks define X server related audit classes which
+# are applicable to Trusted Extensions. X server audit events are mapped
+# to these classes per the following criteria:
+#
+# xp : Protocols audited for use of privilege (successful or otherwise).
+# E.g., ChangeWindowAttributes is audited when issued by a client to
+# change attributes of another client's window. This class also includes
+# any administrative protocols (e.g. SetAccessControl).
+# xc : Server objects creation/destruction; e.g., CreateWindow.
+# xs : Protocols that do not return X error messages to clients on failure for
+# lack for security attributes. E.g., GetImage does not return BadWindow
+# error if it cannot read from a window for lack of privilege. It just
+# does not read from that window.
+# These events should be selected for audit on success only. Selecting
+# them for failure will cause a lot of noise in the audit trail.
+# xx : All above X classes.
+#
+0x00400000:xp:X - privileged/administrative operations
+0x00800000:xc:X - object create/destroy
+0x01000000:xs:X - operations that always silently fail, if bad
+0x01c00000:xx:X - all X events (meta-class)
+#
0x20000000:io:ioctl
0x40000000:ex:exec
0x80000000:ot:other
diff --git a/usr/src/lib/libbsm/audit_event.txt b/usr/src/lib/libbsm/audit_event.txt
index 5bcc228838..7403d16365 100644
--- a/usr/src/lib/libbsm/audit_event.txt
+++ b/usr/src/lib/libbsm/audit_event.txt
@@ -1,13 +1,13 @@
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 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.
+# 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
# or http://www.opensolaris.org/os/licensing.
@@ -48,10 +48,25 @@
# 2048 - 32767 Reserved for the Solaris TCB programs.
# 32768 - 65535 Available for third party TCB applications.
#
-# 6144 - 32767 SunOS 5.X user level audit events
+#
+# Allocation of reserved kernel events:
+# (NOTE: the kernel event table, and possibly MAX_KEVENTS, must be updated
+# in audit_kevents.h when changes are made to kernel events.)
+# 1 - 511 allocated for Solaris
+# 512 - 1023 allocated for Trusted Solaris/Trusted Extensions
+# 1024 - 2047 (reserved but not allocated)
+#
+# Allocation of user level audit events:
+# 2048 - 5999 (reserved but not allocated)
+# 6000 - 7999 allocated for Solaris
+# 8000 - 8999 (reserved but not allocated)
+# 9000 - 9999 allocated for Trusted Solaris/Trusted Extensions
+# 10000 - 32767 (reserved but not allocated)
+# 32768 - 65535 (Available for third party TCB applications)
#
#
# kernel audit events
+# 1 - 511 allocated for Solaris
#
0:AUE_NULL:indir system call:no
1:AUE_EXIT:exit(2):ps
@@ -173,8 +188,6 @@
113:AUE_SYSTEMBOOT:system booted:na
114:AUE_ASYNC_DAEMON_EXIT:async_daemon(2) exited:no
115:AUE_NFSSVC_EXIT:nfssvc(2) exited:no
-128:AUE_WRITEL:writel(2):no
-129:AUE_WRITEVL:writevl(2):no
130:AUE_GETAUID:getauid(2):aa
131:AUE_SETAUID:setauid(2):aa
132:AUE_GETAUDIT:getaudit(2):aa
@@ -328,7 +341,12 @@
292:AUE_CRYPTOADM:kernel cryptographic framework:as
293:AUE_CONFIGSSL:configure kernel SSL:as
#
+# Trusted Solaris/Trusted Extensions kernel audit events
+# 512 - 1023 allocated for Trusted Solaris/Trusted Extensions
+#
+#
# user level audit events
+# 6000 - 7999 allocated for Solaris
#
# 2048 - 6143 Reserved
#
@@ -409,3 +427,113 @@
6225:AUE_inetd_failrate:inetd failrate:na
6226:AUE_inetd_ratelimit:inetd ratelimit:na
6227:AUE_zlogin:login - zlogin:lo
+#
+# Trusted Solaris/Trusted Extensions user level audit events
+# 9000 - 9999 allocated for Trusted Solaris/Trusted Extensions
+#
+9035:AUE_sl_change:Workspace label change:ap
+9037:AUE_file_copy:file copy:fm
+9038:AUE_file_move:file move:fm
+9039:AUE_sel_mgr_xfer:selection manager transfer:fm
+9101:AUE_ClientConnect:client connection to x server:lo
+9102:AUE_ClientDisconnect:client disconn. from x server:lo
+9120:AUE_ChangeProperty:XChangeProperty(3X11):xc
+9121:AUE_DeleteProperty:XDeleteProperty(3X11):xc
+9137:AUE_GrabServer:XGrabServer(3X11):ot
+9138:AUE_UngrabServer:XUngrabServer(3X11):ot
+9146:AUE_SetFontPath:XSetFontPath(3X11):ot
+9173:AUE_InstallColormap:XInstallColormap(3X11):ot
+9174:AUE_UninstallColormap:XUninstallColormap(3X11):xp
+9193:AUE_SetScreenSaver:XSetScreenSaver(3X11):xp
+9194:AUE_ChangeHosts:XChangeHosts(3X11):ot
+9195:AUE_SetAccessControl:XSetAccessControl(3X11):xp
+9196:AUE_SetCloseDownMode:XSetCloseDownMode(3X11):xs
+9197:AUE_KillClient:XKillClient(3X11):xc
+9202:AUE_XExtensions:X server extensions:xp
+9103:AUE_CreateWindow:XCreateWindow(3X11):xc
+9104:AUE_ChangeWindowAttributes:XChangeWindowAttributes(3X11):xp
+9105:AUE_GetWindowAttributes:XGetWindowAttributes(3X11):xp
+9106:AUE_DestroyWindow:XDestroyWindow(3X11):xc
+9107:AUE_DestroySubwindows:XDestroySubwindows(3X11):xc
+9108:AUE_ChangeSaveSet:XChangeSaveSet(3X11):xp
+9109:AUE_ReparentWindow:XReparentWindow(3X11):xp
+9110:AUE_MapWindow:XMapWindow(3X11):xp
+9111:AUE_MapSubwindows:XMapSubwindows(3X11):xp
+9112:AUE_UnmapWindow:XUnmapWindow(3X11):xp
+9113:AUE_UnmapSubwindows:XUnmapSubwindows(3X11):xp
+9114:AUE_ConfigureWindow:XConfigureWindow(3X11):xp
+9115:AUE_CirculateWindow:XCirculateWindow(3X11):xp
+9116:AUE_GetGeometry:XGetGeometry(3X11):xp
+9117:AUE_QueryTree:XQueryTree(3X11):xp
+9118:AUE_InternAtom:XInternAtom(3X11):xs
+9119:AUE_GetAtomName:XGetAtomName(3X11):xs
+9122:AUE_GetProperty:XGetProperty(3X11):xp
+9123:AUE_ListProperties:XListProperties(3X11):xp
+9124:AUE_SetSelectionOwner:XSetSelectionOwner(3X11):xp
+9125:AUE_GetSelectionOwner:XGetSelectionOwner(3X11):xs
+9126:AUE_ConvertSelection:XConvertSelection(3X11):xs
+9127:AUE_SendEvent:XSendEvent(3X11):xs
+9128:AUE_GrabPointer:XGrabPointer(3X11):xs
+9129:AUE_UngrabPointer:XUngrabPointer(3X11):xs
+9130:AUE_GrabButton:XGrabButton(3X11):xp
+9131:AUE_UngrabButton:XUngrabButton(3X11):xs
+9132:AUE_ChangeActivePointerGrab:XChangeActivePointerGrab(3X11):xs
+9133:AUE_GrabKeyboard:XGrabKeyboard(3X11):xp
+9134:AUE_UngrabKeyboard:XUngrabKeyboard(3X11):xs
+9135:AUE_GrabKey:XGrabKey(3X11):xp
+9136:AUE_UngrabKey:XUngrabKey(3X11):xp
+9139:AUE_QueryPointer:XQueryPointer(3X11):xp
+9140:AUE_GetMotionEvents:XGetMotionEvents(3X11):xp
+9141:AUE_TranslateCoords:XTranslateCoords(3X11):xp
+9142:AUE_WarpPointer:XWarpPointer(3X11):xs
+9143:AUE_SetInputFocus:XSetInputFocus(3X11):xs
+9144:AUE_GetInputFocus:XGetInputFocus(3X11):xs
+9145:AUE_QueryKeymap:XQueryKeymap(3X11):xp
+9147:AUE_FreePixmap:XFreePixmap(3X11):xc
+9148:AUE_ChangeGC:XChangeGC(3X11):xp
+9149:AUE_CopyGC:XCopyGC(3X11):xp
+9150:AUE_SetDashes:XSetDashes(3X11):xp
+9151:AUE_SetClipRectangles:XSetClipRectangles(3X11):xp
+9152:AUE_FreeGC:XFreeGC(3X11):xc
+9153:AUE_ClearArea:XClearArea(3X11):xp
+9154:AUE_CopyArea:XCopyArea(3X11):xs
+9155:AUE_CopyPlane:XCopyPlane(3X11):xs
+9156:AUE_PolyPoint:XPolyPoint(3X11):xp
+9157:AUE_PolyLine:XPolyLine(3X11):xp
+9158:AUE_PolySegment:XPolySegment(3X11):xp
+9159:AUE_PolyRectangle:XPolyRectangle(3X11):xs
+9160:AUE_PolyArc:XPolyArc(3X11):xp
+9161:AUE_FillPolygon:XFillPolygon(3X11):xp
+9162:AUE_PolyFillRectangle:XPolyFillRectangle(3X11):xp
+9163:AUE_PolyFillArc:XPolyFillArc(3X11):xp
+9164:AUE_PutImage:XPutImage(3X11):xp
+9165:AUE_GetImage:XGetImage(3X11):xs
+9166:AUE_PolyText8:XPolyText8(3X11):xp
+9167:AUE_PolyText16:XPolyText16(3X11):xp
+9168:AUE_ImageText8:XImageText8(3X11):xp
+9169:AUE_ImageText16:XImageText16(3X11):xp
+9170:AUE_CreateColormap:XCreateColormap(3X11):xc
+9171:AUE_FreeColormap:XFreeColormap(3X11):xc
+9172:AUE_CopyColormapAndFree:XCopyColormapAndFree(3X11):xp
+9175:AUE_ListInstalledColormaps:XListInstalledColormaps(3X11):xs
+9176:AUE_AllocColor:XAllocColor(3X11):xc
+9177:AUE_AllocNamedColor:XAllocNamedColor(3X11):xc
+9178:AUE_AllocColorCells:XAllocColorCells(3X11):xc
+9179:AUE_AllocColorPlanes:XAllocColorPlanes(3X11):xc
+9180:AUE_FreeColors:XFreeColors(3X11):xc
+9181:AUE_StoreColors:XStoreColors(3X11):xp
+9182:AUE_StoreNamedColor:XStoreNamedColor(3X11):xp
+9183:AUE_QueryColors:XQueryColors(3X11):xp
+9184:AUE_LookupColor:XLookupColor(3X11):xp
+9185:AUE_CreateCursor:XCreateCursor(3X11):xc
+9186:AUE_CreateGlyphCursor:XCreateGlyphCursor(3X11):xc
+9187:AUE_FreeCursor:XFreeCursor(3X11):xc
+9188:AUE_RecolorCursor:XRecolorCursor(3X11):xp
+9189:AUE_ChangeKeyboardMapping:XChangeKeyboardMapping(3X11):xs
+9190:AUE_ChangeKeyboardControl:XChangeKeyboardControl(3X11):xs
+9191:AUE_Bell:XBell(3X11):xs
+9192:AUE_ChangePointerControl:XChangePointerControl(3X11):xs
+9198:AUE_RotateProperties:XRotateProperties(3X11):xp
+9199:AUE_ForceScreenSaver:XForceScreenSaver(3X11):xp
+9200:AUE_SetPointerMapping:XSetPointerMapping(3X11):xs
+9201:AUE_SetModifierMapping:XSetModifierMapping(3X11):xs
diff --git a/usr/src/lib/libbsm/common/adt_token.c b/usr/src/lib/libbsm/common/adt_token.c
index 49720539c7..1c6aec718b 100644
--- a/usr/src/lib/libbsm/common/adt_token.c
+++ b/usr/src/lib/libbsm/common/adt_token.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -22,7 +21,7 @@
/*
* adt_token.c
*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* This file does not provide any user callable functions. See adt.c
@@ -41,6 +40,7 @@
#include <sys/priv_names.h>
#include <sys/types.h>
#include <sys/vnode.h>
+#include <tsol/label.h>
#include <time.h>
#include <unistd.h>
@@ -530,6 +530,9 @@ adt_to_subject(datadef *def, void *p_data, int required,
au_to_newgroups(0, grouplist));
}
}
+
+ if (is_system_labeled())
+ (void) au_write(event->ae_event_handle, au_to_mylabel());
}
/*
diff --git a/usr/src/lib/libbsm/common/au_to.c b/usr/src/lib/libbsm/common/au_to.c
index 8c8fe49820..3747994d76 100644
--- a/usr/src/lib/libbsm/common/au_to.c
+++ b/usr/src/lib/libbsm/common/au_to.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -42,6 +41,9 @@
#include <netinet/in.h>
#include <netinet/in_pcb.h>
#include <string.h>
+#include <zone.h>
+#include <sys/tsol/label.h>
+#include <sys/tsol/label_macro.h>
#define NGROUPS 16 /* XXX - temporary */
@@ -1242,6 +1244,50 @@ au_to_xselect(char *pstring, char *type, short dlen, char *data)
}
/*
+ * au_to_label
+ * return s:
+ * pointer to token chain containing a sensitivity label token.
+ */
+token_t *
+au_to_label(bslabel_t *label)
+{
+ token_t *token; /* local token */
+ adr_t adr; /* adr memory stream header */
+ char data_header = AUT_LABEL; /* header for this token */
+ short bs = sizeof (bslabel_t);
+
+ token = get_token(sizeof (char) + bs);
+ if (token == NULL)
+ return (NULL);
+ adr_start(&adr, token->tt_data);
+ adr_char(&adr, &data_header, 1);
+ adr_char(&adr, (char *)label, bs);
+
+ return (token);
+}
+
+/*
+ * au_to_mylabel
+ * return s:
+ * pointer to a slabel token.
+ */
+token_t *
+au_to_mylabel(void)
+{
+ bslabel_t slabel;
+ zoneid_t zid = getzoneid();
+
+ if (zid == GLOBAL_ZONEID) {
+ bsllow(&slabel);
+ } else {
+ if (zone_getattr(zid, ZONE_ATTR_SLBL, &slabel,
+ sizeof (bslabel_t)) < 0)
+ return (NULL);
+ }
+ return (au_to_label(&slabel));
+}
+
+/*
* au_to_zonename
* return s:
* pointer to a zonename token.
diff --git a/usr/src/lib/libbsm/common/audit_allocate.c b/usr/src/lib/libbsm/common/audit_allocate.c
index e5d8e04d8a..35af6d9b53 100644
--- a/usr/src/lib/libbsm/common/audit_allocate.c
+++ b/usr/src/lib/libbsm/common/audit_allocate.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,13 +19,14 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/types.h>
+#include <tsol/label.h>
#include <bsm/audit.h>
#include <bsm/libbsm.h>
#include <bsm/audit_private.h>
@@ -136,6 +136,8 @@ audit_allocate_record(status)
}
(void) au_write(ad, au_to_newgroups(ng, grplst));
}
+ if (is_system_labeled())
+ (void) au_write(ad, au_to_mylabel());
if (status)
(void) au_write(ad, au_to_exit(status, -1));
diff --git a/usr/src/lib/libbsm/common/audit_ftpd.c b/usr/src/lib/libbsm/common/audit_ftpd.c
index fb04a40579..023e78cb33 100644
--- a/usr/src/lib/libbsm/common/audit_ftpd.c
+++ b/usr/src/lib/libbsm/common/audit_ftpd.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,6 +36,7 @@
#include <sys/socket.h>
#include <sys/sockio.h>
#include <netinet/in.h>
+#include <tsol/label.h>
#include <bsm/audit.h>
#include <bsm/audit_record.h>
@@ -187,6 +187,9 @@ generate_record(
(void) au_write(rd, au_to_subject_ex(uid, uid, gid,
ruid, rgid, pid, pid, &info.ai_termid));
+ if (is_system_labeled())
+ (void) au_write(rd, au_to_mylabel());
+
/* add return token */
errno = 0;
if (err) {
@@ -291,6 +294,9 @@ audit_ftpd_logout(void)
(void) au_write(rd, au_to_subject_ex(info.ai_auid, euid,
egid, uid, gid, pid, pid, &info.ai_termid));
+ if (is_system_labeled())
+ (void) au_write(rd, au_to_mylabel());
+
/* add return token */
errno = 0;
#ifdef _LP64
diff --git a/usr/src/lib/libbsm/common/audit_rexd.c b/usr/src/lib/libbsm/common/audit_rexd.c
index a868c17909..5c48b810b6 100644
--- a/usr/src/lib/libbsm/common/audit_rexd.c
+++ b/usr/src/lib/libbsm/common/audit_rexd.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -39,6 +38,7 @@
#include <syslog.h>
#include <pwd.h>
#include <netinet/in.h>
+#include <tsol/label.h>
#include <locale.h>
#include "generic.h"
@@ -204,6 +204,8 @@ audit_rexd_fail(msg, hostname, user, uid, gid, shell, cmd)
(void) au_write(rd,
au_to_subject_ex(uid, uid, gid, uid, gid, pid, pid,
&info.ai_termid));
+ if (is_system_labeled())
+ (void) au_write(rd, au_to_mylabel());
/* add reason for failure */
(void) au_write(rd, au_to_text(msg));
@@ -328,6 +330,8 @@ char **cmd; /* argv to be executed locally, may be NULL */
(void) au_write(rd,
au_to_subject_ex(uid, uid, gid, uid, gid, pid, pid,
&info.ai_termid));
+ if (is_system_labeled())
+ (void) au_write(rd, au_to_mylabel());
/* add hostname of machine requesting service */
diff --git a/usr/src/lib/libbsm/common/audit_rexecd.c b/usr/src/lib/libbsm/common/audit_rexecd.c
index 79e33ce765..bb32ed9643 100644
--- a/usr/src/lib/libbsm/common/audit_rexecd.c
+++ b/usr/src/lib/libbsm/common/audit_rexecd.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -39,6 +38,7 @@
#include <syslog.h>
#include <pwd.h>
#include <netinet/in.h>
+#include <tsol/label.h>
#include <locale.h>
#include "generic.h"
@@ -197,6 +197,8 @@ char *cmdbuf; /* command line to be executed locally */
/* add subject token */
(void) au_write(rd,
au_to_subject_ex(uid, uid, gid, uid, gid, pid, pid, &tid));
+ if (is_system_labeled())
+ (void) au_write(rd, au_to_mylabel());
/* add reason for failure */
(void) au_write(rd, au_to_text(msg));
@@ -306,6 +308,8 @@ char *cmdbuf; /* command line to be executed locally */
/* add subject token */
(void) au_write(rd,
au_to_subject_ex(uid, uid, gid, uid, gid, pid, pid, &tid));
+ if (is_system_labeled())
+ (void) au_write(rd, au_to_mylabel());
/* add hostname of machine requesting service */
(void) snprintf(buf, sizeof (buf), dgettext(bsm_dom,
diff --git a/usr/src/lib/libbsm/common/audit_rshd.c b/usr/src/lib/libbsm/common/audit_rshd.c
index f06ba169c7..7ff2523355 100644
--- a/usr/src/lib/libbsm/common/audit_rshd.c
+++ b/usr/src/lib/libbsm/common/audit_rshd.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -37,6 +36,7 @@
#include <string.h>
#include <syslog.h>
#include <netinet/in.h>
+#include <tsol/label.h>
#include <locale.h>
#include <unistd.h>
#include <generic.h>
@@ -134,6 +134,8 @@ generate_record(char *remuser, /* username at machine requesting service */
(void) au_write(rd, au_to_subject_ex(uid, uid, gid, uid, gid, pid, pid,
&info.ai_termid));
+ if (is_system_labeled())
+ (void) au_write(rd, au_to_mylabel());
gtxt = dgettext(bsm_dom, "cmd %s");
tlen = strlen(gtxt) + strlen(cmdbuf) + 1;
diff --git a/usr/src/lib/libbsm/common/devalloc.c b/usr/src/lib/libbsm/common/devalloc.c
new file mode 100644
index 0000000000..4541191349
--- /dev/null
+++ b/usr/src/lib/libbsm/common/devalloc.c
@@ -0,0 +1,1723 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <utime.h>
+#include <synch.h>
+#include <strings.h>
+#include <string.h>
+#include <libintl.h>
+#include <errno.h>
+#include <auth_list.h>
+#include <bsm/devices.h>
+#include <bsm/devalloc.h>
+
+#define DA_DEFS "/etc/security/tsol/devalloc_defaults"
+
+extern int _readbufline(char *, int, char *, int, int *);
+extern char *strtok_r(char *, const char *, char **);
+extern char *_strtok_escape(char *, char *, char **);
+extern int getdaon(void);
+extern int da_matchname(devalloc_t *, char *);
+extern int da_match(devalloc_t *, da_args *);
+extern int dmap_matchname(devmap_t *, char *);
+extern int dm_match(devmap_t *, da_args *);
+
+/*
+ * The following structure is for recording old entries to be retained.
+ * We read the entries from the database into a linked list in memory,
+ * then turn around and write them out again.
+ */
+typedef struct strentry {
+ struct strentry *se_next;
+ char se_str[4096 + 1];
+} strentry_t;
+
+/*
+ * da_check_longindevperm -
+ * reads /etc/logindevperm and checks if specified device is in the file.
+ * returns 1 if specified device found in /etc/logindevperm, else returns 0
+ */
+int
+da_check_logindevperm(char *devname)
+{
+ int ret = 0;
+ int fd = -1;
+ int nlen, plen, slen, lineno, fsize;
+ char line[MAX_CANON];
+ char *field_delims = " \t\n";
+ char *fbuf = NULL;
+ char *ptr, *device;
+ char *lasts = NULL;
+ FILE *fp;
+ struct stat f_stat;
+
+ /*
+ * check if /etc/logindevperm exists and get its size
+ */
+ if ((fd = open(LOGINDEVPERM, O_RDONLY)) == -1)
+ return (0);
+ if (fstat(fd, &f_stat) != 0) {
+ (void) close(fd);
+ return (0);
+ }
+ fsize = f_stat.st_size;
+ if ((fbuf = (char *)malloc(fsize)) == NULL) {
+ (void) close(fd);
+ return (0);
+ }
+ if ((fp = fdopen(fd, "r")) == NULL) {
+ free(fbuf);
+ (void) close(fd);
+ return (0);
+ }
+
+ /*
+ * read and parse /etc/logindevperm
+ */
+ plen = nlen = lineno = 0;
+ while (fgets(line, MAX_CANON, fp) != NULL) {
+ lineno++;
+ if ((ptr = strchr(line, '#')) != NULL)
+ *ptr = '\0'; /* handle comments */
+ if (strtok_r(line, field_delims, &lasts) == NULL)
+ continue; /* ignore blank lines */
+ if (strtok_r(NULL, field_delims, &lasts) == NULL)
+ /* invalid entry */
+ continue;
+ if ((ptr = strtok_r(NULL, field_delims, &lasts)) == NULL)
+ /* empty device list */
+ continue;
+ nlen = strlen(ptr) + 1; /* +1 terminator */
+ nlen += (plen + 1);
+ if (plen == 0)
+ slen = snprintf(fbuf, nlen, "%s", ptr);
+ else
+ slen = snprintf(fbuf + plen, nlen - plen, ":%s", ptr);
+ if (slen >= fsize) {
+ fbuf[0] = '\0';
+ (void) fclose(fp);
+ return (slen);
+ }
+ plen += slen;
+ }
+ (void) fclose(fp);
+
+ /*
+ * check if devname exists in /etc/logindevperm
+ */
+ device = strtok_r(fbuf, ":", &lasts);
+ while (device != NULL) {
+ /*
+ * device and devname may be one of these types -
+ * /dev/xx
+ * /dev/xx*
+ * /dev/dir/xx
+ * /dev/dir/xx*
+ * /dev/dir/"*"
+ */
+ if (strcmp(device, devname) == 0) {
+ /* /dev/xx, /dev/dir/xx */
+ free(fbuf);
+ return (1);
+ }
+ if ((ptr = strrchr(device, KV_WILDCHAR)) != NULL) {
+ /* all wildcard types */
+ *ptr = '\0';
+ if (strncmp(device, devname, strlen(device)) == 0) {
+ free(fbuf);
+ return (1);
+ }
+ }
+ device = strtok_r(NULL, ":", &lasts);
+ }
+
+ return (ret);
+}
+
+/*
+ * _da_read_file -
+ * establishes readers/writer lock on fname; reads in the file if its
+ * contents changed since the last time we read it.
+ * returns size of buffer read, or -1 on failure.
+ */
+int
+_da_read_file(char *fname, char **fbuf, time_t *ftime, rwlock_t *flock,
+ int flag)
+{
+ int fd = -1;
+ int fsize = 0;
+ time_t newtime;
+ FILE *fp = NULL;
+ struct stat f_stat;
+
+ if (flag & DA_FORCE)
+ *ftime = 0;
+
+ /* check the size and the time stamp on the file */
+ if (rw_rdlock(flock) != 0)
+ return (-1);
+ if (stat(fname, &f_stat) != 0) {
+ (void) rw_unlock(flock);
+ return (-1);
+ }
+ fsize = f_stat.st_size;
+ newtime = f_stat.st_mtime;
+ (void) rw_unlock(flock);
+
+ while (newtime > *ftime) {
+ /*
+ * file has been modified since we last read it; or this
+ * is a forced read.
+ * read file into the buffer with rw lock.
+ */
+ if (rw_wrlock(flock) != 0)
+ return (-1);
+ if ((fp = fopen(fname, "r")) == NULL) {
+ (void) rw_unlock(flock);
+ return (-1);
+ }
+ fd = fileno(fp);
+ if (*fbuf != NULL) {
+ free(*fbuf);
+ *fbuf = NULL;
+ }
+ if ((*fbuf = malloc(fsize)) == NULL) {
+ (void) rw_unlock(flock);
+ (void) close(fd);
+ return (-1);
+ }
+ if (read(fd, *fbuf, fsize) < fsize) {
+ free(*fbuf);
+ (void) rw_unlock(flock);
+ (void) close(fd);
+ return (-1);
+ }
+ (void) rw_unlock(flock);
+ /*
+ * verify that the file did not change just after we read it.
+ */
+ if (rw_rdlock(flock) != 0) {
+ free(*fbuf);
+ (void) close(fd);
+ return (-1);
+ }
+ if (stat(fname, &f_stat) != 0) {
+ free(*fbuf);
+ (void) rw_unlock(flock);
+ (void) close(fd);
+ return (-1);
+ }
+ fsize = f_stat.st_size;
+ newtime = f_stat.st_mtime;
+ (void) rw_unlock(flock);
+ (void) close(fd);
+ *ftime = newtime;
+ }
+
+ return (fsize);
+}
+
+/*
+ * _update_zonename -
+ * add/remove current zone's name to the given devalloc_t.
+ */
+void
+_update_zonename(da_args *dargs, devalloc_t *dap)
+{
+ int i, j;
+ int oldsize, newsize;
+ int has_zonename = 0;
+ char *zonename;
+ kva_t *newkva, *oldkva;
+ kv_t *newdata, *olddata;
+ devinfo_t *devinfo;
+
+ devinfo = dargs->devinfo;
+ oldkva = dap->da_devopts;
+ if (oldkva == NULL) {
+ if (dargs->optflag & DA_REMOVE_ZONE)
+ return;
+ if (dargs->optflag & DA_ADD_ZONE) {
+ newkva = _str2kva(devinfo->devopts, KV_ASSIGN,
+ KV_TOKEN_DELIMIT);
+ if (newkva != NULL)
+ dap->da_devopts = newkva;
+ return;
+ }
+ }
+ newsize = oldsize = oldkva->length;
+ if (kva_match(oldkva, DAOPT_ZONE))
+ has_zonename = 1;
+ if (dargs->optflag & DA_ADD_ZONE) {
+ if ((zonename = index(devinfo->devopts, '=')) == NULL)
+ return;
+ zonename++;
+ if (has_zonename) {
+ (void) _insert2kva(oldkva, DAOPT_ZONE, zonename);
+ return;
+ }
+ newsize += 1;
+ } else if (dargs->optflag & DA_REMOVE_ZONE) {
+ if (has_zonename) {
+ newsize -= 1;
+ if (newsize == 0) {
+ /*
+ * If zone name was the only key/value pair,
+ * put 'reserved' in the empty slot.
+ */
+ _kva_free(oldkva);
+ dap->da_devopts = NULL;
+ return;
+ }
+ } else {
+ return;
+ }
+ }
+ newkva = _new_kva(newsize);
+ newkva->length = 0;
+ newdata = newkva->data;
+ olddata = oldkva->data;
+ for (i = 0, j = 0; i < oldsize; i++) {
+ if ((dargs->optflag & DA_REMOVE_ZONE) &&
+ (strcmp(olddata[i].key, DAOPT_ZONE) == 0))
+ continue;
+ newdata[j].key = strdup(olddata[i].key);
+ newdata[j].value = strdup(olddata[i].value);
+ newkva->length++;
+ j++;
+ }
+ if (dargs->optflag & DA_ADD_ZONE) {
+ newdata[j].key = strdup(DAOPT_ZONE);
+ newdata[j].value = strdup(zonename);
+ newkva->length++;
+ }
+ _kva_free(oldkva);
+ dap->da_devopts = newkva;
+}
+
+/*
+ * _dmap2str -
+ * converts a device_map entry into a printable string
+ * returns 0 on success, -1 on error.
+ */
+/*ARGSUSED*/
+static int
+_dmap2str(da_args *dargs, devmap_t *dmp, char *buf, int size, const char *sep)
+{
+ int length;
+
+ length = snprintf(buf, size, "%s%s", dmp->dmap_devname, sep);
+ if (length >= size)
+ return (-1);
+ length += snprintf(buf + length, size - length, "%s%s",
+ dmp->dmap_devtype, sep);
+ if (length >= size)
+ return (-1);
+ length += snprintf(buf + length, size - length, "%s\n",
+ dmp->dmap_devlist);
+ if (length >= size)
+ return (-1);
+ return (0);
+}
+
+/*
+ * _dmap2strentry -
+ * calls dmap2str to break given devmap_t into printable entry.
+ * returns pointer to decoded entry, NULL on error.
+ */
+static strentry_t *
+_dmap2strentry(da_args *dargs, devmap_t *devmapp)
+{
+ strentry_t *sep;
+
+ if ((sep = (strentry_t *)malloc(sizeof (strentry_t))) == NULL)
+ return (NULL);
+ if (_dmap2str(dargs, devmapp, sep->se_str, sizeof (sep->se_str),
+ KV_TOKEN_DELIMIT"\\\n\t") != 0) {
+ free(sep);
+ return (NULL);
+ }
+ return (sep);
+}
+
+/*
+ * fix_optstr -
+ * removes trailing ':' from buf.
+ */
+void
+fix_optstr(char *buf)
+{
+ char *p = NULL;
+
+ if (p = rindex(buf, ':'))
+ *p = ';';
+}
+
+/*
+ * _da2str -
+ * converts a device_allocate entry into a printable string
+ * returns 0 on success, -1 on error.
+ */
+static int
+_da2str(da_args *dargs, devalloc_t *dap, char *buf, int size, const char *sep,
+ const char *osep)
+{
+ int length;
+ int matching_entry = 0;
+ char **dnames;
+
+ if (dargs->optflag & DA_UPDATE &&
+ (dargs->optflag & DA_ADD_ZONE ||
+ dargs->optflag & DA_REMOVE_ZONE) &&
+ dargs->devnames) {
+ for (dnames = dargs->devnames; *dnames != NULL; dnames++) {
+ if (da_matchname(dap, *dnames)) {
+ matching_entry = 1;
+ break;
+ }
+ }
+ }
+ length = snprintf(buf, size, "%s%s", dap->da_devname, sep);
+ if (length >= size)
+ return (-1);
+ length += snprintf(buf + length, size - length, "%s%s",
+ dap->da_devtype, sep);
+ if (length >= size)
+ return (-1);
+ if (matching_entry)
+ _update_zonename(dargs, dap);
+ if ((dap->da_devopts == NULL) || ((dap->da_devopts->length == 1) &&
+ (strcmp(dap->da_devopts->data->key, DA_RESERVED) == 0))) {
+ length += snprintf(buf + length, size - length, "%s%s",
+ DA_RESERVED, sep);
+ } else {
+ if (_kva2str(dap->da_devopts, buf + length, size - length,
+ KV_ASSIGN, (char *)osep) != 0)
+ return (-1);
+ length = strlen(buf);
+ }
+ if (dap->da_devopts)
+ fix_optstr(buf);
+ if (length >= size)
+ return (-1);
+ length += snprintf(buf + length, size - length, "%s%s",
+ DA_RESERVED, sep);
+ if (length >= size)
+ return (-1);
+ length += snprintf(buf + length, size - length, "%s%s",
+ dap->da_devauth ? dap->da_devauth : DA_ANYUSER, sep);
+ if (length >= size)
+ return (-1);
+ length += snprintf(buf + length, size - length, "%s\n",
+ dap->da_devexec ? dap->da_devexec : "");
+ if (length >= size)
+ return (-1);
+
+ return (0);
+}
+
+/*
+ * _da2strentry -
+ * calls da2str to break given devalloc_t into printable entry.
+ * returns pointer to decoded entry, NULL on error.
+ */
+static strentry_t *
+_da2strentry(da_args *dargs, devalloc_t *dap)
+{
+ strentry_t *sep;
+
+ if ((sep = (strentry_t *)malloc(sizeof (strentry_t))) == NULL)
+ return (NULL);
+ if (_da2str(dargs, dap, sep->se_str, sizeof (sep->se_str),
+ KV_DELIMITER "\\\n\t", KV_TOKEN_DELIMIT "\\\n\t") != 0) {
+ free(sep);
+ return (NULL);
+ }
+ return (sep);
+}
+
+/*
+ * _def2str
+ * converts da_defs_t into a printable string.
+ * returns 0 on success, -1 on error.
+ */
+static int
+_def2str(da_defs_t *da_defs, char *buf, int size, const char *sep)
+{
+ int length;
+
+ length = snprintf(buf, size, "%s%s", da_defs->devtype, sep);
+ if (length >= size)
+ return (-1);
+ if (da_defs->devopts) {
+ if (_kva2str(da_defs->devopts, buf + length, size - length,
+ KV_ASSIGN, KV_DELIMITER) != 0)
+ return (-1);
+ length = strlen(buf);
+ }
+ if (length >= size)
+ return (-1);
+
+ return (0);
+}
+
+/*
+ * _def2strentry
+ * calls _def2str to break given da_defs_t into printable entry.
+ * returns pointer decoded entry, NULL on error.
+ */
+static strentry_t *
+_def2strentry(da_defs_t *da_defs)
+{
+ strentry_t *sep;
+
+ if ((sep = (strentry_t *)malloc(sizeof (strentry_t))) == NULL)
+ return (NULL);
+ if (_def2str(da_defs, sep->se_str, sizeof (sep->se_str),
+ KV_TOKEN_DELIMIT) != 0) {
+ free(sep);
+ return (NULL);
+ }
+
+ return (sep);
+}
+
+/*
+ * _build_defattrs
+ * cycles through all defattr entries, stores them in memory. removes
+ * entries with the given search_key (device type).
+ * returns 0 if given entry not found, 1 if given entry removed, 2 on
+ * error.
+ */
+static int
+_build_defattrs(da_args *dargs, strentry_t **head_defent)
+{
+ int rc = 0;
+ da_defs_t *da_defs;
+ strentry_t *tail_str, *tmp_str;
+
+ setdadefent();
+ while ((da_defs = getdadefent()) != NULL) {
+ rc = !(strcmp(da_defs->devtype, dargs->devinfo->devtype));
+ if (rc && dargs->optflag & DA_ADD &&
+ !(dargs->optflag & DA_FORCE)) {
+ /*
+ * During DA_ADD, we keep an existing entry unless
+ * we have DA_FORCE set to override that entry.
+ */
+ dargs->optflag |= DA_NO_OVERRIDE;
+ rc = 0;
+ }
+ if (rc == 0) {
+ tmp_str = _def2strentry(da_defs);
+ if (tmp_str == NULL) {
+ freedadefent(da_defs);
+ enddadefent();
+ return (2);
+ }
+ /* retaining defattr entry: tmp_str->se_str */
+ tmp_str->se_next = NULL;
+ if (*head_defent == NULL) {
+ *head_defent = tail_str = tmp_str;
+ } else {
+ tail_str->se_next = tmp_str;
+ tail_str = tmp_str;
+ }
+ }
+ freedadefent(da_defs);
+ }
+ enddadefent();
+
+ return (rc);
+}
+
+/*
+ * _build_lists -
+ * cycles through all the entries, stores them in memory. removes entries
+ * with the given search_key (device name or type).
+ * returns 0 if given entry not found, 1 if given entry removed, 2 on
+ * error.
+ */
+static int
+_build_lists(da_args *dargs, strentry_t **head_devallocp,
+ strentry_t **head_devmapp)
+{
+ int rc = 0;
+ devalloc_t *devallocp;
+ devmap_t *devmapp;
+ strentry_t *tail_str;
+ strentry_t *tmp_str;
+
+ if (dargs->optflag & DA_MAPS_ONLY)
+ goto dmap_only;
+
+ /* build device_allocate */
+ setdaent();
+ while ((devallocp = getdaent()) != NULL) {
+ rc = da_match(devallocp, dargs);
+ if (rc && dargs->optflag & DA_ADD &&
+ !(dargs->optflag & DA_FORCE)) {
+ /*
+ * During DA_ADD, we keep an existing entry unless
+ * we have DA_FORCE set to override that entry.
+ */
+ dargs->optflag |= DA_NO_OVERRIDE;
+ rc = 0;
+ }
+ if (rc == 0) {
+ tmp_str = _da2strentry(dargs, devallocp);
+ if (tmp_str == NULL) {
+ freedaent(devallocp);
+ enddaent();
+ return (2);
+ }
+ /* retaining devalloc entry: tmp_str->se_str */
+ tmp_str->se_next = NULL;
+ if (*head_devallocp == NULL) {
+ *head_devallocp = tail_str = tmp_str;
+ } else {
+ tail_str->se_next = tmp_str;
+ tail_str = tmp_str;
+ }
+ }
+ freedaent(devallocp);
+ }
+ enddaent();
+
+dmap_only:
+ if (dargs->optflag & DA_ALLOC_ONLY)
+ return (rc);
+
+ /* build device_maps */
+ rc = 0;
+ setdmapent();
+ while ((devmapp = getdmapent()) != NULL) {
+ rc = dm_match(devmapp, dargs);
+ if (rc && dargs->optflag & DA_ADD &&
+ !(dargs->optflag & DA_FORCE)) {
+ /*
+ * During DA_ADD, we keep an existing entry unless
+ * we have DA_FORCE set to override that entry.
+ */
+ dargs->optflag |= DA_NO_OVERRIDE;
+ rc = 0;
+ }
+ if (rc == 0) {
+ tmp_str = _dmap2strentry(dargs, devmapp);
+ if (tmp_str == NULL) {
+ freedmapent(devmapp);
+ enddmapent();
+ return (2);
+ }
+ /* retaining devmap entry: tmp_str->se_str */
+ tmp_str->se_next = NULL;
+ if (*head_devmapp == NULL) {
+ *head_devmapp = tail_str = tmp_str;
+ } else {
+ tail_str->se_next = tmp_str;
+ tail_str = tmp_str;
+ }
+ }
+ freedmapent(devmapp);
+ }
+ enddmapent();
+
+ return (rc);
+}
+
+/*
+ * _write_defattrs
+ * writes current entries to devalloc_defaults.
+ */
+static void
+_write_defattrs(FILE *fp, strentry_t *head_defent)
+{
+ strentry_t *tmp_str;
+
+ for (tmp_str = head_defent; tmp_str != NULL;
+ tmp_str = tmp_str->se_next) {
+ (void) fputs(tmp_str->se_str, fp);
+ (void) fputs("\n", fp);
+ }
+
+}
+
+/*
+ * _write_device_allocate -
+ * writes current entries in the list to device_allocate.
+ */
+static void
+_write_device_allocate(char *odevalloc, FILE *dafp, strentry_t *head_devallocp)
+{
+ int is_on = -1;
+ strentry_t *tmp_str;
+ struct stat dastat;
+
+ (void) fseek(dafp, (off_t)0, SEEK_SET);
+
+ /*
+ * if the devalloc on/off string existed before,
+ * put it back before anything else.
+ * we need to check for the string only if the file
+ * exists.
+ */
+ if (stat(odevalloc, &dastat) == 0) {
+ is_on = da_is_on();
+ if (is_on == 0)
+ (void) fputs(DA_OFF_STR, dafp);
+ else if (is_on == 1)
+ (void) fputs(DA_ON_STR, dafp);
+ }
+ tmp_str = head_devallocp;
+ while (tmp_str) {
+ (void) fputs(tmp_str->se_str, dafp);
+ (void) fputs("\n", dafp);
+ tmp_str = tmp_str->se_next;
+ }
+}
+
+/*
+ * _write_device_maps -
+ * writes current entries in the list to device_maps.
+ */
+static void
+_write_device_maps(FILE *dmfp, strentry_t *head_devmapp)
+{
+ strentry_t *tmp_str;
+
+ (void) fseek(dmfp, (off_t)0, SEEK_SET);
+
+ tmp_str = head_devmapp;
+ while (tmp_str) {
+ (void) fputs(tmp_str->se_str, dmfp);
+ (void) fputs("\n", dmfp);
+ tmp_str = tmp_str->se_next;
+ }
+}
+
+/*
+ * _write_new_defattrs
+ * writes the new entry to devalloc_defaults.
+ * returns 0 on success, -1 on error.
+ */
+static int
+_write_new_defattrs(FILE *fp, da_args *dargs)
+{
+ int count;
+ char *tok = NULL, *tokp = NULL;
+ char *lasts;
+ devinfo_t *devinfo = dargs->devinfo;
+
+ if (fseek(fp, (off_t)0, SEEK_END) == (off_t)-1)
+ return (-1);
+ if (!devinfo->devopts)
+ return (0);
+ (void) fprintf(fp, "%s%s", (devinfo->devtype ? devinfo->devtype : ""),
+ KV_TOKEN_DELIMIT);
+ if ((tokp = (char *)malloc(strlen(devinfo->devopts))) != NULL) {
+ (void) strcpy(tokp, devinfo->devopts);
+ if ((tok = strtok_r(tokp, KV_DELIMITER, &lasts)) != NULL) {
+ (void) fprintf(fp, "%s", tok);
+ count = 1;
+ }
+ while ((tok = strtok_r(NULL, KV_DELIMITER, &lasts)) != NULL) {
+ if (count)
+ (void) fprintf(fp, "%s", KV_DELIMITER);
+ (void) fprintf(fp, "%s", tok);
+ count++;
+ }
+ } else {
+ (void) fprintf(fp, "%s", devinfo->devopts);
+ }
+
+ return (0);
+}
+
+/*
+ * _write_new_entry -
+ * writes the new devalloc_t to device_allocate or the new devmap_t to
+ * device_maps.
+ * returns 0 on success, -1 on error.
+ */
+static int
+_write_new_entry(FILE *fp, da_args *dargs, int flag)
+{
+ int count;
+ char *tok = NULL, *tokp = NULL;
+ char *lasts;
+ devinfo_t *devinfo = dargs->devinfo;
+
+ if (flag & DA_MAPS_ONLY)
+ goto dmap_only;
+
+ if (fseek(fp, (off_t)0, SEEK_END) == (off_t)-1)
+ return (-1);
+
+ (void) fprintf(fp, "%s%s\\\n\t",
+ (devinfo->devname ? devinfo->devname : ""), KV_DELIMITER);
+ (void) fprintf(fp, "%s%s\\\n\t",
+ (devinfo->devtype ? devinfo->devtype : ""), KV_DELIMITER);
+ if (devinfo->devopts == NULL) {
+ (void) fprintf(fp, "%s%s\\\n\t", DA_RESERVED,
+ KV_DELIMITER);
+ } else {
+ if ((tokp = (char *)malloc(strlen(devinfo->devopts))) != NULL) {
+ (void) strcpy(tokp, devinfo->devopts);
+ if ((tok = strtok_r(tokp, KV_TOKEN_DELIMIT, &lasts)) !=
+ NULL) {
+ (void) fprintf(fp, "%s", tok);
+ count = 1;
+ }
+ while ((tok = strtok_r(NULL, KV_TOKEN_DELIMIT,
+ &lasts)) != NULL) {
+ if (count)
+ (void) fprintf(fp, "%s",
+ KV_TOKEN_DELIMIT "\\\n\t");
+ (void) fprintf(fp, "%s", tok);
+ count++;
+ }
+ if (count)
+ (void) fprintf(fp, "%s",
+ KV_DELIMITER "\\\n\t");
+ } else {
+ (void) fprintf(fp, "%s%s", devinfo->devopts,
+ KV_DELIMITER "\\\n\t");
+ }
+ }
+ (void) fprintf(fp, "%s%s\\\n\t", DA_RESERVED, KV_DELIMITER);
+ (void) fprintf(fp, "%s%s\\\n\t",
+ (devinfo->devauths ? devinfo->devauths : DA_ANYUSER),
+ KV_DELIMITER);
+ (void) fprintf(fp, "%s\n",
+ (devinfo->devexec ? devinfo->devexec : KV_DELIMITER));
+
+dmap_only:
+ if (flag & DA_ALLOC_ONLY)
+ return (0);
+
+ if (fseek(fp, (off_t)0, SEEK_END) == (off_t)-1)
+ return (-1);
+
+ (void) fprintf(fp, "%s%s\\\n",
+ (devinfo->devname ? devinfo->devname : ""), KV_TOKEN_DELIMIT);
+ (void) fprintf(fp, "\t%s%s\\\n",
+ (devinfo->devtype ? devinfo->devtype : ""), KV_TOKEN_DELIMIT);
+ (void) fprintf(fp, "\t%s\n",
+ (devinfo->devlist ? devinfo->devlist : KV_TOKEN_DELIMIT));
+
+ return (0);
+}
+
+/*
+ * _da_lock_devdb -
+ * locks the database files; lock can be either broken explicitly by
+ * closing the fd of the lock file, or it expires automatically at process
+ * termination.
+ * returns fd of the lock file or -1 on error.
+ */
+int
+_da_lock_devdb(char *rootdir)
+{
+ int lockfd = -1;
+ char *lockfile;
+ char path[MAXPATHLEN];
+ int size = sizeof (path);
+
+ if (rootdir == NULL) {
+ lockfile = DA_DB_LOCK;
+ } else {
+ path[0] = '\0';
+ if (snprintf(path, size, "%s%s", rootdir, DA_DB_LOCK) >= size)
+ return (-1);
+ lockfile = path;
+ }
+
+ if ((lockfd = open(lockfile, O_RDWR | O_CREAT, 0600)) == -1)
+ /* cannot open lock file */
+ return (-1);
+
+ (void) fchown(lockfd, DA_UID, DA_GID);
+
+ if (lseek(lockfd, (off_t)0, SEEK_SET) == -1) {
+ /* cannot position lock file */
+ (void) close(lockfd);
+ return (-1);
+ }
+ if (lockf(lockfd, F_TLOCK, 0) == -1) {
+ /* cannot set lock */
+ (void) close(lockfd);
+ return (-1);
+ }
+ (void) utime(lockfile, NULL);
+
+ return (lockfd);
+}
+
+/*
+ * da_open_devdb -
+ * opens one or both database files - device_allocate, device_maps - in
+ * the specified mode.
+ * locks the database files; lock is either broken explicitly by the
+ * caller by closing the lock file fd, or it expires automatically at
+ * process termination.
+ * writes the file pointer of opened file in the input args - dafp, dmfp.
+ * returns fd of the lock file on success, -2 if database file does not
+ * exist, -1 on other errors.
+ */
+int
+da_open_devdb(char *rootdir, FILE **dafp, FILE **dmfp, int flag)
+{
+ int oflag = 0;
+ int fda = -1;
+ int fdm = -1;
+ int lockfd = -1;
+ char *fname;
+ char *fmode;
+ char path[MAXPATHLEN];
+ FILE *devfile;
+
+ if ((dafp == NULL) && (dmfp == NULL))
+ return (-1);
+
+ if (flag & DA_RDWR) {
+ oflag = DA_RDWR;
+ fmode = "r+";
+ } else if (flag & DA_RDONLY) {
+ oflag = DA_RDONLY;
+ fmode = "r";
+ }
+
+ if ((lockfd = _da_lock_devdb(rootdir)) == -1)
+ return (-1);
+
+ if ((dafp == NULL) || (flag & DA_MAPS_ONLY))
+ goto dmap_only;
+
+ path[0] = '\0';
+
+ /*
+ * open the device allocation file
+ */
+ if (rootdir == NULL) {
+ fname = DEVALLOC;
+ } else {
+ if (snprintf(path, sizeof (path), "%s%s", rootdir,
+ DEVALLOC) >= sizeof (path)) {
+ if (lockfd != -1)
+ (void) close(lockfd);
+ return (-1);
+ }
+ fname = path;
+ }
+ if ((fda = open(fname, oflag, DA_DBMODE)) == -1) {
+ if (lockfd != -1)
+ (void) close(lockfd);
+ return ((errno == ENOENT) ? -2 : -1);
+ }
+ if ((devfile = fdopen(fda, fmode)) == NULL) {
+ (void) close(fda);
+ if (lockfd != -1)
+ (void) close(lockfd);
+ return (-1);
+ }
+ *dafp = devfile;
+ (void) fchmod(fda, DA_DBMODE);
+
+ if ((flag & DA_ALLOC_ONLY))
+ goto out;
+
+dmap_only:
+ path[0] = '\0';
+ /*
+ * open the device map file
+ */
+ if (rootdir == NULL) {
+ fname = DEVMAP;
+ } else {
+ if (snprintf(path, sizeof (path), "%s%s", rootdir,
+ DEVMAP) >= sizeof (path)) {
+ (void) close(fda);
+ if (lockfd != -1)
+ (void) close(lockfd);
+ return (-1);
+ }
+ fname = path;
+ }
+
+ if ((fdm = open(fname, oflag, DA_DBMODE)) == -1) {
+ if (lockfd != -1)
+ (void) close(lockfd);
+ return ((errno == ENOENT) ? -2 : -1);
+ }
+
+ if ((devfile = fdopen(fdm, fmode)) == NULL) {
+ (void) close(fdm);
+ (void) close(fda);
+ if (lockfd != -1)
+ (void) close(lockfd);
+ return (-1);
+ }
+ *dmfp = devfile;
+ (void) fchmod(fdm, DA_DBMODE);
+
+out:
+ return (lockfd);
+}
+
+/*
+ * _record_on_off -
+ * adds either DA_ON_STR or DA_OFF_STR to device_allocate
+ * returns 0 on success, -1 on error.
+ */
+static int
+_record_on_off(da_args *dargs, FILE *tafp, FILE *dafp)
+{
+ int dafd;
+ int nsize;
+ int nitems = 1;
+ int actionlen;
+ int str_found = 0;
+ int len = 0, nlen = 0, plen = 0;
+ char *ptr = NULL;
+ char *actionstr;
+ char *nbuf = NULL;
+ char line[MAX_CANON];
+ struct stat dastat;
+
+ if (dargs->optflag & DA_ON)
+ actionstr = DA_ON_STR;
+ else
+ actionstr = DA_OFF_STR;
+ actionlen = strlen(actionstr);
+ dafd = fileno(dafp);
+ if (fstat(dafd, &dastat) == -1)
+ return (-1);
+
+ /* check the old device_allocate for on/off string */
+ ptr = fgets(line, MAX_CANON, dafp);
+ if (ptr != NULL) {
+ if ((strcmp(line, DA_ON_STR) == 0) ||
+ (strcmp(line, DA_OFF_STR) == 0)) {
+ str_found = 1;
+ nsize = dastat.st_size;
+ }
+ }
+ if (!ptr || !str_found) {
+ /*
+ * the file never had either the on or the off string;
+ * make room for it.
+ */
+ str_found = 0;
+ nsize = dastat.st_size + actionlen + 1;
+ }
+ if ((nbuf = (char *)malloc(nsize)) == NULL)
+ return (-1);
+ nbuf[0] = '\0';
+ /* put the on/off string */
+ (void) strcpy(nbuf, actionstr);
+ nlen = strlen(nbuf);
+ plen = nlen;
+ if (ptr && !str_found) {
+ /* now put the first line that we read in fgets */
+ nlen = plen + strlen(line) + 1;
+ len = snprintf(nbuf + plen, nlen - plen, "%s", line);
+ if (len >= nsize) {
+ free(nbuf);
+ return (-1);
+ }
+ plen += len;
+ }
+
+ /* now get the rest of the old file */
+ while (fgets(line, MAX_CANON, dafp) != NULL) {
+ nlen = plen + strlen(line) + 1;
+ len = snprintf(nbuf + plen, nlen - plen, "%s", line);
+ if (len >= nsize) {
+ free(nbuf);
+ return (-1);
+ }
+ plen += len;
+ }
+ len = strlen(nbuf) + 1;
+ if (len < nsize)
+ nbuf[len] = '\n';
+
+ /* write the on/off str + the old device_allocate to the temp file */
+ if (fwrite(nbuf, nsize, nitems, tafp) < nitems) {
+ free(nbuf);
+ return (-1);
+ }
+
+ free(nbuf);
+
+ return (0);
+}
+
+/*
+ * da_update_defattrs -
+ * writes default attributes to devalloc_defaults
+ * returns 0 on success, -1 on error.
+ */
+int
+da_update_defattrs(da_args *dargs)
+{
+ int rc = 0, lockfd = 0, tmpfd = 0;
+ char *defpath = DEFATTRS;
+ char *tmpdefpath = TMPATTRS;
+ FILE *tmpfp = NULL;
+ struct stat dstat;
+ strentry_t *head_defent = NULL;
+
+ if (dargs == NULL)
+ return (0);
+ if ((lockfd = _da_lock_devdb(NULL)) == -1)
+ return (-1);
+ if ((tmpfd = open(tmpdefpath, O_RDWR|O_CREAT, DA_DBMODE)) == -1) {
+ (void) close(lockfd);
+ return (-1);
+ }
+ (void) fchown(tmpfd, DA_UID, DA_GID);
+ if ((tmpfp = fdopen(tmpfd, "r+")) == NULL) {
+ (void) close(tmpfd);
+ (void) unlink(tmpdefpath);
+ (void) close(lockfd);
+ return (-1);
+ }
+ /*
+ * examine all entries, remove an old one if required, check
+ * if a new one needs to be added.
+ */
+ if (stat(defpath, &dstat) == 0) {
+ if ((rc = _build_defattrs(dargs, &head_defent)) != 0) {
+ if (rc == 1) {
+ (void) close(tmpfd);
+ (void) unlink(tmpdefpath);
+ (void) close(lockfd);
+ return (rc);
+ }
+ }
+ }
+ /*
+ * write back any existing entries.
+ */
+ _write_defattrs(tmpfp, head_defent);
+
+ if (dargs->optflag & DA_ADD && !(dargs->optflag & DA_NO_OVERRIDE)) {
+ /* add new entries */
+ rc = _write_new_defattrs(tmpfp, dargs);
+ (void) fclose(tmpfp);
+ } else {
+ (void) fclose(tmpfp);
+ }
+ if (rename(tmpdefpath, defpath) != 0) {
+ rc = -1;
+ (void) unlink(tmpdefpath);
+ }
+ (void) close(lockfd);
+
+ return (rc);
+}
+
+/*
+ * da_update_device -
+ * writes devices entries to device_allocate and device_maps.
+ * returns 0 on success, -1 on error.
+ */
+int
+da_update_device(da_args *dargs)
+{
+ int rc;
+ int tafd = -1, tmfd = -1;
+ int lockfd = -1;
+ char *rootdir = NULL;
+ char *apathp = NULL, *mpathp = NULL, *dapathp = NULL,
+ *dmpathp = NULL;
+ char apath[MAXPATHLEN], mpath[MAXPATHLEN],
+ dapath[MAXPATHLEN], dmpath[MAXPATHLEN];
+ FILE *tafp = NULL, *tmfp = NULL, *dafp = NULL;
+ struct stat dastat;
+ devinfo_t *devinfo;
+ strentry_t *head_devmapp = NULL;
+ strentry_t *head_devallocp = NULL;
+
+ if (dargs == NULL)
+ return (0);
+
+ rootdir = dargs->rootdir;
+ devinfo = dargs->devinfo;
+
+ /*
+ * adding/removing entries should be done in both
+ * device_allocate and device_maps. updates can be
+ * done in both or either of the files.
+ */
+ if (dargs->optflag & DA_ADD || dargs->optflag & DA_REMOVE) {
+ if (dargs->optflag & DA_ALLOC_ONLY ||
+ dargs->optflag & DA_MAPS_ONLY)
+ return (0);
+ }
+
+ /*
+ * name, type and list are required fields for adding a new
+ * device.
+ */
+ if ((dargs->optflag & DA_ADD) &&
+ ((devinfo->devname == NULL) ||
+ (devinfo->devtype == NULL) ||
+ (devinfo->devlist == NULL))) {
+ return (-1);
+ }
+
+ if (rootdir != NULL) {
+ if (snprintf(apath, sizeof (apath), "%s%s", rootdir,
+ TMPALLOC) >= sizeof (apath))
+ return (-1);
+ apathp = apath;
+ if (snprintf(dapath, sizeof (dapath), "%s%s", rootdir,
+ DEVALLOC) >= sizeof (dapath))
+ return (-1);
+ dapathp = dapath;
+ if (!(dargs->optflag & DA_ALLOC_ONLY)) {
+ if (snprintf(mpath, sizeof (mpath), "%s%s", rootdir,
+ TMPMAP) >= sizeof (mpath))
+ return (-1);
+ mpathp = mpath;
+ if (snprintf(dmpath, sizeof (dmpath), "%s%s", rootdir,
+ DEVMAP) >= sizeof (dmpath))
+ return (-1);
+ dmpathp = dmpath;
+ }
+ } else {
+ apathp = TMPALLOC;
+ dapathp = DEVALLOC;
+ mpathp = TMPMAP;
+ dmpathp = DEVMAP;
+ }
+
+ if (dargs->optflag & DA_MAPS_ONLY)
+ goto dmap_only;
+
+ /*
+ * Check if we are here just to record on/off status of
+ * device_allocation.
+ */
+ if (dargs->optflag & DA_ON || dargs->optflag & DA_OFF)
+ lockfd = da_open_devdb(dargs->rootdir, &dafp, NULL,
+ DA_RDONLY|DA_ALLOC_ONLY);
+ else
+ lockfd = _da_lock_devdb(rootdir);
+ if (lockfd == -1)
+ return (-1);
+
+ if ((tafd = open(apathp, O_RDWR|O_CREAT, DA_DBMODE)) == -1) {
+ (void) close(lockfd);
+ (void) fclose(dafp);
+ return (-1);
+ }
+ (void) fchown(tafd, DA_UID, DA_GID);
+ if ((tafp = fdopen(tafd, "r+")) == NULL) {
+ (void) close(tafd);
+ (void) unlink(apathp);
+ (void) fclose(dafp);
+ (void) close(lockfd);
+ return (-1);
+ }
+
+ /*
+ * We don't need to parse the file if we are here just to record
+ * on/off status of device_allocation.
+ */
+ if (dargs->optflag & DA_ON || dargs->optflag & DA_OFF) {
+ if (_record_on_off(dargs, tafp, dafp) == -1) {
+ (void) close(tafd);
+ (void) unlink(apathp);
+ (void) fclose(dafp);
+ (void) close(lockfd);
+ return (-1);
+ }
+ (void) fclose(dafp);
+ goto out;
+ }
+
+ /*
+ * examine all the entries, remove an old one if forced to,
+ * and check that they are suitable for updating.
+ * we need to do this only if the file exists already.
+ */
+ if (stat(dapathp, &dastat) == 0) {
+ if ((rc = _build_lists(dargs, &head_devallocp,
+ &head_devmapp)) != 0) {
+ if (rc != 1) {
+ (void) close(tafd);
+ (void) unlink(apathp);
+ (void) close(lockfd);
+ return (rc);
+ }
+ }
+ }
+
+ /*
+ * write back any existing devalloc entries, along with
+ * the devalloc on/off string.
+ */
+ _write_device_allocate(dapathp, tafp, head_devallocp);
+
+ if (dargs->optflag & DA_ALLOC_ONLY)
+ goto out;
+
+dmap_only:
+ if ((tmfd = open(mpathp, O_RDWR|O_CREAT, DA_DBMODE)) == -1) {
+ (void) close(tafd);
+ (void) unlink(apathp);
+ (void) close(lockfd);
+ return (-1);
+ }
+ (void) fchown(tmfd, DA_UID, DA_GID);
+ if ((tmfp = fdopen(tmfd, "r+")) == NULL) {
+ (void) close(tafd);
+ (void) unlink(apathp);
+ (void) close(tmfd);
+ (void) unlink(mpathp);
+ (void) close(lockfd);
+ return (-1);
+ }
+
+ /* write back any existing devmap entries */
+ if (head_devmapp != NULL)
+ _write_device_maps(tmfp, head_devmapp);
+
+out:
+ if (dargs->optflag & DA_ADD && !(dargs->optflag & DA_NO_OVERRIDE)) {
+ /* add any new entries */
+ rc = _write_new_entry(tafp, dargs, DA_ALLOC_ONLY);
+ (void) fclose(tafp);
+
+ if (rc == 0)
+ rc = _write_new_entry(tmfp, dargs, DA_MAPS_ONLY);
+ (void) fclose(tmfp);
+ } else {
+ if (tafp)
+ (void) fclose(tafp);
+ if (tmfp)
+ (void) fclose(tmfp);
+ }
+
+ rc = 0;
+ if (!(dargs->optflag & DA_MAPS_ONLY)) {
+ if (rename(apathp, dapathp) != 0) {
+ rc = -1;
+ (void) unlink(apathp);
+ }
+ }
+ if (!(dargs->optflag & DA_ALLOC_ONLY)) {
+ if (rename(mpathp, dmpathp) != 0) {
+ rc = -1;
+ (void) unlink(mpathp);
+ }
+ }
+
+ (void) close(lockfd);
+
+ return (rc);
+}
+
+/*
+ * da_add_list -
+ * adds new /dev link name to the linked list of devices.
+ * returns 0 if link added successfully, -1 on error.
+ */
+int
+da_add_list(devlist_t *dlist, char *link, int new_instance, int flag)
+{
+ int instance;
+ int nlen, plen;
+ int new_entry = 0;
+ char *dtype, *dexec, *tname, *kval;
+ char *minstr = NULL, *maxstr = NULL;
+ char dname[DA_MAXNAME];
+ kva_t *kva;
+ deventry_t *dentry = NULL, *nentry = NULL, *pentry = NULL;
+ da_defs_t *da_defs;
+
+ if (dlist == NULL || link == NULL)
+ return (-1);
+
+ dname[0] = '\0';
+ if (flag & DA_AUDIO) {
+ dentry = dlist->audio;
+ tname = DA_AUDIO_NAME;
+ dtype = DA_AUDIO_TYPE;
+ dexec = DA_DEFAULT_AUDIO_CLEAN;
+ } else if (flag & DA_CD) {
+ dentry = dlist->cd;
+ tname = DA_CD_NAME;
+ dtype = DA_CD_TYPE;
+ dexec = DA_DEFAULT_DISK_CLEAN;
+ } else if (flag & DA_FLOPPY) {
+ dentry = dlist->floppy;
+ tname = DA_FLOPPY_NAME;
+ dtype = DA_FLOPPY_TYPE;
+ dexec = DA_DEFAULT_DISK_CLEAN;
+ } else if (flag & DA_TAPE) {
+ dentry = dlist->tape;
+ tname = DA_TAPE_NAME;
+ dtype = DA_TAPE_TYPE;
+ dexec = DA_DEFAULT_TAPE_CLEAN;
+ } else if (flag & DA_RMDISK) {
+ dentry = dlist->rmdisk;
+ tname = DA_RMDISK_NAME;
+ dtype = DA_RMDISK_TYPE;
+ dexec = DA_DEFAULT_DISK_CLEAN;
+ } else {
+ return (-1);
+ }
+
+ for (nentry = dentry; nentry != NULL; nentry = nentry->next) {
+ pentry = nentry;
+ (void) sscanf(nentry->devinfo.devname, "%*[a-z]%d", &instance);
+ if (nentry->devinfo.instance == new_instance)
+ /*
+ * Add the new link name to the list of links
+ * that the device 'dname' has.
+ */
+ break;
+ }
+
+ if (nentry == NULL) {
+ /*
+ * Either this is the first entry ever, or no matching entry
+ * was found. Create a new one and add to the list.
+ */
+ if (dentry == NULL) /* first entry ever */
+ instance = 0;
+ else /* no matching entry */
+ instance++;
+ (void) snprintf(dname, sizeof (dname), "%s%d", tname, instance);
+ if ((nentry = (deventry_t *)malloc(sizeof (deventry_t))) ==
+ NULL)
+ return (-1);
+ if (pentry != NULL)
+ pentry->next = nentry;
+ new_entry = 1;
+ nentry->devinfo.devname = strdup(dname);
+ nentry->devinfo.devtype = dtype;
+ nentry->devinfo.devauths = DEFAULT_DEV_ALLOC_AUTH;
+ nentry->devinfo.devexec = dexec;
+ nentry->devinfo.instance = new_instance;
+ /*
+ * Look for default label range, authorizations and cleaning
+ * program in devalloc_defaults. If label range is not
+ * specified in devalloc_defaults, assume it to be admin_low
+ * to admin_high.
+ */
+ minstr = DA_DEFAULT_MIN;
+ maxstr = DA_DEFAULT_MAX;
+ setdadefent();
+ if (da_defs = getdadeftype(nentry->devinfo.devtype)) {
+ kva = da_defs->devopts;
+ if ((kval = kva_match(kva, DAOPT_MINLABEL)) != NULL)
+ minstr = strdup(kval);
+ if ((kval = kva_match(kva, DAOPT_MAXLABEL)) != NULL)
+ maxstr = strdup(kval);
+ if ((kval = kva_match(kva, DAOPT_AUTHS)) != NULL)
+ nentry->devinfo.devauths = strdup(kval);
+ if ((kval = kva_match(kva, DAOPT_CSCRIPT)) != NULL)
+ nentry->devinfo.devexec = strdup(kval);
+ freedadefent(da_defs);
+ }
+ enddadefent();
+ kval = NULL;
+ nlen = strlen(DAOPT_MINLABEL) + strlen(KV_ASSIGN) +
+ strlen(minstr) + strlen(KV_TOKEN_DELIMIT) +
+ strlen(DAOPT_MAXLABEL) + strlen(KV_ASSIGN) + strlen(maxstr)
+ + 1; /* +1 for terminator */
+ if (kval = (char *)malloc(nlen))
+ (void) snprintf(kval, nlen, "%s%s%s%s%s%s%s",
+ DAOPT_MINLABEL, KV_ASSIGN, minstr, KV_TOKEN_DELIMIT,
+ DAOPT_MAXLABEL, KV_ASSIGN, maxstr);
+ nentry->devinfo.devopts = kval;
+
+ nentry->devinfo.devlist = NULL;
+ nentry->next = NULL;
+ }
+
+ nlen = strlen(link) + 1; /* +1 terminator */
+ if (nentry->devinfo.devlist) {
+ plen = strlen(nentry->devinfo.devlist);
+ nlen = nlen + plen + 1; /* +1 for blank to separate entries */
+ } else {
+ plen = 0;
+ }
+
+ if ((nentry->devinfo.devlist =
+ (char *)realloc(nentry->devinfo.devlist, nlen)) == NULL) {
+ if (new_entry) {
+ nentry->devinfo.devname = NULL;
+ free(nentry->devinfo.devname);
+ nentry = NULL;
+ free(nentry);
+ if (pentry != NULL)
+ pentry->next = NULL;
+ }
+ return (-1);
+ }
+
+ if (plen == 0)
+ (void) snprintf(nentry->devinfo.devlist, nlen, "%s", link);
+ else
+ (void) snprintf(nentry->devinfo.devlist + plen, nlen - plen,
+ " %s", link);
+
+ if (pentry == NULL) {
+ /*
+ * This is the first entry of this device type.
+ */
+ if (flag & DA_AUDIO)
+ dlist->audio = nentry;
+ else if (flag & DA_CD)
+ dlist->cd = nentry;
+ else if (flag & DA_FLOPPY)
+ dlist->floppy = nentry;
+ else if (flag & DA_TAPE)
+ dlist->tape = nentry;
+ else if (flag & DA_RMDISK)
+ dlist->rmdisk = nentry;
+ }
+
+ return (0);
+}
+
+/*
+ * da_remove_list -
+ * removes a /dev link name from the linked list of devices.
+ * returns type of device if link for that device removed
+ * successfully, else returns -1 on error.
+ * if all links for a device are removed, stores that device
+ * name in devname.
+ */
+int
+da_remove_list(devlist_t *dlist, char *link, int type, char *devname, int size)
+{
+ int flag;
+ int remove_dev = 0;
+ int nlen, plen, slen;
+ char *lasts, *lname, *oldlist;
+ struct stat rmstat;
+ deventry_t *dentry, *current, *prev;
+
+ if (type != NULL)
+ flag = type;
+ else if (link == NULL)
+ return (-1);
+ else if (strstr(link, DA_AUDIO_NAME) || strstr(link, DA_SOUND_NAME))
+ flag = DA_AUDIO;
+ else if (strstr(link, "dsk") || strstr(link, "rdsk") ||
+ strstr(link, "sr") || strstr(link, "rsr"))
+ flag = DA_CD;
+ else if (strstr(link, "fd") || strstr(link, "rfd") ||
+ strstr(link, "diskette") || strstr(link, "rdiskette"))
+ flag = DA_FLOPPY;
+ else if (strstr(link, DA_TAPE_NAME))
+ flag = DA_TAPE;
+ else
+ flag = DA_RMDISK;
+
+ switch (type) {
+ case DA_AUDIO:
+ dentry = dlist->audio;
+ break;
+ case DA_CD:
+ dentry = dlist->cd;
+ break;
+ case DA_FLOPPY:
+ dentry = dlist->floppy;
+ break;
+ case DA_TAPE:
+ dentry = dlist->tape;
+ break;
+ case DA_RMDISK:
+ dentry = dlist->rmdisk;
+ break;
+ default:
+ return (-1);
+ }
+
+ if ((type != NULL) && (link == NULL)) {
+ for (current = dentry, prev = dentry; current != NULL;
+ current = current->next) {
+ oldlist = strdup(current->devinfo.devlist);
+ for (lname = strtok_r(oldlist, " ", &lasts);
+ lname != NULL;
+ lname = strtok_r(NULL, " ", &lasts)) {
+ if (stat(lname, &rmstat) != 0) {
+ remove_dev = 1;
+ goto remove_dev;
+ }
+ }
+ prev = current;
+ }
+ return (-1);
+ }
+
+ for (current = dentry, prev = dentry; current != NULL;
+ current = current->next) {
+ plen = strlen(current->devinfo.devlist);
+ nlen = strlen(link);
+ if (plen == nlen) {
+ if (strcmp(current->devinfo.devlist, link) == 0) {
+ /* last name in the list */
+ remove_dev = 1;
+ break;
+ }
+ }
+ if (strstr(current->devinfo.devlist, link)) {
+ nlen = plen - nlen + 1;
+ oldlist = strdup(current->devinfo.devlist);
+ if ((current->devinfo.devlist =
+ (char *)realloc(current->devinfo.devlist,
+ nlen)) == NULL) {
+ free(oldlist);
+ return (-1);
+ }
+ current->devinfo.devlist[0] = '\0';
+ nlen = plen = slen = 0;
+ for (lname = strtok_r(oldlist, " ", &lasts);
+ lname != NULL;
+ lname = strtok_r(NULL, " ", &lasts)) {
+ if (strcmp(lname, link) == 0)
+ continue;
+ nlen = strlen(lname) + plen + 1;
+ if (plen == 0) {
+ slen =
+ snprintf(current->devinfo.devlist,
+ nlen, "%s", lname);
+ } else {
+ slen =
+ snprintf(current->devinfo.devlist +
+ plen, nlen - plen, " %s",
+ lname);
+ }
+ plen = plen + slen + 1;
+ }
+ free(oldlist);
+ break;
+ }
+ prev = current;
+ }
+
+remove_dev:
+ if (remove_dev == 1) {
+ (void) strlcpy(devname, current->devinfo.devname, size);
+ free(current->devinfo.devname);
+ free(current->devinfo.devlist);
+ current->devinfo.devname = current->devinfo.devlist = NULL;
+ prev->next = current->next;
+ free(current);
+ current = NULL;
+ }
+ if ((remove_dev == 1) && (prev->devinfo.devname == NULL)) {
+ if (prev->next) {
+ /*
+ * what we removed above was the first entry
+ * in the list. make the next entry to be the
+ * first.
+ */
+ current = prev->next;
+ } else {
+ /*
+ * the matching entry was the only entry in the list
+ * for this type.
+ */
+ current = NULL;
+ }
+ if (flag & DA_AUDIO)
+ dlist->audio = current;
+ else if (flag & DA_CD)
+ dlist->cd = current;
+ else if (flag & DA_FLOPPY)
+ dlist->floppy = current;
+ else if (flag & DA_TAPE)
+ dlist->tape = current;
+ else if (flag & DA_RMDISK)
+ dlist->rmdisk = current;
+ }
+
+ return (flag);
+}
+
+/*
+ * da_is_on -
+ * checks if device allocation feature is turned on.
+ * returns 1 if on, 0 if off, -1 if status string not
+ * found in device_allocate.
+ */
+int
+da_is_on()
+{
+ return (getdaon());
+}
+
+/*
+ * da_print_device -
+ * debug routine to print device entries.
+ */
+void
+da_print_device(int flag, devlist_t *devlist)
+{
+ deventry_t *entry, *dentry;
+ devinfo_t *devinfo;
+
+ if (flag & DA_AUDIO)
+ dentry = devlist->audio;
+ else if (flag & DA_CD)
+ dentry = devlist->cd;
+ else if (flag & DA_FLOPPY)
+ dentry = devlist->floppy;
+ else if (flag & DA_TAPE)
+ dentry = devlist->tape;
+ else if (flag & DA_RMDISK)
+ dentry = devlist->rmdisk;
+ else
+ return;
+
+ for (entry = dentry; entry != NULL; entry = entry->next) {
+ devinfo = &(entry->devinfo);
+ (void) fprintf(stdout, "name: %s\n", devinfo->devname);
+ (void) fprintf(stdout, "type: %s\n", devinfo->devtype);
+ (void) fprintf(stdout, "auth: %s\n", devinfo->devauths);
+ (void) fprintf(stdout, "exec: %s\n", devinfo->devexec);
+ (void) fprintf(stdout, "list: %s\n\n", devinfo->devlist);
+ }
+}
diff --git a/usr/src/lib/libbsm/common/devalloc.h b/usr/src/lib/libbsm/common/devalloc.h
new file mode 100644
index 0000000000..7952a302f5
--- /dev/null
+++ b/usr/src/lib/libbsm/common/devalloc.h
@@ -0,0 +1,185 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _DEVALLOC_H
+#define _DEVALLOC_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/param.h>
+#include <secdb.h>
+
+/*
+ * These are unsupported, SUNWprivate interfaces.
+ */
+
+#define DA_UID (uid_t)0 /* root */
+#define DA_GID (gid_t)3 /* sys */
+#define LOGINDEVPERM "/etc/logindevperm"
+#define DA_DB_LOCK "/etc/security/.da_db_lock"
+#define DA_DEV_LOCK "/etc/security/.da_dev_lock"
+#define DEVALLOC "/etc/security/device_allocate"
+#define DEVMAP "/etc/security/device_maps"
+#define DEFATTRS "/etc/security/tsol/devalloc_defaults"
+#define TMPALLOC "/etc/security/.device_allocate"
+#define TMPMAP "/etc/security/.device_maps"
+#define TMPATTRS "/etc/security/tsol/.devalloc_defaults"
+
+#define DA_DEFAULT_MIN "admin_low"
+#define DA_DEFAULT_MAX "admin_high"
+#define DA_DEFAULT_CLEAN "/bin/true"
+#define DA_DEFAULT_AUDIO_CLEAN "/etc/security/lib/audio_clean_wrapper"
+#define DA_DEFAULT_DISK_CLEAN "/etc/security/lib/disk_clean"
+#define DA_DEFAULT_TAPE_CLEAN "/etc/security/lib/st_clean"
+
+#define DA_ON_STR "DEVICE_ALLOCATION=ON\n"
+#define DA_OFF_STR "DEVICE_ALLOCATION=OFF\n"
+#define DA_IS_LABELED "system_labeled"
+#define DA_LABEL_CHECK "/usr/bin/plabel"
+#define DA_DBMODE 0644
+#define DA_COUNT 5 /* allocatable devices suppported */
+ /* audio, cd, floppy, rmdisk, tape */
+#define DA_AUTHLEN MAX_CANON /* approx. sum of strlen of all */
+ /* device auths in auth_list.h */
+#define DA_MAXNAME 80
+#define DA_BUFSIZE 4096
+
+#define DA_RDWR O_RDWR|O_CREAT|O_NONBLOCK
+#define DA_RDONLY O_RDONLY|O_NONBLOCK
+
+#define DA_ANYUSER "*"
+#define DA_NOUSER "@"
+
+#define ALLOC_UID (uid_t)0 /* root */
+#define ALLOC_GID (gid_t)3 /* sys */
+#define ALLOC_ERRID (uid_t)2 /* bin */
+#define ALLOC_MODE 0600
+#define DEALLOC_MODE 0000
+
+#define DA_SILENT 0x00000001
+#define DA_VERBOSE 0x00000002
+#define DA_ADD 0x00000004
+#define DA_REMOVE 0x00000008
+#define DA_UPDATE 0x00000010
+#define DA_ADD_ZONE 0x00000020
+#define DA_REMOVE_ZONE 0x00000040
+#define DA_FORCE 0x00000080
+#define DA_ALLOC_ONLY 0x00000100
+#define DA_MAPS_ONLY 0x00000200
+#define DA_ON 0x00000400
+#define DA_OFF 0x00000800
+#define DA_NO_OVERRIDE 0x00001000
+#define DA_DEFATTRS 0x00002000
+
+#define DA_AUDIO 0x00001000
+#define DA_CD 0x00002000
+#define DA_FLOPPY 0x00004000
+#define DA_TAPE 0x00008000
+#define DA_RMDISK 0x00010000
+
+#define DA_AUDIO_NAME "audio"
+#define DA_SOUND_NAME "sound"
+#define DA_AUDIO_TYPE DA_AUDIO_NAME
+#define DA_AUDIO_DIR "/dev/sound/"
+
+#define DA_CD_NAME "cdrom"
+#define DA_CD_TYPE "sr"
+
+#define DA_DISK_DIR "/dev/dsk/"
+#define DA_DISK_DIRR "/dev/rdsk/"
+#define DA_DISKR_DIR "/dev/(r)dsk"
+
+#define DA_FLOPPY_NAME "floppy"
+#define DA_FLOPPY_TYPE "fd"
+
+#define DA_RMDISK_NAME "rmdisk"
+#define DA_RMDISK_TYPE DA_RMDISK_NAME
+
+#define DA_TAPE_NAME "tape"
+#define DA_TAPE_DIR "/dev/rmt/"
+#define DA_TAPE_TYPE "st"
+
+typedef struct _devinfo_t {
+ char *devname;
+ char *devtype;
+ char *devauths;
+ char *devexec;
+ char *devopts;
+ char *devlist;
+ int instance;
+} devinfo_t;
+
+typedef struct _deventry_t {
+ devinfo_t devinfo;
+ struct _deventry_t *next;
+} deventry_t;
+
+typedef struct _devlist_t {
+ deventry_t *audio;
+ deventry_t *cd;
+ deventry_t *floppy;
+ deventry_t *tape;
+ deventry_t *rmdisk;
+} devlist_t;
+
+typedef struct _da_optargs {
+ int optflag;
+ char *rootdir;
+ char **devnames;
+ devinfo_t *devinfo;
+} da_args;
+
+typedef struct _da_defs {
+ char *devtype;
+ kva_t *devopts;
+} da_defs_t;
+
+da_defs_t *getdadefent(void);
+da_defs_t *getdadeftype(char *);
+void freedadefent(da_defs_t *);
+void setdadefent(void);
+void enddadefent(void);
+int da_is_on(void);
+int da_check_logindevperm(char *);
+int da_open_devdb(char *, FILE **, FILE **, int);
+int da_update_device(da_args *);
+int da_update_defattrs(da_args *);
+int da_add_list(devlist_t *, char *, int, int);
+int da_remove_list(devlist_t *, char *, int, char *, int);
+void da_print_device(int, devlist_t *);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DEVALLOC_H */
diff --git a/usr/src/lib/libbsm/common/devices.h b/usr/src/lib/libbsm/common/devices.h
index 609a0aeb1a..04a3edceea 100644
--- a/usr/src/lib/libbsm/common/devices.h
+++ b/usr/src/lib/libbsm/common/devices.h
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -33,36 +32,55 @@
extern "C" {
#endif
-typedef struct { /* see getdmapent(3) */
- char *dmap_devname;
- char *dmap_devtype;
- char *dmap_devlist;
-} devmap_t;
+#include <stdio.h>
+#include <secdb.h>
+
+/*
+ * These are unsupported, SUN-private interfaces.
+ */
-devmap_t *getdmapent(void);
-devmap_t *getdmaptype(char *);
-devmap_t *getdmapnam(char *);
-devmap_t *getdmapdev(char *);
-void setdmapent(void);
-void enddmapent(void);
-void setdmapfile(char *);
+#define DAOPT_AUTHS "auths"
+#define DAOPT_CSCRIPT "cleanscript"
+#define DAOPT_MINLABEL "minlabel"
+#define DAOPT_MAXLABEL "maxlabel"
+#define DAOPT_ZONE "zone"
+#define DA_RESERVED "reserved"
-typedef struct { /* see getdaent(3) */
- char *da_devname;
- char *da_devtype;
- char *da_devmin;
- char *da_devmax;
- char *da_devauth;
- char *da_devexec;
+typedef struct {
+ char *da_devname;
+ char *da_devtype;
+ char *da_devauth;
+ char *da_devexec;
+ kva_t *da_devopts;
} devalloc_t;
-devalloc_t *getdaent(void);
-devalloc_t *getdatype(char *);
-devalloc_t *getdanam(char *);
-devalloc_t *getdadev(char *);
-void setdaent(void);
-void enddaent(void);
-void setdafile(char *);
+typedef struct {
+ char *dmap_devname;
+ char *dmap_devtype;
+ char *dmap_devlist;
+ char **dmap_devarray;
+} devmap_t;
+
+int getdadmline(char *, int, FILE *);
+
+devalloc_t *getdaent(void);
+devalloc_t *getdatype(char *);
+devalloc_t *getdanam(char *);
+void setdaent(void);
+void enddaent(void);
+void freedaent(devalloc_t *);
+void setdafile(char *);
+
+devmap_t *getdmapent(void);
+devmap_t *getdmaptype(char *);
+devmap_t *getdmapnam(char *);
+devmap_t *getdmapdev(char *);
+void setdmapent(void);
+void enddmapent(void);
+void freedmapent(devmap_t *);
+void setdmapfile(char *);
+char *getdmapfield(char *);
+char *getdmapdfield(char *);
#ifdef __cplusplus
}
diff --git a/usr/src/lib/libbsm/common/generic.c b/usr/src/lib/libbsm/common/generic.c
index 457b2e8c37..d5953826b9 100644
--- a/usr/src/lib/libbsm/common/generic.c
+++ b/usr/src/lib/libbsm/common/generic.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -37,6 +36,7 @@
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
+#include <tsol/label.h>
#include <bsm/audit.h>
#include <bsm/libbsm.h>
#include <bsm/audit_uevents.h>
@@ -426,6 +426,9 @@ aug_audit(void)
(void) au_write(ad, au_to_newgroups(ng, grplst));
}
}
+ if (is_system_labeled())
+ (void) au_write(ad, au_to_mylabel());
+
if (aug_text != NULL) {
(void) au_write(ad, au_to_text(aug_text));
}
diff --git a/usr/src/lib/libbsm/common/getdadefs.c b/usr/src/lib/libbsm/common/getdadefs.c
new file mode 100644
index 0000000000..3f62566293
--- /dev/null
+++ b/usr/src/lib/libbsm/common/getdadefs.c
@@ -0,0 +1,234 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <string.h>
+#include <stdlib.h>
+#include <bsm/devices.h>
+#include <bsm/devalloc.h>
+
+char *strtok_r(char *, const char *, char **);
+
+/* externs from getdaent.c */
+extern char *trim_white(char *);
+extern int pack_white(char *);
+extern char *getdadmfield(char *, char *);
+extern int getdadmline(char *, int, FILE *);
+
+extern char *_strdup_null(char *);
+
+static struct _dadefbuff {
+ FILE *_dadeff;
+ /* pointer into /etc/security/tsol/devalloc_defaults */
+ da_defs_t _interpdadefs;
+ char _interpdadefline[DA_BUFSIZE + 1];
+ char *_DADEFS;
+} *__dadefbuff;
+
+#define dadeff (_df->_dadeff)
+#define interpdadefs (_df->_interpdadefs)
+#define interpdadefline (_df->_interpdadefline)
+#define DADEFS_FILE (_df->_DADEFS)
+
+static da_defs_t *dadef_interpret(char *);
+int dadef_matchtype(da_defs_t *, char *);
+
+/*
+ * _dadefalloc -
+ * allocates common buffers and structures.
+ * returns pointer to the new structure, else returns NULL on error.
+ */
+static struct _dadefbuff *
+_dadefalloc(void)
+{
+ struct _dadefbuff *_df = __dadefbuff;
+
+ if (_df == NULL) {
+ _df = (struct _dadefbuff *)calloc((unsigned)1,
+ (unsigned)sizeof (*__dadefbuff));
+ if (_df == NULL)
+ return (NULL);
+ DADEFS_FILE = "/etc/security/tsol/devalloc_defaults";
+ __dadefbuff = _df;
+ }
+
+ return (__dadefbuff);
+}
+
+/*
+ * setdadefent -
+ * rewinds devalloc_defaults file to the begining.
+ */
+
+void
+setdadefent(void)
+{
+ struct _dadefbuff *_df = _dadefalloc();
+
+ if (_df == NULL)
+ return;
+ if (dadeff == NULL)
+ dadeff = fopen(DADEFS_FILE, "r");
+ else
+ rewind(dadeff);
+}
+
+/*
+ * enddadefent -
+ * closes devalloc_defaults file.
+ */
+
+void
+enddadefent(void)
+{
+ struct _dadefbuff *_df = _dadefalloc();
+
+ if (_df == NULL)
+ return;
+ if (dadeff != NULL) {
+ (void) fclose(dadeff);
+ dadeff = NULL;
+ }
+}
+
+void
+freedadefent(da_defs_t *da_def)
+{
+ if (da_def == NULL)
+ return;
+ _kva_free(da_def->devopts);
+ da_def->devopts = NULL;
+}
+
+/*
+ * getdadefent -
+ * When first called, returns a pointer to the first da_defs_t
+ * structure in devalloc_defaults; thereafter, it returns a pointer to the
+ * next da_defs_t structure in the file. Thus, successive calls can be
+ * used to search the entire file.
+ * call to getdadefent should be bracketed by setdadefent and enddadefent.
+ * returns NULL on error.
+ */
+da_defs_t *
+getdadefent(void)
+{
+ char line1[DA_BUFSIZE + 1];
+ da_defs_t *da_def;
+ struct _dadefbuff *_df = _dadefalloc();
+
+ if ((_df == 0) || (dadeff == NULL))
+ return (NULL);
+
+ while (getdadmline(line1, (int)sizeof (line1), dadeff) != 0) {
+ if ((da_def = dadef_interpret(line1)) == NULL)
+ continue;
+ return (da_def);
+ }
+
+ return (NULL);
+}
+
+/*
+ * getdadeftype -
+ * searches from the beginning of devalloc_defaults for the device
+ * specified by its type.
+ * call to getdadeftype should be bracketed by setdadefent and enddadefent.
+ * returns pointer to da_defs_t for the device if it is found, else
+ * returns NULL if device not found or in case of error.
+ */
+da_defs_t *
+getdadeftype(char *type)
+{
+ char line1[DA_BUFSIZE + 1];
+ da_defs_t *da_def;
+ struct _dadefbuff *_df = _dadefalloc();
+
+ if ((type == NULL) || (_df == NULL) || (dadeff == NULL))
+ return (NULL);
+
+ while (getdadmline(line1, (int)sizeof (line1), dadeff) != 0) {
+ if (strstr(line1, type) == NULL)
+ continue;
+ if ((da_def = dadef_interpret(line1)) == NULL)
+ continue;
+ if (dadef_matchtype(da_def, type))
+ return (da_def);
+ freedadefent(da_def);
+ }
+
+ return (NULL);
+}
+
+/*
+ * dadef_matchtype -
+ * checks if the specified da_defs_t is for the device type specified.
+ * returns 1 if match found, else, returns 0.
+ */
+int
+dadef_matchtype(da_defs_t *da_def, char *type)
+{
+ if (da_def->devtype == NULL)
+ return (0);
+
+ return ((strcmp(da_def->devtype, type) == 0));
+}
+
+/*
+ * dadef_interpret -
+ * parses val and initializes pointers in da_defs_t.
+ * returns pointer to parsed da_defs_t entry, else returns NULL on error.
+ */
+static da_defs_t *
+dadef_interpret(char *val)
+{
+ struct _dadefbuff *_df = _dadefalloc();
+ int i;
+ char *opts;
+ kva_t *kvap;
+ kv_t *kvp;
+
+ if (_df == NULL)
+ return (NULL);
+
+ (void) strcpy(interpdadefline, val);
+ interpdadefs.devtype = getdadmfield(interpdadefline, KV_TOKEN_DELIMIT);
+ opts = getdadmfield(NULL, KV_TOKEN_DELIMIT);
+ interpdadefs.devopts = NULL;
+ if (interpdadefs.devtype == NULL)
+ return (NULL);
+ if (opts != NULL)
+ interpdadefs.devopts =
+ _str2kva(opts, KV_ASSIGN, KV_DELIMITER);
+ /* remove any extraneous whitespace in the options */
+ if ((kvap = interpdadefs.devopts) != NULL) {
+ for (i = 0, kvp = kvap->data; i < kvap->length; i++, kvp++) {
+ (void) pack_white(kvp->key);
+ (void) pack_white(kvp->value);
+ }
+ }
+
+ return (&interpdadefs);
+}
diff --git a/usr/src/lib/libbsm/common/getdaent.c b/usr/src/lib/libbsm/common/getdaent.c
index f461015dbc..2deb5a65d6 100644
--- a/usr/src/lib/libbsm/common/getdaent.c
+++ b/usr/src/lib/libbsm/common/getdaent.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -19,320 +18,242 @@
*
* CDDL HEADER END
*/
-
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
-#include <stdio.h>
+#ifndef lint
+static char sccsid[] = "%Z%%M% %I% %E% SMI";
+#endif
+
+#include <ctype.h>
#include <string.h>
-#include <malloc.h>
+#include <stdlib.h>
+#include <tsol/label.h>
#include <bsm/devices.h>
+#include <bsm/devalloc.h>
-#define MAXINT 0x7fffffff;
-#ifdef SunOS_CMW
-extern char *calloc();
-#endif
+extern char *_strdup_null(char *);
static struct _dabuff {
- devalloc_t _NULLDA;
- FILE *_daf; /* pointer into /etc/security/device_allocate */
- devalloc_t _interpdevalloc;
- char _interpline[BUFSIZ + 1];
- char *_DEVALLOC;
+ FILE *_daf; /* pointer into /etc/security/device_allocate */
+ devalloc_t _interpdevalloc;
+ char _interpdaline[DA_BUFSIZE + 1];
+ char *_DEVALLOC;
} *__dabuff;
-#define NULLDA (_da->_NULLDA)
-#define daf (_da->_daf)
-#define interpdevalloc (_da->_interpdevalloc)
-#define interpline (_da->_interpline)
-#define DEVALLOC (_da->_DEVALLOC)
-static devalloc_t *interpret();
-static int matchname();
+#define daf (_da->_daf)
+#define interpdevalloc (_da->_interpdevalloc)
+#define interpdaline (_da->_interpdaline)
+#define DEVALLOC_FILE (_da->_DEVALLOC)
+static devalloc_t *da_interpret(char *);
+
+int da_matchname(devalloc_t *, char *);
+int da_matchtype(devalloc_t *, char *);
+
+static int system_labeled = 0;
/*
- * trim_white(ptr) trims off leading and trailing white space from a NULL
- * terminated string pointed to by "ptr". The leading white space is skipped
- * by moving the pointer forward. The trailing white space is removed by
- * nulling the white space characters. The pointer is returned to the white
- * string. If the resulting string is null in length then a NULL pointer is
- * returned. If "ptr" is NULL then a NULL pointer is returned.
+ * trim_white -
+ * trims off leading and trailing white space from input string.
+ * The leading white space is skipped by moving the pointer forward.
+ * The trailing white space is removed by nulling the white space
+ * characters.
+ * returns pointer to non-white string, else returns NULL if input string
+ * is null or if the resulting string has zero length.
*/
-static char *
-trim_white(ptr)
-char *ptr;
+char *
+trim_white(char *ptr)
{
- register char *tptr;
- register int cnt;
+ char *tptr;
+
if (ptr == NULL)
return (NULL);
- while ((*ptr == ' ') || (*ptr == '\t')) {
+ while (isspace(*ptr))
ptr++;
- }
- cnt = strlen(ptr);
- if (cnt != 0) {
- tptr = ptr + cnt - 1;
- while ((*tptr == ' ') || (*tptr == '\t')) {
- *tptr = '\0';
- tptr--;
- }
- }
- if (*ptr == NULL)
+ tptr = ptr + strlen(ptr);
+ while (tptr != ptr && isspace(tptr[-1]))
+ --tptr;
+ *tptr = '\0';
+ if (*ptr == '\0')
return (NULL);
+
return (ptr);
}
-
/*
- * scan string pointed to by pointer "p"
- * find next colin or end of line. Null it and
- * return pointer to next char.
+ * pack_white -
+ * trims off multiple occurrences of white space from input string.
+ * returns the number of spaces retained
*/
-static char *
-daskip(p)
-register char *p;
+int
+pack_white(char *ptr)
{
- while (*p && *p != ';' && *p != '\n')
- ++p;
- if (*p == '\n')
- *p = '\0';
- else if (*p != '\0')
- *p++ = '\0';
- return (p);
-}
+ int cnt = 0;
+ char *tptr, ch;
+ if (ptr == NULL)
+ return (0);
+ tptr = ptr;
+ while (isspace(*tptr))
+ tptr++;
+ for (;;) {
+ while ((ch = *tptr) != '\0' && !isspace(ch)) {
+ *ptr++ = ch;
+ tptr++;
+ }
+ while (isspace(*tptr))
+ tptr++;
+ if (*tptr == '\0')
+ break;
+ *ptr++ = ' ';
+ cnt++;
+ }
+ *ptr = '\0';
-/*
- * scan string pointed to by pointer "p"
- * find next colin or end of line. Null it and
- * return pointer to next char.
- */
-static char *
-dadskip(p)
-register char *p;
-{
- while (*p && *p != ' ' && *p != '\n')
- ++p;
- if (*p != '\0')
- *p++ = '\0';
- return (p);
+ return (cnt);
}
-
/*
- * _daalloc() allocates common buffers and structures used by the device
- * allocate library routines. Then returns a pointer to a structure. The
- * returned pointer will be null if there is an error condition.
+ * getdadmline -
+ * reads one device_alloc/device_maps line from stream into buff of len
+ * bytes. Continued lines from stream are concatenated into one line in
+ * buff. Comments are removed from buff.
+ * returns the number of characters in buff, else returns 0 if no
+ * characters are read or an error occurred.
*/
-static struct _dabuff *
-_daalloc()
+int
+getdadmline(char *buff, int len, FILE *stream)
{
- register struct _dabuff *_da = __dabuff;
-
- if (_da == 0) {
- _da = (struct _dabuff *)
- calloc((size_t)1, sizeof (*__dabuff));
- if (_da == 0)
- return (0);
- DEVALLOC = "/etc/security/device_allocate";
- __dabuff = _da;
- }
- return (__dabuff);
-}
+ int tmpcnt;
+ int charcnt = 0;
+ int fileerr = 0;
+ int contline = 0;
+ char *cp;
+ char *ccp;
-
-/*
- * getdaline(buff,len,stream) reads one device allocate line from "stream" into
- * "buff" on "len" bytes. Continued lines from "stream" are concatinated
- * into one line in "buff". Comments are removed from "buff". The number of
- * characters in "buff" is returned. If no characters are read or an err or
- * occured then "0" is returned
- */
-static int
-getdaline(buff, len, stream)
- char *buff;
- int len;
- FILE *stream;
-{
- register struct _dabuff *_da = _daalloc();
- char *cp;
- char *ccp;
- int tmpcnt;
- int charcnt = 0;
- int fileerr = 0;
- int contline;
- if (_da == 0)
- return (0);
do {
cp = buff;
*cp = NULL;
do {
+ contline = 0;
if (fgets(cp, len - charcnt, stream) == NULL) {
fileerr = 1;
break;
}
- ccp = strpbrk(cp, "\\\n");
+ ccp = strchr(cp, '\n');
if (ccp != NULL) {
- if (*ccp == '\\')
+ if (ccp != cp && ccp[-1] == '\\') {
+ ccp--;
contline = 1;
- else
+ }
+ else
contline = 0;
*ccp = NULL;
}
tmpcnt = strlen(cp);
- if (tmpcnt != 0) {
- cp += tmpcnt;
- charcnt += tmpcnt;
- }
+ cp += tmpcnt;
+ charcnt += tmpcnt;
} while ((contline) || (charcnt == 0));
ccp = strpbrk(buff, "#");
if (ccp != NULL)
*ccp = NULL;
charcnt = strlen(buff);
} while ((fileerr == 0) && (charcnt == 0));
- if (fileerr)
+
+ if (fileerr && !charcnt)
return (0);
- else
+ else
return (charcnt);
}
-char *
-getdafield(ptr)
-char *ptr;
-{
- static char *tptr;
- if (ptr == NULL)
- ptr = tptr;
- if (ptr == NULL)
- return (NULL);
- tptr = daskip(ptr);
- ptr = trim_white(ptr);
- if (ptr == NULL)
- return (NULL);
- if (*ptr == NULL)
- return (NULL);
- return (ptr);
-}
-
-char *
-getdadfield(ptr)
-char *ptr;
-{
- static char *tptr;
- if (ptr != NULL) {
- ptr = trim_white(ptr);
- } else {
- ptr = tptr;
- }
- if (ptr == NULL)
- return (NULL);
- tptr = dadskip(ptr);
- if (ptr == NULL)
- return (NULL);
- if (*ptr == NULL)
- return (NULL);
- return (ptr);
-}
-
/*
- * getdadev(dev) searches from the beginning of the file until a logical
- * device matching "dev" is found and returns a pointer to the particular
- * structure in which it was found. If an EOF or an error is encountered on
- * reading, these functions return a NULL pointer.
+ * _daalloc -
+ * allocates common buffers and structures.
+ * returns pointer to the new structure, else returns NULL on error.
*/
-#ifdef NOTDEF
-devalloc_t *
-getdadev(name)
- register char *name;
+static struct _dabuff *
+_daalloc(void)
{
- register struct _dabuff *_da = _daalloc();
- devalloc_t *da;
- char line[BUFSIZ + 1];
+ struct _dabuff *_da = __dabuff;
- if (_da == 0)
- return (0);
- setdaent();
- if (!daf)
- return ((devalloc_t *)NULL);
- while (getdaline(line, sizeof (line), daf) != 0) {
- if ((da = interpret(line)) == NULL)
- continue;
- if (matchdev(&da, name)) {
- enddaent();
- return (da);
- }
+ if (_da == NULL) {
+ _da = (struct _dabuff *)calloc((unsigned)1,
+ (unsigned)sizeof (*__dabuff));
+ if (_da == NULL)
+ return (NULL);
+ DEVALLOC_FILE = "/etc/security/device_allocate";
+ daf = NULL;
+ __dabuff = _da;
+ system_labeled = is_system_labeled();
}
- enddaent();
- return ((devalloc_t *)NULL);
-}
-
-#endif /* NOTDEF */
+ return (__dabuff);
+}
/*
- * getdanam(name) searches from the beginning of the file until a audit-name
- * matching "name" is found and returns a pointer to the particular structure
- * in which it was found. If an EOF or an error is encountered on reading,
- * these functions return a NULL pointer.
+ * getdadmfield -
+ * gets individual fields separated by skip in ptr.
*/
-devalloc_t *
-getdanam(name)
- register char *name;
+char *
+getdadmfield(char *ptr, char *skip)
{
- register struct _dabuff *_da = _daalloc();
- devalloc_t *da;
- char line[BUFSIZ + 1];
+ static char *tptr = NULL;
+ char *pend;
- if (_da == 0)
- return (0);
- setdaent();
- if (!daf)
- return ((devalloc_t *)NULL);
- while (getdaline(line, (int)sizeof (line), daf) != 0) {
- if ((da = interpret(line)) == NULL)
- continue;
- if (matchname(&da, name)) {
- enddaent();
- return (da);
- }
- }
- enddaent();
- return ((devalloc_t *)NULL);
-}
+ /* check for a continuing search */
+ if (ptr == NULL)
+ ptr = tptr;
+ /* check for source end */
+ if (ptr == NULL || *ptr == '\0')
+ return (NULL);
+ /* find terminator */
+ pend = strpbrk(ptr, skip);
+ /* terminate and set continuation pointer */
+ if (pend != NULL) {
+ *pend++ = '\0';
+ tptr = pend;
+ } else
+ tptr = NULL;
+ /*
+ * trim off any surrounding white space, return what's left
+ */
+ return (trim_white(ptr));
+}
/*
- * setdaent() essentially rewinds the device_allocate file to the begining.
+ * setdaent -
+ * rewinds the device_allocate file to the begining.
*/
void
-setdaent()
+setdaent(void)
{
- register struct _dabuff *_da = _daalloc();
+ struct _dabuff *_da = _daalloc();
- if (_da == 0)
+ if (_da == NULL)
return;
- if (daf == NULL) {
- daf = fopen(DEVALLOC, "r");
- } else
+ if (daf == NULL)
+ daf = fopen(DEVALLOC_FILE, "r");
+ else
rewind(daf);
}
-
/*
- * enddaent() may be called to close the device_allocate file when processing
- * is complete.
+ * enddaent -
+ * closes device_allocate file.
*/
void
-enddaent()
+enddaent(void)
{
- register struct _dabuff *_da = _daalloc();
+ struct _dabuff *_da = _daalloc();
- if (_da == 0)
+ if (_da == NULL)
return;
if (daf != NULL) {
(void) fclose(daf);
@@ -340,173 +261,294 @@ enddaent()
}
}
-
/*
- * setdafile(name) changes the default device_allocate file to "name" thus
- * allowing alternate device_allocate files to be used. Note: it does not
- * close the previous file . If this is desired, enddaent should be called
- * prior to it.
+ * setdafile -
+ * changes the default device_allocate file to the one specified.
+ * It does not close the previous file. If this is desired, enddaent
+ * should be called prior to setdafile.
*/
void
-setdafile(file)
-char *file;
+setdafile(char *file)
{
- register struct _dabuff *_da = _daalloc();
+ struct _dabuff *_da = _daalloc();
- if (_da == 0)
+ if (_da == NULL)
return;
if (daf != NULL) {
(void) fclose(daf);
daf = NULL;
}
- DEVALLOC = file;
+ DEVALLOC_FILE = file;
}
+void
+freedaent(devalloc_t *dap)
+{
+ if (dap == NULL)
+ return;
+ _kva_free(dap->da_devopts);
+ dap->da_devopts = NULL;
+}
/*
- * getdatype(tp) When first called, returns a pointer to the
- * first devalloc_t structure in the file with device-type matching
- * "tp"; thereafter, it returns a pointer to the next devalloc_t
- * structure in the file with device-type matching "tp".
- * Thus successive calls can be used to search the
- * entire file for entries having device-type matching "tp".
- * A null pointer is returned on error.
+ * getdaon -
+ * checks if device_allocate has string DEVICE_ALLOCATION=ON or
+ * DEVICE_ALLOCATION=OFF string in it.
+ * returns 1 if the string is DEVICE_ALLOCATION=ON, 0 if it is
+ * DEVICE_ALLOCATION=OFF, -1 if neither string present.
+ */
+int
+getdaon()
+{
+ int is_on = -1;
+ char line1[DA_BUFSIZE + 1];
+ struct _dabuff *_da = _daalloc();
+
+ setdaent();
+ if ((_da == NULL) || (daf == NULL)) {
+ enddaent();
+ return (is_on);
+ }
+ while (getdadmline(line1, (int)sizeof (line1), daf) != 0) {
+ if (strncmp(line1, DA_ON_STR, (strlen(DA_ON_STR) - 1)) == 0) {
+ is_on = 1;
+ break;
+ } else if (strncmp(line1, DA_OFF_STR,
+ (strlen(DA_OFF_STR) - 1)) == 0) {
+ is_on = 0;
+ break;
+ }
+ }
+ enddaent();
+
+ return (is_on);
+}
+
+/*
+ * getdaent -
+ * When first called, returns a pointer to the first devalloc_t
+ * structure in device_allocate; thereafter, it returns a pointer to the
+ * next devalloc_t structure in the file. Thus, successive calls can be
+ * used to search the entire file.
+ * call to getdaent should be bracketed by setdaent and enddaent.
+ * returns NULL on error.
*/
devalloc_t *
-getdatype(tp)
- char *tp;
+getdaent(void)
{
- register struct _dabuff *_da = _daalloc();
- char line1[BUFSIZ + 1];
- devalloc_t *da;
+ char line1[DA_BUFSIZE + 1];
+ devalloc_t *da;
+ struct _dabuff *_da = _daalloc();
- if (_da == 0)
- return (0);
- if (daf == NULL && (daf = fopen(DEVALLOC, "r")) == NULL) {
+ if ((_da == 0) || (daf == NULL))
return (NULL);
+
+ while (getdadmline(line1, (int)sizeof (line1), daf) != 0) {
+ if ((strncmp(line1, DA_ON_STR, (strlen(DA_ON_STR) - 1)) == 0) ||
+ (strncmp(line1, DA_OFF_STR, (strlen(DA_OFF_STR) - 1)) == 0))
+ continue;
+ if ((da = da_interpret(line1)) == NULL)
+ continue;
+ return (da);
}
- do {
- if (getdaline(line1, (int)sizeof (line1), daf) == 0)
- return (NULL);
- if ((da = interpret(line1)) == NULL)
- return (NULL);
- } while (strcmp(tp, da->da_devtype) != 0);
- return (da);
+ return (NULL);
}
-
/*
- * getdaent() When first called, returns a pointer to the first devalloc_t
- * structure in the file; thereafter, it returns a pointer to the next
- * devalloc_t structure in the file. Thus successive calls can be used to
- * search the entire file. A null pointer is returned on error.
+ * getdanam
+ * searches from the beginning of device_allocate for the device specified
+ * by its name.
+ * call to getdanam should be bracketed by setdaent and enddaent.
+ * returns pointer to devalloc_t for the device if it is found, else
+ * returns NULL if device not found or in case of error.
*/
devalloc_t *
-getdaent()
+getdanam(char *name)
{
- register struct _dabuff *_da = _daalloc();
- char line1[BUFSIZ + 1];
- devalloc_t *da;
+ char line[DA_BUFSIZE + 1];
+ devalloc_t *da;
+ struct _dabuff *_da = _daalloc();
- if (_da == 0)
- return (0);
- if (daf == NULL && (daf = fopen(DEVALLOC, "r")) == NULL) {
+ if ((name == NULL) || (_da == 0) || (daf == NULL))
return (NULL);
+
+ while (getdadmline(line, (int)sizeof (line), daf) != 0) {
+ if (strstr(line, name) == NULL)
+ continue;
+ if ((da = da_interpret(line)) == NULL)
+ continue;
+ if (da_matchname(da, name)) {
+ enddaent();
+ return (da);
+ }
+ freedaent(da);
}
- if (getdaline(line1, (int)sizeof (line1), daf) == 0)
- return (NULL);
- if ((da = interpret(line1)) == NULL)
- return (NULL);
- return (da);
+ return (NULL);
}
-
/*
- * matchdev(dap,dev) The dev_list in the structure pointed to by "dap" is
- * searched for string "dev". If a match occures then a "1" is returned
- * otherwise a "0" is returned.
+ * getdatype -
+ * searches from the beginning of device_allocate for the device specified
+ * by its type.
+ * call to getdatype should be bracketed by setdaent and enddaent.
+ * returns pointer to devalloc_t for the device if it is found, else
+ * returns NULL if device not found or in case of error.
*/
-#ifdef NOTDEF
-static
-matchdev(dap, dev)
- devalloc_t **dap;
- char *dev;
+devalloc_t *
+getdatype(char *type)
{
- register struct _dabuff *_da = _daalloc();
- devalloc_t *da = *dap;
- char tmpdev[BUFSIZ + 1];
- int charcnt;
- int tmpcnt;
- char *cp;
- char *tcp;
- char *last;
-
- charcnt = strlen(dev);
- if (_da == 0)
- return (0);
- if (da->da_devlist == NULL)
- return (0);
- (void) strcpy(tmpdev, da->da_devlist);
- tcp = tmpdev;
- while ((cp = strtok_r(tcp, " ", &last)) != NULL) {
- tcp = NULL;
- tmpcnt = strlen(cp);
- if (tmpcnt != charcnt)
+ char line1[DA_BUFSIZE + 1];
+ devalloc_t *da;
+ struct _dabuff *_da = _daalloc();
+
+ if ((type == NULL) || (_da == NULL) || (daf == NULL))
+ return (NULL);
+
+ while (getdadmline(line1, (int)sizeof (line1), daf) != 0) {
+ if (strstr(line1, type) == NULL)
+ continue;
+ if ((da = da_interpret(line1)) == NULL)
continue;
- if (strcmp(cp, dev) == 0)
- return (1);
+ if (da_matchtype(da, type))
+ return (da);
+ freedaent(da);
}
- return (0);
+
+ return (NULL);
}
-#endif /* NOTDEF */
/*
- * matchname(dap,name) The audit-name in the structure pointed to by "dap" is
- * searched for string "name". If a match occures then a "1" is returned
- * otherwise a "0" is returned.
+ * da_matchname -
+ * checks if the specified devalloc_t is for the device specified.
+ * returns 1 if it is, else returns 0.
*/
-static int
-matchname(dap, name)
- devalloc_t **dap;
- char *name;
+int
+da_matchname(devalloc_t *dap, char *name)
{
- register struct _dabuff *_da = _daalloc();
- devalloc_t *da = *dap;
-
- if (_da == 0)
- return (0);
- if (da->da_devname == NULL)
+ if (dap->da_devname == NULL)
return (0);
- if (strlen(da->da_devname) != strlen(name))
+
+ return ((strcmp(dap->da_devname, name) == 0));
+}
+
+/*
+ * da_matchtype -
+ * checks if the specified devalloc_t is for the device type specified.
+ * returns 1 if match found, else, returns 0.
+ */
+int
+da_matchtype(devalloc_t *da, char *type)
+{
+ if (da->da_devtype == NULL)
return (0);
- if (strcmp(da->da_devname, name) == 0)
- return (1);
- return (0);
+
+ return ((strcmp(da->da_devtype, type) == 0));
}
+/*
+ * da_match -
+ * calls da_matchname or da_matchdev as appropriate.
+ */
+int
+da_match(devalloc_t *dap, da_args *dargs)
+{
+ if (dargs->devinfo->devname)
+ return (da_matchname(dap, dargs->devinfo->devname));
+ else if (dargs->devinfo->devtype)
+ return (da_matchtype(dap, dargs->devinfo->devtype));
+
+ return (0);
+}
/*
- * interpret(val) string "val" is parsed and the pointers in a devalloc_t
- * structure are initialized to point to fields in "val". A pointer to this
- * structure is returned.
+ * da_interpret -
+ * parses val and initializes pointers in devalloc_t.
+ * returns pointer to parsed devalloc_t entry, else returns NULL on error.
*/
static devalloc_t *
-interpret(val)
-char *val;
+da_interpret(char *val)
{
- register struct _dabuff *_da = _daalloc();
+ struct _dabuff *_da = _daalloc();
+ char *opts;
+ int i;
+ kva_t *kvap;
+ kv_t *kvp;
- if (_da == 0)
- return (0);
- (void) strcpy(interpline, val);
- interpdevalloc.da_devname = getdafield(interpline);
- interpdevalloc.da_devtype = getdafield((char *)NULL);
- interpdevalloc.da_devmin = getdafield((char *)NULL);
- interpdevalloc.da_devmax = getdafield((char *)NULL);
- interpdevalloc.da_devauth = getdafield((char *)NULL);
- interpdevalloc.da_devexec = getdafield((char *)NULL);
+ if (_da == NULL)
+ return (NULL);
+
+ (void) strcpy(interpdaline, val);
+ interpdevalloc.da_devname = getdadmfield(interpdaline, KV_DELIMITER);
+ interpdevalloc.da_devtype = getdadmfield(NULL, KV_DELIMITER);
+ opts = getdadmfield(NULL, KV_DELIMITER);
+ (void) getdadmfield(NULL, KV_DELIMITER); /* reserved field */
+ interpdevalloc.da_devauth = getdadmfield(NULL, KV_DELIMITER);
+ interpdevalloc.da_devexec = getdadmfield(NULL, KV_DELIMITER);
+ interpdevalloc.da_devopts = NULL;
+ if (interpdevalloc.da_devname == NULL ||
+ interpdevalloc.da_devtype == NULL)
+ return (NULL);
+ if ((opts != NULL) &&
+ (strncmp(opts, DA_RESERVED, strlen(DA_RESERVED)) != 0)) {
+ interpdevalloc.da_devopts =
+ _str2kva(opts, KV_ASSIGN, KV_TOKEN_DELIMIT);
+ }
+ /* remove any extraneous whitespace in the options */
+ if ((kvap = interpdevalloc.da_devopts) != NULL) {
+ for (i = 0, kvp = kvap->data; i < kvap->length; i++, kvp++) {
+ (void) pack_white(kvp->key);
+ (void) pack_white(kvp->value);
+ }
+ }
+
+ if (system_labeled) {
+ /* if label range is not defined, use the default range. */
+ int i = 0, nlen = 0;
+ char *minstr = NULL, *maxstr = NULL;
+ kva_t *nkvap = NULL;
+ kv_t *ndata = NULL, *odata = NULL;
+
+ if (kvap == NULL) {
+ nlen = 2; /* minlabel, maxlabel */
+ } else {
+ nlen += kvap->length;
+ if ((minstr = kva_match(kvap, DAOPT_MINLABEL)) == NULL)
+ nlen++;
+ if ((maxstr = kva_match(kvap, DAOPT_MAXLABEL)) == NULL)
+ nlen++;
+ }
+ if ((minstr != NULL) && (maxstr != NULL))
+ /*
+ * label range provided; we don't need to construct
+ * default range.
+ */
+ goto out;
+ nkvap = _new_kva(nlen);
+ ndata = nkvap->data;
+ if (kvap != NULL) {
+ for (i = 0; i < kvap->length; i++) {
+ odata = kvap->data;
+ ndata[i].key = _strdup_null(odata[i].key);
+ ndata[i].value = _strdup_null(odata[i].value);
+ nkvap->length++;
+ }
+ }
+ if (minstr == NULL) {
+ ndata[i].key = strdup(DAOPT_MINLABEL);
+ ndata[i].value = strdup(DA_DEFAULT_MIN);
+ nkvap->length++;
+ i++;
+ }
+ if (maxstr == NULL) {
+ ndata[i].key = strdup(DAOPT_MAXLABEL);
+ ndata[i].value = strdup(DA_DEFAULT_MAX);
+ nkvap->length++;
+ }
+ interpdevalloc.da_devopts = nkvap;
+ }
+out:
return (&interpdevalloc);
}
diff --git a/usr/src/lib/libbsm/common/getdevicerange.c b/usr/src/lib/libbsm/common/getdevicerange.c
new file mode 100644
index 0000000000..6b993de18f
--- /dev/null
+++ b/usr/src/lib/libbsm/common/getdevicerange.c
@@ -0,0 +1,109 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+#include <errno.h>
+#include <tsol/label.h>
+#include <bsm/devices.h>
+
+
+/*
+ * getdevicerange
+ * Gets the minimum and maximum labels within which the device can
+ * be used. If label range is not specified for the device in
+ * device_allocate, defaults to admin_low and admin_high.
+ * Returns malloc'ed blrange pointer, or NULL on any error.
+ */
+blrange_t *
+getdevicerange(const char *dev)
+{
+ int err;
+ char *lstr;
+ devalloc_t *da;
+ devmap_t *dm;
+ blrange_t *range;
+
+ errno = 0;
+ if ((range = malloc(sizeof (blrange_t))) == NULL)
+ return (NULL);
+ if ((range->lower_bound = blabel_alloc()) == NULL) {
+ free(range);
+ return (NULL);
+ }
+ if ((range->upper_bound = blabel_alloc()) == NULL) {
+ blabel_free(range->lower_bound);
+ free(range);
+ return (NULL);
+ }
+
+ /*
+ * If an entry is found for the named device,
+ * return its label range.
+ */
+ setdaent();
+ if ((da = getdanam((char *)dev)) == NULL) {
+ setdmapent();
+ /* check for an actual device file */
+ if ((dm = getdmapdev((char *)dev)) != NULL) {
+ da = getdanam(dm->dmap_devname);
+ freedmapent(dm);
+ }
+ enddmapent();
+ }
+ enddaent();
+ if (da == NULL) {
+ bsllow(range->lower_bound);
+ bslhigh(range->upper_bound);
+ } else {
+ lstr = kva_match(da->da_devopts, DAOPT_MINLABEL);
+ if (lstr == NULL) {
+ bsllow(range->lower_bound);
+ } else if (stobsl(lstr, range->lower_bound, NO_CORRECTION,
+ &err) == 0) {
+ blabel_free(range->lower_bound);
+ blabel_free(range->upper_bound);
+ free(range);
+ errno = ENOTSUP;
+ return (NULL);
+ }
+ lstr = kva_match(da->da_devopts, DAOPT_MAXLABEL);
+ if (lstr == NULL) {
+ bslhigh(range->upper_bound);
+ } else if (stobsl(lstr, range->upper_bound, NO_CORRECTION,
+ &err) == 0) {
+ blabel_free(range->lower_bound);
+ blabel_free(range->upper_bound);
+ free(range);
+ errno = ENOTSUP;
+ return (NULL);
+ }
+ freedaent(da);
+ }
+
+ return (range);
+}
diff --git a/usr/src/lib/libbsm/common/getdment.c b/usr/src/lib/libbsm/common/getdment.c
index 9e4556c9c7..2b13f5bc6e 100644
--- a/usr/src/lib/libbsm/common/getdment.c
+++ b/usr/src/lib/libbsm/common/getdment.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,446 +19,486 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
-#include <stdio.h>
#include <string.h>
-#include <malloc.h>
+#include <stdlib.h>
#include <bsm/devices.h>
-#include <sys/errno.h>
+#include <bsm/devalloc.h>
-#define MAXINT 0x7fffffff;
+char *strtok_r(char *, const char *, char **);
+
+/* externs from getdaent.c */
+extern char *trim_white(char *);
+extern int pack_white(char *);
+extern char *getdadmfield(char *, char *);
+extern int getdadmline(char *, int, FILE *);
static struct _dmapbuff {
- devmap_t _NULLDM;
- FILE *_dmapf; /* pointer into /etc/security/device_maps */
- devmap_t _interpdevmap;
- char _interpline[BUFSIZ + 1];
- char *_DEVMAP;
+ FILE *_dmapf; /* for /etc/security/device_maps */
+ devmap_t _interpdevmap;
+ char _interpdmline[DA_BUFSIZE + 1];
+ char *_DEVMAP;
} *__dmapbuff;
-#define NULLDM (_dmap->_NULLDM)
-#define dmapf (_dmap->_dmapf)
-#define interpdevmap (_dmap->_interpdevmap)
-#define interpline (_dmap->_interpline)
-#define DEVMAP (_dmap->_DEVMAP)
-static devmap_t *interpret();
-static int matchdev();
-static int matchname();
+#define dmapf (_dmap->_dmapf)
+#define interpdevmap (_dmap->_interpdevmap)
+#define interpdmline (_dmap->_interpdmline)
+#define DEVMAPS_FILE (_dmap->_DEVMAP)
+
+devmap_t *dmap_interpret(char *, devmap_t *);
+static devmap_t *dmap_interpretf(char *, devmap_t *);
+static devmap_t *dmap_dlexpand(devmap_t *);
+
+int dmap_matchdev(devmap_t *, char *);
+int dmap_matchname(devmap_t *, char *);
+
+
/*
- * trim_white(ptr) trims off leading and trailing white space from a NULL
- * terminated string pointed to by "ptr". The leading white space is skipped
- * by moving the pointer forward. The trailing white space is removed by
- * nulling the white space characters. The pointer is returned to the white
- * string. If the resulting string is null in length then a NULL pointer is
- * returned. If "ptr" is NULL then a NULL pointer is returned.
+ * _dmapalloc -
+ * allocates common buffers and structures.
+ * returns pointer to the new structure, else returns NULL on error.
*/
-static char *
-trim_white(char *ptr)
+static struct _dmapbuff *
+_dmapalloc(void)
{
- register char *tptr;
- register int cnt;
- if (ptr == NULL)
- return (NULL);
- while ((*ptr == ' ') || (*ptr == '\t')) {
- ptr++;
- }
- cnt = strlen(ptr);
- if (cnt != 0) {
- tptr = ptr + cnt - 1;
- while ((*tptr == ' ') || (*tptr == '\t')) {
- *tptr = '\0';
- tptr--;
- }
+ struct _dmapbuff *_dmap = __dmapbuff;
+
+ if (_dmap == NULL) {
+ _dmap = (struct _dmapbuff *)calloc((unsigned)1,
+ (unsigned)sizeof (*__dmapbuff));
+ if (_dmap == NULL)
+ return (NULL);
+ DEVMAPS_FILE = "/etc/security/device_maps";
+ dmapf = NULL;
+ __dmapbuff = _dmap;
}
- if (*ptr == NULL)
- return (NULL);
- return (ptr);
+
+ return (_dmap);
}
+
/*
- * scan string pointed to by pointer "p"
- * find next colin or end of line. Null it and
- * return pointer to next char.
+ * setdmapent -
+ * rewinds the device_maps file to the beginning.
*/
-static char *
-dmapskip(register char *p)
+void
+setdmapent(void)
{
- while (*p && *p != ':' && *p != '\n')
- ++p;
- if (*p == '\n')
- *p = '\0';
- else if (*p != '\0')
- *p++ = '\0';
- return (p);
+ struct _dmapbuff *_dmap = _dmapalloc();
+
+ if (_dmap == NULL)
+ return;
+ if (dmapf == NULL)
+ dmapf = fopen(DEVMAPS_FILE, "r");
+ else
+ rewind(dmapf);
}
+
/*
- * scan string pointed to by pointer "p"
- * find next colin or end of line. Null it and
- * return pointer to next char.
+ * enddmapent -
+ * closes device_maps file.
*/
-static char *
-dmapdskip(register char *p)
+void
+enddmapent(void)
{
- while (*p && *p != ' ' && *p != '\n')
- ++p;
- if (*p != '\0')
- *p++ = '\0';
- return (p);
+ struct _dmapbuff *_dmap = _dmapalloc();
+
+ if (_dmap == NULL)
+ return;
+ if (dmapf != NULL) {
+ (void) fclose(dmapf);
+ dmapf = NULL;
+ }
}
-/*
- * _dmapalloc() allocates common buffers and structures used by the device
- * maps library routines. Then returns a pointer to a structure. The
- * returned pointer will be null if there is an error condition.
- */
-static struct _dmapbuff *
-_dmapalloc(void)
+void
+freedmapent(devmap_t *dmap)
{
- register struct _dmapbuff *_dmap = __dmapbuff;
-
- if (_dmap == 0) {
- _dmap = (struct _dmapbuff *)
- calloc((unsigned)1, (unsigned)sizeof (*__dmapbuff));
- if (_dmap == 0)
- return (0);
- DEVMAP = "/etc/security/device_maps";
- __dmapbuff = _dmap;
+ char **darp;
+
+ if ((darp = dmap->dmap_devarray) != NULL) {
+ while (*darp != NULL)
+ free(*darp++);
+ free(dmap->dmap_devarray);
+ dmap->dmap_devarray = NULL;
}
- return (__dmapbuff);
}
+
/*
- * getdmapline(buff,len,stream) reads one device maps line from "stream" into
- * "buff" on "len" bytes. Continued lines from "stream" are concatinated
- * into one line in "buff". Comments are removed from "buff". The number of
- * characters in "buff" is returned. If no characters are read or an error
- * occured then "0" is returned
+ * setdmapfile -
+ * changes the default device_maps file to the one specified.
+ * It does not close the previous file. If this is desired, enddmapent
+ * should be called prior to setdampfile.
*/
-static int
-getdmapline(char *buff, int len, FILE *stream)
+void
+setdmapfile(char *file)
{
- register struct _dmapbuff *_dmap = _dmapalloc();
- char *cp;
- char *ccp;
- size_t tmpcnt;
- int charcnt = 0;
- int fileerr = 0;
- int contline;
- if (_dmap == 0)
- return (0);
- do {
- cp = buff;
- *cp = NULL;
- do {
- if ((len - charcnt <= 1) ||
- (fgets(cp, len - charcnt, stream) == NULL)) {
- fileerr = 1;
- break;
- }
- ccp = strpbrk(cp, "\\\n");
- if (ccp != NULL) {
- if (*ccp == '\\')
- contline = 1;
- else
- contline = 0;
- *ccp = NULL;
- }
- tmpcnt = strlen(cp);
- if (tmpcnt != 0) {
- cp += tmpcnt;
- charcnt += tmpcnt;
- }
- } while ((contline) || (charcnt == 0));
- ccp = strpbrk(buff, "#");
- if (ccp != NULL)
- *ccp = NULL;
- charcnt = strlen(buff);
- } while ((fileerr == 0) && (charcnt == 0));
- if (fileerr && !charcnt)
- return (0);
- else
- return (charcnt);
+ struct _dmapbuff *_dmap = _dmapalloc();
+
+ if (_dmap == NULL)
+ return;
+ if (dmapf != NULL) {
+ (void) fclose(dmapf);
+ dmapf = NULL;
+ }
+ DEVMAPS_FILE = file;
}
-char
-*getdmapfield(char *ptr)
+
+/*
+ * getdmapent -
+ * When first called, returns a pointer to the first devmap_t structure
+ * in device_maps; thereafter, it returns a pointer to the next devmap_t
+ * structure in the file. Thus successive calls can be used to read the
+ * entire file.
+ * call to getdmapent should be bracketed by setdmapent and enddmapent.
+ * returns pointer to devmap_t found, else returns NULL if no entry found
+ * or on error.
+ */
+devmap_t *
+getdmapent(void)
{
- static char *tptr;
- if (ptr == NULL)
- ptr = tptr;
- if (ptr == NULL)
- return (NULL);
- tptr = dmapskip(ptr);
- ptr = trim_white(ptr);
- if (ptr == NULL)
- return (NULL);
- if (*ptr == NULL)
+ devmap_t *dmap;
+ struct _dmapbuff *_dmap = _dmapalloc();
+
+ if ((_dmap == 0) || (dmapf == NULL))
return (NULL);
- return (ptr);
-}
-char
-*getdmapdfield(char *ptr)
-{
- static char *tptr;
- if (ptr != NULL) {
- ptr = trim_white(ptr);
- } else {
- ptr = tptr;
+
+ while (getdadmline(interpdmline, (int)sizeof (interpdmline),
+ dmapf) != 0) {
+ if ((dmap = dmap_interpret(interpdmline,
+ &interpdevmap)) == NULL)
+ continue;
+ return (dmap);
}
- if (ptr == NULL)
- return (NULL);
- tptr = dmapdskip(ptr);
- if (ptr == NULL)
- return (NULL);
- if (*ptr == NULL)
- return (NULL);
- return (ptr);
+
+ return (NULL);
}
+
/*
- * getdmapdev(dev) searches from the beginning of the file until a logical
- * device matching "dev" is found and returns a pointer to the particular
- * structure in which it was found. If an EOF or an error is encountered on
- * reading, these functions return a NULL pointer.
+ * getdmapnam -
+ * searches from the beginning of device_maps for the device specified by
+ * its name.
+ * call to getdmapnam should be bracketed by setdmapent and enddmapent.
+ * returns pointer to devmapt_t for the device if it is found, else
+ * returns NULL if device not found or in case of error.
*/
devmap_t *
-getdmapdev(register char *name)
+getdmapnam(char *name)
{
- register struct _dmapbuff *_dmap = _dmapalloc();
- devmap_t *dmap;
- char line[BUFSIZ + 1];
+ devmap_t *dmap;
+ struct _dmapbuff *_dmap = _dmapalloc();
- if (_dmap == 0)
- return (0);
- setdmapent();
- if (!dmapf)
+ if ((name == NULL) || (_dmap == 0) || (dmapf == NULL))
return (NULL);
- while (getdmapline(line, (int)sizeof (line), dmapf) != 0) {
- if ((dmap = interpret(line)) == NULL)
+
+ while (getdadmline(interpdmline, (int)sizeof (interpdmline),
+ dmapf) != 0) {
+ if (strstr(interpdmline, name) == NULL)
continue;
- if (matchdev(&dmap, name)) {
+ if ((dmap = dmap_interpretf(interpdmline,
+ &interpdevmap)) == NULL)
+ continue;
+ if (dmap_matchname(dmap, name)) {
+ if ((dmap = dmap_dlexpand(dmap)) == NULL)
+ continue;
enddmapent();
return (dmap);
}
+ freedmapent(dmap);
}
- enddmapent();
+
return (NULL);
}
+
/*
- * getdmapnam(name) searches from the beginning of the file until a audit-name
- * matching "name" is found and returns a pointer to the particular structure
- * in which it was found. If an EOF or an error is encountered on reading,
- * these functions return a NULL pointer.
+ * getdmapdev -
+ * searches from the beginning of device_maps for the device specified by
+ * its logical name.
+ * call to getdmapdev should be bracketed by setdmapent and enddmapent.
+ * returns pointer to the devmap_t for the device if device is found,
+ * else returns NULL if device not found or on error.
*/
devmap_t *
-getdmapnam(register char *name)
+getdmapdev(char *dev)
{
- register struct _dmapbuff *_dmap = _dmapalloc();
- devmap_t *dmap;
- char line[BUFSIZ + 1];
+ devmap_t *dmap;
+ struct _dmapbuff *_dmap = _dmapalloc();
- if (_dmap == 0)
- return (0);
- setdmapent();
- if (!dmapf)
+ if ((dev == NULL) || (_dmap == 0) || (dmapf == NULL))
return (NULL);
- while (getdmapline(line, (int)sizeof (line), dmapf) != 0) {
- if ((dmap = interpret(line)) == NULL)
+
+ while (getdadmline(interpdmline, (int)sizeof (interpdmline),
+ dmapf) != 0) {
+ if ((dmap = dmap_interpret(interpdmline,
+ &interpdevmap)) == NULL)
continue;
- if (matchname(&dmap, name)) {
+ if (dmap_matchdev(dmap, dev)) {
enddmapent();
return (dmap);
}
+ freedmapent(dmap);
}
- enddmapent();
+
return (NULL);
}
/*
- * setdmapent() essentially rewinds the device_maps file to the begining.
+ * getdmaptype -
+ * searches from the beginning of device_maps for the device specified by
+ * its type.
+ * call to getdmaptype should be bracketed by setdmapent and enddmapent.
+ * returns pointer to devmap_t found, else returns NULL if no entry found
+ * or on error.
*/
-
-void
-setdmapent(void)
+devmap_t *
+getdmaptype(char *type)
{
- register struct _dmapbuff *_dmap = _dmapalloc();
+ devmap_t *dmap;
+ struct _dmapbuff *_dmap = _dmapalloc();
+ if ((type == NULL) || (_dmap == 0) || (dmapf == NULL))
+ return (NULL);
- if (_dmap == 0)
- return;
+ while (getdadmline(interpdmline, (int)sizeof (interpdmline),
+ dmapf) != 0) {
+ if ((dmap = dmap_interpretf(interpdmline,
+ &interpdevmap)) == NULL)
+ continue;
+ if (dmap->dmap_devtype != NULL &&
+ strcmp(type, dmap->dmap_devtype) == 0) {
+ if ((dmap = dmap_dlexpand(dmap)) == NULL)
+ continue;
+ return (dmap);
+ }
+ freedmapent(dmap);
+ }
- if (dmapf == NULL) {
- dmapf = fopen(DEVMAP, "r");
- } else
- rewind(dmapf);
+ return (NULL);
}
-
/*
- * enddmapent() may be called to close the device_maps file when processing
- * is complete.
+ * dmap_matchdev -
+ * checks if the specified devmap_t is for the device specified.
+ * returns 1 if it is, else returns 0.
*/
-
-void
-enddmapent(void)
+int
+dmap_matchdev(devmap_t *dmap, char *dev)
{
- register struct _dmapbuff *_dmap = _dmapalloc();
+ char **dva;
+ char *dv;
- if (_dmap == 0)
- return;
- if (dmapf != NULL) {
- (void) fclose(dmapf);
- dmapf = NULL;
+ if (dmap->dmap_devarray == NULL)
+ return (0);
+ for (dva = dmap->dmap_devarray; (dv = *dva) != NULL; dva ++) {
+ if (strcmp(dv, dev) == 0)
+ return (1);
}
-}
+ return (0);
+}
/*
- * setdmapfile(name) changes the default device_maps file to "name" thus
- * allowing alternate device_maps files to be used. Note: it does not
- * close the previous file . If this is desired, enddmapent should be called
- * prior to it.
+ * dmap_matchtype -
+ * checks if the specified devmap_t is for the device specified.
+ * returns 1 if it is, else returns 0.
*/
-void
-setdmapfile(char *file)
+int
+dmap_matchtype(devmap_t *dmap, char *type)
{
- register struct _dmapbuff *_dmap = _dmapalloc();
+ if ((dmap->dmap_devtype == NULL) || (type == NULL))
+ return (0);
- if (_dmap == 0)
- return;
- if (dmapf != NULL) {
- (void) fclose(dmapf);
- dmapf = NULL;
- }
- DEVMAP = file;
+ return ((strcmp(dmap->dmap_devtype, type) == 0));
}
+
/*
- * getdmaptype(tp) When first called, returns a pointer to the
- * first devmap_t structure in the file with device-type matching
- * "tp"; thereafter, it returns a pointer to the next devmap_t
- * structure in the file with device-type matching "tp".
- * Thus successive calls can be used to search the
- * entire file for entries having device-type matching "tp".
- * A null pointer is returned on error.
+ * dmap_matchname -
+ * checks if the specified devmap_t is for the device specified.
+ * returns 1 if it is, else returns 0.
*/
-devmap_t *
-getdmaptype(char *tp)
+int
+dmap_matchname(devmap_t *dmap, char *name)
{
- register struct _dmapbuff *_dmap = _dmapalloc();
- char line1[BUFSIZ + 1];
- devmap_t *dmap;
-
- if (_dmap == 0)
+ if (dmap->dmap_devname == NULL)
return (0);
- if (dmapf == NULL && (dmapf = fopen(DEVMAP, "r")) == NULL) {
- return (NULL);
- }
- do {
- if (getdmapline(line1, (int)sizeof (line1), dmapf) == 0)
- return (NULL);
- if ((dmap = interpret(line1)) == NULL)
- return (NULL);
- } while (strcmp(tp, dmap->dmap_devtype) != 0);
- return (dmap);
+ return ((strcmp(dmap->dmap_devname, name) == 0));
}
/*
- * getdmapent() When first called, returns a pointer to the first devmap_t
- * structure in the file; thereafter, it returns a pointer to the next devmap_t
- * structure in the file. Thus successive calls can be used to search the
- * entire file. A null pointer is returned on error.
+ * dm_match -
+ * calls dmap_matchname or dmap_matchtype as appropriate.
*/
-devmap_t *
-getdmapent(void)
+int
+dm_match(devmap_t *dmap, da_args *dargs)
{
- register struct _dmapbuff *_dmap = _dmapalloc();
- char line1[BUFSIZ + 1];
- devmap_t *dmap;
+ if (dargs->devinfo->devname)
+ return (dmap_matchname(dmap, dargs->devinfo->devname));
+ else if (dargs->devinfo->devtype)
+ return (dmap_matchtype(dmap, dargs->devinfo->devtype));
- if (_dmap == 0)
- return (0);
- if (dmapf == NULL && (dmapf = fopen(DEVMAP, "r")) == NULL) {
- return (NULL);
- }
- if (getdmapline(line1, (int)sizeof (line1), dmapf) == 0)
+ return (0);
+}
+
+/*
+ * dmap_interpret -
+ * calls dmap_interpretf and dmap_dlexpand to parse devmap_t line.
+ * returns pointer to parsed devmapt_t entry, else returns NULL on error.
+ */
+devmap_t *
+dmap_interpret(char *val, devmap_t *dm)
+{
+ if (dmap_interpretf(val, dm) == NULL)
return (NULL);
- if ((dmap = interpret(line1)) == NULL)
+ return (dmap_dlexpand(dm));
+}
+
+/*
+ * dmap_interpretf -
+ * parses string "val" and initializes pointers in the given devmap_t to
+ * fields in "val".
+ * returns pointer to updated devmap_t.
+ */
+static devmap_t *
+dmap_interpretf(char *val, devmap_t *dm)
+{
+ dm->dmap_devname = getdadmfield(val, KV_TOKEN_DELIMIT);
+ dm->dmap_devtype = getdadmfield(NULL, KV_TOKEN_DELIMIT);
+ dm->dmap_devlist = getdadmfield(NULL, KV_TOKEN_DELIMIT);
+ dm->dmap_devarray = NULL;
+ if (dm->dmap_devname == NULL ||
+ dm->dmap_devtype == NULL ||
+ dm->dmap_devlist == NULL)
return (NULL);
- return (dmap);
+
+ return (dm);
}
+
/*
- * matchdev(dmapp,dev) The dev_list in the structure pointed to by "dmapp" is
- * searched for string "dev". If a match occures then a "1" is returned
- * otherwise a "0" is returned.
+ * dmap_dlexpand -
+ * expands dmap_devlist of the form `devlist_generate`
+ * returns unexpanded form if there is no '\`' or in case of error.
*/
-static int
-matchdev(devmap_t **dmapp, char *dev)
+static devmap_t *
+dmap_dlexpand(devmap_t *dmp)
{
- register struct _dmapbuff *_dmap = _dmapalloc();
- devmap_t *dmap = *dmapp;
- char tmpdev[BUFSIZ + 1];
- int charcnt;
- int tmpcnt;
- char *cp;
- char *tcp;
- char *last;
- charcnt = strlen(dev);
- if (_dmap == 0)
- return (0);
- if (dmap->dmap_devlist == NULL)
- return (0);
- (void) strcpy(tmpdev, dmap->dmap_devlist);
- tcp = tmpdev;
- while ((cp = strtok_r(tcp, " ", &last)) != NULL) {
- tcp = NULL;
- tmpcnt = strlen(cp);
- if (tmpcnt != charcnt)
- continue;
- if (strcmp(cp, dev) == 0)
- return (1);
+ char tmplist[DA_BUFSIZE + 1];
+ char *cp, *cpl, **darp;
+ int count;
+ FILE *expansion;
+
+ dmp->dmap_devarray = NULL;
+ if (dmp->dmap_devlist == NULL)
+ return (NULL);
+ if (*(dmp->dmap_devlist) != '`') {
+ (void) strcpy(tmplist, dmp->dmap_devlist);
+ } else {
+ (void) strcpy(tmplist, dmp->dmap_devlist + 1);
+ if ((cp = strchr(tmplist, '`')) != NULL)
+ *cp = '\0';
+ if ((expansion = popen(tmplist, "r")) == NULL)
+ return (NULL);
+ count = fread(tmplist, 1, sizeof (tmplist) - 1, expansion);
+ (void) pclose(expansion);
+ tmplist[count] = '\0';
}
- return (0);
+
+ /* cleanup the list */
+ count = pack_white(tmplist);
+ dmp->dmap_devarray = darp =
+ (char **)malloc((count + 2) * sizeof (char *));
+ if (darp == NULL)
+ return (NULL);
+ cp = tmplist;
+ while ((cp = strtok_r(cp, " ", &cpl)) != NULL) {
+ *darp = strdup(cp);
+ if (*darp == NULL) {
+ freedmapent(dmp);
+ return (NULL);
+ }
+ darp++;
+ cp = NULL;
+ }
+ *darp = NULL;
+
+ return (dmp);
}
+
/*
- * matchname(dmapp,name) The audit-name in the structure pointed to by "dmapp"
- * is searched for string "name". If a match occures then a "1" is returned
- * otherwise a "0" is returned.
+ * dmapskip -
+ * scans input string to find next colon or end of line.
+ * returns pointer to next char.
*/
-static int
-matchname(devmap_t **dmapp, char *name)
+static char *
+dmapskip(char *p)
{
- register struct _dmapbuff *_dmap = _dmapalloc();
- devmap_t *dmap = *dmapp;
+ while (*p && *p != ':' && *p != '\n')
+ ++p;
+ if (*p == '\n')
+ *p = '\0';
+ else if (*p != '\0')
+ *p++ = '\0';
- if (_dmap == 0)
- return (0);
- if (dmap->dmap_devname == NULL)
- return (0);
- if (strlen(dmap->dmap_devname) != strlen(name))
- return (0);
- if (strcmp(dmap->dmap_devname, name) == 0)
- return (1);
- return (0);
+ return (p);
}
+
/*
- * interpret(val) string "val" is parsed and the pointers in a devmap_t
- * structure are initialized to point to fields in "val". A pointer to this
- * structure is returned.
+ * dmapdskip -
+ * scans input string to find next space or end of line.
+ * returns pointer to next char.
*/
-static devmap_t *
-interpret(char *val)
+static char *
+dmapdskip(p)
+ register char *p;
{
- register struct _dmapbuff *_dmap = _dmapalloc();
+ while (*p && *p != ' ' && *p != '\n')
+ ++p;
+ if (*p != '\0')
+ *p++ = '\0';
- if (_dmap == 0)
- return (0);
- (void) strcpy(interpline, val);
- interpdevmap.dmap_devname = getdmapfield(interpline);
- interpdevmap.dmap_devtype = getdmapfield((char *)NULL);
- interpdevmap.dmap_devlist = getdmapfield((char *)NULL);
+ return (p);
+}
+
+char *
+getdmapfield(char *ptr)
+{
+ static char *tptr;
- return (&interpdevmap);
+ if (ptr == NULL)
+ ptr = tptr;
+ if (ptr == NULL)
+ return (NULL);
+ tptr = dmapskip(ptr);
+ ptr = trim_white(ptr);
+ if (ptr == NULL)
+ return (NULL);
+ if (*ptr == NULL)
+ return (NULL);
+
+ return (ptr);
+}
+
+char *
+getdmapdfield(char *ptr)
+{
+ static char *tptr;
+ if (ptr != NULL) {
+ ptr = trim_white(ptr);
+ } else {
+ ptr = tptr;
+ }
+ if (ptr == NULL)
+ return (NULL);
+ tptr = dmapdskip(ptr);
+ if (ptr == NULL)
+ return (NULL);
+ if (*ptr == NULL)
+ return (NULL);
+
+ return (ptr);
}
diff --git a/usr/src/lib/libbsm/common/llib-lbsm b/usr/src/lib/libbsm/common/llib-lbsm
index b95cf4f0d3..a00c330276 100644
--- a/usr/src/lib/libbsm/common/llib-lbsm
+++ b/usr/src/lib/libbsm/common/llib-lbsm
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -23,12 +22,13 @@
/* PROTOLIB1 */
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <bsm/devices.h>
+#include <bsm/devalloc.h>
#include <bsm/audit.h>
#include <bsm/libbsm.h>
#include <bsm/audit_record.h>
diff --git a/usr/src/lib/libbsm/mkhdr.sh b/usr/src/lib/libbsm/mkhdr.sh
index ca1be7eaec..3de666cb2f 100644
--- a/usr/src/lib/libbsm/mkhdr.sh
+++ b/usr/src/lib/libbsm/mkhdr.sh
@@ -3,9 +3,8 @@
# 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.
+# 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
# or http://www.opensolaris.org/os/licensing.
@@ -21,8 +20,12 @@
# CDDL HEADER END
#
#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
# ident "%Z%%M% %I% %E% SMI"
#
+
# Automagically generate the audit_uevents.h header file.
#
DATABASE=audit_event.txt
@@ -30,8 +33,8 @@ HEADER_FILE=audit_uevents.h
cat <<EOF > $HEADER_FILE
/*
- * Copyright (c) 1993-2001, Sun Microsystems, Inc.
- * All Rights Reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#ifndef _BSM_AUDIT_UEVENTS_H
@@ -57,12 +60,31 @@ EOF
nawk -F: '{if ((NF == 4) && substr($1,0,1) != "#")
if ($1 >= 2048) {
- printf("#define %s ",$2)
- if (length($2) < 8)
- printf(" ")
- if (length($2) < 16)
- printf(" ")
- printf("%s /* =%s %s */\n",$1,$4,$3)
+ # compute total output line length first
+ tlen = length($2);
+ llen = 8 + tlen;
+ llen += 8 - (llen % 8);
+ if (llen < 32)
+ llen = 32;
+ llen += length($1);
+ llen += 8 - (llen % 8);
+ llen += 5 + length($4) + length($3) + 3;
+
+ # if line is too long, then print the comment first
+ if (llen > 80)
+ printf("/* =%s %s */\n", $4, $3);
+
+ printf("#define\t%s\t", $2)
+ if (tlen < 8)
+ printf("\t");
+ if (tlen < 16)
+ printf("\t")
+ printf("%s", $1);
+
+ if (llen > 80)
+ printf("\n");
+ else
+ printf("\t/* =%s %s */\n", $4, $3);
}
}' \
< $DATABASE >> $HEADER_FILE
diff --git a/usr/src/lib/libbsm/spec/Makefile.targ b/usr/src/lib/libbsm/spec/Makefile.targ
index a4a58c29f8..1784ff6015 100644
--- a/usr/src/lib/libbsm/spec/Makefile.targ
+++ b/usr/src/lib/libbsm/spec/Makefile.targ
@@ -2,9 +2,8 @@
# 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.
+# 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
# or http://www.opensolaris.org/os/licensing.
@@ -18,11 +17,13 @@
# 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.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
#
# lib/libbsm/spec/Makefile.targ
@@ -36,6 +37,7 @@ OBJECTS = au_open.o \
audit.o \
auditon.o \
auditsvc.o \
+ devalloc.o \
exceptions.o \
getacinfo.o \
getauclassent.o \
diff --git a/usr/src/lib/libbsm/spec/devalloc.spec b/usr/src/lib/libbsm/spec/devalloc.spec
new file mode 100644
index 0000000000..3861d93b6c
--- /dev/null
+++ b/usr/src/lib/libbsm/spec/devalloc.spec
@@ -0,0 +1,220 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libbsm/spec/devalloc.spec
+
+function getdadmline
+include <bsm/devices.h>
+declaration int getdadmline(char *, int, FILE *)
+version SUNWprivate_1.1
+end
+
+function getdmapdfield
+include <bsm/devices.h>
+declaration char *getdmapdfield(char *)
+version SUNWprivate_1.1
+end
+
+function setdaent
+include <bsm/devices.h>
+declaration void setdaent(void)
+version SUNWprivate_1.1
+end
+
+function enddaent
+include <bsm/devices.h>
+declaration void enddaent(void)
+version SUNWprivate_1.1
+end
+
+function setdafile
+include <bsm/devices.h>
+declaration void setdafile(char *)
+version SUNWprivate_1.1
+end
+
+function freedaent
+include <bsm/devices.h>
+declaration void freedaent(devalloc_t *)
+version SUNWprivate_1.1
+end
+
+function getdaent
+include <bsm/devices.h>
+declaration devalloc_t *getdaent(void)
+version SUNWprivate_1.1
+end
+
+function getdanam
+include <bsm/devices.h>
+declaration devalloc_t *getdanam(char *)
+version SUNWprivate_1.1
+end
+
+function getdatype
+include <bsm/devices.h>
+declaration devalloc_t *getdatype(char *)
+version SUNWprivate_1.1
+end
+
+function setdmapent
+include <bsm/devices.h>
+declaration void setdmapent(void)
+version SUNWprivate_1.1
+end
+
+function enddmapent
+include <bsm/devices.h>
+declaration void enddmapent(void)
+version SUNWprivate_1.1
+end
+
+function setdmapfile
+include <bsm/devices.h>
+declaration void setdmapfile(char *)
+version SUNWprivate_1.1
+end
+
+function freedmapent
+include <bsm/devices.h>
+declaration void freedmapent(devmap_t *)
+version SUNWprivate_1.1
+end
+
+function getdmapent
+include <bsm/devices.h>
+declaration devmap_t *getdmapent(void)
+version SUNWprivate_1.1
+end
+
+function getdmapnam
+include <bsm/devices.h>
+declaration devmap_t *getdmapnam(char *)
+version SUNWprivate_1.1
+end
+
+function getdmapdev
+include <bsm/devices.h>
+declaration devmap_t *getdmapdev(char *)
+version SUNWprivate_1.1
+end
+
+function getdmaptype
+include <bsm/devices.h>
+declaration devmap_t *getdmaptype(char *)
+version SUNWprivate_1.1
+end
+
+function getdmapfield
+include <bsm/devices.h>
+declaration char *getdmapfield(char *)
+version SUNWprivate_1.1
+end
+
+function setdadefent
+include <bsm/devalloc.h>
+declaration void setdadefent(void)
+version SUNWprivate_1.1
+end
+
+function enddadefent
+include <bsm/devalloc.h>
+declaration void enddadefent(void)
+version SUNWprivate_1.1
+end
+
+function freedadefent
+include <bsm/devalloc.h>
+declaration void freedadefent(da_defs_t *)
+version SUNWprivate_1.1
+end
+
+function getdadefent
+include <bsm/devalloc.h>
+declaration da_defs_t *getdadefent(void)
+version SUNWprivate_1.1
+end
+
+function getdadeftype
+include <bsm/devalloc.h>
+declaration da_defs_t *getdadeftype(char *)
+version SUNWprivate_1.1
+end
+
+function da_is_on
+include <bsm/devalloc.h>
+declaration int da_is_on(void)
+version SUNWprivate_1.1
+end
+
+function da_check_logindevperm
+include <bsm/devalloc.h>
+declaration int da_check_logindevperm(char *)
+version SUNWprivate_1.1
+end
+
+function da_open_devdb
+include <bsm/devalloc.h>
+declaration int da_open_devdb(char *, FILE **, FILE **, int)
+version SUNWprivate_1.1
+end
+
+function da_update_device
+include <bsm/devalloc.h>
+declaration int da_update_device(da_args *)
+version SUNWprivate_1.1
+end
+
+function da_update_defattrs
+include <bsm/devalloc.h>
+declaration int da_update_defattrs(da_args *)
+version SUNWprivate_1.1
+end
+
+function da_add_list
+include <bsm/devalloc.h>
+declaration int da_add_list(devlist_t *, char *, int, int)
+version SUNWprivate_1.1
+end
+
+function da_remove_list
+include <bsm/devalloc.h>
+declaration int da_remove_list(devlist_t *, char *, int, char *, int)
+version SUNWprivate_1.1
+end
+
+function da_print_device
+include <bsm/devalloc.h>
+declaration void da_print_device(int, devlist_t *)
+version SUNWprivate_1.1
+end
+
+function getdevicerange
+include <sys/tsol/label.h> <bsm/devices.h>
+declaration int getdevicerange(const char *, brange_t *);
+version SUNWprivate_1.1
+end
diff --git a/usr/src/lib/libbsm/spec/private.spec b/usr/src/lib/libbsm/spec/private.spec
index 1435ae29e9..95cc9e1795 100644
--- a/usr/src/lib/libbsm/spec/private.spec
+++ b/usr/src/lib/libbsm/spec/private.spec
@@ -242,6 +242,18 @@ declaration token_t *au_to_xselect(char *pstring, char *type, \
version SUNWprivate_1.1
end
+function au_to_mylabel
+include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
+declaration token_t *au_to_mylabel(void)
+version SUNWprivate_1.1
+end
+
+function au_to_label
+include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
+declaration token_t *au_to_label(bslabel_t *label)
+version SUNWprivate_1.1
+end
+
function audit_allocate_argv
include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
declaration int audit_allocate_argv(int flg, int argc, char *argv[])
@@ -644,18 +656,6 @@ declaration int cannot_audit(int force)
version SUNWprivate_1.1
end
-function enddaent
-include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
-declaration void enddaent(void)
-version SUNWprivate_1.1
-end
-
-function enddmapent
-include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
-declaration void enddmapent(void)
-version SUNWprivate_1.1
-end
-
function _openac
include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>
declaration au_acinfo_t *_openac(char *)
@@ -704,96 +704,6 @@ declaration int _getacflg(au_acinfo_t *, char *, int)
version SUNWprivate_1.1
end
-function getdadfield
-include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
-declaration char *getdadfield(char *ptr)
-version SUNWprivate_1.1
-end
-
-function getdaent
-include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
-declaration devalloc_t *getdaent(void)
-version SUNWprivate_1.1
-end
-
-function getdafield
-include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
-declaration char *getdafield(char *ptr)
-version SUNWprivate_1.1
-end
-
-function getdanam
-include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
-declaration devalloc_t *getdanam(char *name)
-version SUNWprivate_1.1
-end
-
-function getdatype
-include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
-declaration devalloc_t *getdatype(char *tp)
-version SUNWprivate_1.1
-end
-
-function getdmapdev
-include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
-declaration devmap_t *getdmapdev(char *name)
-version SUNWprivate_1.1
-end
-
-function getdmapdfield
-include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
-declaration char *getdmapdfield(char *ptr)
-version SUNWprivate_1.1
-end
-
-function getdmapent
-include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
-declaration devmap_t *getdmapent(void)
-version SUNWprivate_1.1
-end
-
-function getdmapfield
-include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
-declaration char *getdmapfield(char *ptr)
-version SUNWprivate_1.1
-end
-
-function getdmapnam
-include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
-declaration devmap_t *getdmapnam(char *name)
-version SUNWprivate_1.1
-end
-
-function getdmaptype
-include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
-declaration devmap_t *getdmaptype(char *tp)
-version SUNWprivate_1.1
-end
-
-function setdaent
-include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
-declaration void setdaent(void)
-version SUNWprivate_1.1
-end
-
-function setdafile
-include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
-declaration void setdafile(char *file)
-version SUNWprivate_1.1
-end
-
-function setdmapent
-include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
-declaration void setdmapent(void)
-version SUNWprivate_1.1
-end
-
-function setdmapfile
-include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
-declaration void setdmapfile(char *file)
-version SUNWprivate_1.1
-end
-
function audit_at_create
include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
version SUNWprivate_1.1
@@ -1124,3 +1034,15 @@ errno EAGAIN EBADF EBUSY EFBIG EINTR EINVAL EIO \
ENXIO EPERM EWOULDBLOCK
exception $return == -1
end
+
+function au_to_privset
+include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
+declaration token_t *au_to_privset(const char *priv_type, const priv_set_t *privilege)
+version SUNWprivate_1.1
+end
+
+function au_to_uauth
+include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h>
+declaration token_t *au_to_uauth(char *text)
+version SUNWprivate_1.1
+end
diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile
index f5f2219db9..646428e3e4 100644
--- a/usr/src/lib/libc/amd64/Makefile
+++ b/usr/src/lib/libc/amd64/Makefile
@@ -772,6 +772,7 @@ PORTSYS= \
getpeerucred.o \
inst_sync.o \
issetugid.o \
+ label.o \
libc_link.o \
libc_open.o \
lockf.o \
diff --git a/usr/src/lib/libc/i386/Makefile.com b/usr/src/lib/libc/i386/Makefile.com
index 4e9df745fc..e4156e0ae6 100644
--- a/usr/src/lib/libc/i386/Makefile.com
+++ b/usr/src/lib/libc/i386/Makefile.com
@@ -811,6 +811,7 @@ PORTSYS= \
getpeerucred.o \
inst_sync.o \
issetugid.o \
+ label.o \
libc_link.o \
libc_open.o \
lockf.o \
diff --git a/usr/src/lib/libc/inc/synonyms.h b/usr/src/lib/libc/inc/synonyms.h
index b392b4140a..179f25f627 100644
--- a/usr/src/lib/libc/inc/synonyms.h
+++ b/usr/src/lib/libc/inc/synonyms.h
@@ -481,6 +481,7 @@ extern "C" {
#define isphonogram _isphonogram
#define issetugid _issetugid
#define isspecial _isspecial
+#define is_system_labeled _is_system_labeled
#define iswalnum _iswalnum
#define iswalpha _iswalpha
#define iswcntrl _iswcntrl
@@ -1039,6 +1040,7 @@ extern "C" {
#define ucred_getegid _ucred_getegid
#define ucred_geteuid _ucred_geteuid
#define ucred_getgroups _ucred_getgroups
+#define ucred_getlabel _ucred_getlabel
#define ucred_getpflags _ucred_getpflags
#define ucred_getpid _ucred_getpid
#define ucred_getprivset _ucred_getprivset
diff --git a/usr/src/lib/libc/port/gen/ucred.c b/usr/src/lib/libc/port/gen/ucred.c
index 8367c0f90c..b500617d48 100644
--- a/usr/src/lib/libc/port/gen/ucred.c
+++ b/usr/src/lib/libc/port/gen/ucred.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -43,6 +42,7 @@
#pragma weak ucred_getauid = _ucred_getauid
#pragma weak ucred_getasid = _ucred_getasid
#pragma weak ucred_getatid = _ucred_getatid
+#pragma weak ucred_getlabel = _ucred_getlabel
#pragma weak ucred_getamask = _ucred_getamask
#pragma weak ucred_size = _ucred_size
@@ -66,6 +66,7 @@
#include <sys/procfs.h>
#include <sys/sysmacros.h>
#include <sys/zone.h>
+#include <tsol/label.h>
ucred_t *
_ucred_alloc(void)
@@ -260,6 +261,20 @@ ucred_getzoneid(const ucred_t *uc)
return (uc->uc_zoneid);
}
+bslabel_t *
+ucred_getlabel(const ucred_t *uc)
+{
+ /* LINTED: alignment */
+ bslabel_t *slabel = UCLABEL(uc);
+
+ if (!is_system_labeled() || slabel == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ return (slabel);
+}
+
/*
* For now, assume single bit flags.
*/
diff --git a/usr/src/lib/libc/port/llib-lc b/usr/src/lib/libc/port/llib-lc
index 31c57bd49b..9930b72c9c 100644
--- a/usr/src/lib/libc/port/llib-lc
+++ b/usr/src/lib/libc/port/llib-lc
@@ -1740,3 +1740,6 @@ volatile sc_shared_t *volatile *_thr_schedctl(void);
/* private interface to unmount all autofs mounts */
int _autofssys(enum autofssys_op, void *);
+
+/* label.c */
+extern int is_system_labeled(void);
diff --git a/usr/src/lib/libc/port/sys/label.c b/usr/src/lib/libc/port/sys/label.c
new file mode 100644
index 0000000000..15c476ba8d
--- /dev/null
+++ b/usr/src/lib/libc/port/sys/label.c
@@ -0,0 +1,54 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#pragma weak is_system_labeled = _is_system_labeled
+
+#include "synonyms.h"
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <sys/tsol/tsyscall.h>
+#include <unistd.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "libc.h"
+
+static int _is_labeled = -1;
+
+/*
+ * is_system_labeled :
+ * Return the status of MAC labeling on this system.
+ * Returns 0 if labeling is not installed or not active,
+ */
+int
+is_system_labeled(void)
+{
+ if (_is_labeled >= 0)
+ return (_is_labeled); /* fast path if cached */
+
+ return (_is_labeled = syscall(SYS_labelsys, TSOL_SYSLABELING));
+}
diff --git a/usr/src/lib/libc/port/sys/zone.c b/usr/src/lib/libc/port/sys/zone.c
index fc852c4dd5..12e34c0de6 100644
--- a/usr/src/lib/libc/port/sys/zone.c
+++ b/usr/src/lib/libc/port/sys/zone.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,14 +36,15 @@
#include <sys/priv.h>
#include <priv_private.h>
#include <zone.h>
+#include <sys/tsol/label.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <errno.h>
-extern zoneid_t
+zoneid_t
zone_create(const char *name, const char *root, const struct priv_set *privs,
const char *rctls, size_t rctlsz, const char *zfs, size_t zfssz,
- int *extended_error)
+ int *extended_error, int match, int doi, const bslabel_t *label)
{
zone_def zd;
priv_data_t *d;
@@ -60,6 +60,9 @@ zone_create(const char *name, const char *root, const struct priv_set *privs,
zd.zfsbuf = zfs;
zd.zfsbufsz = zfssz;
zd.extended_error = extended_error;
+ zd.match = match;
+ zd.doi = doi;
+ zd.label = label;
return ((zoneid_t)syscall(SYS_zone, ZONE_CREATE, &zd));
}
diff --git a/usr/src/lib/libc/sparc/Makefile b/usr/src/lib/libc/sparc/Makefile
index 587a8d0306..7b5a74a3a3 100644
--- a/usr/src/lib/libc/sparc/Makefile
+++ b/usr/src/lib/libc/sparc/Makefile
@@ -836,6 +836,7 @@ PORTSYS= \
getpeerucred.o \
inst_sync.o \
issetugid.o \
+ label.o \
libc_link.o \
libc_open.o \
lockf.o \
diff --git a/usr/src/lib/libc/sparcv9/Makefile b/usr/src/lib/libc/sparcv9/Makefile
index d2c0bd1f8c..55d2c9d7be 100644
--- a/usr/src/lib/libc/sparcv9/Makefile
+++ b/usr/src/lib/libc/sparcv9/Makefile
@@ -781,6 +781,7 @@ PORTSYS= \
getpeerucred.o \
inst_sync.o \
issetugid.o \
+ label.o \
libc_link.o \
libc_open.o \
lockf.o \
diff --git a/usr/src/lib/libc/spec/gen.spec b/usr/src/lib/libc/spec/gen.spec
index cf7993a61c..55d40dd946 100644
--- a/usr/src/lib/libc/spec/gen.spec
+++ b/usr/src/lib/libc/spec/gen.spec
@@ -4698,6 +4698,17 @@ weak ucred_getzoneid
version SUNW_1.22
end
+function ucred_getlabel
+include <ucred.h>
+declaration bslabel_t *ucred_getlabel(const ucred_t *)
+version SUNW_1.22.2
+end
+
+function _ucred_getlabel
+weak ucred_getlabel
+version SUNW_1.22.2
+end
+
function ucred_getpflags
include <ucred.h>
declaration uint_t ucred_getpflags(const ucred_t *, uint_t)
diff --git a/usr/src/lib/libc/spec/sys.spec b/usr/src/lib/libc/spec/sys.spec
index 7b181ab7d5..1e928c42b8 100644
--- a/usr/src/lib/libc/spec/sys.spec
+++ b/usr/src/lib/libc/spec/sys.spec
@@ -1,13 +1,12 @@
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 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.
+# 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
# or http://www.opensolaris.org/os/licensing.
@@ -3432,9 +3431,11 @@ end
function zone_create
include <zone.h>
-declaration zoneid_t zone_create(const char *zone_name, \
- const char *zone_root, const priv_set_t *zone_privs, \
- const char *rctlbuf, size_t rctlbufsz, int *)
+declaration zoneid_t zone_create(const char *name, const char *root, \
+ const struct priv_set *privs, const char *rctls, \
+ size_t rctlsz, const char *zfs, size_t zfssz, \
+ int *extended_error, int match, \
+ int doi, const bslabel_t *label)
version SUNWprivate_1.1
exception $return == -1
end
@@ -3519,3 +3520,13 @@ function _getzonenamebyid
weak getzonenamebyid
version SUNWprivate_1.1
end
+
+function is_system_labeled
+declaration int is_system_labeled(void)
+version SUNW_1.22.2
+end
+
+function _is_system_labeled
+weak is_system_labeled
+version SUNWprivate_1.1
+end
diff --git a/usr/src/lib/libc/spec/versions b/usr/src/lib/libc/spec/versions
index 210eb67629..cbfc8b9c6b 100644
--- a/usr/src/lib/libc/spec/versions
+++ b/usr/src/lib/libc/spec/versions
@@ -1,13 +1,12 @@
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 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.
+# 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
# or http://www.opensolaris.org/os/licensing.
@@ -26,6 +25,7 @@
#
i386 {
+ SUNW_1.22.2: {SUNW_1.22.1};
SUNW_1.22.1: {SUNW_1.22};
SUNW_1.22: {SUNW_1.21.3};
SUNW_1.21.3: {SUNW_1.21.2};
@@ -62,6 +62,7 @@ i386 {
SUNWprivate_1.1;
}
amd64 {
+ SUNW_1.22.2: {SUNW_1.22.1};
SUNW_1.22.1: {SUNW_1.22};
SUNW_1.22: {SUNW_1.21.3};
SUNW_1.21.3: {SUNW_1.21.2};
@@ -98,6 +99,7 @@ amd64 {
SUNWprivate_1.1;
}
sparc {
+ SUNW_1.22.2: {SUNW_1.22.1};
SUNW_1.22.1: {SUNW_1.22};
SUNW_1.22: {SUNW_1.21.3};
SUNW_1.21.3: {SUNW_1.21.2};
@@ -135,6 +137,7 @@ sparc {
SUNWprivate_1.1;
}
sparcv9 {
+ SUNW_1.22.2: {SUNW_1.22.1};
SUNW_1.22.1: {SUNW_1.22};
SUNW_1.22: {SUNW_1.21.3};
SUNW_1.21.3: {SUNW_1.21.2};
diff --git a/usr/src/lib/libipsecutil/common/ipsec_util.h b/usr/src/lib/libipsecutil/common/ipsec_util.h
index 70bedb66bd..3e8876db93 100644
--- a/usr/src/lib/libipsecutil/common/ipsec_util.h
+++ b/usr/src/lib/libipsecutil/common/ipsec_util.h
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -45,9 +44,11 @@ extern "C" {
#include <err.h>
#include <net/pfpolicy.h>
+#ifndef A_CNT
/* macros for array manipulation */
#define A_CNT(arr) (sizeof (arr)/sizeof (arr[0]))
#define A_END(arr) (&arr[A_CNT(arr)])
+#endif
/* used for file parsing */
#define NBUF_SIZE 16
diff --git a/usr/src/lib/libldap5/Makefile.com b/usr/src/lib/libldap5/Makefile.com
index b641d18cd3..a90c72761d 100644
--- a/usr/src/lib/libldap5/Makefile.com
+++ b/usr/src/lib/libldap5/Makefile.com
@@ -1,5 +1,25 @@
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -68,7 +88,7 @@ SRCS= $(BEROBJS:%.o=../sources/ldap/ber/%.c) \
LIBS = $(DYNLIB) $(LINTLIB)
DYNFLAGS += $(ZNODELETE)
-CPPFLAGS += -I$(COM_INC)
+CPPFLAGS= $(COM_INC) $(CPPFLAGS.master)
# definitions for lint
diff --git a/usr/src/lib/libnsl/Makefile b/usr/src/lib/libnsl/Makefile
index 756e9d14d1..04728bf54a 100644
--- a/usr/src/lib/libnsl/Makefile
+++ b/usr/src/lib/libnsl/Makefile
@@ -2,9 +2,8 @@
# 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.
+# 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
# or http://www.opensolaris.org/os/licensing.
@@ -18,6 +17,8 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
+
+
#
#
# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
@@ -27,7 +28,7 @@
#
# lib/libnsl/Makefile
#
-PROTOCOL_DIR= $(ROOT)/usr/include/rpcsvc
+PROTOCOL_DIR= $(ROOTHDRDIR)/rpcsvc
PROTOCOL_SRCDIR= $(SRC)/head/rpcsvc
PROTOCOL_UTS_SRCDIR= $(SRC)/uts/common/rpc
@@ -71,9 +72,9 @@ CLEANFILES += $(DERIVED_FILES)
# include library definitions
include ../Makefile.lib
-SED= sed
-CP= cp
-GREP= grep
+# header file delivered to /usr/include; internal to ON build process
+HDRS = nss.h
+HDRDIR = nss
LIBRARY= libnsl.a
TEXT_DOMAIN= SUNW_OST_NETRPC
@@ -99,6 +100,11 @@ headers: $(PROTOCOL_DIR) .WAIT $(PROTOCOL_FILES) $(PROTOCOL_FILES_UTS) \
install: all $(SUBDIRS)
+install_h: $(ROOTHDRS)
+
+# nss.h isn't delivered; no reason to check
+check:
+
clean clobber delete lint package: $(SUBDIRS)
$(PROTOCOL_DIR):
diff --git a/usr/src/lib/libnsl/Makefile.com b/usr/src/lib/libnsl/Makefile.com
index 7945cdb4c2..0159a59cba 100644
--- a/usr/src/lib/libnsl/Makefile.com
+++ b/usr/src/lib/libnsl/Makefile.com
@@ -2,9 +2,8 @@
# 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.
+# 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
# or http://www.opensolaris.org/os/licensing.
@@ -18,6 +17,8 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
+
+
#
#
# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
@@ -190,7 +191,8 @@ MAPOPTS= $(MAPFILES:%=-M%)
# then use the environment variable LD_OPTIONS=-Dgot,detail to have the
# linker print out the list of GOT hogs..
-GOTHOGS = dial.o print_obj.o clnt_perror.o
+GOTHOGS = dial.o print_obj.o clnt_perror.o nsl_stdio_prv.o netdir.o \
+ algs.o netselect.o
BIGPICS = $(GOTHOGS:%=pics/%)
$(BIGPICS) := sparc_C_PICFLAGS = $(C_BIGPICFLAGS)
$(BIGPICS) := i386_C_PICFLAGS = $(C_BIGPICFLAGS)
diff --git a/usr/src/lib/libnsl/nss/nss.h b/usr/src/lib/libnsl/nss/nss.h
index 7efd4e83ee..e3f1463dcd 100644
--- a/usr/src/lib/libnsl/nss/nss.h
+++ b/usr/src/lib/libnsl/nss/nss.h
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -64,6 +63,14 @@ extern void _nss_initf_ipnodes(nss_db_params_t *);
extern void order_haddrlist_af(sa_family_t, char **);
extern int nss_ioctl(int, int, void *);
+/* parse.c */
+extern char *_strtok_escape(char *, char *, char **);
+extern char *_strpbrk_escape(char *, char *);
+extern char *_escape(char *, char *);
+extern char *_unescape(char *, char *);
+extern char *_strdup_null(char *);
+extern int _readbufline(char *, int, char *, int, int *);
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/lib/libnsl/rpc/clnt_bcast.c b/usr/src/lib/libnsl/rpc/clnt_bcast.c
index fc18ed6236..ab16e8a595 100644
--- a/usr/src/lib/libnsl/rpc/clnt_bcast.c
+++ b/usr/src/lib/libnsl/rpc/clnt_bcast.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -43,6 +42,7 @@
*/
#include "mt.h"
+#include "rpc_mt.h"
#include <string.h>
#include <strings.h>
#include <rpc/rpc.h>
@@ -51,8 +51,6 @@
#include <netdir.h>
#ifdef PORTMAP
#include <rpc/pmap_prot.h>
-#include <rpc/pmap_clnt.h>
-#include <rpc/pmap_rmt.h>
#endif
#ifdef RPC_DEBUG
#include <stdio.h>
@@ -187,11 +185,13 @@ rpc_broadcast_exp(const rpcprog_t prog, const rpcvers_t vers,
stat = RPC_CANTSEND;
continue;
}
+ __rpc_set_mac_options(fd, nconf, prog);
if (t_bind(fd, NULL, NULL) == -1) {
(void) t_close(fd);
stat = RPC_CANTSEND;
continue;
}
+
/* Do protocol specific negotiating for broadcast */
if (netdir_options(nconf, ND_SET_BROADCAST, fd, NULL)) {
(void) t_close(fd);
diff --git a/usr/src/lib/libnsl/rpc/clnt_generic.c b/usr/src/lib/libnsl/rpc/clnt_generic.c
index add0dfe880..f3507134ce 100644
--- a/usr/src/lib/libnsl/rpc/clnt_generic.c
+++ b/usr/src/lib/libnsl/rpc/clnt_generic.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -403,6 +402,8 @@ clnt_create_service_timed(const char *host, const char *service,
if (fd < __rpc_minfd)
fd = __rpc_raise_fd(fd);
+ __rpc_set_mac_options(fd, nconf, prog);
+
/* LINTED pointer cast */
if ((tbind = (struct t_bind *)t_alloc(fd, T_BIND, T_ADDR))
== NULL) {
@@ -622,6 +623,7 @@ _clnt_tli_create_timed(int fd, const struct netconfig *nconf,
if (fd < __rpc_minfd)
fd = __rpc_raise_fd(fd);
madefd = TRUE;
+ __rpc_set_mac_options(fd, nconf, prog);
if (t_bind(fd, NULL, NULL) == -1)
goto err;
switch (nconf->nc_semantics) {
diff --git a/usr/src/lib/libnsl/rpc/rpc_mt.h b/usr/src/lib/libnsl/rpc/rpc_mt.h
index 52b49c3a82..75e93f390f 100644
--- a/usr/src/lib/libnsl/rpc/rpc_mt.h
+++ b/usr/src/lib/libnsl/rpc/rpc_mt.h
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -36,6 +35,7 @@
#include <sys/types.h>
#include <rpc/rpc.h>
+#include <netconfig.h>
#ifdef __cplusplus
extern "C" {
@@ -94,6 +94,8 @@ extern int __getpublickey_cached(char *, char *, int *);
extern void __getpublickey_flush(const char *);
extern int __can_use_af(sa_family_t);
extern int __rpc_raise_fd(int);
+extern void __rpc_set_mac_options(int, const struct netconfig *,
+ rpcprog_t);
extern void __tli_sys_strerror(char *, size_t, int, int);
#ifdef __cplusplus
diff --git a/usr/src/lib/libnsl/rpc/svc_dg.c b/usr/src/lib/libnsl/rpc/svc_dg.c
index 8a73cb8faa..b66ba988f0 100644
--- a/usr/src/lib/libnsl/rpc/svc_dg.c
+++ b/usr/src/lib/libnsl/rpc/svc_dg.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@@ -44,6 +43,7 @@
#include "rpc_mt.h"
#include <stdio.h>
#include <sys/types.h>
+#include <sys/sysmacros.h>
#include <rpc/rpc.h>
#include <errno.h>
#include <syslog.h>
@@ -284,6 +284,37 @@ svc_dg_stat(SVCXPRT *xprt)
return (XPRT_IDLE);
}
+/*
+ * Find the SCM_UCRED in src and place a pointer to that option alone in dest.
+ * Note that these two 'netbuf' structures might be the same one, so the code
+ * has to be careful about referring to src after changing dest.
+ */
+static void
+extract_cred(const struct netbuf *src, struct netbuf *dest)
+{
+ char *cp = src->buf;
+ unsigned int len = src->len;
+ const struct T_opthdr *opt;
+ unsigned int olen;
+
+ while (len >= sizeof (*opt)) {
+ /* LINTED: pointer alignment */
+ opt = (const struct T_opthdr *)cp;
+ olen = opt->len;
+ if (olen > len || olen < sizeof (*opt) ||
+ !IS_P2ALIGNED(olen, sizeof (t_uscalar_t)))
+ break;
+ if (opt->level == SOL_SOCKET && opt->name == SCM_UCRED) {
+ dest->buf = cp;
+ dest->len = olen;
+ return;
+ }
+ cp += olen;
+ len -= olen;
+ }
+ dest->len = 0;
+}
+
static bool_t
svc_dg_recv(SVCXPRT *xprt, struct rpc_msg *msg)
{
@@ -354,9 +385,10 @@ again:
/* tu_data.addr is already set */
tu_data->udata.buf = reply;
tu_data->udata.len = (uint_t)replylen;
- tu_data->opt.len = 0;
+ extract_cred(&tu_data->opt, &tu_data->opt);
(void) t_sndudata(xprt->xp_fd, tu_data);
tu_data->udata.buf = (char *)rpc_buffer(xprt);
+ tu_data->opt.buf = (char *)su->opts;
return (FALSE);
}
}
@@ -425,7 +457,7 @@ svc_dg_reply(SVCXPRT *xprt, struct rpc_msg *msg)
slen = (int)XDR_GETPOS(xdrs);
tu_data->udata.len = slen;
- tu_data->opt.len = 0;
+ extract_cred(&su->optbuf, &tu_data->opt);
try_again:
if (t_sndudata(xprt->xp_fd, tu_data) == 0) {
stat = TRUE;
@@ -440,6 +472,7 @@ try_again:
"svc_dg_reply: t_sndudata error t_errno=%d errno=%d\n",
t_errno, errno);
}
+ tu_data->opt.buf = (char *)su->opts;
}
return (stat);
}
diff --git a/usr/src/lib/libnsl/rpc/svc_generic.c b/usr/src/lib/libnsl/rpc/svc_generic.c
index 10f6ce1508..a0673e43c8 100644
--- a/usr/src/lib/libnsl/rpc/svc_generic.c
+++ b/usr/src/lib/libnsl/rpc/svc_generic.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -52,7 +51,14 @@
#include <malloc.h>
#include <string.h>
#include <stropts.h>
-
+#include <tsol/label.h>
+#include <nfs/nfs.h>
+#include <nfs/nfs_acl.h>
+#include <rpcsvc/mount.h>
+#include <rpcsvc/nsm_addr.h>
+#include <rpcsvc/rquota.h>
+#include <rpcsvc/sm_inter.h>
+#include <rpcsvc/nlm_prot.h>
extern int __svc_vc_setflag(SVCXPRT *, int);
@@ -80,6 +86,22 @@ extern bool_t __rpc_try_doors(const char *, bool_t *);
SVCXPRT_LIST *_svc_xprtlist = NULL;
extern mutex_t xprtlist_lock;
+static SVCXPRT * svc_tli_create_common(int, const struct netconfig *,
+ const struct t_bind *, uint_t, uint_t, boolean_t);
+
+boolean_t
+is_multilevel(rpcprog_t prognum)
+{
+ /* This is a list of identified multilevel service provider */
+ if ((prognum == MOUNTPROG) || (prognum == NFS_PROGRAM) ||
+ (prognum == NFS_ACL_PROGRAM) || (prognum == NLM_PROG) ||
+ (prognum == NSM_ADDR_PROGRAM) || (prognum == RQUOTAPROG) ||
+ (prognum == SM_PROG))
+ return (B_TRUE);
+
+ return (B_FALSE);
+}
+
void
__svc_free_xprtlist(void)
{
@@ -162,6 +184,7 @@ svc_tp_create(void (*dispatch)(), const rpcprog_t prognum,
const rpcvers_t versnum, const struct netconfig *nconf)
{
SVCXPRT *xprt;
+ boolean_t anon_mlp = B_FALSE;
if (nconf == NULL) {
(void) syslog(LOG_ERR,
@@ -169,7 +192,11 @@ svc_tp_create(void (*dispatch)(), const rpcprog_t prognum,
prognum, versnum);
return (NULL);
}
- xprt = svc_tli_create(RPC_ANYFD, nconf, NULL, 0, 0);
+
+ /* Some programs need to allocate MLP for multilevel services */
+ if (is_system_labeled() && is_multilevel(prognum))
+ anon_mlp = B_TRUE;
+ xprt = svc_tli_create_common(RPC_ANYFD, nconf, NULL, 0, 0, anon_mlp);
if (xprt == NULL)
return (NULL);
(void) rpcb_unset(prognum, versnum, (struct netconfig *)nconf);
@@ -183,6 +210,13 @@ svc_tp_create(void (*dispatch)(), const rpcprog_t prognum,
return (xprt);
}
+SVCXPRT *
+svc_tli_create(const int fd, const struct netconfig *nconf,
+ const struct t_bind *bindaddr, const uint_t sendsz, const uint_t recvsz)
+{
+ return (svc_tli_create_common(fd, nconf, bindaddr, sendsz, recvsz, 0));
+}
+
/*
* If fd is RPC_ANYFD, then it opens a fd for the given transport
* provider (nconf cannot be NULL then). If the t_state is T_UNBND and
@@ -193,8 +227,9 @@ svc_tp_create(void (*dispatch)(), const rpcprog_t prognum,
* If sendsz or recvsz are zero, their default values are chosen.
*/
SVCXPRT *
-svc_tli_create(const int ofd, const struct netconfig *nconf,
- const struct t_bind *bindaddr, const uint_t sendsz, const uint_t recvsz)
+svc_tli_create_common(const int ofd, const struct netconfig *nconf,
+ const struct t_bind *bindaddr, const uint_t sendsz,
+ const uint_t recvsz, boolean_t mlp_flag)
{
SVCXPRT *xprt = NULL; /* service handle */
struct t_info tinfo; /* transport info */
@@ -293,6 +328,17 @@ svc_tli_create(const int ofd, const struct netconfig *nconf,
switch (state) {
bool_t tcp, exclbind;
case T_UNBND:
+ /* If this is a labeled system, then ask for an MLP */
+ if (is_system_labeled() &&
+ (strcmp(nconf->nc_protofmly, NC_INET) == 0 ||
+ strcmp(nconf->nc_protofmly, NC_INET6) == 0)) {
+ (void) __rpc_tli_set_options(fd, SOL_SOCKET,
+ SO_RECVUCRED, 1);
+ if (mlp_flag)
+ (void) __rpc_tli_set_options(fd, SOL_SOCKET,
+ SO_ANON_MLP, 1);
+ }
+
/*
* {TCP,UDP}_EXCLBIND has the following properties
* - an fd bound to port P via IPv4 will prevent an IPv6
diff --git a/usr/src/lib/libnsl/rpc/ti_opts.c b/usr/src/lib/libnsl/rpc/ti_opts.c
index 1b5e910261..ae32fa9788 100644
--- a/usr/src/lib/libnsl/rpc/ti_opts.c
+++ b/usr/src/lib/libnsl/rpc/ti_opts.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -59,11 +58,10 @@
#include <alloca.h>
#include <stdlib.h>
#include <zone.h>
+#include <tsol/label.h>
-extern const char *inet_ntop(int, const void *, char *, socklen_t);
extern bool_t __svc_get_door_ucred(const SVCXPRT *, ucred_t *);
-
/*
* This routine is typically called on the server side if the server
* wants to know the caller ucred. Called typically by rpcbind. It
@@ -494,6 +492,8 @@ __rpc_tli_set_options(int fd, int optlevel, int optname, int optval)
case SO_REUSEADDR:
case SO_DGRAM_ERRIND:
case SO_RECVUCRED:
+ case SO_ANON_MLP:
+ case SO_MAC_EXEMPT:
case TCP_EXCLBIND:
case UDP_EXCLBIND:
/* LINTED */
@@ -548,3 +548,34 @@ __tli_sys_strerror(char *buf, size_t buflen, int tli_err, int sys_err)
(void) strlcpy(buf, errorstr, buflen);
}
}
+
+/*
+ * Depending on the specified RPC number, attempt to set mac_exempt
+ * option on the opened socket; these requests need to be able to do MAC
+ * MAC read-down operations. Privilege is needed to set this option.
+ */
+
+void
+__rpc_set_mac_options(int fd, const struct netconfig *nconf, rpcprog_t prognum)
+{
+ int ret = 0;
+
+ if (!is_system_labeled())
+ return;
+
+ if (strcmp(nconf->nc_protofmly, NC_INET) != 0 &&
+ strcmp(nconf->nc_protofmly, NC_INET6) != 0)
+ return;
+
+ if (is_multilevel(prognum)) {
+ ret = __rpc_tli_set_options(fd, SOL_SOCKET, SO_MAC_EXEMPT, 1);
+ if (ret < 0) {
+ char errorstr[100];
+
+ __tli_sys_strerror(errorstr, sizeof (errorstr),
+ t_errno, errno);
+ (void) syslog(LOG_ERR, "rpc_set_mac_options: %s",
+ errorstr);
+ }
+ }
+}
diff --git a/usr/src/lib/libsldap/common/ns_common.c b/usr/src/lib/libsldap/common/ns_common.c
index b3a812e92f..05323c204b 100644
--- a/usr/src/lib/libsldap/common/ns_common.c
+++ b/usr/src/lib/libsldap/common/ns_common.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -82,6 +81,8 @@ static ns_service_map ns_def_map[] = {
{ "profile", "ou=profile,", NULL },
{ "printers", "ou=printers,", NULL },
{ "automount", "", NULL },
+ { "tnrhtp", "ou=ipTnet,", NULL },
+ { "tnrhdb", "ou=ipTnet,", "tnrhtp" },
{ NULL, NULL, NULL }
};
diff --git a/usr/src/lib/libsldap/common/ns_sldap.h b/usr/src/lib/libsldap/common/ns_sldap.h
index 8e8c59113c..0138c1e3d5 100644
--- a/usr/src/lib/libsldap/common/ns_sldap.h
+++ b/usr/src/lib/libsldap/common/ns_sldap.h
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -450,6 +449,8 @@ typedef struct _ns_automount {
#define NS_LDAP_TYPE_AUUSER "audit_user"
#define NS_LDAP_TYPE_BOOTPARAMS "bootparams"
#define NS_LDAP_TYPE_AUTOMOUNT "auto_"
+#define NS_LDAP_TYPE_TNRHDB "tnrhdb"
+#define NS_LDAP_TYPE_TNRHTP "tnrhtp"
/*
* service descriptor/attribute mapping structure
diff --git a/usr/src/lib/libsldap/common/ns_writes.c b/usr/src/lib/libsldap/common/ns_writes.c
index 146752c88a..217586e340 100644
--- a/usr/src/lib/libsldap/common/ns_writes.c
+++ b/usr/src/lib/libsldap/common/ns_writes.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -56,6 +55,8 @@
#include <prof_attr.h>
#include <user_attr.h>
#include <bsm/libbsm.h>
+#include <sys/tsol/tndb.h>
+#include <tsol/label.h>
/*
@@ -3246,7 +3247,128 @@ __s_cvt_audituser(const void *data, char **rdn,
return (NS_LDAP_SUCCESS);
}
+/*
+ * Conversion: tnrhtp
+ * Input format: tsol_tpstr_t
+ * Exported objectclass: ipTnetTemplate
+ */
+static int
+__s_cvt_tnrhtp(const void *data, char **rdn,
+ ns_ldap_entry_t **entry, ns_ldap_error_t **errorp)
+{
+ ns_ldap_entry_t *e;
+ int rc;
+ char trdn[RDNSIZE];
+ /* routine specific */
+ int max_attr = 2;
+ tsol_tpstr_t *ptr;
+ static char *oclist[] = {
+ "ipTnetTemplate",
+ "top",
+ NULL
+ };
+
+ if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL)
+ return (NS_LDAP_OP_FAILED);
+
+ *entry = e = __s_mk_entry(oclist, max_attr);
+ if (e == NULL)
+ return (NS_LDAP_MEMORY);
+
+ /* Convert the structure */
+ ptr = (tsol_tpstr_t *)data;
+
+ if ((ptr->template == NULL) || (strlen(ptr->template) <= 1)) {
+ __ns_ldap_freeEntry(e);
+ *entry = NULL;
+ return (NS_LDAP_INVALID_PARAM);
+ }
+
+ /* Create an appropriate rdn */
+ (void) snprintf(trdn, RDNSIZE, "ipTnetTemplateName=%s", ptr->template);
+ *rdn = strdup(trdn);
+ if (*rdn == NULL) {
+ __ns_ldap_freeEntry(e);
+ *entry = NULL;
+ return (NS_LDAP_MEMORY);
+ }
+
+ rc = __s_add_attr(e, "ipTnetTemplateName", ptr->template);
+ if (rc != NS_LDAP_SUCCESS) {
+ __s_cvt_freeEntryRdn(entry, rdn);
+ return (rc);
+ }
+
+ rc = __s_add_attr(e, "SolarisAttrKeyValue", ptr->attrs);
+ if (rc != NS_LDAP_SUCCESS) {
+ __s_cvt_freeEntryRdn(entry, rdn);
+ return (rc);
+ }
+ return (NS_LDAP_SUCCESS);
+}
+/*
+ * Conversion: tnrhdb
+ * Input format: tsol_rhstr_t
+ * Exported objectclass: ipTnetHost
+ */
+static int
+__s_cvt_tnrhdb(const void *data, char **rdn,
+ ns_ldap_entry_t **entry, ns_ldap_error_t **errorp)
+{
+ ns_ldap_entry_t *e;
+ int rc;
+ char trdn[RDNSIZE];
+ /* routine specific */
+ tsol_rhstr_t *ptr;
+ int max_attr = 2;
+ static char *oclist[] = {
+ "ipTnetHost",
+ "ipTnetTemplate",
+ "top",
+ NULL
+ };
+
+ if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL)
+ return (NS_LDAP_OP_FAILED);
+
+ *entry = e = __s_mk_entry(oclist, max_attr);
+ if (e == NULL)
+ return (NS_LDAP_MEMORY);
+
+ /* Convert the structure */
+ ptr = (tsol_rhstr_t *)data;
+
+ if ((ptr->address == NULL) || (strlen(ptr->address) <= 1) ||
+ (ptr->template == NULL) || (strlen(ptr->template) <= 1)) {
+ __ns_ldap_freeEntry(e);
+ *entry = NULL;
+ return (NS_LDAP_INVALID_PARAM);
+ }
+
+ /* Create an appropriate rdn */
+ (void) snprintf(trdn, RDNSIZE, "ipTnetNumber=%s", ptr->address);
+ *rdn = strdup(trdn);
+ if (*rdn == NULL) {
+ __ns_ldap_freeEntry(e);
+ *entry = NULL;
+ return (NS_LDAP_MEMORY);
+ }
+
+ rc = __s_add_attr(e, "ipTnetNumber", ptr->address);
+ if (rc != NS_LDAP_SUCCESS) {
+ __s_cvt_freeEntryRdn(entry, rdn);
+ return (rc);
+ }
+
+ rc = __s_add_attr(e, "ipTnetTemplateName", ptr->template);
+ if (rc != NS_LDAP_SUCCESS) {
+ __s_cvt_freeEntryRdn(entry, rdn);
+ return (rc);
+ }
+
+ return (NS_LDAP_SUCCESS);
+}
/*
* Add Typed Entry Conversion data structures
*/
@@ -3283,6 +3405,8 @@ static __ns_cvt_type_t __s_cvtlist[] = {
{ NS_LDAP_TYPE_AUTOMOUNT, 0, __s_cvt_auto_mount },
{ NS_LDAP_TYPE_PUBLICKEY, AE, __s_cvt_publickey },
{ NS_LDAP_TYPE_AUUSER, AE, __s_cvt_audituser },
+ { NS_LDAP_TYPE_TNRHTP, 0, __s_cvt_tnrhtp },
+ { NS_LDAP_TYPE_TNRHDB, 0, __s_cvt_tnrhdb },
{ NULL, 0, NULL },
};
diff --git a/usr/src/lib/libtsnet/Makefile b/usr/src/lib/libtsnet/Makefile
new file mode 100644
index 0000000000..aa06ccdef0
--- /dev/null
+++ b/usr/src/lib/libtsnet/Makefile
@@ -0,0 +1,67 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.lib
+
+HDRS = libtsnet.h
+HDRDIR = common
+SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+all := TARGET= all
+clean := TARGET= clean
+clobber := TARGET= clobber
+install := TARGET= install
+lint := TARGET= lint
+
+POFILE = libtsnet.po
+MSGFILES = common/misc.i
+
+.KEEP_STATE:
+
+all install: spec .WAIT $(SUBDIRS)
+
+clean clobber: spec $(SUBDIRS)
+
+lint: $(SUBDIRS)
+
+install_h: $(ROOTHDRS)
+
+check: $(CHECKHDRS)
+
+_msg: $(MSGDOMAINPOFILE)
+
+$(POFILE): $(MSGFILES)
+ $(BUILDPO.msgfiles)
+
+spec $(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include $(SRC)/Makefile.msg.targ
+include ../Makefile.targ
diff --git a/usr/src/lib/libtsnet/Makefile.com b/usr/src/lib/libtsnet/Makefile.com
new file mode 100644
index 0000000000..c77b2403ad
--- /dev/null
+++ b/usr/src/lib/libtsnet/Makefile.com
@@ -0,0 +1,63 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+LIBRARY = libtsnet.a
+VERS = .1
+
+OBJECTS = \
+ misc.o \
+ tnrh.o tnrhtp.o tnmlp.o \
+ tsol_getrhent.o tsol_gettpent.o \
+ tsol_sgetrhent.o tsol_sgettpent.o tsol_sgetzcent.o
+
+include ../../Makefile.lib
+
+# install this library in the root filesystem
+include ../../Makefile.rootfs
+
+LIBS = $(DYNLIB) $(LINTLIB)
+$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC)
+
+LAZYLIBS = $(ZLAZYLOAD) -ltsol $(ZNOLAZYLOAD)
+LDLIBS += -lsocket -lnsl -lc -lsecdb $(LAZYLIBS)
+lint := LAZYLIBS = -ltsol
+
+SRCDIR = ../common
+MAPDIR = ../spec/$(TRANSMACH)
+SPECMAPFILE = $(MAPDIR)/mapfile
+
+LIBTSOLINC = $(SRC)/lib/libtsol/common
+
+CPPFLAGS += -D_REENTRANT -I$(LIBTSOLINC)
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+lint: lintcheck
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/libtsnet/amd64/Makefile b/usr/src/lib/libtsnet/amd64/Makefile
new file mode 100644
index 0000000000..69cf39010b
--- /dev/null
+++ b/usr/src/lib/libtsnet/amd64/Makefile
@@ -0,0 +1,31 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+include ../Makefile.com
+include ../../Makefile.lib.64
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
diff --git a/usr/src/lib/libtsnet/common/libtsnet.h b/usr/src/lib/libtsnet/common/libtsnet.h
new file mode 100644
index 0000000000..2aa6d5fc56
--- /dev/null
+++ b/usr/src/lib/libtsnet/common/libtsnet.h
@@ -0,0 +1,148 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * All symbols and functions in this header file and library are private to Sun
+ * Microsystems. The only guarantee that is made is that if your application
+ * uses them, it will break on upgrade.
+ */
+
+#ifndef _LIBTSNET_H
+#define _LIBTSNET_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <sys/tsol/tndb.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TNRHTP_PATH "/etc/security/tsol/tnrhtp"
+#define TNRHDB_PATH "/etc/security/tsol/tnrhdb"
+#define TNZONECFG_PATH "/etc/security/tsol/tnzonecfg"
+
+#define TNDB_COMMA ", \t"
+
+/*
+ * String parsing routines
+ *
+ * These functions are in four logical groups: one for template (tnrhtp)
+ * entries, one for remote host (tnrhdb) entries, one for zone configuration
+ * (tnzonecfg) entries, and a fourth for routing attributes.
+ *
+ * In each group, there are functions that parse from a string or database, and
+ * a function to free returned entries. The parsing functions all take a
+ * pointer to an integer and a pointer to a character pointer for returning
+ * errors. On error, the returned entry pointer is NULL, the integer is set to
+ * one of the LTSNET_* errors below, and the character pointer points to the
+ * location of the error. (For the functions that iterate on a database, this
+ * points into static storage in the library. This storage is associated with
+ * the iterator.)
+ *
+ * The functions that do look-ups based on a value (name or address) do not
+ * return errors other than "not found," which is signaled by a return value of
+ * NULL.
+ */
+
+/* Template entry parsing */
+extern tsol_tpent_t *tsol_gettpbyname(const char *);
+extern tsol_tpent_t *tsol_gettpent(void);
+extern tsol_tpent_t *tsol_fgettpent(FILE *);
+extern void tsol_freetpent(tsol_tpent_t *);
+extern void tsol_settpent(int);
+extern void tsol_endtpent(void);
+extern int str_to_tpstr(const char *, int, void *, char *, int);
+extern tsol_tpent_t *tpstr_to_ent(tsol_tpstr_t *, int *, char **);
+
+/* Remote host entry parsing */
+extern tsol_rhent_t *tsol_getrhbyaddr(const void *, size_t, int);
+extern tsol_rhent_t *tsol_getrhent(void);
+extern tsol_rhent_t *tsol_fgetrhent(FILE *);
+extern void tsol_freerhent(tsol_rhent_t *);
+extern void tsol_setrhent(int);
+extern void tsol_endrhent(void);
+extern int str_to_rhstr(const char *, int, void *, char *, int);
+extern tsol_rhent_t *rhstr_to_ent(tsol_rhstr_t *, int *, char **);
+extern tsol_host_type_t tsol_getrhtype(char *);
+
+
+/* Zone configuration parsing */
+extern tsol_zcent_t *tsol_sgetzcent(const char *, int *, char **);
+extern void tsol_freezcent(tsol_zcent_t *);
+
+/* Routing attribute parsing */
+extern const char *sl_to_str(const bslabel_t *);
+struct rtsa_s;
+extern const char *rtsa_to_str(const struct rtsa_s *, char *, size_t);
+extern boolean_t rtsa_keyword(const char *, struct rtsa_s *, int *, char **);
+extern const char *parse_entry(char *, size_t, const char *, const char *);
+
+/* Convert LTSNET_* to a printable string */
+extern const char *tsol_strerror(int, int);
+
+/* System calls; these return -1 on error and set errno */
+extern int tnrhtp(int, tsol_tpent_t *);
+extern int tnrh(int, tsol_rhent_t *);
+extern int tnmlp(int, tsol_mlpent_t *);
+
+/*
+ * Errors that can occur in the parsing routines. Note that not all errors are
+ * possible with every routine. Must be kept in sync with list in misc.c.
+ */
+#define LTSNET_NONE 0 /* No error */
+#define LTSNET_SYSERR 1 /* System error; see errno */
+#define LTSNET_EMPTY 2 /* Empty string or end of list */
+#define LTSNET_ILL_ENTRY 3 /* Entry is malformed */
+#define LTSNET_NO_NAME 4 /* Missing name */
+#define LTSNET_NO_ATTRS 5 /* Missing template attributes */
+#define LTSNET_ILL_NAME 6 /* Illegal name */
+#define LTSNET_ILL_KEYDELIM 7 /* Illegal keyword delimiter */
+#define LTSNET_ILL_KEY 8 /* Unknown keyword */
+#define LTSNET_DUP_KEY 9 /* Duplicate keyword */
+#define LTSNET_ILL_VALDELIM 10 /* Illegal value delimiter */
+#define LTSNET_NO_HOSTTYPE 11 /* Missing host type */
+#define LTSNET_ILL_HOSTTYPE 12 /* Illegal host type */
+#define LTSNET_NO_LABEL 13 /* Missing label */
+#define LTSNET_ILL_LABEL 14 /* Illegal label */
+#define LTSNET_NO_RANGE 15 /* Missing label range */
+#define LTSNET_ILL_RANGE 16 /* Illegal label range */
+#define LTSNET_NO_LOWERBOUND 17 /* No lower bound in range */
+#define LTSNET_ILL_LOWERBOUND 18 /* Illegal lower bound in range */
+#define LTSNET_NO_UPPERBOUND 19 /* No upper bound in range */
+#define LTSNET_ILL_UPPERBOUND 20 /* Illegal upper bound in range */
+#define LTSNET_NO_DOI 21 /* Missing DOI */
+#define LTSNET_ILL_DOI 22 /* Illegal DOI */
+#define LTSNET_SET_TOO_BIG 23 /* Too many entries in set */
+#define LTSNET_NO_ADDR 24 /* Missing address/network */
+#define LTSNET_ILL_ADDR 25 /* Illegal address/network */
+#define LTSNET_ILL_FLAG 26 /* Illegal flag */
+#define LTSNET_ILL_MLP 27 /* Illegal MLP specification */
+#define LTSNET_BAD_TYPE 28 /* Unacceptable keyword for type */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBTSNET_H */
diff --git a/usr/src/lib/libtsnet/common/llib-ltsnet b/usr/src/lib/libtsnet/common/llib-ltsnet
new file mode 100644
index 0000000000..4dbadf3b68
--- /dev/null
+++ b/usr/src/lib/libtsnet/common/llib-ltsnet
@@ -0,0 +1,32 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/* LINTLIBRARY */
+/* PROTOLIB1 */
+
+#include <libtsnet.h>
diff --git a/usr/src/lib/libtsnet/common/misc.c b/usr/src/lib/libtsnet/common/misc.c
new file mode 100644
index 0000000000..9e8c20cdc8
--- /dev/null
+++ b/usr/src/lib/libtsnet/common/misc.c
@@ -0,0 +1,359 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * From "misc.c 5.15 00/05/31 SMI; TSOL 2.x"
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Miscellaneous user interfaces to trusted label functions.
+ */
+
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <errno.h>
+#include <libintl.h>
+#include <libtsnet.h>
+#include <tsol/label.h>
+
+#include <net/route.h>
+
+#define MAX_STRING_SIZE 256
+#define MAX_ATTR_LEN 1024
+
+/*
+ * Parse off an entry from a line. Entry is stored in 'outbuf'. Returned
+ * value is a pointer to the first unprocessed input character from 'instr'.
+ */
+const char *
+parse_entry(char *outbuf, size_t outlen, const char *instr,
+ const char *delimit)
+{
+ boolean_t escape_state = B_FALSE;
+ boolean_t any_white;
+ char chr;
+
+ any_white = strchr(delimit, '\n') != NULL;
+
+ /*
+ * User may specify outlen as 0 to skip over a field without storing
+ * it anywhere. Otherwise, we need at least one byte for the
+ * terminating NUL plus one byte to store another byte from instr.
+ */
+ while (outlen != 1 && (chr = *instr++) != '\0') {
+ if (!escape_state) {
+ if (chr == '\\') {
+ escape_state = B_TRUE;
+ continue;
+ }
+ if (strchr(delimit, chr) != NULL)
+ break;
+ if (any_white && isspace(chr))
+ break;
+ }
+ escape_state = B_FALSE;
+ if (outlen > 0) {
+ *outbuf++ = chr;
+ outlen--;
+ }
+ }
+ if (outlen != 1)
+ instr--;
+ if (escape_state)
+ instr--;
+ if (outlen > 0)
+ *outbuf = '\0';
+ return (instr);
+}
+
+const char *
+sl_to_str(const bslabel_t *sl)
+{
+ const char *sl_str;
+ static const char unknown_str[] = "UNKNOWN";
+
+ if (sl == NULL)
+ return (unknown_str);
+
+ if ((sl_str = sbsltos(sl, MAX_STRING_SIZE)) == NULL &&
+ (sl_str = bsltoh(sl)) == NULL)
+ sl_str = unknown_str;
+ return (sl_str);
+}
+
+static const char *rtsa_keywords[] = {
+#define SAK_MINSL 0
+ "min_sl",
+#define SAK_MAXSL 1
+ "max_sl",
+#define SAK_DOI 2
+ "doi",
+#define SAK_CIPSO 3
+ "cipso",
+#define SAK_INVAL 4
+ NULL
+};
+
+const char *
+rtsa_to_str(const struct rtsa_s *rtsa, char *line, size_t len)
+{
+ size_t slen;
+ uint32_t mask, i;
+
+ slen = 0;
+ *line = '\0';
+ mask = rtsa->rtsa_mask;
+
+ for (i = 1; mask != 0 && i != 0 && slen < len - 1; i <<= 1) {
+ if (!(i & (RTSA_MINSL|RTSA_MAXSL|RTSA_DOI|RTSA_CIPSO)))
+ continue;
+ if (!(i & mask))
+ continue;
+ if (slen != 0)
+ line[slen++] = ',';
+ switch (i & mask) {
+ case RTSA_MINSL:
+ slen += snprintf(line + slen, len - slen, "min_sl=%s",
+ sl_to_str(&rtsa->rtsa_slrange.lower_bound));
+ break;
+ case RTSA_MAXSL:
+ slen += snprintf(line + slen, len - slen, "max_sl=%s",
+ sl_to_str(&rtsa->rtsa_slrange.upper_bound));
+ break;
+ case RTSA_DOI:
+ slen += snprintf(line + slen, len - slen, "doi=%d",
+ rtsa->rtsa_doi);
+ break;
+ case RTSA_CIPSO:
+ slen += snprintf(line + slen, len - slen, "cipso");
+ break;
+ }
+ }
+
+ return (line);
+}
+
+boolean_t
+rtsa_keyword(const char *options, struct rtsa_s *sp, int *errp, char **errstrp)
+{
+ const char *valptr, *nxtopt;
+ uint32_t mask = 0, doi;
+ int key;
+ bslabel_t min_sl, max_sl;
+ char attrbuf[MAX_ATTR_LEN];
+ const char **keyword;
+ int err;
+ char *errstr, *cp;
+
+ if (errp == NULL)
+ errp = &err;
+ if (errstrp == NULL)
+ errstrp = &errstr;
+
+ *errstrp = (char *)options;
+
+ while (*options != '\0') {
+ valptr = parse_entry(attrbuf, sizeof (attrbuf), options, ",=");
+
+ if (attrbuf[0] == '\0') {
+ *errstrp = (char *)options;
+ *errp = LTSNET_ILL_ENTRY;
+ return (B_FALSE);
+ }
+ for (keyword = rtsa_keywords; *keyword != NULL; keyword++)
+ if (strcmp(*keyword, attrbuf) == 0)
+ break;
+ if ((key = keyword - rtsa_keywords) == SAK_INVAL) {
+ *errstrp = (char *)options;
+ *errp = LTSNET_ILL_KEY;
+ return (B_FALSE);
+ }
+ if ((key == SAK_CIPSO && *valptr == '=') ||
+ (key != SAK_CIPSO && *valptr != '=')) {
+ *errstrp = (char *)valptr;
+ *errp = LTSNET_ILL_VALDELIM;
+ return (B_FALSE);
+ }
+
+ nxtopt = valptr;
+ if (*valptr == '=') {
+ valptr++;
+ nxtopt = parse_entry(attrbuf, sizeof (attrbuf),
+ valptr, ",=");
+ if (*nxtopt == '=') {
+ *errstrp = (char *)nxtopt;
+ *errp = LTSNET_ILL_KEYDELIM;
+ return (B_FALSE);
+ }
+ }
+ if (*nxtopt == ',')
+ nxtopt++;
+
+ switch (key) {
+ case SAK_MINSL:
+ if (mask & RTSA_MINSL) {
+ *errstrp = (char *)options;
+ *errp = LTSNET_DUP_KEY;
+ return (B_FALSE);
+ }
+ if (stobsl(attrbuf, &min_sl, NO_CORRECTION,
+ &err) != 1) {
+ *errstrp = (char *)valptr;
+ *errp = LTSNET_ILL_LOWERBOUND;
+ return (B_FALSE);
+ }
+ mask |= RTSA_MINSL;
+ break;
+
+ case SAK_MAXSL:
+ if (mask & RTSA_MAXSL) {
+ *errstrp = (char *)options;
+ *errp = LTSNET_DUP_KEY;
+ return (B_FALSE);
+ }
+ if (stobsl(attrbuf, &max_sl, NO_CORRECTION,
+ &err) != 1) {
+ *errstrp = (char *)valptr;
+ *errp = LTSNET_ILL_UPPERBOUND;
+ return (B_FALSE);
+ }
+ mask |= RTSA_MAXSL;
+ break;
+
+ case SAK_DOI:
+ if (mask & RTSA_DOI) {
+ *errstrp = (char *)options;
+ *errp = LTSNET_DUP_KEY;
+ return (B_FALSE);
+ }
+ errno = 0;
+ doi = strtoul(attrbuf, &cp, 0);
+ if (doi == 0 || errno != 0 || *cp != '\0') {
+ *errstrp = (char *)valptr;
+ *errp = LTSNET_ILL_DOI;
+ return (B_FALSE);
+ }
+ mask |= RTSA_DOI;
+ break;
+
+ case SAK_CIPSO:
+ if (mask & RTSA_CIPSO) {
+ *errstrp = (char *)options;
+ *errp = LTSNET_DUP_KEY;
+ return (B_FALSE);
+ }
+ mask |= RTSA_CIPSO;
+ break;
+ }
+
+ options = nxtopt;
+ }
+
+ /* Defaults to CIPSO if not specified */
+ mask |= RTSA_CIPSO;
+
+ /* If RTSA_CIPSO is specified, RTSA_DOI must be specified */
+ if (!(mask & RTSA_DOI)) {
+ *errp = LTSNET_NO_DOI;
+ return (B_FALSE);
+ }
+
+ /* SL range must be specified */
+ if (!(mask & (RTSA_MINSL|RTSA_MAXSL))) {
+ *errp = LTSNET_NO_RANGE;
+ return (B_FALSE);
+ }
+ if (!(mask & RTSA_MINSL)) {
+ *errp = LTSNET_NO_LOWERBOUND;
+ return (B_FALSE);
+ }
+ if (!(mask & RTSA_MAXSL)) {
+ *errp = LTSNET_NO_UPPERBOUND;
+ return (B_FALSE);
+ }
+
+ /* SL range must have upper bound dominating lower bound */
+ if (!bldominates(&max_sl, &min_sl)) {
+ *errp = LTSNET_ILL_RANGE;
+ return (B_FALSE);
+ }
+
+ if (mask & RTSA_MINSL)
+ sp->rtsa_slrange.lower_bound = min_sl;
+ if (mask & RTSA_MAXSL)
+ sp->rtsa_slrange.upper_bound = max_sl;
+ if (mask & RTSA_DOI)
+ sp->rtsa_doi = doi;
+ sp->rtsa_mask = mask;
+
+ return (B_TRUE);
+}
+
+/* Keep in sync with libtsnet.h */
+static const char *tsol_errlist[] = {
+ "No error",
+ "System error",
+ "Empty string or end of list",
+ "Entry is malformed",
+ "Missing name",
+ "Missing attributes",
+ "Illegal name",
+ "Illegal keyword delimiter",
+ "Unknown keyword",
+ "Duplicate keyword",
+ "Illegal value delimiter",
+ "Missing host type",
+ "Illegal host type",
+ "Missing label",
+ "Illegal label",
+ "Missing label range",
+ "Illegal label range",
+ "No lower bound in range",
+ "Illegal lower bound in range",
+ "No upper bound in range",
+ "Illegal upper bound in range",
+ "Missing DOI",
+ "Illegal DOI",
+ "Too many entries in set",
+ "Missing address/network",
+ "Illegal address/network",
+ "Illegal flag",
+ "Illegal MLP specification",
+ "Unacceptable keyword for type"
+};
+static const int tsol_nerr = sizeof (tsol_errlist) / sizeof (*tsol_errlist);
+
+const char *
+tsol_strerror(int libtserr, int errnoval)
+{
+ if (libtserr == LTSNET_SYSERR)
+ return (strerror(errnoval));
+ if (libtserr >= 0 && libtserr < tsol_nerr)
+ return (gettext(tsol_errlist[libtserr]));
+ return (gettext("Unknown error"));
+}
diff --git a/usr/src/lib/libtsnet/common/synonyms.h b/usr/src/lib/libtsnet/common/synonyms.h
new file mode 100644
index 0000000000..ed28e16910
--- /dev/null
+++ b/usr/src/lib/libtsnet/common/synonyms.h
@@ -0,0 +1,52 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * From "synonyms.h 7.2 99/06/21 SMI; TSOL 2.x"
+ */
+
+#ifndef _SYNONYMS_H
+#define _SYNONYMS_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__STDC__)
+
+/* external data */
+
+/* functions */
+#define tnrh _tnrh
+#define tnrhtp _tnrhtp
+#define tnmlp _tnmlp
+
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYNONYMS_H */
diff --git a/usr/src/lib/libtsnet/common/tnmlp.c b/usr/src/lib/libtsnet/common/tnmlp.c
new file mode 100644
index 0000000000..ea4e1c2fc9
--- /dev/null
+++ b/usr/src/lib/libtsnet/common/tnmlp.c
@@ -0,0 +1,49 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "synonyms.h"
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <libtsnet.h>
+#include <sys/tsol/tsyscall.h>
+
+/*
+ * tnmlp(2TSOL) - manipulate kernel trusted network multilevel port
+ * entries
+ *
+ * This is the library interface to the system call.
+ */
+
+#ifdef __STDC__
+#pragma weak tnmlp = _tnmlp
+#endif
+
+int
+tnmlp(int cmd, tsol_mlpent_t *buf)
+{
+ return (syscall(SYS_labelsys, TSOL_TNMLP, cmd, buf));
+}
diff --git a/usr/src/lib/libtsnet/common/tnrh.c b/usr/src/lib/libtsnet/common/tnrh.c
new file mode 100644
index 0000000000..3213005cc9
--- /dev/null
+++ b/usr/src/lib/libtsnet/common/tnrh.c
@@ -0,0 +1,48 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "synonyms.h"
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <libtsnet.h>
+#include <sys/tsol/tsyscall.h>
+
+/*
+ * tnrh(2TSOL) - manipulate kernel trusted network remote hosts cache
+ *
+ * This is the library interface to the system call.
+ */
+
+#ifdef __STDC__
+#pragma weak tnrh = _tnrh
+#endif
+
+int
+tnrh(int cmd, tsol_rhent_t *buf)
+{
+ return (syscall(SYS_labelsys, TSOL_TNRH, cmd, buf));
+}
diff --git a/usr/src/lib/libtsnet/common/tnrhtp.c b/usr/src/lib/libtsnet/common/tnrhtp.c
new file mode 100644
index 0000000000..9591b6ad60
--- /dev/null
+++ b/usr/src/lib/libtsnet/common/tnrhtp.c
@@ -0,0 +1,49 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "synonyms.h"
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <libtsnet.h>
+#include <sys/tsol/tsyscall.h>
+
+/*
+ * tnrhtp(2TSOL) - manipulate kernel trusted network remote host
+ * templates cache
+ *
+ * This is the library interface to the system call.
+ */
+
+#ifdef __STDC__
+#pragma weak tnrhtp = _tnrhtp
+#endif
+
+int
+tnrhtp(int cmd, tsol_tpent_t *buf)
+{
+ return (syscall(SYS_labelsys, TSOL_TNRHTP, cmd, buf));
+}
diff --git a/usr/src/lib/libtsnet/common/tsol_getrhent.c b/usr/src/lib/libtsnet/common/tsol_getrhent.c
new file mode 100644
index 0000000000..24455f0960
--- /dev/null
+++ b/usr/src/lib/libtsnet/common/tsol_getrhent.c
@@ -0,0 +1,257 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * From "tsol_getrhent.c 7.6 00/09/22 SMI; TSOL 2.x"
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <nss_dbdefs.h>
+#include <libtsnet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <secdb.h>
+#include <nss.h>
+#include <libtsnet.h>
+#include <libintl.h>
+
+extern void _nss_XbyY_fgets(FILE *, nss_XbyY_args_t *); /* from lib.c */
+
+static int tsol_rh_stayopen; /* Unsynchronized, but it affects only */
+ /* efficiency, not correctness */
+static DEFINE_NSS_DB_ROOT(db_root);
+static DEFINE_NSS_GETENT(context);
+
+static void
+_nss_initf_tsol_rh(nss_db_params_t *p)
+{
+ p->name = NSS_DBNAM_TSOL_RH;
+ p->default_config = NSS_DEFCONF_TSOL_RH;
+}
+
+tsol_rhent_t *
+tsol_getrhbyaddr(const void *addrp, size_t len, int af)
+{
+ int err = 0;
+ char *errstr = NULL;
+ char buf[NSS_BUFLEN_TSOL_RH];
+ tsol_rhstr_t result;
+ tsol_rhstr_t *rhstrp = NULL;
+ nss_XbyY_args_t arg;
+
+ NSS_XbyY_INIT(&arg, &result, buf, sizeof (buf), str_to_rhstr);
+
+ arg.key.hostaddr.addr = (const char *)addrp;
+ arg.key.hostaddr.len = len;
+ arg.key.hostaddr.type = af;
+ arg.stayopen = tsol_rh_stayopen;
+ arg.h_errno = TSOL_NOT_FOUND;
+ arg.status = nss_search(&db_root, _nss_initf_tsol_rh,
+ NSS_DBOP_TSOL_RH_BYADDR, &arg);
+ rhstrp = (tsol_rhstr_t *)NSS_XbyY_FINI(&arg);
+
+#ifdef DEBUG
+ (void) fprintf(stdout, "tsol_getrhbyaddr %s: %s\n",
+ (char *)addrp, rhstrp ? rhstrp->template : "NULL");
+#endif /* DEBUG */
+
+ if (rhstrp == NULL)
+ return (NULL);
+
+ return (rhstr_to_ent(rhstrp, &err, &errstr));
+}
+
+void
+tsol_setrhent(int stay)
+{
+ tsol_rh_stayopen |= stay;
+ nss_setent(&db_root, _nss_initf_tsol_rh, &context);
+}
+
+void
+tsol_endrhent(void)
+{
+ tsol_rh_stayopen = 0;
+ nss_endent(&db_root, _nss_initf_tsol_rh, &context);
+ nss_delete(&db_root);
+}
+
+tsol_rhent_t *
+tsol_getrhent(void)
+{
+ int err = 0;
+ char *errstr = NULL;
+ char buf[NSS_BUFLEN_TSOL_RH];
+ tsol_rhstr_t result;
+ tsol_rhstr_t *rhstrp = NULL;
+ nss_XbyY_args_t arg;
+
+ NSS_XbyY_INIT(&arg, &result, buf, sizeof (buf), str_to_rhstr);
+ /* No key, no stayopen */
+ arg.status = nss_getent(&db_root, _nss_initf_tsol_rh, &context, &arg);
+ rhstrp = (tsol_rhstr_t *)NSS_XbyY_FINI(&arg);
+
+#ifdef DEBUG
+ (void) fprintf(stdout, "tsol_getrhent: %s\n",
+ rhstrp ? rhstrp->template : "NULL");
+#endif /* DEBUG */
+
+ if (rhstrp == NULL)
+ return (NULL);
+
+ return (rhstr_to_ent(rhstrp, &err, &errstr));
+}
+
+tsol_rhent_t *
+tsol_fgetrhent(FILE *f)
+{
+ int err = 0;
+ char *errstr = NULL;
+ char buf[NSS_BUFLEN_TSOL_RH];
+ tsol_rhstr_t result;
+ tsol_rhstr_t *rhstrp = NULL;
+ tsol_rhent_t *rhentp = NULL;
+ nss_XbyY_args_t arg;
+
+ NSS_XbyY_INIT(&arg, &result, buf, sizeof (buf), str_to_rhstr);
+ _nss_XbyY_fgets(f, &arg);
+ rhstrp = (tsol_rhstr_t *)NSS_XbyY_FINI(&arg);
+ if (rhstrp == NULL)
+ return (NULL);
+ rhentp = rhstr_to_ent(rhstrp, &err, &errstr);
+ while (rhentp == NULL) {
+ /*
+ * Loop until we find a non-blank, non-comment line, or
+ * until EOF. No need to log blank lines, comments.
+ */
+ if (err != LTSNET_EMPTY)
+ (void) fprintf(stderr, "%s: %.32s%s: %s\n",
+ gettext("Error parsing tnrhdb file"), errstr,
+ (strlen(errstr) > 32)? "...": "",
+ (char *)tsol_strerror(err, errno));
+ _nss_XbyY_fgets(f, &arg);
+ rhstrp = (tsol_rhstr_t *)NSS_XbyY_FINI(&arg);
+ if (rhstrp == NULL) /* EOF */
+ return (NULL);
+ rhentp = rhstr_to_ent(rhstrp, &err, &errstr);
+ }
+ return (rhentp);
+}
+
+/*
+ * This is the callback routine for nss.
+ */
+int
+str_to_rhstr(const char *instr, int lenstr, void *entp, char *buffer,
+ int buflen)
+{
+ int len;
+ char *str = NULL;
+ char *last = NULL;
+ char *sep = KV_TOKEN_DELIMIT;
+ tsol_rhstr_t *rhstrp = (tsol_rhstr_t *)entp;
+
+ if ((instr >= buffer && (buffer + buflen) > instr) ||
+ (buffer >= instr && (instr + lenstr) > buffer))
+ return (NSS_STR_PARSE_PARSE);
+ if (lenstr >= buflen)
+ return (NSS_STR_PARSE_ERANGE);
+ (void) strncpy(buffer, instr, buflen);
+ str = _strtok_escape(buffer, sep, &last);
+ rhstrp->address = _do_unescape(str);
+ /*
+ * _do_unesape uses isspace() which removes "\n".
+ * we keep "\n" as we use it in checking for
+ * blank lines.
+ */
+ if (strcmp(instr, "\n") == 0)
+ rhstrp->address = "\n";
+ rhstrp->template = _strtok_escape(NULL, sep, &last);
+ if (rhstrp->template != NULL) {
+ len = strlen(rhstrp->template);
+ if (rhstrp->template[len - 1] == '\n')
+ rhstrp->template[len - 1] = '\0';
+ }
+ if (rhstrp->address == NULL)
+ rhstrp->family = 0;
+ else if (strchr(rhstrp->address, ':') == NULL)
+ rhstrp->family = AF_INET;
+ else
+ rhstrp->family = AF_INET6;
+
+#ifdef DEBUG
+ (void) fprintf(stdout,
+ "str_to_rhstr:str - %s\taddress - %s\n\ttemplate - %s\n",
+ instr, rhstrp->address ? rhstrp->address : "NULL",
+ rhstrp->template ? rhstrp->template : "NULL");
+#endif /* DEBUG */
+
+ return (NSS_STR_PARSE_SUCCESS);
+}
+
+tsol_host_type_t
+tsol_getrhtype(char *rhost) {
+ int herr;
+ struct hostent *hp;
+ in6_addr_t in6;
+ char abuf[INET6_ADDRSTRLEN];
+ tsol_rhent_t rhent;
+ tsol_tpent_t tp;
+
+ if ((hp = getipnodebyname(rhost, AF_INET6,
+ AI_ALL | AI_ADDRCONFIG | AI_V4MAPPED, &herr)) == NULL) {
+ return (UNLABELED);
+ }
+
+ (void) memset(&rhent, 0, sizeof (rhent));
+ (void) memcpy(&in6, hp->h_addr, hp->h_length);
+
+ if (IN6_IS_ADDR_V4MAPPED(&in6)) {
+ rhent.rh_address.ta_family = AF_INET;
+ IN6_V4MAPPED_TO_INADDR(&in6, &rhent.rh_address.ta_addr_v4);
+ (void) inet_ntop(AF_INET, &rhent.rh_address.ta_addr_v4, abuf,
+ sizeof (abuf));
+ } else {
+ rhent.rh_address.ta_family = AF_INET6;
+ rhent.rh_address.ta_addr_v6 = in6;
+ (void) inet_ntop(AF_INET6, &in6, abuf, sizeof (abuf));
+ }
+
+ if (tnrh(TNDB_GET, &rhent) != 0)
+ return (UNLABELED);
+
+ if (rhent.rh_template[0] == '\0')
+ return (UNLABELED);
+
+ (void) strlcpy(tp.name, rhent.rh_template, sizeof (tp.name));
+
+ if (tnrhtp(TNDB_GET, &tp) != 0)
+ return (UNLABELED);
+
+ return (tp.host_type);
+}
diff --git a/usr/src/lib/libtsnet/common/tsol_gettpent.c b/usr/src/lib/libtsnet/common/tsol_gettpent.c
new file mode 100644
index 0000000000..ab20c85620
--- /dev/null
+++ b/usr/src/lib/libtsnet/common/tsol_gettpent.c
@@ -0,0 +1,195 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * From "tsol_gettpent.c 7.13 00/10/13 SMI; TSOL 2.x"
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <string.h>
+#include <nss_dbdefs.h>
+#include <libtsnet.h>
+#include <secdb.h>
+#include <nss.h>
+#include <libintl.h>
+
+extern void _nss_XbyY_fgets(FILE *, nss_XbyY_args_t *); /* from lib.c */
+
+static int tsol_tp_stayopen; /* Unsynchronized, but it affects only */
+ /* efficiency, not correctness */
+static DEFINE_NSS_DB_ROOT(db_root);
+static DEFINE_NSS_GETENT(context);
+
+
+static void
+_nss_initf_tsol_tp(nss_db_params_t *p)
+{
+ p->name = NSS_DBNAM_TSOL_TP;
+ p->default_config = NSS_DEFCONF_TSOL_TP;
+}
+
+tsol_tpent_t *
+tsol_gettpbyname(const char *name)
+{
+ int err = 0;
+ char *errstr = NULL;
+ char buf[NSS_BUFLEN_TSOL_TP];
+ tsol_tpstr_t result;
+ tsol_tpstr_t *tpstrp = NULL;
+ nss_XbyY_args_t arg;
+
+ NSS_XbyY_INIT(&arg, &result, buf, sizeof (buf), str_to_tpstr);
+
+ arg.key.name = name;
+ arg.stayopen = tsol_tp_stayopen;
+ arg.h_errno = TSOL_NOT_FOUND;
+ arg.status = nss_search(&db_root, _nss_initf_tsol_tp,
+ NSS_DBOP_TSOL_TP_BYNAME, &arg);
+ tpstrp = (tsol_tpstr_t *)NSS_XbyY_FINI(&arg);
+
+#ifdef DEBUG
+ (void) fprintf(stdout, "tsol_gettpbyname %s: %s\n",
+ name, tpstrp ? tpstrp->template : "NULL");
+#endif /* DEBUG */
+
+ if (tpstrp == NULL)
+ return (NULL);
+
+ return (tpstr_to_ent(tpstrp, &err, &errstr));
+}
+
+void
+tsol_settpent(int stay)
+{
+ tsol_tp_stayopen |= stay;
+ nss_setent(&db_root, _nss_initf_tsol_tp, &context);
+}
+
+void
+tsol_endtpent(void)
+{
+ tsol_tp_stayopen = 0;
+ nss_endent(&db_root, _nss_initf_tsol_tp, &context);
+ nss_delete(&db_root);
+}
+
+tsol_tpent_t *
+tsol_gettpent(void)
+{
+ int err = 0;
+ char *errstr = NULL;
+ char buf[NSS_BUFLEN_TSOL_TP];
+ tsol_tpstr_t result;
+ tsol_tpstr_t *tpstrp = NULL;
+ nss_XbyY_args_t arg;
+
+ NSS_XbyY_INIT(&arg, &result, buf, sizeof (buf), str_to_tpstr);
+ /* No key, no stayopen */
+ arg.status = nss_getent(&db_root, _nss_initf_tsol_tp, &context, &arg);
+ tpstrp = (tsol_tpstr_t *)NSS_XbyY_FINI(&arg);
+
+#ifdef DEBUG
+ (void) fprintf(stdout, "tsol_gettpent: %s\n",
+ tpstrp ? tpstrp->template : "NULL");
+#endif /* DEBUG */
+
+ if (tpstrp == NULL)
+ return (NULL);
+
+ return (tpstr_to_ent(tpstrp, &err, &errstr));
+}
+
+tsol_tpent_t *
+tsol_fgettpent(FILE *f)
+{
+ int err = 0;
+ char *errstr = NULL;
+ char buf[NSS_BUFLEN_TSOL_TP];
+ tsol_tpstr_t result;
+ tsol_tpstr_t *tpstrp = NULL;
+ tsol_tpent_t *tpentp = NULL;
+ nss_XbyY_args_t arg;
+
+ NSS_XbyY_INIT(&arg, &result, buf, sizeof (buf), str_to_tpstr);
+ _nss_XbyY_fgets(f, &arg);
+ tpstrp = (tsol_tpstr_t *)NSS_XbyY_FINI(&arg);
+ if (tpstrp == NULL)
+ return (NULL);
+ tpentp = tpstr_to_ent(tpstrp, &err, &errstr);
+ while (tpentp == NULL) {
+ /*
+ * Loop until we find a non-blank, non-comment line, or
+ * until EOF. No need to log blank lines, comments.
+ */
+ if (err != LTSNET_EMPTY)
+ (void) fprintf(stderr, "%s: %.32s%s: %s\n",
+ gettext("Error parsing tnrhtp file"), errstr,
+ (strlen(errstr) > 32)? "...": "",
+ (char *)tsol_strerror(err, errno));
+ _nss_XbyY_fgets(f, &arg);
+ tpstrp = (tsol_tpstr_t *)NSS_XbyY_FINI(&arg);
+ if (tpstrp == NULL) /* EOF */
+ return (NULL);
+ tpentp = tpstr_to_ent(tpstrp, &err, &errstr);
+ }
+ return (tpentp);
+}
+
+/*
+ * This is the callback routine for nss. It just wraps the tsol_sgettpent
+ * parser.
+ */
+int
+str_to_tpstr(const char *instr, int lenstr, void *entp, char *buffer,
+ int buflen)
+{
+ int len;
+ char *last = NULL;
+ char *sep = KV_TOKEN_DELIMIT;
+ tsol_tpstr_t *tpstrp = (tsol_tpstr_t *)entp;
+
+ if ((instr >= buffer && (buffer + buflen) > instr) ||
+ (buffer >= instr && (instr + lenstr) > buffer))
+ return (NSS_STR_PARSE_PARSE);
+ if (lenstr >= buflen)
+ return (NSS_STR_PARSE_ERANGE);
+ (void) strncpy(buffer, instr, buflen);
+ tpstrp->template = _strtok_escape(buffer, sep, &last);
+ tpstrp->attrs = _strtok_escape(NULL, sep, &last);
+ if (tpstrp->attrs != NULL) {
+ len = strlen(tpstrp->attrs);
+ if (tpstrp->attrs[len - 1] == '\n')
+ tpstrp->attrs[len - 1] = '\0';
+ }
+
+#ifdef DEBUG
+ (void) fprintf(stdout,
+ "str_to_tpstr:\nstr - %s\n\ttemplate - %s\n\tattrs - %s\n",
+ instr, tpstrp->template ? tpstrp->template : "NULL",
+ tpstrp->attrs ? tpstrp->attrs : "NULL");
+#endif /* DEBUG */
+
+ return (NSS_STR_PARSE_SUCCESS);
+}
diff --git a/usr/src/lib/libtsnet/common/tsol_getzcent.c b/usr/src/lib/libtsnet/common/tsol_getzcent.c
new file mode 100644
index 0000000000..4faf1cf5be
--- /dev/null
+++ b/usr/src/lib/libtsnet/common/tsol_getzcent.c
@@ -0,0 +1,141 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <ctype.h>
+#include <nss_dbdefs.h>
+#include <libtsnet.h>
+
+static int tsol_zc_stayopen; /* Unsynchronized, but it affects only */
+ /* efficiency, not correctness */
+static DEFINE_NSS_DB_ROOT(db_root);
+static DEFINE_NSS_GETENT(context);
+
+struct zc_args {
+ tsol_zcent_t *zc;
+ int err;
+ char *errstr;
+ int errno_val;
+};
+
+static int str2tsol_zcent(const char *, int, void *, char *, int);
+
+static void
+_nss_initf_tsol_zc(nss_db_params_t *p)
+{
+ p->name = NSS_DBNAM_TSOL_ZC;
+ p->default_config = NSS_DEFCONF_TSOL_ZC;
+}
+
+/*
+ * This is just a placeholder. The system doesn't currently lookup tnzonecfg
+ * entries via name services.
+ */
+/* ARGSUSED */
+static void
+switch_callback(void *res, const char *zonename, const char *label,
+ const char *flags, const char *privmlp, const char *globalmlp)
+{
+}
+
+tsol_zcent_t *
+tsol_getzcbyname(const char *name)
+{
+ nss_XbyY_args_t arg;
+ struct zc_args zcargs;
+
+ zcargs.zc = NULL;
+ NSS_XbyY_INIT(&arg, &zcargs, (char *)switch_callback, 1,
+ str2tsol_zcent);
+ arg.key.name = name;
+ arg.stayopen = tsol_zc_stayopen;
+ arg.h_errno = TSOL_NOT_FOUND;
+ arg.status = nss_search(&db_root, _nss_initf_tsol_zc,
+ NSS_DBOP_TSOL_ZC_BYNAME, &arg);
+ (void) NSS_XbyY_FINI(&arg);
+ if (arg.status != 0) {
+ tsol_freezcent(zcargs.zc);
+ zcargs.zc = NULL;
+ }
+ return (zcargs.zc);
+}
+
+void
+tsol_setzcent(int stay)
+{
+ tsol_zc_stayopen |= stay;
+ nss_setent(&db_root, _nss_initf_tsol_zc, &context);
+}
+
+void
+tsol_endzcent(void)
+{
+ tsol_zc_stayopen = 0;
+ nss_endent(&db_root, _nss_initf_tsol_zc, &context);
+ nss_delete(&db_root);
+}
+
+struct tsol_zcent *
+tsol_getzcent(void)
+{
+ nss_XbyY_args_t arg;
+ struct zc_args zcargs;
+
+ zcargs.zc = NULL;
+ zcargs.errno_val = errno;
+ NSS_XbyY_INIT(&arg, &zcargs, (char *)switch_callback, 1,
+ str2tsol_zcent);
+ /* No key, no stayopen */
+ arg.status = nss_getent(&db_root, _nss_initf_tsol_zc, &context, &arg);
+ (void) NSS_XbyY_FINI(&arg);
+ if (arg.status != 0) {
+ tsol_freezcent(zcargs.zc);
+ zcargs.zc = NULL;
+ }
+ if (zcargs.zc == NULL && zcargs.err == LTSNET_SYSERR)
+ errno = zcargs.errno_val;
+ return (zcargs.zc);
+}
+
+/*
+ * This is the callback routine for nss. It just wraps the tsol_sgetzcent
+ * parser.
+ */
+/* ARGSUSED */
+static int
+str2tsol_zcent(const char *instr, int lenstr, void *entp, char *buffer,
+ int buflen)
+{
+ struct zc_args *zcargs = entp;
+
+ if (zcargs->zc != NULL)
+ tsol_freezcent(zcargs->zc);
+ zcargs->zc = tsol_sgetzcent(instr, &zcargs->err, &zcargs->errstr);
+ zcargs->errno_val = errno;
+
+ return (zcargs->zc == NULL ? NSS_STR_PARSE_PARSE :
+ NSS_STR_PARSE_SUCCESS);
+}
diff --git a/usr/src/lib/libtsnet/common/tsol_sgetrhent.c b/usr/src/lib/libtsnet/common/tsol_sgetrhent.c
new file mode 100644
index 0000000000..5037b6b37a
--- /dev/null
+++ b/usr/src/lib/libtsnet/common/tsol_sgetrhent.c
@@ -0,0 +1,272 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * From "tsol_tndb_parser.c 7.24 01/09/05 SMI; TSOL 2.x"
+ *
+ * These functions parse entries in the "thrhdb" (remote host database) file.
+ * Each entry in the file has two fields, separated by a colon. The first
+ * field is the IP host or network address. The second is the name of the
+ * template to use (from tnrhtp).
+ *
+ * In order to help preserve sanity, we do not allow more than one unescaped
+ * colon in a line.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <strings.h>
+#include <libtsnet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <inet/ip.h>
+#include <arpa/inet.h>
+#include <nss.h>
+#include <errno.h>
+
+/*
+ * This routine deals with old pre-CIDR subnet address specifications. In the
+ * bad old days, a subnet was represented as:
+ *
+ * Expression Implied Prefix
+ * 10.1.1.0 /24
+ * 10.1.0.0 /16
+ * 10.0.0.0 /8
+ * 0.0.0.0 /0
+ */
+static int
+get_classful_prefix(in_addr_t addr)
+{
+ int bits;
+
+ if (addr == 0)
+ return (0);
+ addr = ntohl(addr);
+ for (bits = IP_ABITS; bits > 0 && (addr & 0xFF) == 0; bits -= 8)
+ addr >>= 8;
+
+ return (bits);
+}
+
+/*
+ * This routine deals with old pre-CIDR network address specifications. In the
+ * bad old days, a network was represented as:
+ *
+ * Expression Implied Prefix
+ * 10.1.1 /24
+ * 10.1 /16
+ * 10 /8
+ *
+ * This routine must compute the mask and left-align the address.
+ */
+static int
+get_network_prefix(in_addr_t *addrp)
+{
+ int bits;
+ in_addr_t addr;
+
+ addr = ntohl(*addrp);
+ for (bits = IP_ABITS; bits > 0 && addr < 0x01000000; bits -= 8)
+ addr <<= 8;
+ *addrp = htonl(addr);
+
+ return (bits);
+}
+
+static boolean_t
+parse_address(tsol_rhent_t *rh, const char *addrbuf)
+{
+ int upper_lim;
+ int len;
+ const uchar_t *aptr;
+
+ if (strchr(addrbuf, ':') == NULL) {
+ /* IPv4 address */
+ rh->rh_address.ta_family = AF_INET;
+ if (inet_pton(AF_INET, addrbuf,
+ &rh->rh_address.ta_addr_v4) > 0) {
+ if (rh->rh_prefix == -1)
+ rh->rh_prefix = get_classful_prefix(rh->
+ rh_address.ta_addr_v4.s_addr);
+ } else if ((rh->rh_address.ta_addr_v4.s_addr =
+ inet_network(addrbuf)) != (in_addr_t)-1) {
+ len = get_network_prefix(&rh->rh_address.ta_addr_v4.
+ s_addr);
+ if (rh->rh_prefix == -1)
+ rh->rh_prefix = len;
+ } else {
+ return (B_FALSE);
+ }
+ upper_lim = IP_ABITS;
+ aptr = (const uchar_t *)&rh->rh_address.ta_addr_v4;
+ } else {
+ /* IPv6 address */
+ rh->rh_address.ta_family = AF_INET6;
+ if (inet_pton(AF_INET6, addrbuf,
+ &rh->rh_address.ta_addr_v6) <= 0)
+ return (B_FALSE);
+ if (rh->rh_prefix == -1)
+ rh->rh_prefix = IPV6_ABITS;
+ upper_lim = IPV6_ABITS;
+ aptr = (const uchar_t *)&rh->rh_address.ta_addr_v6;
+ }
+
+ if (rh->rh_prefix < 0 || rh->rh_prefix > upper_lim)
+ return (B_FALSE);
+
+ /*
+ * Verify that there are no bits set in the "host" portion of the
+ * IP address.
+ */
+ len = rh->rh_prefix;
+ aptr += len / 8;
+ if ((len & 7) != 0) {
+ if ((*aptr++ & (0xff >> (len & 7))) != 0)
+ return (B_FALSE);
+ len = (len + 7) & ~7;
+ }
+ while (len < upper_lim) {
+ if (*aptr++ != 0)
+ return (B_FALSE);
+ len += 8;
+ }
+
+ return (B_TRUE);
+}
+
+tsol_rhent_t *
+rhstr_to_ent(tsol_rhstr_t *rhstrp, int *errp, char **errstrp)
+{
+ int len;
+ int err = 0;
+ char *cp, *cp2, *errstr;
+ char *address = rhstrp->address;
+ char *template = rhstrp->template;
+ char addrbuf[1024];
+ tsol_rhent_t *rhentp = NULL;
+
+ /*
+ * The user can specify NULL pointers for these. Make sure that we
+ * don't have to deal with checking for NULL everywhere by just
+ * pointing to our own variables if the user gives NULL.
+ */
+ if (errp == NULL)
+ errp = &err;
+ if (errstrp == NULL)
+ errstrp = &errstr;
+ /* The default, unless we find a more specific error locus. */
+ *errstrp = address;
+
+ if (address == NULL || *address == '#' || *address == '\n') {
+ *errp = LTSNET_EMPTY;
+ if (template && *template != '\0' && *template != '#' &&
+ *template != '\n')
+ *errstrp = template;
+ else if (address == NULL)
+ *errstrp = " ";
+ goto err_ret;
+ }
+ if (*address == '\0') {
+ *errp = LTSNET_NO_ADDR;
+ if (template && *template != '\0' && *template != '#' &&
+ *template != '\n')
+ *errstrp = template;
+ goto err_ret;
+ }
+ if (template == NULL || *template == '#' || *template == '\n' ||
+ *template == '\0') {
+ *errp = LTSNET_NO_HOSTTYPE;
+ goto err_ret;
+ }
+ if ((rhentp = calloc(1, sizeof (*rhentp))) == NULL) {
+ *errp = LTSNET_SYSERR;
+ return (NULL);
+ }
+ if ((cp = strrchr(address, '/')) != NULL) {
+ len = cp - address;
+ if (len >= sizeof (addrbuf)) {
+ *errp = LTSNET_ILL_ADDR;
+ goto err_ret;
+ }
+ (void) memset(addrbuf, '\0', sizeof (addrbuf));
+ (void) memcpy(addrbuf, address, len);
+ cp++;
+ errno = 0;
+ rhentp->rh_prefix = strtol(cp, &cp2, 0);
+ if (errno != 0) {
+ *errp = LTSNET_SYSERR;
+ *errstrp = cp2;
+ goto err_ret;
+ }
+ if ((isdigit(*cp) == 0)) {
+ *errp = LTSNET_ILL_ADDR;
+ *errstrp = address;
+ goto err_ret;
+ }
+ } else {
+ rhentp->rh_prefix = -1;
+ (void) strlcpy(addrbuf, address, sizeof (addrbuf));
+ }
+ if (strlcpy(rhentp->rh_template, template,
+ sizeof (rhentp->rh_template)) >= sizeof (rhentp->rh_template)) {
+ *errstrp = template;
+ *errp = LTSNET_ILL_NAME;
+ goto err_ret;
+ }
+ if (!parse_address(rhentp, addrbuf)) {
+ *errp = LTSNET_ILL_ADDR;
+ *errstrp = address;
+ goto err_ret;
+ }
+
+#ifdef DEBUG
+ (void) fprintf(stdout, "rhstr_to_ent: %s:%s\n",
+ address, rhentp->rh_template);
+#endif /* DEBUG */
+
+ return (rhentp);
+
+err_ret:
+ err = errno;
+ tsol_freerhent(rhentp);
+ errno = err;
+#ifdef DEBUG
+ (void) fprintf(stderr, "\nrhstr_to_ent: %s: %s\n",
+ *errstrp, (char *)tsol_strerror(*errp, errno));
+#endif /* DEBUG */
+
+ return (NULL);
+}
+
+void
+tsol_freerhent(tsol_rhent_t *rh)
+{
+ if (rh != NULL)
+ free(rh);
+}
diff --git a/usr/src/lib/libtsnet/common/tsol_sgettpent.c b/usr/src/lib/libtsnet/common/tsol_sgettpent.c
new file mode 100644
index 0000000000..37fd75b234
--- /dev/null
+++ b/usr/src/lib/libtsnet/common/tsol_sgettpent.c
@@ -0,0 +1,301 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * From "tsol_tndb_parser.c 7.24 01/09/05 SMI; TSOL 2.x"
+ *
+ * These functions parse entries in the "tnrhtp" (remote host template) file.
+ * Each entry in this file has two fields, separated by a colon. The first
+ * field is the template name. The second is a list of "key=value" attributes,
+ * separated by semicolons.
+ *
+ * In order to help preserve sanity, we do not allow more than one unescaped
+ * colon in a line, nor any unescaped '=' or ';' characters in the template
+ * name. Such things are indicative of typing errors, not intentional
+ * configuration.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <strings.h>
+#include <libtsnet.h>
+#include <tsol/label.h>
+#include <sys/types.h>
+#include <nss.h>
+#include <secdb.h>
+#include <errno.h>
+
+static int
+get_tn_doi(tsol_tpent_t *tpentp, kva_t *kv)
+{
+ char *cp;
+ char *val = NULL;
+
+ val = kva_match(kv, TP_DOI);
+ if (val == NULL)
+ return (LTSNET_NO_DOI);
+
+ errno = 0;
+ tpentp->tp_doi = strtol(val, &cp, 0);
+ if (errno != 0)
+ return (LTSNET_SYSERR);
+ if (*cp != '\0')
+ return (LTSNET_ILL_DOI);
+
+ return (0);
+}
+
+static int
+get_tn_sl_range(brange_t *range, char *min, char *max)
+{
+ int err = 0;
+
+ if (min == NULL && max == NULL)
+ return (LTSNET_NO_RANGE);
+ if (min == NULL)
+ return (LTSNET_NO_LOWERBOUND);
+ if (max == NULL)
+ return (LTSNET_NO_UPPERBOUND);
+
+ if (stobsl(min, &range->lower_bound, NO_CORRECTION, &err) == 0)
+ return (LTSNET_ILL_LOWERBOUND);
+ if (stobsl(max, &range->upper_bound, NO_CORRECTION, &err) == 0)
+ return (LTSNET_ILL_UPPERBOUND);
+ if (!bldominates(&range->upper_bound, &range->lower_bound))
+ return (LTSNET_ILL_RANGE);
+
+ return (0);
+}
+
+static int
+get_tn_sl_set(blset_t *labelset, char *setstr)
+{
+ int sc, err;
+ char *tokp, *finally;
+ bslabel_t *labels;
+
+ (void) memset(labelset, 0, sizeof (blset_t));
+ labels = (bslabel_t *)labelset;
+ tokp = strtok_r(setstr, TNDB_COMMA, &finally);
+ for (sc = 0; tokp != NULL && sc < NSLS_MAX; sc++) {
+ if (stobsl(tokp, &labels[sc], NO_CORRECTION, &err) == 0)
+ return (LTSNET_ILL_LABEL);
+ tokp = strtok_r(NULL, TNDB_COMMA, &finally);
+ }
+ if (tokp != NULL && sc >= NSLS_MAX)
+ return (LTSNET_SET_TOO_BIG);
+
+ return (0);
+}
+
+static int
+parse_remainder(tsol_tpent_t *tpentp, kva_t *kv)
+{
+ int err = 0;
+ char *val = NULL;
+ char *val2 = NULL;
+
+ val = kva_match(kv, TP_HOSTTYPE);
+
+ if (val == NULL)
+ return (LTSNET_NO_HOSTTYPE);
+ if (strcasecmp(val, TP_UNLABELED) == 0)
+ tpentp->host_type = UNLABELED;
+ else if (strcasecmp(val, TP_CIPSO) == 0)
+ tpentp->host_type = SUN_CIPSO;
+ else
+ return (LTSNET_ILL_HOSTTYPE);
+
+ /*
+ * parse fields by host type -
+ * add on to the following if statement for each new host type.
+ */
+ if (tpentp->host_type == UNLABELED) {
+ tpentp->tp_mask_unl = 0;
+ /*
+ * doi
+ */
+ if ((err = get_tn_doi(tpentp, kv)) != 0)
+ return (err);
+ tpentp->tp_mask_unl |= TSOL_MSK_CIPSO_DOI;
+ /*
+ * default label
+ */
+ val = kva_match(kv, TP_DEFLABEL);
+ if (val == NULL)
+ return (LTSNET_NO_LABEL);
+ if (stobsl(val, &tpentp->tp_def_label, NO_CORRECTION,
+ &err) == 0)
+ return (LTSNET_ILL_LABEL);
+ tpentp->tp_mask_unl |= TSOL_MSK_DEF_LABEL;
+ /*
+ * check label range
+ */
+ val = kva_match(kv, TP_MINLABEL);
+ val2 = kva_match(kv, TP_MAXLABEL);
+ if (val == NULL && val2 == NULL) {
+ /*
+ * This is the old format. Use ADMIN_LOW to SL of the
+ * default label as the gw_sl_range.
+ */
+ bsllow(&tpentp->tp_gw_sl_range.lower_bound);
+ tpentp->tp_gw_sl_range.upper_bound =
+ tpentp->tp_def_label;
+ } else {
+ err = get_tn_sl_range(&tpentp->tp_gw_sl_range, val,
+ val2);
+ if (err != 0)
+ return (err);
+ }
+ tpentp->tp_mask_unl |= TSOL_MSK_SL_RANGE_TSOL;
+
+ /*
+ * also label set, if present. (optional)
+ */
+ val = kva_match(kv, TP_SET);
+ if (val != NULL) {
+ err = get_tn_sl_set(&tpentp->tp_gw_sl_set, val);
+ if (err != 0)
+ return (err);
+ tpentp->tp_mask_cipso |= TSOL_MSK_SL_RANGE_TSOL;
+ }
+ } else {
+ tpentp->tp_mask_cipso = 0;
+ /*
+ * doi
+ */
+ if ((err = get_tn_doi(tpentp, kv)) != 0)
+ return (err);
+ tpentp->tp_mask_cipso |= TSOL_MSK_CIPSO_DOI;
+ /*
+ * label range
+ */
+ val = kva_match(kv, TP_MINLABEL);
+ val2 = kva_match(kv, TP_MAXLABEL);
+ err = get_tn_sl_range(&tpentp->tp_sl_range_cipso, val, val2);
+ if (err != 0)
+ return (err);
+ tpentp->tp_mask_cipso |= TSOL_MSK_SL_RANGE_TSOL;
+ /*
+ * also label set, if present. (optional)
+ */
+ val = kva_match(kv, TP_SET);
+ if (val != NULL) {
+ err = get_tn_sl_set(&tpentp->tp_sl_set_cipso, val);
+ if (err != 0)
+ return (err);
+ tpentp->tp_mask_cipso |= TSOL_MSK_SL_RANGE_TSOL;
+ }
+
+ /* CIPSO entries don't support default labels */
+ val = kva_match(kv, TP_DEFLABEL);
+ if (val != NULL)
+ return (LTSNET_BAD_TYPE);
+ }
+
+ return (0);
+}
+
+tsol_tpent_t *
+tpstr_to_ent(tsol_tpstr_t *tpstrp, int *errp, char **errstrp)
+{
+ int err = 0;
+ char *errstr;
+ char *template = tpstrp->template;
+ char *attrs = tpstrp->attrs;
+ kva_t *kv;
+ tsol_tpent_t *tpentp = NULL;
+
+ /*
+ * The user can specify NULL pointers for these. Make sure that we
+ * don't have to deal with checking for NULL everywhere by just
+ * pointing to our own variables if the user gives NULL.
+ */
+ if (errp == NULL)
+ errp = &err;
+ if (errstrp == NULL)
+ errstrp = &errstr;
+ /* The default, unless we find a more specific error locus. */
+ *errstrp = template;
+
+ if (template == NULL || *template == '#' || *template == '\n') {
+ *errp = LTSNET_EMPTY;
+ if (attrs && *attrs != '\0' && *attrs != '#' && *attrs != '\n')
+ *errstrp = attrs;
+ else if (template == NULL)
+ *errstrp = " ";
+ goto err_ret;
+ }
+ if (*template == '\0') {
+ *errp = LTSNET_NO_NAME;
+ if (attrs && *attrs != '\0' && *attrs != '#' && *attrs != '\n')
+ *errstrp = attrs;
+ goto err_ret;
+ }
+ if (attrs == NULL || *attrs == '\0' || *attrs == '#' ||
+ *attrs == '\n') {
+ *errp = LTSNET_NO_ATTRS;
+ goto err_ret;
+ }
+ if ((tpentp = calloc(1, sizeof (*tpentp))) == NULL) {
+ *errp = LTSNET_SYSERR;
+ return (NULL);
+ }
+ if (strlcpy(tpentp->name, template, sizeof (tpentp->name)) >=
+ sizeof (tpentp->name))
+ goto err_ret;
+ kv = _str2kva(attrs, KV_ASSIGN, KV_DELIMITER);
+ *errp = parse_remainder(tpentp, kv);
+ _kva_free(kv);
+ if (*errp == 0) {
+#ifdef DEBUG
+ (void) fprintf(stdout, "tpstr_to_ent: %s:%s\n", tpentp->name,
+ attrs);
+#endif /* DEBUG */
+
+ return (tpentp);
+ }
+
+err_ret:
+ err = errno;
+ tsol_freetpent(tpentp);
+ errno = err;
+#ifdef DEBUG
+ (void) fprintf(stderr, "\ntpstr_to_ent: %s:%s\n",
+ *errstrp, (char *)tsol_strerror(*errp, errno));
+#endif /* DEBUG */
+
+ return (NULL);
+}
+
+void
+tsol_freetpent(tsol_tpent_t *tp)
+{
+ if (tp != NULL)
+ free(tp);
+}
diff --git a/usr/src/lib/libtsnet/common/tsol_sgetzcent.c b/usr/src/lib/libtsnet/common/tsol_sgetzcent.c
new file mode 100644
index 0000000000..657c3be47c
--- /dev/null
+++ b/usr/src/lib/libtsnet/common/tsol_sgetzcent.c
@@ -0,0 +1,285 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * From "tsol_tndb_parser.c 7.24 01/09/05 SMI; TSOL 2.x"
+ *
+ * These functions parse entries in the "tnzonecfg" (zone configuration) file.
+ * Each entry in this file has five fields, separated by a colon. These fields
+ * are:
+ *
+ * zone name : label : flags : zone-specific MLPs : global MLPs
+ *
+ * The fourth and fifth fields contain subfields consisting of MLP entries
+ * separated by semicolons. The MLP entries are of the form:
+ *
+ * port[-port]/protocol
+ *
+ * In order to help preserve sanity, we do not allow more than four unescaped
+ * colons in a line, nor any unescaped ';' characters in the non-MLP fields.
+ * Such things are indicative of typing errors, not intentional configuration.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <strings.h>
+#include <libtsnet.h>
+#include <tsol/label.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <nss.h>
+#include <errno.h>
+#include <secdb.h>
+
+/*
+ * Parse an MLP specification in port1-port2/proto or port/proto form.
+ */
+static int
+str_to_mlp(char *mlp_str, tsol_mlp_t *zone_mlp)
+{
+ char *fieldp;
+ char *lasts, *cp;
+ int i;
+ ulong_t ulv;
+ struct protoent proto;
+ char gbuf[1024];
+
+ (void) memset(zone_mlp, 0, sizeof (tsol_mlp_t));
+
+ fieldp = strtok_r(mlp_str, KV_DELIMITER, &lasts);
+ if (fieldp == NULL)
+ return (-1);
+
+ errno = 0;
+ for (i = 0; fieldp != NULL && i < NMLP_MAX; i++) {
+ ulv = strtoul(fieldp, &cp, 0);
+ zone_mlp[i].mlp_port = (uint16_t)ulv;
+ zone_mlp[i].mlp_port_upper = 0;
+ if (errno != 0 || ulv > 65535)
+ return (-1);
+ if (*cp == '-') {
+ ulv = strtol(cp + 1, &cp, 0);
+ zone_mlp[i].mlp_port_upper = (uint16_t)ulv;
+ if (errno != 0 || ulv > 65535)
+ return (-1);
+ }
+ if (*cp != '/')
+ return (-1);
+ fieldp = cp + 1;
+ ulv = strtol(fieldp, &cp, 0);
+ if (errno == 0 && ulv <= 255 && *cp == '\0')
+ zone_mlp->mlp_ipp = (uint8_t)ulv;
+ else if (getprotobyname_r(fieldp, &proto, gbuf,
+ sizeof (gbuf)) != NULL)
+ zone_mlp->mlp_ipp = proto.p_proto;
+ else
+ return (-1);
+ fieldp = strtok_r(NULL, KV_DELIMITER, &lasts);
+ }
+ return (0);
+}
+
+static boolean_t
+parse_mlp_list(tsol_mlp_t **list, char *str, int *errp, char **errstrp)
+{
+ int mmax;
+ tsol_mlp_t *mlp;
+ char *tokp, *finally;
+ int mc;
+
+ mmax = 0;
+ if ((mlp = *list) != NULL) {
+ while (!TSOL_MLP_END(mlp)) {
+ mmax++;
+ mlp++;
+ }
+ mmax++;
+ }
+ mlp = *list;
+ tokp = strtok_r(str, KV_DELIMITER, &finally);
+ for (mc = 0; tokp != NULL; mc++) {
+ if (mc >= mmax) {
+ mmax += 8;
+ mlp = realloc(mlp, mmax * sizeof (*mlp));
+ if (mlp == NULL) {
+ *errp = LTSNET_SYSERR;
+ *errstrp = tokp;
+ return (B_FALSE);
+ }
+ *list = mlp;
+ }
+ if (str_to_mlp(tokp, mlp + mc) == -1) {
+ *errp = LTSNET_ILL_MLP;
+ *errstrp = tokp;
+ return (B_FALSE);
+ }
+ tokp = strtok_r(NULL, KV_DELIMITER, &finally);
+ }
+ if (mc >= mmax) {
+ mlp = realloc(mlp, (mmax + 1) * sizeof (*mlp));
+ if (mlp == NULL) {
+ *errp = LTSNET_SYSERR;
+ *errstrp = finally;
+ return (B_FALSE);
+ }
+ *list = mlp;
+ }
+ (void) memset(mlp + mc, 0, sizeof (*mlp));
+ return (B_TRUE);
+}
+
+tsol_zcent_t *
+tsol_sgetzcent(const char *instr, int *errp, char **errstrp)
+{
+ int err;
+ char *errstr;
+ tsol_zcent_t *zc;
+ const char *nextf;
+ char *cp;
+ char fieldbuf[1024];
+
+ /*
+ * The user can specify NULL pointers for these. Make sure that we
+ * don't have to deal with checking for NULL everywhere by just
+ * pointing to our own variables if the user gives NULL.
+ */
+ if (errp == NULL)
+ errp = &err;
+ if (errstrp == NULL)
+ errstrp = &errstr;
+
+ /* The default, unless we find a more specific error locus. */
+ *errstrp = (char *)instr;
+
+ if ((zc = calloc(1, sizeof (*zc))) == NULL) {
+ *errp = LTSNET_SYSERR;
+ return (NULL);
+ }
+
+ /* First, parse off the zone name. */
+ instr = parse_entry(zc->zc_name, sizeof (zc->zc_name), instr, "#;:\n");
+ if (zc->zc_name[0] == '\0') {
+ *errstrp = (char *)instr;
+ if (*instr == '\0' || *instr == '#' || *instr == '\n')
+ *errp = LTSNET_EMPTY;
+ else if (*instr == ':')
+ *errp = LTSNET_NO_NAME;
+ else
+ *errp = LTSNET_ILL_NAME;
+ goto err_ret;
+ }
+ if (*instr != ':') {
+ *errstrp = (char *)instr;
+ if (*instr == '=' || *instr == ';')
+ *errp = LTSNET_ILL_NAME;
+ else
+ *errp = LTSNET_ILL_ENTRY;
+ goto err_ret;
+ }
+ instr++;
+
+ /* Field two: parse off the label. */
+ nextf = parse_entry(fieldbuf, sizeof (fieldbuf), instr, "#;:\n");
+ if (*nextf != ':') {
+ *errstrp = (char *)nextf;
+ *errp = LTSNET_ILL_ENTRY;
+ goto err_ret;
+ }
+ if (fieldbuf[0] == '\0') {
+ *errstrp = (char *)instr;
+ *errp = LTSNET_NO_LABEL;
+ goto err_ret;
+ }
+ if (stobsl(fieldbuf, &zc->zc_label, NO_CORRECTION, &err) == 0) {
+ *errstrp = (char *)instr;
+ *errp = LTSNET_ILL_LABEL;
+ goto err_ret;
+ }
+ instr = nextf + 1;
+
+ /* Not in the entry, but should be */
+ zc->zc_doi = 1;
+
+ /* Field three: get match flag */
+ errno = 0;
+ zc->zc_match = (uchar_t)strtol(instr, &cp, 0);
+ if (errno != 0 || (*cp != ':' && *cp != '\0')) {
+ *errp = LTSNET_ILL_FLAG;
+ *errstrp = (char *)instr;
+ goto err_ret;
+ }
+ if (*cp != ':') {
+ *errp = LTSNET_ILL_VALDELIM;
+ *errstrp = cp;
+ goto err_ret;
+ }
+ instr = cp + 1;
+
+ /* Field four: get zone-specific MLP list. */
+ nextf = parse_entry(fieldbuf, sizeof (fieldbuf), instr, "#:\n");
+ if (*nextf != ':') {
+ *errstrp = (char *)nextf;
+ *errp = LTSNET_ILL_ENTRY;
+ goto err_ret;
+ }
+ if (!parse_mlp_list(&zc->zc_private_mlp, fieldbuf, errp, errstrp)) {
+ *errstrp = (char *)instr + (*errstrp - fieldbuf);
+ goto err_ret;
+ }
+ instr = nextf + 1;
+
+ /* Field five: get global MLP list. */
+ nextf = parse_entry(fieldbuf, sizeof (fieldbuf), instr, "#:\n");
+ if (*nextf != '\0' && *nextf != '#' && !isspace(*nextf)) {
+ *errstrp = (char *)nextf;
+ *errp = LTSNET_ILL_ENTRY;
+ goto err_ret;
+ }
+ if (!parse_mlp_list(&zc->zc_shared_mlp, fieldbuf, errp, errstrp)) {
+ *errstrp = (char *)instr + (*errstrp - fieldbuf);
+ goto err_ret;
+ }
+
+ return (zc);
+
+err_ret:
+ err = errno;
+ tsol_freezcent(zc);
+ errno = err;
+ return (NULL);
+}
+
+void
+tsol_freezcent(tsol_zcent_t *zc)
+{
+ if (zc != NULL) {
+ free(zc->zc_private_mlp);
+ free(zc->zc_shared_mlp);
+ free(zc);
+ }
+}
diff --git a/usr/src/lib/libtsnet/i386/Makefile b/usr/src/lib/libtsnet/i386/Makefile
new file mode 100644
index 0000000000..ee3ea88a08
--- /dev/null
+++ b/usr/src/lib/libtsnet/i386/Makefile
@@ -0,0 +1,35 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+MAPDIR= ../spec/i386
+include ../Makefile.com
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
diff --git a/usr/src/lib/libtsnet/sparc/Makefile b/usr/src/lib/libtsnet/sparc/Makefile
new file mode 100644
index 0000000000..73ba2bbce8
--- /dev/null
+++ b/usr/src/lib/libtsnet/sparc/Makefile
@@ -0,0 +1,32 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+all: $(LIBS)
+
+install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
diff --git a/usr/src/lib/libtsnet/sparcv9/Makefile b/usr/src/lib/libtsnet/sparcv9/Makefile
new file mode 100644
index 0000000000..69cf39010b
--- /dev/null
+++ b/usr/src/lib/libtsnet/sparcv9/Makefile
@@ -0,0 +1,31 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+include ../Makefile.com
+include ../../Makefile.lib.64
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
diff --git a/usr/src/lib/libtsnet/spec/Makefile b/usr/src/lib/libtsnet/spec/Makefile
new file mode 100644
index 0000000000..66c61a6d05
--- /dev/null
+++ b/usr/src/lib/libtsnet/spec/Makefile
@@ -0,0 +1,30 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libtsnet/spec/Makefile
+#
+
+include $(SRC)/lib/Makefile.spec.arch
diff --git a/usr/src/lib/libtsnet/spec/Makefile.targ b/usr/src/lib/libtsnet/spec/Makefile.targ
new file mode 100644
index 0000000000..aeafa46121
--- /dev/null
+++ b/usr/src/lib/libtsnet/spec/Makefile.targ
@@ -0,0 +1,35 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libtsnet/spec/Makefile.targ
+#
+
+LIBRARY= libtsnet.a
+VERS= .1
+
+OBJECTS= tsnet.o
+
+SPECCPP += -I../../
diff --git a/usr/src/lib/libtsnet/spec/amd64/Makefile b/usr/src/lib/libtsnet/spec/amd64/Makefile
new file mode 100644
index 0000000000..03d9b122a2
--- /dev/null
+++ b/usr/src/lib/libtsnet/spec/amd64/Makefile
@@ -0,0 +1,33 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+include $(SRC)/lib/Makefile.spec
diff --git a/usr/src/lib/libtsnet/spec/i386/Makefile b/usr/src/lib/libtsnet/spec/i386/Makefile
new file mode 100644
index 0000000000..b378e293ca
--- /dev/null
+++ b/usr/src/lib/libtsnet/spec/i386/Makefile
@@ -0,0 +1,34 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libtsnet/spec/i386/Makefile
+#
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.spec
diff --git a/usr/src/lib/libtsnet/spec/sparc/Makefile b/usr/src/lib/libtsnet/spec/sparc/Makefile
new file mode 100644
index 0000000000..013c8f71b0
--- /dev/null
+++ b/usr/src/lib/libtsnet/spec/sparc/Makefile
@@ -0,0 +1,34 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libtsnet/spec/sparc/Makefile
+#
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.spec
diff --git a/usr/src/lib/libtsnet/spec/sparcv9/Makefile b/usr/src/lib/libtsnet/spec/sparcv9/Makefile
new file mode 100644
index 0000000000..03d9b122a2
--- /dev/null
+++ b/usr/src/lib/libtsnet/spec/sparcv9/Makefile
@@ -0,0 +1,33 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+include $(SRC)/lib/Makefile.spec
diff --git a/usr/src/lib/libtsnet/spec/tsnet.spec b/usr/src/lib/libtsnet/spec/tsnet.spec
new file mode 100644
index 0000000000..78e222075d
--- /dev/null
+++ b/usr/src/lib/libtsnet/spec/tsnet.spec
@@ -0,0 +1,206 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libtsnet/spec/tsnet.spec
+#
+
+function tsol_gettpbyname
+include <libtsnet.h>
+declaration tsol_tpent_t *tsol_gettpbyname(const char *name);
+version SUNWprivate_1.1
+exception $return == 0
+end
+
+function tsol_gettpent
+include <libtsnet.h>
+declaration tsol_tpent_t *tsol_gettpent(void);
+version SUNWprivate_1.1
+exception $return == 0
+end
+
+function tsol_fgettpent
+include <libtsnet.h>
+declaration tsol_tpent_t *tsol_gettpent(FILE *);
+version SUNWprivate_1.1
+exception $return == 0
+end
+
+function tsol_freetpent
+include <libtsnet.h>
+declaration void tsol_freetpent(tsol_tpent_t *);
+version SUNWprivate_1.1
+exception $return == 0
+end
+
+function tsol_settpent
+include <libtsnet.h>
+declaration void tsol_settpent(int stay);
+version SUNWprivate_1.1
+end
+
+function tsol_endtpent
+include <libtsnet.h>
+declaration void tsol_endtpent(void);
+version SUNWprivate_1.1
+end
+
+function str_to_tpstr
+include <libtsnet.h>
+declaration int str_to_tpstr(const char *, int, void *, char *, int);
+version SUNWprivate_1.1
+end
+
+function tpstr_to_ent
+include <libtsnet.h>
+declaration tsol_tpent_t *tpstr_to_ent(tsol_tpstr_t *, int *, char **);
+version SUNWprivate_1.1
+end
+
+function tsol_getrhbyaddr
+include <libtsnet.h>
+declaration tsol_rhent_t *tsol_getrhbyaddr(const void *addr, size_t len, \
+ int type);
+version SUNWprivate_1.1
+exception $return == 0
+end
+
+function tsol_getrhent
+include <libtsnet.h>
+declaration tsol_rhent_t *tsol_getrhent(void);
+version SUNWprivate_1.1
+exception $return == 0
+end
+
+function tsol_fgetrhent
+include <libtsnet.h>
+declaration tsol_rhent_t *tsol_getrhent(FILE *);
+version SUNWprivate_1.1
+exception $return == 0
+end
+
+function tsol_freerhent
+include <libtsnet.h>
+declaration void tsol_freerhent(tsol_rhent_t *);
+version SUNWprivate_1.1
+exception $return == 0
+end
+
+function tsol_setrhent
+include <libtsnet.h>
+declaration void tsol_setrhent(int stay);
+version SUNWprivate_1.1
+end
+
+function tsol_endrhent
+include <libtsnet.h>
+declaration void tsol_endrhent(void);
+version SUNWprivate_1.1
+end
+
+function str_to_rhstr
+include <libtsnet.h>
+declaration int str_to_rhstr(const char *, int, void *, char *, int);
+version SUNWprivate_1.1
+end
+
+function rhstr_to_ent
+include <libtsnet.h>
+declaration tsol_rhent_t *rhstr_to_ent(tsol_rhstr_t *, int *, char **);
+version SUNWprivate_1.1
+end
+
+function tsol_getrhtype
+include <libtsnet.h>
+declaration tsol_host_type_t tsol_getrhtype(char *);
+version SUNWprivate_1.1
+end
+
+function tsol_sgetzcent
+include <libtsnet.h>
+declaration tsol_zcent_t *tsol_sgetzcent(const char *instr, int *errp, \
+ char **errstrp);
+version SUNWprivate_1.1
+exception $return == 0
+end
+
+function tsol_freezcent
+include <libtsnet.h>
+declaration void tsol_freezcent(tsol_zcent_t *);
+version SUNWprivate_1.1
+exception $return == 0
+end
+
+function sl_to_str
+include <libtsnet.h>
+declaration const char *sl_to_str(const bslabel_t *sl);
+version SUNWprivate_1.1
+end
+
+function rtsa_to_str
+include <libtsnet.h>
+declaration const char *rtsa_to_str(const struct rtsa_s *rtsa, \
+ char *line, size_t len);
+version SUNWprivate_1.1
+exception $return == 0
+end
+
+function rtsa_keyword
+include <libtsnet.h>
+declaration boolean_t rtsa_keyword(const char *opt, struct rtsa_s *rtsa, \
+ int *errp, char **errstr);
+version SUNWprivate_1.1
+exception $return == 0
+end
+
+function tsol_strerror
+include <libtsnet.h>
+declaration const char *tsol_strerror(int libtserr, int errnoval);
+version SUNWprivate_1.1
+end
+
+function tnrhtp
+include <libtsnet.h>
+declaration int tnrhtp(int cmd, tsol_tpent_t *buf);
+version SUNWprivate_1.1
+errno ENOSYS EFAULT EINVAL ENOENT EOPNOTSUPP EPERM
+exception $return == -1
+end
+
+function tnrh
+include <libtsnet.h>
+declaration int tnrh(int cmd, tsol_rhent_t *buf);
+version SUNWprivate_1.1
+errno ENOSYS EFAULT EINVAL ENOENT EOPNOTSUPP EPERM ENOMEM
+exception $return == -1
+end
+
+function tnmlp
+include <libtsnet.h>
+declaration int tnmlp(int cmd, tsol_mlpent_t *buf);
+version SUNWprivate_1.1
+errno ENOSYS EFAULT EINVAL ENOENT EEXIST EOPNOTSUPP EPERM
+exception $return == -1
+end
diff --git a/usr/src/lib/libtsnet/spec/versions b/usr/src/lib/libtsnet/spec/versions
new file mode 100644
index 0000000000..43c70977f7
--- /dev/null
+++ b/usr/src/lib/libtsnet/spec/versions
@@ -0,0 +1,35 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libtsnet/spec/versions
+#
+
+sparc {
+ SUNWprivate_1.1;
+}
+i386 {
+ SUNWprivate_1.1;
+}
diff --git a/usr/src/lib/libtsol/Makefile b/usr/src/lib/libtsol/Makefile
new file mode 100644
index 0000000000..2bb6a81725
--- /dev/null
+++ b/usr/src/lib/libtsol/Makefile
@@ -0,0 +1,73 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+#
+# lib/libtsol/Makefile
+#
+
+include ../Makefile.lib
+
+HDRS = label.h
+HDRDIR = common
+SUBDIRS = $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+POFILE = libtsol.po
+MSGFILES = common/btos.c common/private.c common/stob.c
+XGETFLAGS = -a
+
+all := TARGET = all
+clean := TARGET = clean
+clobber := TARGET = clobber
+install := TARGET = install
+lint := TARGET = lint
+
+.KEEP_STATE:
+
+# Override so that label.h gets installed where expected.
+ROOTHDRDIR= $(ROOT)/usr/include/tsol
+
+all clean clobber install: spec .WAIT $(SUBDIRS)
+
+lint: $(SUBDIRS)
+
+install_h: $(ROOTHDRS)
+
+check: $(CHECKHDRS)
+
+$(POFILE): $(MSGFILES)
+ $(BUILDPO.msgfiles)
+
+_msg: $(MSGDOMAINPOFILE)
+
+$(SUBDIRS) spec: FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include $(SRC)/Makefile.msg.targ
+include $(SRC)/lib/Makefile.targ
diff --git a/usr/src/lib/libtsol/Makefile.com b/usr/src/lib/libtsol/Makefile.com
new file mode 100644
index 0000000000..46959e7662
--- /dev/null
+++ b/usr/src/lib/libtsol/Makefile.com
@@ -0,0 +1,74 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+#
+# lib/libtsol/Makefile.com
+#
+
+LIBRARY = libtsol.a
+VERS = .2
+
+OBJECTS = \
+ blabel.o btohex.o btos.o call_labeld.o \
+ getlabel.o getplabel.o hextob.o \
+ ltos.o misc.o getpathbylabel.o private.o privlib.o \
+ setflabel.o stob.o stol.o zone.o
+
+include ../../Makefile.lib
+
+# install this library in the root filesystem
+include ../../Makefile.rootfs
+
+LIBS = $(DYNLIB) $(LINTLIB)
+$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
+LDLIBS += -lsecdb -lc
+
+NONCOMMON = $(OBJECTS:blabel.o=)
+lint:= SRCS = $(NONCOMMON:%.o=$(SRCDIR)/%.c) $(COMMONDIR)/blabel.c
+
+SRCDIR = ../common
+MAPDIR = ../spec/$(TRANSMACH)
+SPECMAPFILE = $(MAPDIR)/mapfile
+
+COMMONDIR= $(SRC)/common/tsol
+
+CFLAGS += $(CCVERBOSE)
+CPPFLAGS += -D_REENTRANT -I$(SRCDIR) -I$(COMMONDIR)
+
+LINTFLAGS64 += -Xarch=v9
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+lint: lintcheck
+
+objs/%.o pic_profs/%.o pics/%.o: $(COMMONDIR)/%.c
+ $(COMPILE.c) -o $@ $<
+ $(POST_PROCESS_O)
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/libtsol/amd64/Makefile b/usr/src/lib/libtsol/amd64/Makefile
new file mode 100644
index 0000000000..69cf39010b
--- /dev/null
+++ b/usr/src/lib/libtsol/amd64/Makefile
@@ -0,0 +1,31 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+include ../Makefile.com
+include ../../Makefile.lib.64
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
diff --git a/usr/src/lib/libtsol/common/btohex.c b/usr/src/lib/libtsol/common/btohex.c
new file mode 100644
index 0000000000..19122382c7
--- /dev/null
+++ b/usr/src/lib/libtsol/common/btohex.c
@@ -0,0 +1,200 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * btohex.c - Binary to Hexadecimal string conversion.
+ *
+ * These routines convert binary labels into canonical
+ * hexadecimal representations of the binary form.
+ */
+
+#include <stdlib.h>
+#include <strings.h>
+#include <tsol/label.h>
+#include <sys/tsol/label_macro.h>
+
+/* 0x + Classification + '-' + ll + '-' + Compartments + end of string */
+#define _HEX_SIZE 2+(sizeof (Classification_t)*2)+4+\
+ (sizeof (Compartments_t)*2)+1
+
+static char hex_buf[_HEX_SIZE];
+
+/*
+ * h_alloc - Allocate data storage for a Hexadecimal label string.
+ *
+ * Entry id = Type of label to allocate storage for.
+ * SUN_SL_ID - Sensitivity Label.
+ * SUN_CLR_ID - Clearance.
+ *
+ * Returns NULL, If unable to allocate storage.
+ * Address of buffer.
+ *
+ * Calls malloc;
+ */
+
+char *
+h_alloc(unsigned char id)
+{
+ size_t size;
+
+ switch (id) {
+
+ case SUN_SL_ID:
+ size = _HEX_SIZE;
+ break;
+
+ case SUN_CLR_ID:
+ size = _HEX_SIZE;
+ break;
+
+ default:
+ return (NULL);
+ }
+
+ return ((char *)malloc(size));
+}
+
+
+/*
+ * h_free - Free a Hexadecimal label string.
+ *
+ * Entry hex = Hexadecimal label string.
+ *
+ * Returns none.
+ *
+ * Calls free.
+ */
+
+void
+h_free(char *hex)
+{
+
+ if (hex == NULL)
+ return;
+
+ free(hex);
+}
+
+
+/*
+ * bsltoh_r - Convert a Sensitivity Label into a Hexadecimal label string.
+ *
+ * Entry label = Sensitivity Label to be translated.
+ * hex = Buffer to place converted label.
+ * len = Length of buffer.
+ *
+ * Returns NULL, If invalid label type.
+ * Address of buffer.
+ *
+ * Calls label_to_str, strncpy.
+ */
+
+char *
+bsltoh_r(const m_label_t *label, char *hex)
+{
+ char *h;
+
+ if (label_to_str(label, &h, M_INTERNAL, DEF_NAMES) != 0) {
+ free(h);
+ return (NULL);
+ }
+
+ (void) strncpy(hex, (const char *)h, _HEX_SIZE);
+ free(h);
+ return (hex);
+}
+
+
+/*
+ * bsltoh - Convert a Sensitivity Label into a Hexadecimal label string.
+ *
+ * Entry label = Sensitivity Label to be translated.
+ *
+ * Returns NULL, If invalid label type.
+ * Address of statically allocated hex label string.
+ *
+ * Calls bsltoh_r.
+ *
+ * Uses hex_buf.
+ */
+
+char *
+bsltoh(const m_label_t *label)
+{
+
+ return (bsltoh_r(label, hex_buf));
+}
+
+
+/*
+ * bcleartoh_r - Convert a Clearance into a Hexadecimal label string.
+ *
+ * Entry clearance = Clearance to be translated.
+ * hex = Buffer to place converted label.
+ * len = Length of buffer.
+ *
+ * Returns NULL, If invalid label type.
+ * Address of buffer.
+ *
+ * Calls label_to_str, strncpy.
+ */
+
+char *
+bcleartoh_r(const m_label_t *clearance, char *hex)
+{
+ char *h;
+
+ if (label_to_str(clearance, &h, M_INTERNAL, DEF_NAMES) != 0) {
+ free(h);
+ return (NULL);
+ }
+
+ (void) strncpy(hex, (const char *)h, _HEX_SIZE);
+ free(h);
+ return (hex);
+}
+
+
+/*
+ * bcleartoh - Convert a Clearance into a Hexadecimal label string.
+ *
+ * Entry clearance = Clearance to be translated.
+ *
+ * Returns NULL, If invalid label type.
+ * Address of statically allocated hex label string.
+ *
+ * Calls bcleartoh_r.
+ *
+ * Uses hex_buf.
+ */
+
+char *
+bcleartoh(const m_label_t *clearance)
+{
+
+ return (bcleartoh_r(clearance, hex_buf));
+}
diff --git a/usr/src/lib/libtsol/common/btos.c b/usr/src/lib/libtsol/common/btos.c
new file mode 100644
index 0000000000..7ed4a6cdee
--- /dev/null
+++ b/usr/src/lib/libtsol/common/btos.c
@@ -0,0 +1,485 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Binary label to label string translations.
+ */
+
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <wchar.h>
+
+#include <sys/mman.h>
+
+#include <tsol/label.h>
+
+#include "clnt.h"
+#include "labeld.h"
+#include <sys/tsol/label_macro.h>
+
+#if !defined(TEXT_DOMAIN) /* should be defined by Makefiles */
+#define TEXT_DOMAIN "SYS_TEST"
+#endif /* TEXT_DOMAIN */
+
+static bslabel_t slow; /* static admin_low high sensitivity label */
+static bslabel_t shigh; /* static admin_high sensitivity label */
+static bclear_t clrlow, clrhigh; /* static admin_low and admin_high Clearance */
+
+static char *sstring; /* return string for sb*tos */
+static size_t ssize; /* current size of return string */
+
+static int
+return_string(char **string, int str_len, char *val)
+{
+ char *cpyptr;
+ size_t val_len = strlen(val) + 1;
+
+ if (*string == NULL) {
+ if ((*string = malloc(val_len)) == NULL)
+ return (0);
+ } else if (val_len > str_len) {
+ **string = '\0';
+ return (0);
+ }
+
+ cpyptr = *string;
+ bcopy(val, cpyptr, val_len);
+
+ return (val_len);
+}
+
+void
+set_label_view(uint_t *callflags, uint_t flags)
+{
+ if (flags&VIEW_INTERNAL) {
+ *callflags |= LABELS_VIEW_INTERNAL;
+ } else if (flags&VIEW_EXTERNAL) {
+ *callflags |= LABELS_VIEW_EXTERNAL;
+ }
+}
+
+int
+alloc_string(char **string, size_t size, char val)
+{
+ if (*string == NULL) {
+ if ((*string = malloc(ALLOC_CHUNK)) == NULL)
+ return (0);
+ } else {
+ if ((*string = realloc(*string, size + ALLOC_CHUNK)) == NULL) {
+ **string = val;
+ return (0);
+ }
+ }
+ **string = val;
+ return (ALLOC_CHUNK);
+}
+
+#define slcall callp->param.acall.cargs.bsltos_arg
+#define slret callp->param.aret.rvals.bsltos_ret
+/*
+ * bsltos - Convert Binary Sensitivity Label to Sensitivity Label string.
+ *
+ * Entry label = Binary Sensitivity Label to be converted.
+ * string = NULL ((char *) 0), if memory to be allocated,
+ * otherwise, pointer to preallocated memory.
+ * str_len = Length of preallocated memory, else ignored.
+ * flags = Logical sum of:
+ * LONG_CLASSIFICATION or SHORT_CLASSIFICATION,
+ * LONG_WORDS or SHORT_WORDS,
+ * VIEW_INTERNAL or VIEW_EXTERNAL, and
+ * NO_CLASSIFICATION.
+ * LONG_CLASSIFICATION, use long classification names.
+ * SHORT_CLASSIFICATION, use short classification
+ * names (default).
+ * NO_CLASSIFICATION, don't translate classification.
+ * LONG_WORDS, use the long form of words (default).
+ * SHORTWORDS, use the short form of words where available.
+ * VIEW_INTERNAL, don't promote/demote admin low/high.
+ * VIEW_EXTERNAL, promote/demote admin low/high.
+ *
+ * Exit string = Sensitivity Label string, or empty string if
+ * not enough preallocated memory.
+ *
+ * Returns -1, If unable to access label encodings database.
+ * 0, If unable to allocate string,
+ * or allocated string to short
+ * (and **string = '\0').
+ * length (including null) of Sensitivity Label string,
+ * If successful.
+ *
+ * Calls RPC - LABELS_BSLTOS, BCLHIGH, BCLLOW, BCLTOSL, BLEQUAL,
+ * BLTYPE, SETBSLABEL, UCLNT, memcpy, clnt_call,
+ * clnt_perror, malloc, strcat, strlen.
+ *
+ * Uses ADMIN_HIGH, ADMIN_LOW, shigh, slow.
+ */
+
+ssize_t
+bsltos(const bslabel_t *label, char **string, size_t str_len,
+ int flags)
+{
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize = CALL_SIZE(bsltos_call_t, 0);
+ int rval;
+
+ if (!BLTYPE(label, SUN_SL_ID)) {
+ return (-1);
+ }
+
+ call.callop = BSLTOS;
+ slcall.label = *label;
+ slcall.flags = (flags&NO_CLASSIFICATION) ? LABELS_NO_CLASS : 0;
+ slcall.flags |= (flags&SHORT_CLASSIFICATION ||
+ !(flags&LONG_CLASSIFICATION)) ? LABELS_SHORT_CLASS : 0;
+ slcall.flags |= (flags&SHORT_WORDS && !(flags&LONG_WORDS)) ?
+ LABELS_SHORT_WORDS : 0;
+ set_label_view(&slcall.flags, flags);
+
+ if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) {
+
+ if (callp->reterr != 0)
+ return (-1);
+
+ /* unpack Sensitivity Label */
+
+ rval = return_string(string, str_len, slret.slabel);
+
+ if (callp != &call)
+ (void) munmap((void *)callp, bufsize);
+ return (rval);
+ } else if (rval == NOSERVER) {
+ /* server not present */
+ /* special case admin_high and admin_low */
+
+ if (!BLTYPE(&slow, SUN_SL_ID)) {
+ /* initialize static labels */
+
+ BSLLOW(&slow);
+ BSLHIGH(&shigh);
+ }
+
+ if (BLEQUAL(label, &slow)) {
+ return (return_string(string, str_len, ADMIN_LOW));
+ } else if (BLEQUAL(label, &shigh)) {
+ return (return_string(string, str_len, ADMIN_HIGH));
+ }
+ }
+ return (-1);
+} /* bsltos */
+#undef slcall
+#undef slret
+
+#define clrcall callp->param.acall.cargs.bcleartos_arg
+#define clrret callp->param.aret.rvals.bcleartos_ret
+/*
+ * bcleartos - Convert Binary Clearance to Clearance string.
+ *
+ * Entry clearance = Binary Clearance to be converted.
+ * string = NULL ((char *) 0), if memory to be allocated,
+ * otherwise, pointer to preallocated memory.
+ * str_len = Length of preallocated memory, else ignored.
+ * flags = Logical sum of:
+ * LONG_CLASSIFICATION or SHORT_CLASSIFICATION,
+ * LONG_WORDS or SHORT_WORDS,
+ * VIEW_INTERNAL or VIEW_EXTERNAL.
+ * LONG_CLASSIFICATION, use long classification names.
+ * SHORT_CLASSIFICATION, use short classification
+ * names (default).
+ * LONG_WORDS, use the long form of words (default).
+ * SHORTWORDS, use the short form of words where available.
+ * VIEW_INTERNAL, don't promote/demote admin low/high.
+ * VIEW_EXTERNAL, promote/demote admin low/high.
+ *
+ * Exit string = Clearance string, or empty string if not
+ * enough preallocated memory.
+ *
+ * Returns -1, If unable to access label encodings database.
+ * 0, If unable to allocate string,
+ * or allocated string to short
+ * (and **string = '\0').
+ * length (including null) of Clearance string,
+ * If successful.
+ *
+ * Calls RPC - LABELS_BSLTOS, BCLHIGH, BCLLOW, BCLTOSL, BLEQUAL,
+ * BLTYPE, SETBSLABEL, UCLNT, memcpy, clnt_call,
+ * clnt_perror, malloc, strcat, strlen.
+ *
+ * Uses ADMIN_HIGH, ADMIN_LOW, clrhigh, clrlow.
+ */
+
+ssize_t
+bcleartos(const bclear_t *clearance, char **string, size_t str_len,
+ int flags)
+{
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize = CALL_SIZE(bcleartos_call_t, 0);
+ int rval;
+
+ if (!BLTYPE(clearance, SUN_CLR_ID)) {
+ return (-1);
+ }
+
+ call.callop = BCLEARTOS;
+ clrcall.clear = *clearance;
+ clrcall.flags = (flags&SHORT_CLASSIFICATION ||
+ !(flags&LONG_CLASSIFICATION)) ? LABELS_SHORT_CLASS : 0;
+ clrcall.flags |= (flags&SHORT_WORDS && !(flags&LONG_WORDS)) ?
+ LABELS_SHORT_WORDS : 0;
+ set_label_view(&clrcall.flags, flags);
+
+ if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) {
+
+ if (callp->reterr != 0)
+ return (-1);
+
+ /* unpack Clearance */
+
+ rval = return_string(string, str_len, clrret.cslabel);
+
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (rval);
+ } else if (rval == NOSERVER) {
+ /* server not present */
+ /* special case admin_high and admin_low */
+
+ if (!BLTYPE(&clrlow, SUN_CLR_ID)) {
+ /* initialize static labels */
+
+ BCLEARLOW(&clrlow);
+ BCLEARHIGH(&clrhigh);
+ }
+ if (BLEQUAL(clearance, &clrlow)) {
+ return (return_string(string, str_len, ADMIN_LOW));
+ } else if (BLEQUAL(clearance, &clrhigh)) {
+ return (return_string(string, str_len, ADMIN_HIGH));
+ }
+ }
+ return (-1);
+} /* bcleartos */
+#undef clrcall
+#undef clrret
+
+/*
+ * sbsltos - Convert Sensitivity Label to canonical clipped form.
+ *
+ * Entry label = Sensitivity Label to be converted.
+ * len = Maximum length of translated string, excluding NULL.
+ * 0, full string.
+ * sstring = address of string to translate into.
+ * ssize = size of memory currently allocated to sstring.
+ *
+ * Exit sstring = Newly translated string.
+ * ssize = Updated if more memory pre-allocated.
+ *
+ * Returns NULL, If error, len too small, unable to translate, or get
+ * memory for string.
+ * Address of string containing converted value.
+ *
+ * Calls alloc_string, bsltos, strcpy.
+ *
+ * Uses ssize, sstring.
+ */
+
+char *
+sbsltos(const bslabel_t *label, size_t len)
+{
+ ssize_t slen; /* length including NULL */
+ wchar_t *wstring;
+ int wccount;
+
+ if (ssize == 0) {
+ /* Allocate string memory. */
+ if ((ssize = alloc_string(&sstring, ssize, 's')) == 0)
+ /* can't get initial memory for string */
+ return (NULL);
+ }
+
+again:
+ if ((slen = bsltos(label, &sstring, ssize,
+ (SHORT_CLASSIFICATION | LONG_WORDS))) <= 0) {
+ /* error in translation */
+ if (slen == 0) {
+ if (*sstring == '\0') {
+ int newsize;
+ /* sstring not long enough */
+ if ((newsize = alloc_string(&sstring, ssize,
+ 's')) == 0) {
+ /* Can't get more memory */
+ return (NULL);
+ }
+ ssize += newsize;
+ goto again;
+ }
+ }
+ return (NULL);
+ }
+ if (len == 0) {
+ return (sstring);
+ } else if (len < MIN_SL_LEN) {
+ return (NULL);
+ }
+ if ((wstring = malloc(slen * sizeof (wchar_t))) == NULL)
+ return (NULL);
+ if ((wccount = mbstowcs(wstring, sstring, slen - 1)) == -1) {
+ free(wstring);
+ return (NULL);
+ }
+ if (wccount > len) {
+ wchar_t *clipp = wstring + (len - 2);
+
+ /* Adjust string size to desired length */
+
+ clipp[0] = L'<';
+ clipp[1] = L'-';
+ clipp[2] = L'\0';
+
+ while (wcstombs(NULL, wstring, 0) >= ssize) {
+ int newsize;
+
+ /* sstring not long enough */
+ if ((newsize = alloc_string(&sstring, ssize, 's')) ==
+ 0) {
+ /* Can't get more memory */
+ return (NULL);
+ }
+ ssize += newsize;
+ }
+
+ if ((wccount = wcstombs(sstring, wstring, ssize)) == -1) {
+ free(wstring);
+ return (NULL);
+ }
+ }
+ free(wstring);
+
+ return (sstring);
+} /* sbsltos */
+
+/*
+ * sbcleartos - Convert Clearance to canonical clipped form.
+ *
+ * Entry clearance = Clearance to be converted.
+ * len = Maximum length of translated string, excluding NULL.
+ * 0, full string.
+ * sstring = address of string to translate into.
+ * ssize = size of memory currently allocated to sstring.
+ *
+ * Exit sstring = Newly translated string.
+ * ssize = Updated if more memory pre-allocated.
+ *
+ * Returns NULL, If error, len too small, unable to translate, or get
+ * memory for string.
+ * Address of string containing converted value.
+ *
+ * Calls alloc_string, bcleartos, strcpy.
+ *
+ * Uses ssize, sstring.
+ */
+
+char *
+sbcleartos(const bclear_t *clearance, size_t len)
+{
+ ssize_t slen; /* length including NULL */
+ wchar_t *wstring;
+ int wccount;
+
+ if (ssize == 0) {
+ /* Allocate string memory. */
+ if ((ssize = alloc_string(&sstring, ssize, 'c')) == 0)
+ /* can't get initial memory for string */
+ return (NULL);
+ }
+
+again:
+ if ((slen = bcleartos(clearance, &sstring, ssize,
+ (SHORT_CLASSIFICATION | LONG_WORDS))) <= 0) {
+ /* error in translation */
+ if (slen == 0) {
+ if (*sstring == '\0') {
+ int newsize;
+ /* sstring not long enough */
+ if ((newsize = alloc_string(&sstring, ssize,
+ 'c')) == 0) {
+ /* Can't get more memory */
+ return (NULL);
+ }
+ ssize += newsize;
+ goto again;
+ }
+ }
+ return (NULL);
+ }
+ if (len == 0) {
+ return (sstring);
+ } else if (len < MIN_CLR_LEN) {
+ return (NULL);
+ }
+ if ((wstring = malloc(slen * sizeof (wchar_t))) == NULL)
+ return (NULL);
+ if ((wccount = mbstowcs(wstring, sstring, slen - 1)) == -1) {
+ free(wstring);
+ return (NULL);
+ }
+ if (wccount > len) {
+ wchar_t *clipp = wstring + (len - 2);
+
+ /* Adjust string size to desired length */
+
+ clipp[0] = L'<';
+ clipp[1] = L'-';
+ clipp[2] = L'\0';
+
+ while (wcstombs(NULL, wstring, 0) >= ssize) {
+ int newsize;
+
+ /* sstring not long enough */
+ if ((newsize = alloc_string(&sstring, ssize, 'c')) ==
+ 0) {
+ /* Can't get more memory */
+ free(wstring);
+ return (NULL);
+ }
+ ssize += newsize;
+ }
+ if ((wccount = wcstombs(sstring, wstring, ssize)) == -1) {
+ free(wstring);
+ return (NULL);
+ }
+ }
+ free(wstring);
+
+ return (sstring);
+} /* sbcleartos */
diff --git a/usr/src/lib/libtsol/common/call_labeld.c b/usr/src/lib/libtsol/common/call_labeld.c
new file mode 100644
index 0000000000..35d94450f5
--- /dev/null
+++ b/usr/src/lib/libtsol/common/call_labeld.c
@@ -0,0 +1,308 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <door.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <synch.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "labeld.h"
+
+#ifndef DEBUG
+#define perror(e)
+#endif /* !DEBUG */
+
+/*
+ * Library prototypes to get away from lots of static build problems.
+ */
+
+extern int __nanosleep(const struct timespec *, struct timespec *);
+
+/*
+ * This is cloned from _nsc_trydoorcall used by the nscd client.
+ *
+ * Routine that actually performs the door call.
+ * Note that we cache a file descriptor. We do
+ * the following to prevent disasters:
+ *
+ * 1) Never use 0, 1 or 2; if we get this from the open
+ * we dup it upwards.
+ *
+ * 2) Set the close on exec flags so descriptor remains available
+ * to child processes.
+ *
+ * 3) Verify that the door is still the same one we had before
+ * by using door_info on the client side.
+ *
+ * Note that we never close the file descriptor if it isn't one
+ * we allocated; we check this with door info. The rather tricky
+ * logic is designed to be fast in the normal case (fd is already
+ * allocated and is ok) while handling the case where the application
+ * closed it underneath us or where the nscd dies or re-execs itself
+ * and we're a multi-threaded application. Note that we cannot protect
+ * the application if it closes the fd and it is multi-threaded.
+ *
+ * int __call_labeld(label_door_op **dptr, int *ndata, int *adata);
+ *
+ * *dptr IN: points to arg buffer OUT: points to results buffer
+ * *ndata IN: overall size of buffer OUT: overall size of buffer
+ * *adata IN: size of call data OUT: size of return data
+ *
+ * Note that *dptr may change if provided space as defined by *bufsize is
+ * inadequate. In this case the door call mmaps more space and places
+ * the answer there and sets dptr to contain a pointer to the space, which
+ * should be freed with munmap.
+ *
+ * Returns 0 if the door call reached the server, -1 if contact was not made.
+ *
+ */
+
+
+static mutex_t _door_lock = DEFAULTMUTEX;
+
+int
+__call_labeld(labeld_data_t **dptr, size_t *ndata, size_t *adata)
+{
+ static int doorfd = -1;
+ static door_info_t real_door;
+ struct stat st;
+ door_info_t my_door;
+ door_arg_t param;
+ char door_name[MAXPATHLEN];
+ struct timespec ts;
+ int busy = 0; /* number of busy loops */
+
+#ifdef DEBUG
+ labeld_data_t *callptr = *dptr;
+ int buf_size = *ndata;
+ int return_size = *adata;
+#endif /* DEBUG */
+
+ /*
+ * the first time in we try and open and validate the door.
+ * the validations are that the door must have been
+ * created with the label service door cookie and
+ * that it has the same door ID. If any of these
+ * validations fail we refuse to use the door.
+ */
+ ts.tv_sec = 0; /* initialize nanosecond retry timer */
+ ts.tv_nsec = 100;
+ (void) mutex_lock(&_door_lock);
+
+try_again:
+ if (doorfd == -1) {
+ int tbc[3];
+ int i;
+
+ (void) snprintf(door_name, sizeof (door_name), "%s%s",
+ DOOR_PATH, DOOR_NAME);
+ if ((doorfd = open64(door_name, O_RDONLY, 0)) < 0) {
+ (void) mutex_unlock(&_door_lock);
+ perror("server door open");
+ return (NOSERVER);
+ }
+
+ /*
+ * dup up the file descriptor if we have 0 - 2
+ * to avoid problems with shells stdin/out/err
+ */
+ i = 0;
+ while (doorfd < 3) { /* we have a reserved fd */
+ tbc[i++] = doorfd;
+ if ((doorfd = dup(doorfd)) < 0) {
+ perror("couldn't dup");
+ while (i--)
+ (void) close(tbc[i]);
+ doorfd = -1;
+ (void) mutex_unlock(&_door_lock);
+ return (NOSERVER);
+ }
+ }
+ while (i--)
+ (void) close(tbc[i]);
+
+ /*
+ * mark this door descriptor as close on exec
+ */
+ (void) fcntl(doorfd, F_SETFD, FD_CLOEXEC);
+ if (door_info(doorfd, &real_door) < 0) {
+ /*
+ * we should close doorfd because we just opened it
+ */
+ perror("real door door_info");
+ (void) close(doorfd);
+ doorfd = -1;
+ (void) mutex_unlock(&_door_lock);
+ return (NOSERVER);
+ }
+ if (fstat(doorfd, &st) < 0) {
+ perror("real door fstat");
+ return (NOSERVER);
+ }
+#ifdef DEBUG
+ (void) printf("\treal door %s\n", door_name);
+ (void) printf("\t\tuid = %d, gid = %d, mode = %o\n", st.st_uid,
+ st.st_gid, st.st_mode);
+ (void) printf("\t\toutstanding requests = %d\n", st.st_nlink-1);
+ (void) printf("\t\t pid = %d\n", real_door.di_target);
+ (void) printf("\t\t procedure = %llx\n", real_door.di_proc);
+ (void) printf("\t\t cookie = %llx\n", real_door.di_data);
+ (void) printf("\t\t attributes = %x\n",
+ real_door.di_attributes);
+ if (real_door.di_attributes & DOOR_UNREF)
+ (void) printf("\t\t\t UNREF\n");
+ if (real_door.di_attributes & DOOR_PRIVATE)
+ (void) printf("\t\t\t PRIVATE\n");
+ if (real_door.di_attributes & DOOR_LOCAL)
+ (void) printf("\t\t\t LOCAL\n");
+ if (real_door.di_attributes & DOOR_REVOKED)
+ (void) printf("\t\t\t REVOKED\n");
+ if (real_door.di_attributes & DOOR_DESCRIPTOR)
+ (void) printf("\t\t\t DESCRIPTOR\n");
+ if (real_door.di_attributes & DOOR_RELEASE)
+ (void) printf("\t\t\t RELEASE\n");
+ if (real_door.di_attributes & DOOR_DELAY)
+ (void) printf("\t\t\t DELAY\n");
+ (void) printf("\t\t id = %llx\n", real_door.di_uniquifier);
+#endif /* DEBUG */
+ if ((real_door.di_attributes & DOOR_REVOKED) ||
+ (real_door.di_data != (door_ptr_t)COOKIE)) {
+#ifdef DEBUG
+ (void) printf("real door revoked\n");
+#endif /* DEBUG */
+ (void) close(doorfd);
+ doorfd = -1;
+ (void) mutex_unlock(&_door_lock);
+ return (NOSERVER);
+ }
+ } else {
+ if ((door_info(doorfd, &my_door) < 0) ||
+ (my_door.di_data != (door_ptr_t)COOKIE) ||
+ (my_door.di_uniquifier != real_door.di_uniquifier)) {
+ perror("my door door_info");
+ /*
+ * don't close it - someone else has clobbered fd
+ */
+ doorfd = -1;
+ goto try_again;
+ }
+ if (fstat(doorfd, &st) < 0) {
+ perror("my door fstat");
+ goto try_again;
+ }
+#ifdef DEBUG
+ (void) sprintf(door_name, "%s%s", DOOR_PATH, DOOR_NAME);
+ (void) printf("\tmy door %s\n", door_name);
+ (void) printf("\t\tuid = %d, gid = %d, mode = %o\n", st.st_uid,
+ st.st_gid, st.st_mode);
+ (void) printf("\t\toutstanding requests = %d\n", st.st_nlink-1);
+ (void) printf("\t\t pid = %d\n", my_door.di_target);
+ (void) printf("\t\t procedure = %llx\n", my_door.di_proc);
+ (void) printf("\t\t cookie = %llx\n", my_door.di_data);
+ (void) printf("\t\t attributes = %x\n", my_door.di_attributes);
+ if (my_door.di_attributes & DOOR_UNREF)
+ (void) printf("\t\t\t UNREF\n");
+ if (my_door.di_attributes & DOOR_PRIVATE)
+ (void) printf("\t\t\t PRIVATE\n");
+ if (my_door.di_attributes & DOOR_LOCAL)
+ (void) printf("\t\t\t LOCAL\n");
+ if (my_door.di_attributes & DOOR_REVOKED)
+ (void) printf("\t\t\t REVOKED\n");
+ if (my_door.di_attributes & DOOR_DESCRIPTOR)
+ (void) printf("\t\t\t DESCRIPTOR\n");
+ if (my_door.di_attributes & DOOR_RELEASE)
+ (void) printf("\t\t\t RELEASE\n");
+ if (my_door.di_attributes & DOOR_DELAY)
+ (void) printf("\t\t\t DELAY\n");
+ (void) printf("\t\t id = %llx\n", my_door.di_uniquifier);
+#endif /* DEBUG */
+ if (my_door.di_attributes & DOOR_REVOKED) {
+#ifdef DEBUG
+ (void) printf("my door revoked\n");
+#endif /* DEBUG */
+ (void) close(doorfd); /* labeld exited .... */
+ doorfd = -1; /* try and restart connection */
+ goto try_again;
+ }
+ }
+ (void) mutex_unlock(&_door_lock);
+
+ param.data_ptr = (char *)*dptr;
+ param.data_size = *adata;
+ param.desc_ptr = NULL;
+ param.desc_num = 0;
+ param.rbuf = (char *)*dptr;
+ param.rsize = *ndata;
+
+ if (door_call(doorfd, &param) < 0) {
+ if (errno == EAGAIN && busy++ < 10) {
+ /* adjust backoff */
+ if ((ts.tv_nsec *= 10) >= NANOSEC) {
+ ts.tv_sec++;
+ ts.tv_nsec = 100;
+ }
+ (void) __nanosleep(&ts, NULL);
+#ifdef DEBUG
+ (void) printf("door_call failed EAGAIN # %d\n", busy);
+#endif /* DEBUG */
+ (void) mutex_lock(&_door_lock);
+ goto try_again;
+ }
+ perror("door call");
+ return (NOSERVER);
+ }
+
+ *adata = (int)param.data_size;
+ *ndata = (int)param.rsize;
+ /*LINTED*/
+ *dptr = (labeld_data_t *)param.data_ptr;
+
+ if (*adata == 0 || *dptr == NULL) {
+#ifdef DEBUG
+ (void) printf("\tNo data returned, size = %lu, dptr = %p\n",
+ (unsigned long)*adata, (void *)*dptr);
+#endif /* DEBUG */
+ return (NOSERVER);
+ }
+#ifdef DEBUG
+ (void) printf("call buf = %x, buf size = %d, call size = %d\n",
+ callptr, buf_size, return_size);
+ (void) printf("retn buf = %x, buf size = %d, retn size = %d\n",
+ *dptr, *ndata, *adata);
+ (void) printf("\treply status = %d\n", (*dptr)->param.aret.ret);
+#endif /* DEBUG */
+ return ((*dptr)->param.aret.ret);
+
+} /* __call_labeld */
diff --git a/usr/src/lib/libtsol/common/clnt.h b/usr/src/lib/libtsol/common/clnt.h
new file mode 100644
index 0000000000..bf3845e02c
--- /dev/null
+++ b/usr/src/lib/libtsol/common/clnt.h
@@ -0,0 +1,49 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _CLNT_H
+#define _CLNT_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAXCOLOR 256 /* Max size of a static color string */
+#define MIN_CMW_LEN 8 /* minimum length of clipped CMW Label */
+#define MIN_SL_LEN 3 /* minimum length of clipped SL */
+#define MIN_IL_LEN 3 /* minimum length of clipped IL */
+#define MIN_CLR_LEN 3 /* minimum length of clipped Clearance */
+
+#define ALLOC_CHUNK 1024 /* size of chunk for sb*tos allocs */
+
+extern int alloc_string(char **, size_t, char);
+extern void set_label_view(uint_t *, uint_t);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CLNT_H */
diff --git a/usr/src/lib/libtsol/common/getlabel.c b/usr/src/lib/libtsol/common/getlabel.c
new file mode 100644
index 0000000000..9cca4019f0
--- /dev/null
+++ b/usr/src/lib/libtsol/common/getlabel.c
@@ -0,0 +1,66 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * String to binary label translations.
+ */
+
+#include <ctype.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <tsol/label.h>
+#include <sys/tsol/label_macro.h>
+
+#include <sys/syscall.h>
+#include <sys/tsol/tsyscall.h>
+
+#include <sys/types.h>
+
+/*
+ * getlabel(3TSOL) - get file label
+ *
+ * This is the library interface to the system call.
+ */
+
+int
+getlabel(const char *path, bslabel_t *label)
+{
+ return (syscall(SYS_labelsys, TSOL_GETLABEL, path, label));
+}
+
+/*
+ * fgetlabel(3TSOL) - get file label
+ *
+ * This is the library interface to the system call.
+ */
+int
+fgetlabel(int fd, bslabel_t *label)
+{
+ return (syscall(SYS_labelsys, TSOL_FGETLABEL, fd, label));
+}
diff --git a/usr/src/lib/libtsol/common/getpathbylabel.c b/usr/src/lib/libtsol/common/getpathbylabel.c
new file mode 100644
index 0000000000..0f8c5597d0
--- /dev/null
+++ b/usr/src/lib/libtsol/common/getpathbylabel.c
@@ -0,0 +1,503 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * Name: getpathbylabel.c
+ *
+ * Description: Returns the global zone pathname corresponding
+ * to the specified label. The pathname does
+ * not need to match an existing file system object.
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <tsol/label.h>
+#include <stdlib.h>
+#include <zone.h>
+#include <sys/mntent.h>
+#include <sys/mnttab.h>
+#include <stdarg.h>
+
+/*
+ * This structure is used to chain mntent structures into a list
+ * and to cache stat information for each member of the list.
+ */
+struct mntlist {
+ struct mnttab *mntl_mnt;
+ struct mntlist *mntl_next;
+};
+
+
+/*
+ * Return a pointer to the trailing suffix of full that follows the prefix
+ * given by pref. If pref isn't a prefix of full, return NULL. Apply
+ * pathname semantics to the prefix test, so that pref must match at a
+ * component boundary.
+ */
+static char *
+pathsuffix(char *full, char *pref)
+{
+ int preflen;
+
+ if (full == NULL || pref == NULL)
+ return (NULL);
+
+ preflen = strlen(pref);
+ if (strncmp(pref, full, preflen) != 0)
+ return (NULL);
+
+ /*
+ * pref is a substring of full. To be a subpath, it cannot cover a
+ * partial component of full. The last clause of the test handles the
+ * special case of the root.
+ */
+ if (full[preflen] != '\0' && full[preflen] != '/' && preflen > 1)
+ return (NULL);
+
+ if (preflen == 1 && full[0] == '/')
+ return (full);
+ else
+ return (full + preflen);
+}
+
+/*
+ * Return zero iff the path named by sub is a leading subpath
+ * of the path named by full.
+ *
+ * Treat null paths as matching nothing.
+ */
+static int
+subpath(char *full, char *sub)
+{
+ return (pathsuffix(full, sub) == NULL);
+}
+
+static void
+tsol_mnt_free(struct mnttab *mnt)
+{
+ if (mnt->mnt_special)
+ free(mnt->mnt_special);
+ if (mnt->mnt_mountp)
+ free(mnt->mnt_mountp);
+ if (mnt->mnt_fstype)
+ free(mnt->mnt_fstype);
+ if (mnt->mnt_mntopts)
+ free(mnt->mnt_mntopts);
+ free(mnt);
+}
+
+static void
+tsol_mlist_free(struct mntlist *mlist)
+{
+ struct mntlist *mlp;
+
+ for (mlp = mlist; mlp; mlp = mlp->mntl_next) {
+ struct mnttab *mnt = mlp->mntl_mnt;
+
+ if (mnt)
+ tsol_mnt_free(mnt);
+ free(mlp);
+ }
+}
+
+static struct mnttab *
+mntdup(struct mnttab *mnt)
+{
+ struct mnttab *new;
+
+ new = (struct mnttab *)malloc(sizeof (*new));
+ if (new == NULL)
+ return (NULL);
+
+ new->mnt_special = NULL;
+ new->mnt_mountp = NULL;
+ new->mnt_fstype = NULL;
+ new->mnt_mntopts = NULL;
+
+ new->mnt_special = strdup(mnt->mnt_special);
+ if (new->mnt_special == NULL) {
+ tsol_mnt_free(new);
+ return (NULL);
+ }
+ new->mnt_mountp = strdup(mnt->mnt_mountp);
+ if (new->mnt_mountp == NULL) {
+ tsol_mnt_free(new);
+ return (NULL);
+ }
+ new->mnt_fstype = strdup(mnt->mnt_fstype);
+ if (new->mnt_fstype == NULL) {
+ tsol_mnt_free(new);
+ return (NULL);
+ }
+ new->mnt_mntopts = strdup(mnt->mnt_mntopts);
+ if (new->mnt_mntopts == NULL) {
+ tsol_mnt_free(new);
+ return (NULL);
+ }
+ return (new);
+}
+
+static struct mntlist *
+tsol_mkmntlist(void)
+{
+ FILE *mounted;
+ struct mntlist *mntl;
+ struct mntlist *mntst = NULL;
+ struct mnttab mnt;
+
+ if ((mounted = fopen(MNTTAB, "r")) == NULL) {
+ perror(MNTTAB);
+ return (NULL);
+ }
+ resetmnttab(mounted);
+ while (getmntent(mounted, &mnt) == NULL) {
+ mntl = (struct mntlist *)malloc(sizeof (*mntl));
+ if (mntl == NULL) {
+ tsol_mlist_free(mntst);
+ mntst = NULL;
+ break;
+ }
+ mntl->mntl_mnt = mntdup((struct mnttab *)(&mnt));
+ if (mntl->mntl_mnt == NULL) {
+ tsol_mlist_free(mntst);
+ mntst = NULL;
+ break;
+ }
+ mntl->mntl_next = mntst;
+ mntst = mntl;
+ }
+ (void) fclose(mounted);
+ return (mntst);
+}
+
+/*
+ * This function attempts to convert local zone NFS mounted pathnames
+ * into equivalent global zone NFS mounted pathnames. At present
+ * it only works for automounted filesystems. It depends on the
+ * assumption that both the local and global zone automounters
+ * share the same nameservices. It also assumes that any automount
+ * map used by a local zone is available to the global zone automounter.
+ *
+ * The algorithm used consists of three phases.
+ *
+ * 1. The local zone's mnttab is searched to find the automount map
+ * with the closest matching mountpath.
+ *
+ * 2. The matching autmount map name is looked up in the global zone's
+ * mnttab to determine the path where it should be mounted in the
+ * global zone.
+ *
+ * 3. A pathname covered by an appropiate autofs trigger mount in
+ * the global zone is generated as the resolved pathname
+ *
+ * Among the things that can go wrong is that global zone doesn't have
+ * a matching automount map or the mount was not done via the automounter.
+ * Either of these cases return a NULL path.
+ */
+#define ZONE_OPT "zone="
+static int
+getnfspathbyautofs(struct mntlist *mlist, zoneid_t zoneid,
+ struct mnttab *autofs_mnt, char *globalpath, char *zonepath, int global_len)
+{
+ struct mntlist *mlp;
+ char zonematch[ZONENAME_MAX + 20];
+ char zonename[ZONENAME_MAX];
+ int longestmatch;
+ struct mnttab *mountmatch;
+
+ if (autofs_mnt) {
+ mountmatch = autofs_mnt;
+ longestmatch = strlen(mountmatch->mnt_mountp);
+ } else {
+ /*
+ * First we need to get the zonename to look for
+ */
+ if (zone_getattr(zoneid, ZONE_ATTR_NAME, zonename,
+ ZONENAME_MAX) == -1) {
+ return (0);
+ }
+
+ (void) strncpy(zonematch, ZONE_OPT, sizeof (zonematch));
+ (void) strlcat(zonematch, zonename, sizeof (zonematch));
+
+ /*
+ * Find the best match for an automount map that
+ * corresponds to the local zone's pathname
+ */
+ longestmatch = 0;
+ for (mlp = mlist; mlp; mlp = mlp->mntl_next) {
+ struct mnttab *mnt = mlp->mntl_mnt;
+ int len;
+ int matchfound;
+ char *token;
+ char *lasts;
+ char mntopts[MAXPATHLEN];
+
+ if (subpath(globalpath, mnt->mnt_mountp) != 0)
+ continue;
+ if (strcmp(mnt->mnt_fstype, MNTTYPE_AUTOFS))
+ continue;
+
+ matchfound = 0;
+ (void) strncpy(mntopts, mnt->mnt_mntopts, MAXPATHLEN);
+ if ((token = strtok_r(mntopts, ",", &lasts)) != NULL) {
+ if (strcmp(token, zonematch) == 0) {
+ matchfound = 1;
+ } else while ((token = strtok_r(NULL, ",",
+ &lasts)) != NULL) {
+ if (strcmp(token, zonematch) == 0) {
+ matchfound = 1;
+ break;
+ }
+ }
+ }
+ if (matchfound) {
+ len = strlen(mnt->mnt_mountp);
+ if (len > longestmatch) {
+ mountmatch = mnt;
+ longestmatch = len;
+ }
+ }
+ }
+ }
+ if (longestmatch == 0) {
+ return (0);
+ } else {
+ /*
+ * Now we may have found the corresponding autofs mount
+ * Try to find the matching global zone autofs entry
+ */
+
+ for (mlp = mlist; mlp; mlp = mlp->mntl_next) {
+ char p[MAXPATHLEN];
+ size_t zp_len;
+ size_t mp_len;
+
+ struct mnttab *mnt = mlp->mntl_mnt;
+
+ if (strcmp(mountmatch->mnt_special,
+ mnt->mnt_special) != 0)
+ continue;
+ if (strcmp(mnt->mnt_fstype, MNTTYPE_AUTOFS))
+ continue;
+ if (strstr(mnt->mnt_mntopts, ZONE_OPT) != NULL)
+ continue;
+ /*
+ * OK, we have a matching global zone automap
+ * so adjust the path for the global zone.
+ */
+ zp_len = strlen(zonepath);
+ mp_len = strlen(mnt->mnt_mountp);
+ (void) strncpy(p, globalpath + zp_len, MAXPATHLEN);
+ /*
+ * If both global zone and zone-relative
+ * mountpoint match, just use the same pathname
+ */
+ if (strncmp(mnt->mnt_mountp, p, mp_len) == 0) {
+ (void) strncpy(globalpath, p, global_len);
+ return (1);
+ } else {
+ (void) strncpy(p, globalpath, MAXPATHLEN);
+ (void) strncpy(globalpath, mnt->mnt_mountp,
+ global_len);
+ (void) strlcat(globalpath,
+ p + strlen(mountmatch->mnt_mountp),
+ global_len);
+ return (1);
+ }
+ }
+ return (0);
+ }
+}
+
+ /*
+ * Find the pathname for the entry in mlist that corresponds to the
+ * file named by path (i.e., that names a mount table entry for the
+ * file system in which path lies).
+ *
+ * Return 0 is there an error.
+ */
+ static int
+ getglobalpath(const char *path, zoneid_t zoneid, struct mntlist *mlist,
+ char *globalpath)
+ {
+ struct mntlist *mlp;
+ char lofspath[MAXPATHLEN];
+ char zonepath[MAXPATHLEN];
+ int longestmatch;
+ struct mnttab *mountmatch;
+
+ if (zoneid != GLOBAL_ZONEID) {
+ char *prefix;
+
+ if ((prefix = getzonerootbyid(zoneid)) == NULL) {
+ return (0);
+ }
+ (void) strncpy(zonepath, prefix, MAXPATHLEN);
+ (void) strlcpy(globalpath, prefix, MAXPATHLEN);
+ (void) strlcat(globalpath, path, MAXPATHLEN);
+ free(prefix);
+ } else {
+ (void) strlcpy(globalpath, path, MAXPATHLEN);
+ }
+
+ for (;;) {
+ longestmatch = 0;
+ for (mlp = mlist; mlp; mlp = mlp->mntl_next) {
+ struct mnttab *mnt = mlp->mntl_mnt;
+ int len;
+
+ if (subpath(globalpath, mnt->mnt_mountp) != 0)
+ continue;
+ len = strlen(mnt->mnt_mountp);
+ if (len > longestmatch) {
+ mountmatch = mnt;
+ longestmatch = len;
+ }
+ }
+ /*
+ * Handle interesting mounts.
+ */
+ if ((strcmp(mountmatch->mnt_fstype, MNTTYPE_NFS) == 0) ||
+ (strcmp(mountmatch->mnt_fstype, MNTTYPE_AUTOFS) == 0)) {
+ if (zoneid > GLOBAL_ZONEID) {
+ struct mnttab *m = NULL;
+
+ if (strcmp(mountmatch->mnt_fstype,
+ MNTTYPE_AUTOFS) == 0)
+ m = mountmatch;
+ if (getnfspathbyautofs(mlist, zoneid, m,
+ globalpath, zonepath, MAXPATHLEN) == 0) {
+ return (0);
+ }
+ }
+ break;
+ } else if (strcmp(mountmatch->mnt_fstype, MNTTYPE_LOFS) == 0) {
+ /*
+ * count up what's left
+ */
+ int remainder;
+
+ remainder = strlen(globalpath) - longestmatch;
+ if (remainder > 0) {
+ path = pathsuffix(globalpath,
+ mountmatch->mnt_mountp);
+ (void) strlcpy(lofspath, path, MAXPATHLEN);
+ }
+ (void) strlcpy(globalpath, mountmatch->mnt_special,
+ MAXPATHLEN);
+ if (remainder > 0) {
+ (void) strlcat(globalpath, lofspath,
+ MAXPATHLEN);
+ }
+ } else {
+ if ((zoneid > GLOBAL_ZONEID) &&
+ (strncmp(path, "/home/", strlen("/home/")) == 0)) {
+ char zonename[ZONENAME_MAX];
+
+ /*
+ * If this is a cross-zone reference to
+ * a home directory, it must be corrected.
+ * We should only get here if the zone's
+ * automounter hasn't yet mounted its
+ * autofs trigger on /home.
+ *
+ * Since it is likely to do so in the
+ * future, we will assume that the global
+ * zone already has an equivalent autofs
+ * mount established. By convention,
+ * this should be mounted at the
+ * /zone/<zonename>
+ */
+
+ if (zone_getattr(zoneid, ZONE_ATTR_NAME,
+ zonename, ZONENAME_MAX) == -1) {
+ return (0);
+ } else {
+ (void) snprintf(globalpath, MAXPATHLEN,
+ "/zone/%s%s", zonename, path);
+ }
+ }
+ break;
+ }
+ }
+ return (1);
+}
+
+
+/*
+ * This function is only useful for global zone callers
+ * It uses the global zone mnttab to translate local zone pathnames
+ * into global zone pathnames.
+ */
+char *
+getpathbylabel(const char *path_name, char *resolved_path, size_t bufsize,
+ const bslabel_t *sl) {
+ char ret_path[MAXPATHLEN]; /* pathname to return */
+ zoneid_t zoneid;
+ struct mntlist *mlist;
+
+ if (getzoneid() != GLOBAL_ZONEID) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ if (path_name[0] != '/') { /* need absolute pathname */
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ if (resolved_path == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ if ((zoneid = getzoneidbylabel(sl)) == -1)
+ return (NULL);
+
+ /*
+ * Construct the list of mounted file systems.
+ */
+
+ if ((mlist = tsol_mkmntlist()) == NULL) {
+ return (NULL);
+ }
+ if (getglobalpath(path_name, zoneid, mlist, ret_path) == 0) {
+ tsol_mlist_free(mlist);
+ return (NULL);
+ }
+ tsol_mlist_free(mlist);
+ if (strlen(ret_path) >= bufsize) {
+ errno = EFAULT;
+ return (NULL);
+ }
+ return (strcpy(resolved_path, ret_path));
+} /* end getpathbylabel() */
diff --git a/usr/src/lib/libtsol/common/getplabel.c b/usr/src/lib/libtsol/common/getplabel.c
new file mode 100644
index 0000000000..49aeeb66fe
--- /dev/null
+++ b/usr/src/lib/libtsol/common/getplabel.c
@@ -0,0 +1,59 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+#include <zone.h>
+#include <tsol/label.h>
+#include <sys/tsol/label_macro.h>
+#include <sys/types.h>
+#include <sys/zone.h>
+
+/*
+ * getplabel(2TSOL) - get process sensitivity label
+ */
+
+int
+getplabel(bslabel_t *label_p)
+{
+ zoneid_t zoneid;
+
+ zoneid = (int)getzoneid();
+ if (zoneid == GLOBAL_ZONEID) {
+ bslhigh(label_p);
+ } else {
+ bslabel_t *sl;
+
+ sl = getzonelabelbyid(zoneid);
+ if (sl == NULL) {
+ return (-1);
+ } else {
+ *label_p = *sl;
+ free(sl);
+ }
+ }
+ return (0);
+}
diff --git a/usr/src/lib/libtsol/common/hextob.c b/usr/src/lib/libtsol/common/hextob.c
new file mode 100644
index 0000000000..758969e688
--- /dev/null
+++ b/usr/src/lib/libtsol/common/hextob.c
@@ -0,0 +1,97 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * hextob.c - Hexadecimal string to binary label conversion.
+ *
+ * These routines convert canonical hexadecimal representations
+ * of internal labels into binary form.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <tsol/label.h>
+#include <sys/tsol/label_macro.h>
+
+/*
+ * htobsl - Convert a Hexadecimal label string to a Sensitivity Label.
+ *
+ * Entry s = Hexadecimal label string to be converted.
+ *
+ * Exit label = Sensitivity Label converted, if successful.
+ * Unchanged, if not successful.
+ *
+ * Returns 1, If successful.
+ * 0, Otherwise.
+ *
+ * Calls str_to_label, m_label_free.
+ */
+
+int
+htobsl(const char *s, m_label_t *label)
+{
+ m_label_t *l = NULL;
+
+ if (str_to_label(s, &l, MAC_LABEL, L_NO_CORRECTION, NULL) == -1) {
+ m_label_free(l);
+ return (0);
+ }
+ *label = *l;
+ m_label_free(l);
+ return (1);
+}
+
+/*
+ * htobclear - Convert a Hexadecimal label string to a Clearance.
+ *
+ * Entry s = Hexadecimal label string to be converted.
+ *
+ * Exit clearance = Clearnace converted, if successful.
+ * Unchanged, if not successful.
+ *
+ * Returns 1, If successful.
+ * 0, Otherwise.
+ *
+ * Calls str_to_label, m_label_free.
+ */
+
+int
+htobclear(const char *s, m_label_t *clearance)
+{
+ m_label_t *c = NULL;
+
+ if (str_to_label(s, &c, USER_CLEAR, L_NO_CORRECTION, NULL) == -1) {
+ m_label_free(c);
+ return (0);
+ }
+ *clearance = *c;
+ m_label_free(c);
+ return (1);
+}
diff --git a/usr/src/lib/libtsol/common/label.h b/usr/src/lib/libtsol/common/label.h
new file mode 100644
index 0000000000..6a5bfdc205
--- /dev/null
+++ b/usr/src/lib/libtsol/common/label.h
@@ -0,0 +1,242 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _TSOL_LABEL_H
+#define _TSOL_LABEL_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/tsol/label.h>
+#include <priv.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Procedural Interface Structure Definitions */
+
+struct label_info { /* structure returned by label_info */
+ short ilabel_len; /* max Information Label length */
+ short slabel_len; /* max Sensitivity Label length */
+ short clabel_len; /* max CMW Label length */
+ short clear_len; /* max Clearance Label length */
+ short vers_len; /* version string length */
+ short header_len; /* max len of banner page header */
+ short protect_as_len; /* max len of banner page protect as */
+ short caveats_len; /* max len of banner page caveats */
+ short channels_len; /* max len of banner page channels */
+};
+
+typedef struct label_set_identifier { /* valid label set identifier */
+ int type; /* type of the set */
+ char *name; /* name of the set if needed */
+} set_id;
+
+struct name_fields { /* names for label builder fields */
+ char *class_name; /* Classifications field name */
+ char *comps_name; /* Compartments field name */
+ char *marks_name; /* Markings field name */
+};
+
+/* Label Set Identifier Types */
+
+/*
+ * The accreditation ranges as specified in the label encodings file.
+ * The name parameter is ignored.
+ *
+ * System Accreditation Range is all valid labels plus Admin High and Low.
+ *
+ * User Accreditation Range is valid user labels as defined in the
+ * ACCREDITATION RANGE: section of the label encodings file.
+ */
+
+#define SYSTEM_ACCREDITATION_RANGE 1
+#define USER_ACCREDITATION_RANGE 2
+
+
+/* System Call Interface Definitions */
+
+extern int getlabel(const char *, m_label_t *);
+extern int fgetlabel(int, m_label_t *);
+
+extern int getplabel(m_label_t *);
+extern int setflabel(const char *, m_label_t *);
+extern char *getpathbylabel(const char *, char *, size_t,
+ const m_label_t *sl);
+extern m_label_t *getzonelabelbyid(zoneid_t);
+extern m_label_t *getzonelabelbyname(const char *);
+extern zoneid_t getzoneidbylabel(const m_label_t *);
+extern char *getzonenamebylabel(const m_label_t *);
+extern char *getzonerootbyid(zoneid_t);
+extern char *getzonerootbyname(const char *);
+extern char *getzonerootbylabel(const m_label_t *);
+extern m_label_t *getlabelbypath(const char *);
+
+
+/* Flag word values */
+
+#define ALL_ENTRIES 0x00000000
+#define ACCESS_RELATED 0x00000001
+#define ACCESS_MASK 0x0000FFFF
+#define ACCESS_SHIFT 0
+
+#define LONG_WORDS 0x00010000 /* use long names */
+#define SHORT_WORDS 0x00020000 /* use short names if present */
+#define LONG_CLASSIFICATION 0x00040000 /* use long classification */
+#define SHORT_CLASSIFICATION 0x00080000 /* use short classification */
+#define NO_CLASSIFICATION 0x00100000 /* don't translate the class */
+#define VIEW_INTERNAL 0x00200000 /* don't promote/demote */
+#define VIEW_EXTERNAL 0x00400000 /* promote/demote label */
+
+#define NEW_LABEL 0x00000001 /* create a full new label */
+#define NO_CORRECTION 0x00000002 /* don't correct label errors */
+ /* implies NEW_LABEL */
+
+#define CVT_DIM 0x01 /* display word dimmed */
+#define CVT_SET 0x02 /* display word currently set */
+
+/* Procedure Interface Definitions available to user */
+
+/* APIs shared with the kernel are in <sys/tsol/label.h */
+
+extern m_label_t *blabel_alloc(void);
+extern void blabel_free(m_label_t *);
+extern size_t blabel_size(void);
+extern char *bsltoh(const m_label_t *);
+extern char *bcleartoh(const m_label_t *);
+
+extern char *bsltoh_r(const m_label_t *, char *);
+extern char *bcleartoh_r(const m_label_t *, char *);
+extern char *h_alloc(uint8_t);
+extern void h_free(char *);
+
+extern int htobsl(const char *, m_label_t *);
+extern int htobclear(const char *, m_label_t *);
+
+extern m_range_t *getuserrange(const char *);
+extern m_range_t *getdevicerange(const char *);
+
+extern int set_effective_priv(priv_op_t, int, ...);
+extern int set_inheritable_priv(priv_op_t, int, ...);
+extern int set_permitted_priv(priv_op_t, int, ...);
+extern int is_system_labeled(void);
+
+/* Procedures needed for multi-level printing */
+
+extern int tsol_check_admin_auth(uid_t uid);
+
+/* APIs implemented via labeld */
+
+extern int blinset(const m_label_t *, const set_id *);
+extern int labelinfo(struct label_info *);
+extern ssize_t labelvers(char **, size_t);
+extern char *bltocolor(const m_label_t *);
+extern char *bltocolor_r(const m_label_t *, size_t, char *);
+
+extern ssize_t bsltos(const m_label_t *, char **, size_t, int);
+extern ssize_t bcleartos(const m_label_t *, char **, size_t, int);
+
+
+extern char *sbsltos(const m_label_t *, size_t);
+extern char *sbcleartos(const m_label_t *, size_t);
+
+
+extern int stobsl(const char *, m_label_t *, int, int *);
+extern int stobclear(const char *, m_label_t *, int, int *);
+extern int bslvalid(const m_label_t *);
+extern int bclearvalid(const m_label_t *);
+
+/* Manifest human readable label names */
+
+#define ADMIN_LOW "ADMIN_LOW"
+#define ADMIN_HIGH "ADMIN_HIGH"
+
+/* DIA label conversion and parsing */
+
+/* Conversion types */
+
+typedef enum _m_label_str {
+ M_LABEL = 1, /* process or user clearance */
+ M_INTERNAL = 2, /* internal form for use in public databases */
+ M_COLOR = 3, /* process label color */
+ PRINTER_TOP_BOTTOM = 4, /* DIA banner page top/bottom */
+ PRINTER_LABEL = 5, /* DIA banner page label */
+ PRINTER_CAVEATS = 6, /* DIA banner page caveats */
+ PRINTER_CHANNELS = 7 /* DIA banner page handling channels */
+} m_label_str_t;
+
+/* Flags for conversion, not all flags apply to all types */
+#define DEF_NAMES 0x1
+#define SHORT_NAMES 0x3 /* short names are prefered where defined */
+#define LONG_NAMES 0x4 /* long names are prefered where defined */
+
+extern int label_to_str(const m_label_t *, char **, const m_label_str_t,
+ uint_t);
+
+/* Parsing types */
+typedef enum _m_label_type {
+ MAC_LABEL = 1, /* process or object label */
+ USER_CLEAR = 2 /* user's clearance (LUB) */
+} m_label_type_t;
+
+/* Flags for parsing */
+
+#define L_DEFAULT 0x0
+#define L_MODIFY_EXISTING 0x1 /* start parsing with existing label */
+#define L_NO_CORRECTION 0x2 /* must be correct by l_e rules */
+
+/* EINVAL sub codes */
+
+#define M_BAD_STRING -3 /* DIA L_BAD_LABEL */
+ /* bad requested label type, bad previous label type */
+#define M_BAD_LABEL -2 /* DIA L_BAD_CLASSIFICATION, */
+
+extern int str_to_label(const char *, m_label_t **, const m_label_type_t,
+ uint_t, int *);
+
+extern m_label_t *m_label_alloc(const m_label_type_t);
+
+extern int m_label_dup(m_label_t **, const m_label_t *);
+
+extern void m_label_free(m_label_t *);
+
+/* Contract Private interfaces with the label builder GUIs */
+
+extern int bslcvtfull(const m_label_t *, const m_range_t *, int,
+ char **, char **[], char **[], char *[], int *, int *);
+extern int bslcvt(const m_label_t *, int, char **, char *[]);
+extern int bclearcvtfull(const m_label_t *, const m_range_t *, int,
+ char **, char **[], char **[], char *[], int *, int *);
+extern int bclearcvt(const m_label_t *, int, char **, char *[]);
+
+extern int labelfields(struct name_fields *);
+extern int userdefs(m_label_t *, m_label_t *);
+extern int zonecopy(m_label_t *, char *, char *, char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_TSOL_LABEL_H */
diff --git a/usr/src/lib/libtsol/common/labeld.h b/usr/src/lib/libtsol/common/labeld.h
new file mode 100644
index 0000000000..aa95982998
--- /dev/null
+++ b/usr/src/lib/libtsol/common/labeld.h
@@ -0,0 +1,473 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LABELD_H
+#define _LABELD_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <tsol/label.h>
+#include <sys/tsol/label_macro.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Definitions for the call parameters for the door-based label
+ * translation service.
+ */
+
+#define BUFSIZE 4096
+
+#define DOOR_PATH "/var/tsol/doors/"
+#define DOOR_NAME "labeld"
+#define COOKIE (void *)0x6c616264 /* "labd" */
+
+/* Op codes */
+
+/* Labeld Commands */
+
+#define LABELDNULL 1
+
+/* Miscellaneous */
+
+#define BLINSET 10
+#define BSLVALID 11
+#define BILVALID 12
+#define BCLEARVALID 13
+#define LABELINFO 14
+#define LABELVERS 15
+#define BLTOCOLOR 16
+
+/* Binary to String Label Translation */
+
+#define BSLTOS 23
+#define BCLEARTOS 25
+
+/* String to Binary Label Translation */
+
+#define STOBSL 31
+#define STOBCLEAR 33
+
+/*
+ * Dimming List Routines
+ * Contract private for label builders
+ */
+
+#define BSLCVT 40
+#define BCLEARCVT 42
+#define LABELFIELDS 43
+#define UDEFS 44
+
+#define GETFLABEL 45
+#define SETFLABEL 46
+#define ZCOPY 47
+
+/* NEW LABELS */
+/* DIA printer banner labels */
+
+#define PR_CAVEATS 101
+#define PR_CHANNELS 102
+#define PR_LABEL 103
+#define PR_TOP 104
+
+/* DIA label to string */
+
+#define LTOS 105
+
+/* DIA string to label */
+
+#define STOL 106
+
+/* Structures */
+
+typedef uint_t bufp_t; /* offset into buf[] in/out string buffer */
+
+/* Null call */
+
+typedef struct {
+ int null;
+} null_call_t;
+
+typedef struct {
+ int null;
+} null_ret_t;
+
+/* Miscellaneous interfaces */
+
+typedef struct {
+ bslabel_t label;
+ int type;
+} inset_call_t;
+
+typedef struct {
+ int inset;
+} inset_ret_t;
+
+typedef struct {
+ bslabel_t label;
+} slvalid_call_t;
+
+typedef struct {
+ int valid;
+} slvalid_ret_t;
+
+typedef struct {
+ bclear_t clear;
+} clrvalid_call_t;
+
+typedef struct {
+ int valid;
+} clrvalid_ret_t;
+
+typedef struct {
+ int null;
+} info_call_t;
+
+typedef struct {
+ struct label_info info;
+} info_ret_t;
+
+typedef struct {
+ int null;
+} vers_call_t;
+
+typedef struct {
+ char vers[BUFSIZE];
+} vers_ret_t;
+
+typedef struct {
+ blevel_t label;
+} color_call_t;
+
+typedef struct {
+ char color[BUFSIZE];
+} color_ret_t;
+
+/* Binary Label to String interfaces */
+
+typedef struct {
+ bslabel_t label;
+ uint_t flags;
+} bsltos_call_t;
+
+typedef struct {
+ char slabel[BUFSIZE];
+} bsltos_ret_t;
+
+typedef struct {
+ bclear_t clear;
+ uint_t flags;
+} bcleartos_call_t;
+
+typedef struct {
+ char cslabel[BUFSIZE];
+} bcleartos_ret_t;
+
+/* String to Binary Label interfaces */
+
+typedef struct {
+ bslabel_t label;
+ uint_t flags;
+ char string[BUFSIZE];
+} stobsl_call_t;
+
+typedef struct {
+ bslabel_t label;
+} stobsl_ret_t;
+
+typedef struct {
+ bclear_t clear;
+ uint_t flags;
+ char string[BUFSIZE];
+} stobclear_call_t;
+
+typedef struct {
+ bclear_t clear;
+} stobclear_ret_t;
+
+/*
+ * The following Dimming List and Miscellaneous interfaces
+ * implement contract private interfaces for the label builder
+ * interfaces.
+ */
+
+/* Dimming List interfaces */
+
+typedef struct {
+ bslabel_t label;
+ brange_t bounds;
+ uint_t flags;
+} bslcvt_call_t;
+
+typedef struct {
+ bufp_t string;
+ bufp_t dim;
+ bufp_t lwords;
+ bufp_t swords;
+ size_t d_len;
+ size_t l_len;
+ size_t s_len;
+ int first_comp;
+ int first_mark;
+ char buf[BUFSIZE];
+} cvt_ret_t;
+
+typedef cvt_ret_t bslcvt_ret_t;
+
+typedef struct {
+ bclear_t clear;
+ brange_t bounds;
+ uint_t flags;
+} bclearcvt_call_t;
+
+typedef cvt_ret_t bclearcvt_ret_t;
+
+/* Miscellaneous interfaces */
+
+typedef struct {
+ int null;
+} fields_call_t;
+
+typedef struct {
+ bufp_t classi;
+ bufp_t compsi;
+ bufp_t marksi;
+ char buf[BUFSIZE];
+} fields_ret_t;
+
+typedef struct {
+ int null;
+} udefs_call_t;
+
+typedef struct {
+ bslabel_t sl;
+ bclear_t clear;
+} udefs_ret_t;
+
+typedef struct {
+ bslabel_t sl;
+ char pathname[BUFSIZE];
+} setfbcl_call_t;
+
+typedef struct {
+ int status;
+} setfbcl_ret_t;
+
+typedef struct {
+ bslabel_t src_win_sl;
+ int transfer_mode;
+ bufp_t remote_dir;
+ bufp_t filename;
+ bufp_t local_dir;
+ bufp_t display;
+ char buf[BUFSIZE];
+} zcopy_call_t;
+
+typedef struct {
+ int status;
+} zcopy_ret_t;
+
+typedef struct {
+ m_label_t label;
+ uint_t flags;
+} pr_call_t;
+
+typedef struct {
+ char buf[BUFSIZE];
+} pr_ret_t;
+
+typedef struct {
+ m_label_t label;
+ uint_t flags;
+} ls_call_t;
+
+typedef struct {
+ char buf[BUFSIZE];
+} ls_ret_t;
+
+typedef struct {
+ m_label_t label;
+ uint_t flags;
+ char string[BUFSIZE];
+} sl_call_t;
+
+typedef struct {
+ m_label_t label;
+} sl_ret_t;
+
+/* Labeld operation call structure */
+
+typedef struct {
+ uint_t op;
+ union {
+ null_call_t null_arg;
+
+ inset_call_t inset_arg;
+ slvalid_call_t slvalid_arg;
+ clrvalid_call_t clrvalid_arg;
+ info_call_t info_arg;
+ vers_call_t vers_arg;
+ color_call_t color_arg;
+
+ bsltos_call_t bsltos_arg;
+ bcleartos_call_t bcleartos_arg;
+
+ stobsl_call_t stobsl_arg;
+ stobclear_call_t stobclear_arg;
+
+ bslcvt_call_t bslcvt_arg;
+ bclearcvt_call_t bclearcvt_arg;
+ fields_call_t fields_arg;
+ udefs_call_t udefs_arg;
+ setfbcl_call_t setfbcl_arg;
+ zcopy_call_t zcopy_arg;
+ pr_call_t pr_arg;
+ ls_call_t ls_arg;
+ sl_call_t sl_arg;
+ } cargs;
+} labeld_call_t;
+
+/* Labeld operation return structure */
+
+typedef struct {
+ int ret; /* labeld return codes */
+ int err; /* function error codes */
+ union {
+ null_ret_t null_ret;
+
+ inset_ret_t inset_ret;
+ slvalid_ret_t slvalid_ret;
+ clrvalid_ret_t clrvalid_ret;
+ info_ret_t info_ret;
+ vers_ret_t vers_ret;
+ color_ret_t color_ret;
+
+ bsltos_ret_t bsltos_ret;
+ bcleartos_ret_t bcleartos_ret;
+
+ stobsl_ret_t stobsl_ret;
+ stobclear_ret_t stobclear_ret;
+
+ bslcvt_ret_t bslcvt_ret;
+ bclearcvt_ret_t bclearcvt_ret;
+ fields_ret_t fields_ret;
+ udefs_ret_t udefs_ret;
+ setfbcl_ret_t setfbcl_ret;
+ zcopy_ret_t zcopy_ret;
+ pr_ret_t pr_ret;
+ ls_ret_t ls_ret;
+ sl_ret_t sl_ret;
+ } rvals;
+} labeld_ret_t;
+
+/* Labeld call/return structure */
+
+typedef struct {
+ union {
+ labeld_call_t acall;
+ labeld_ret_t aret;
+ } param;
+} labeld_data_t;
+
+#define callop param.acall.op
+#define retret param.aret.ret
+#define reterr param.aret.err
+
+#define CALL_SIZE(type, buf) (size_t)(sizeof (type) + sizeof (int) + (buf))
+#define RET_SIZE(type, buf) (size_t)(sizeof (type) + 2*sizeof (int) + (buf))
+
+/* Labeld common client call function */
+
+int
+__call_labeld(labeld_data_t **dptr, size_t *ndata, size_t *adata);
+
+/* Return Codes */
+
+#define SUCCESS 1 /* Call OK */
+#define NOTFOUND -1 /* Function not found */
+#define SERVERFAULT -2 /* Internal labeld error */
+#define NOSERVER -3 /* No server thread available, try later */
+
+/* Flag Translation Values */
+
+#define L_NEW_LABEL 0x10000000
+
+/* GFI FLAGS */
+
+#define GFI_FLAG_MASK 0x0000FFFF
+#define GFI_ACCESS_RELATED 0x00000001
+
+/* binary to ASCII */
+
+#define LABELS_NO_CLASS 0x00010000
+#define LABELS_SHORT_CLASS 0x00020000
+#define LABELS_SHORT_WORDS 0x00040000
+
+/* Label view */
+
+#define LABELS_VIEW_INTERNAL 0x00100000
+#define LABELS_VIEW_EXTERNAL 0x00200000
+
+/* Dimming list (convert -- b*cvt* ) */
+
+#define LABELS_FULL_CONVERT 0x00010000
+
+/* ASCII to binary */
+
+#define LABELS_NEW_LABEL 0x00010000
+#define LABELS_FULL_PARSE 0x00020000
+#define LABELS_ONLY_INFO_LABEL 0x00040000
+
+#define MOVE_FILE 0
+#define COPY_FILE 1
+#define LINK_FILE 2
+
+#define PIPEMSG_FILEOP_ERROR 1
+#define PIPEMSG_EXIST_ERROR 2
+#define PIPEMSG_DONE 7
+#define PIPEMSG_PATH_ERROR 20
+#define PIPEMSG_ZONE_ERROR 21
+#define PIPEMSG_LABEL_ERROR 22
+#define PIPEMSG_READ_ERROR 23
+#define PIPEMSG_READONLY_ERROR 24
+#define PIPEMSG_WRITE_ERROR 25
+#define PIPEMSG_CREATE_ERROR 26
+#define PIPEMSG_DELETE_ERROR 27
+#define PIPEMSG_CANCEL 101
+#define PIPEMSG_PROCEED 102
+#define PIPEMSG_MERGE 103
+#define PIPEMSG_REPLACE_BUFFER 104
+#define PIPEMSG_RENAME_BUFFER 105
+#define PIPEMSG_MULTI_PROCEED 106
+#define PIPEMSG_RENAME_FILE 107
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LABELD_H */
diff --git a/usr/src/lib/libtsol/common/llib-ltsol b/usr/src/lib/libtsol/common/llib-ltsol
new file mode 100644
index 0000000000..1d4acc5a3a
--- /dev/null
+++ b/usr/src/lib/libtsol/common/llib-ltsol
@@ -0,0 +1,35 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/* LINTLIBRARY */
+/* PROTOLIB1 */
+
+#include <tsol/label.h>
+#include <sys/tsol/label.h>
+#include <sys/tsol/priv.h>
+#include <sys/tsol/label_macro.h>
diff --git a/usr/src/lib/libtsol/common/ltos.c b/usr/src/lib/libtsol/common/ltos.c
new file mode 100644
index 0000000000..16feabbf41
--- /dev/null
+++ b/usr/src/lib/libtsol/common/ltos.c
@@ -0,0 +1,283 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/tsol/label_macro.h>
+
+#include <tsol/label.h>
+
+#include "clnt.h"
+#include "labeld.h"
+
+static _mac_label_impl_t low;
+static _mac_label_impl_t high;
+static int inited = 0;
+
+/* 0x + Classification + '-' + ll + '-' + Compartments + end of string */
+#define _HEX_SIZE 2+(sizeof (Classification_t)*2)+4+\
+ (sizeof (Compartments_t)*2)+1
+
+/* 0x + Classification + '-' + ll + '-' + end of string */
+#define _MIN_HEX (2 + (sizeof (Classification_t)*2) + 4 + 1)
+
+static char digits[] = "0123456789abcdef";
+
+#define HEX(h, i, l, s) \
+ for (; i < s; /* */) {\
+ h[i++] = digits[(unsigned int)(*l >> 4)];\
+ h[i++] = digits[(unsigned int)(*l++&0xF)]; }
+
+static int
+__hex(char **s, const m_label_t *l)
+{
+ char *hex;
+ int i = 0;
+ uchar_t *hl;
+ int hex_len;
+ uchar_t *len;
+
+ hl = (uchar_t *)&(((_mac_label_impl_t *)l)->_c_len);
+ len = hl;
+
+ if (*len == 0) {
+ /* old binary label */
+ hex_len = _HEX_SIZE;
+ } else {
+ hex_len = _MIN_HEX + (*len * sizeof (uint32_t) * 2);
+ }
+
+ if ((hex = malloc(hex_len)) == NULL) {
+ return (-1);
+ }
+
+ /* header */
+
+ hex[i++] = '0';
+ hex[i++] = 'x';
+
+ /* classification */
+
+ hl++; /* start at classification */
+ HEX(hex, i, hl, 6);
+
+ /* Add compartments length */
+ hex[i++] = '-';
+ HEX(hex, i, len, 9);
+ hex[i++] = '-';
+
+ /* compartments */
+ HEX(hex, i, hl, hex_len-1);
+ hex[i] = '\0';
+
+ /* truncate trailing zeros */
+
+ while (hex[i-1] == '0' && hex[i-2] == '0') {
+ i -= 2;
+ }
+ hex[i] = '\0';
+
+ if ((*s = strdup(hex)) == NULL) {
+ free(hex);
+ return (-1);
+ }
+
+ free(hex);
+ return (0);
+
+}
+
+/*
+ * label_to_str -- convert a label to the requested type of string.
+ *
+ * Entry l = label to convert;
+ * t = type of conversion;
+ * f = flags for conversion type;
+ *
+ * Exit *s = allocated converted string;
+ * Caller must call free() to free.
+ *
+ * Returns 0, success.
+ * -1, error, errno set; *s = NULL.
+ *
+ * Calls labeld
+ */
+
+int
+label_to_str(const m_label_t *l, char **s, const m_label_str_t t, uint_t f)
+{
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize;
+ int err;
+
+ if (inited == 0) {
+ inited = 1;
+ _BSLLOW(&low);
+ _BSLHIGH(&high);
+ }
+
+#define lscall callp->param.acall.cargs.ls_arg
+#define lsret callp->param.aret.rvals.ls_ret
+ switch (t) {
+ case M_LABEL:
+ call.callop = LTOS;
+ lscall.label = *l;
+ lscall.flags = f;
+ datasize = CALL_SIZE(ls_call_t, 0);
+ if ((err = __call_labeld(&callp, &bufsize, &datasize)) ==
+ SUCCESS) {
+ if (callp->reterr != 0) {
+ errno = EINVAL;
+ *s = NULL;
+ return (-1);
+ }
+ if ((*s = strdup(lsret.buf)) == NULL) {
+ return (-1);
+ }
+ if (callp != &call) {
+ /* release returned buffer */
+ (void) munmap((void *)callp, bufsize);
+ }
+ return (0);
+ }
+ switch (err) {
+ case NOSERVER:
+ /* server not present */
+ /* special case admin_low and admin_high */
+
+ if (_MEQUAL(&low, (_mac_label_impl_t *)l)) {
+ if ((*s = strdup(ADMIN_LOW)) == NULL) {
+ return (-1);
+ }
+ return (0);
+ } else if (_MEQUAL(&high, (_mac_label_impl_t *)l)) {
+ if ((*s = strdup(ADMIN_HIGH)) == NULL) {
+ return (-1);
+ }
+ return (0);
+ }
+ errno = ENOTSUP;
+ break;
+ default:
+ errno = EINVAL;
+ break;
+ }
+ *s = NULL;
+ return (-1);
+#undef lscall
+#undef lsret
+
+ case M_INTERNAL: {
+ if (!(_MTYPE(l, SUN_MAC_ID) ||
+ _MTYPE(l, SUN_UCLR_ID))) {
+ errno = EINVAL;
+ return (-1);
+ }
+ if (_MEQUAL(&low, (_mac_label_impl_t *)l)) {
+ if ((*s = strdup(ADMIN_LOW)) == NULL) {
+ return (-1);
+ }
+ return (0);
+ }
+ if (_MEQUAL(&high, (_mac_label_impl_t *)l)) {
+ if ((*s = strdup(ADMIN_HIGH)) == NULL) {
+ return (-1);
+ }
+ return (0);
+ }
+
+ return (__hex(s, l));
+ }
+
+#define ccall callp->param.acall.cargs.color_arg
+#define cret callp->param.aret.rvals.color_ret
+ case M_COLOR:
+ datasize = CALL_SIZE(color_call_t, 0);
+ call.callop = BLTOCOLOR;
+ ccall.label = *l;
+
+ if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
+ errno = ENOTSUP;
+ *s = NULL;
+ return (-1);
+ } if (callp->reterr != 0) {
+ errno = EINVAL;
+ *s = NULL;
+ return (-1);
+ }
+ if ((*s = strdup(cret.color)) == NULL) {
+ return (-1);
+ }
+ return (0);
+#undef ccall
+#undef cret
+
+#define prcall callp->param.acall.cargs.pr_arg
+#define prret callp->param.aret.rvals.pr_ret
+ case PRINTER_TOP_BOTTOM:
+ call.callop = PR_TOP;
+ break;
+ case PRINTER_LABEL:
+ call.callop = PR_LABEL;
+ break;
+ case PRINTER_CAVEATS:
+ call.callop = PR_CAVEATS;
+ break;
+ case PRINTER_CHANNELS:
+ call.callop = PR_CHANNELS;
+ break;
+ default:
+ errno = EINVAL;
+ *s = NULL;
+ return (-1);
+ }
+ /* do the common printer calls */
+ datasize = CALL_SIZE(pr_call_t, 0);
+ prcall.label = *l;
+ prcall.flags = f;
+ if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
+ errno = ENOTSUP;
+ *s = NULL;
+ return (-1);
+ } if (callp->reterr != 0) {
+ errno = EINVAL;
+ *s = NULL;
+ return (-1);
+ }
+ if ((*s = strdup(prret.buf)) == NULL) {
+ return (-1);
+ }
+ return (0);
+#undef prcall
+#undef prret
+}
diff --git a/usr/src/lib/libtsol/common/misc.c b/usr/src/lib/libtsol/common/misc.c
new file mode 100644
index 0000000000..14113f22be
--- /dev/null
+++ b/usr/src/lib/libtsol/common/misc.c
@@ -0,0 +1,476 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+/*
+ * Miscellaneous user interfaces to trusted label functions.
+ *
+ */
+
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <sys/mman.h>
+
+#include <tsol/label.h>
+
+#include "labeld.h"
+#include "clnt.h"
+#include <sys/tsol/label_macro.h>
+#include <secdb.h>
+#include <user_attr.h>
+
+static bslabel_t slow, shigh; /* static Admin Low and High SLs */
+static bclear_t clow, chigh; /* static Admin Low and High CLRs */
+
+static char color[MAXCOLOR];
+
+
+#define incall callp->param.acall.cargs.inset_arg
+#define inret callp->param.aret.rvals.inset_ret
+/*
+ * blinset - Check in a label set.
+ *
+ * Entry label = Sensitivity Label to check.
+ * id = Label set identifier of set to check.
+ *
+ * Exit None.
+ *
+ * Returns -1, If label set unavailable, or server failure.
+ * 0, If label not in label set.
+ * 1, If label is in the label set.
+ *
+ * Calls __call_labeld(BLINSET), BLTYPE, BSLLOW, BSLHIGH.
+ *
+ * Uses slow, shigh.
+ */
+
+int
+blinset(const bslabel_t *label, const set_id *id)
+{
+ if (id->type == SYSTEM_ACCREDITATION_RANGE) {
+ if (!BLTYPE(&slow, SUN_SL_ID)) {
+ /* initialize static labels. */
+
+ BSLLOW(&slow);
+ BSLHIGH(&shigh);
+ }
+
+ if (BLTYPE(label, SUN_SL_ID) &&
+ (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh)))
+
+ return (1);
+ }
+ if (id->type == USER_ACCREDITATION_RANGE ||
+ id->type == SYSTEM_ACCREDITATION_RANGE) {
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize = CALL_SIZE(inset_call_t, 0);
+
+ call.callop = BLINSET;
+ incall.label = *label;
+ incall.type = id->type;
+
+ if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
+ /* process error */
+
+ return (-1);
+ }
+ return (inret.inset);
+ } else {
+ /*
+ * Only System and User Accreditation Ranges presently
+ * implemented.
+ */
+ return (-1);
+ }
+}
+#undef incall
+#undef inret
+
+#define slvcall callp->param.acall.cargs.slvalid_arg
+#define slvret callp->param.aret.rvals.slvalid_ret
+/*
+ * bslvalid - Check Sensitivity Label for validity.
+ *
+ * Entry label = Sensitivity Label to check.
+ *
+ * Exit None.
+ *
+ * Returns -1, If unable to access label encodings file, or server failure.
+ * 0, If label not valid.
+ * 1, If label is valid.
+ *
+ * Calls __call_labeld(BSLVALID), BLTYPE, BSLLOW, BSLHIGH.
+ *
+ * Uses slow, shigh.
+ *
+ */
+
+int
+bslvalid(const bslabel_t *label)
+{
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize = CALL_SIZE(slvalid_call_t, 0);
+
+ if (!BLTYPE(&slow, SUN_SL_ID)) {
+ /* initialize static labels. */
+
+ BSLLOW(&slow);
+ BSLHIGH(&shigh);
+ }
+
+ if (BLTYPE(label, SUN_SL_ID) &&
+ (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh))) {
+
+ return (1);
+ }
+
+ call.callop = BSLVALID;
+ slvcall.label = *label;
+
+ if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
+ /* process error */
+
+ return (-1);
+ }
+ return (slvret.valid);
+}
+#undef slvcall
+#undef slvret
+
+#define clrvcall callp->param.acall.cargs.clrvalid_arg
+#define clrvret callp->param.aret.rvals.clrvalid_ret
+/*
+ * bclearvalid - Check Clearance for validity.
+ *
+ * Entry clearance = Clearance to check.
+ *
+ * Exit None.
+ *
+ * Returns -1, If unable to access label encodings file, or server failure.
+ * 0, If label not valid.
+ * 1, If label is valid.
+ *
+ * Calls __call_labeld(BCLEARVALID), BLTYPE, BCLEARLOW, BCLEARHIGH.
+ *
+ * Uses clow, chigh.
+ *
+ */
+
+int
+bclearvalid(const bclear_t *clearance)
+{
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize = CALL_SIZE(clrvalid_call_t, 0);
+
+ if (!BLTYPE(&clow, SUN_CLR_ID)) {
+ /* initialize static labels. */
+
+ BCLEARLOW(&clow);
+ BCLEARHIGH(&chigh);
+ }
+
+ if (BLTYPE(clearance, SUN_CLR_ID) &&
+ (BLEQUAL(clearance, &clow) || BLEQUAL(clearance, &chigh))) {
+
+ return (1);
+ }
+
+ call.callop = BCLEARVALID;
+ clrvcall.clear = *clearance;
+
+ if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
+ /* process error */
+
+ return (-1);
+ }
+ return (clrvret.valid);
+}
+#undef clrvcall
+#undef clrvret
+
+#define inforet callp->param.aret.rvals.info_ret
+/*
+ * labelinfo - Get information about the label encodings file.
+ *
+ * Entry info = Address of label_info structure to update.
+ *
+ * Exit info = Updated.
+ *
+ * Returns -1, If unable to access label encodings file, or server failure.
+ * 1, If successful.
+ *
+ * Calls __call_labeld(LABELINFO).
+ */
+
+int
+labelinfo(struct label_info *info)
+{
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize = CALL_SIZE(info_call_t, 0);
+ int rval;
+
+ call.callop = LABELINFO;
+
+ if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) {
+ /* process error */
+
+ return (-1);
+ }
+ *info = inforet.info;
+ return (rval);
+}
+#undef inforet
+
+#define lvret callp->param.aret.rvals.vers_ret
+/*
+ * labelvers - Get version string of the label encodings file.
+ *
+ * Entry version = Address of string pointer to return.
+ * len = Length of string if pre-allocated.
+ *
+ * Exit version = Updated.
+ *
+ * Returns -1, If unable to access label encodings file, or server failure.
+ * 0, If unable to allocate version string,
+ * or pre-allocated version string to short
+ * (and **version = '\0').
+ * length (including null) of version string, If successful.
+ *
+ * Calls __call_labeld(LABELVERS)
+ * malloc, strlen.
+ */
+
+ssize_t
+labelvers(char **version, size_t len)
+{
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize = CALL_SIZE(vers_call_t, 0);
+ size_t ver_len;
+
+ call.callop = LABELVERS;
+
+ if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
+
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (-1);
+ }
+
+ /* unpack length */
+
+ ver_len = strlen(lvret.vers) + 1;
+ if (*version == NULL) {
+ if ((*version = malloc(ver_len)) == NULL) {
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (0);
+ }
+ } else if (ver_len > len) {
+ **version = '\0';
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (0);
+ }
+ (void) strcpy(*version, lvret.vers);
+
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (ver_len);
+} /* labelvers */
+#undef lvret
+
+#define ccall callp->param.acall.cargs.color_arg
+#define cret callp->param.aret.rvals.color_ret
+/*
+ * bltocolor - get ASCII color name of label.
+ *
+ * Entry label = Sensitivity Level of color to get.
+ * size = Size of the color_name array.
+ * color_name = Storage for ASCII color name string to be returned.
+ *
+ * Exit None.
+ *
+ * Returns NULL, If error (label encodings file not accessible,
+ * invalid label, no color for this label).
+ * Address of color_name parameter containing ASCII color name
+ * defined for the label.
+ *
+ * Calls __call_labeld(BLTOCOLOR), strlen.
+ */
+
+char *
+bltocolor_r(const blevel_t *label, size_t size, char *color_name)
+{
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize = CALL_SIZE(color_call_t, 0);
+ char *colorp;
+
+ call.callop = BLTOCOLOR;
+ ccall.label = *label;
+
+ if ((__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) ||
+ (callp->reterr != 0) ||
+ (strlen(cret.color) >= size)) {
+
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (NULL);
+ }
+
+ colorp = strcpy(color_name, cret.color);
+
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (colorp);
+} /* bltocolor_r */
+#undef ccall
+#undef cret
+
+/*
+ * bltocolor - get ASCII color name of label.
+ *
+ * Entry label = Sensitivity Level of color to get.
+ *
+ * Exit None.
+ *
+ * Returns NULL, If error (label encodings file not accessible,
+ * invalid label, no color for this label).
+ * Address of statically allocated string containing ASCII
+ * color name defined for the classification contained
+ * in label.
+ *
+ * Uses color.
+ *
+ * Calls bltocolor_r.
+ */
+
+char *
+bltocolor(const blevel_t *label)
+{
+ return (bltocolor_r(label, sizeof (color), color));
+} /* bltocolor */
+
+blevel_t *
+blabel_alloc(void)
+{
+ return (m_label_alloc(MAC_LABEL));
+}
+
+void
+blabel_free(blevel_t *label_p)
+{
+ free(label_p);
+}
+
+size_t
+blabel_size(void)
+{
+ return (sizeof (blevel_t));
+}
+
+/*
+ * getuserrange - get label range for user
+ *
+ * Entry username of user
+ *
+ * Exit None.
+ *
+ * Returns NULL, If memory allocation failure or userdefs failure.
+ * otherwise returns the allocates m_range_t with the
+ * user's min and max labels set.
+ */
+
+m_range_t *
+getuserrange(const char *username)
+{
+ char *kv_str = NULL;
+ userattr_t *userp = NULL;
+ m_range_t *range;
+ int err;
+
+ /*
+ * Get some memory
+ */
+
+ if ((range = malloc(sizeof (m_range_t))) == NULL) {
+ return (NULL);
+ }
+ if ((range->lower_bound = m_label_alloc(MAC_LABEL)) == NULL) {
+ free(range);
+ return (NULL);
+ }
+ if ((range->upper_bound = m_label_alloc(USER_CLEAR)) == NULL) {
+ m_label_free(range->lower_bound);
+ free(range);
+ return (NULL);
+ }
+ /*
+ * Since user_attr entries are optional, start with
+ * the system default values
+ */
+ if ((userdefs(range->lower_bound, range->upper_bound)) == -1) {
+ m_label_free(range->lower_bound);
+ m_label_free(range->upper_bound);
+ free(range);
+ return (NULL);
+ }
+ /*
+ * If the user has an explicit min_label or clearance,
+ * then use it instead.
+ */
+ if ((userp = getusernam(username)) == NULL) {
+ return (range);
+ }
+ if ((kv_str = kva_match(userp->attr, USERATTR_MINLABEL)) != NULL)
+ (void) stobsl(kv_str, range->lower_bound, NO_CORRECTION, &err);
+ if ((kv_str = kva_match(userp->attr, USERATTR_CLEARANCE)) != NULL)
+ (void) stobclear(kv_str, range->upper_bound, NO_CORRECTION,
+ &err);
+ free_userattr(userp);
+ return (range);
+}
diff --git a/usr/src/lib/libtsol/common/private.c b/usr/src/lib/libtsol/common/private.c
new file mode 100644
index 0000000000..3052624f1c
--- /dev/null
+++ b/usr/src/lib/libtsol/common/private.c
@@ -0,0 +1,660 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Label library contract private interfaces.
+ *
+ * Binary labels to String labels with dimming word lists.
+ * Dimming word list titles.
+ * Default user labels.
+ */
+
+#include <locale.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+
+#include <sys/mman.h>
+
+#include <tsol/label.h>
+
+#include "clnt.h"
+#include "labeld.h"
+
+/*
+ * cvt memory:
+ *
+ * cvt: char *long_words[display_size]; Pointers to long words
+ * char *short_words[display_size]; Pointers to short words
+ * dim: char display[display_size]; Dim | Set
+ *
+ * strings associated with long and short words.
+ *
+ */
+
+/*
+ * Sensitivity Label words.
+ */
+
+static char *slcvt = NULL;
+static int slcvtsize = 0;
+static char *sldim;
+
+static char *slstring = NULL;
+static int slstringsize = 0;
+static brange_t sbounds;
+
+/*
+ * Clearance words.
+ */
+
+static char *clrcvt = NULL;
+static int clrcvtsize = 0;
+static char *clrdim;
+
+static char *clrstring = NULL;
+static int clrstringsize = 0;
+static brange_t cbounds;
+
+static
+int
+alloc_words(char **words, const size_t size)
+{
+ if (*words == NULL) {
+ if ((*words = malloc(size)) == NULL)
+ return (0);
+ } else {
+ if ((*words = realloc(*words, size)) == NULL) {
+ return (0);
+ }
+ }
+ return (1);
+}
+
+/*
+ * build_strings - Build the static strings and dimming list for a
+ * converted label.
+ *
+ * Entry new_string = Newly converted string.
+ * new_words_size = Size of words associated with newly converted
+ * label.
+ * number_of_words = Number of words associated with newly
+ * converted label.
+ * full = 1, if static words lists to be updated.
+ * 0, if only string and dimming list to be updated.
+ *
+ * Exit static_string_size = Updated if needed.
+ * static_string = Updated to new label string.
+ * static_words_size = Updated if needed.
+ * static_words = Updated to new words list, if needed.
+ * static_dimming = Updated to new dimming state.
+ * long_words = Updated to new long words pointers, if needed.
+ * short_words = Updated to new short words pointers, if needed.
+ *
+ *
+ * Returns 0, If unable to allocate memory.
+ * 1, If successful.
+ *
+ * Calls alloc_string, alloc_words, memcpy, strcpy, strlen.
+ */
+
+static
+int
+build_strings(int *static_string_size, char **static_string, char *new_string,
+ int *static_words_size, int new_words_size, char **static_words,
+ char **static_dimming, int number_of_words, char *long_words,
+ char *short_words, char *dimming_list, int full)
+{
+ char **l;
+ char **s;
+ char *w;
+ char *l_w = long_words;
+ char *s_w = short_words;
+ int i;
+ int len;
+ int newsize;
+
+ if (*static_string_size == 0) { /* Allocate string memory. */
+ if ((*static_string_size = alloc_string(static_string,
+ *static_string_size, 'C')) == 0)
+ /* can't get string memory for string */
+ return (0);
+ }
+
+again:
+ if (*static_string_size < (int)strlen(new_string)+1) {
+ /* need longer string */
+ if ((newsize = alloc_string(static_string, *static_string_size,
+ 'C')) == 0)
+ /* can't get more string memory */
+ return (0);
+
+ *static_string_size += newsize;
+ goto again;
+ }
+ bcopy(new_string, *static_string, strlen(new_string) + 1);
+
+ if (full) {
+ if (*static_words_size < new_words_size &&
+ !alloc_words(static_words, new_words_size)) {
+ /* can't get more words memory */
+ return (0);
+ } else {
+ *static_words_size = new_words_size;
+ }
+ /*LINTED*/
+ l = (char **)*static_words;
+ s = l + number_of_words;
+ *static_dimming = (char *)(s + number_of_words);
+ w = *static_dimming + number_of_words;
+ for (i = 0; i < number_of_words; i++) {
+ *l = w;
+ (void) strcpy(w, l_w);
+ w += (len = strlen(l_w) + 1);
+ l_w += len;
+ if (*s_w == '\000') {
+ *s = NULL;
+ s_w++;
+ } else {
+ *s = w;
+ (void) strcpy(w, s_w);
+ w += (len = strlen(s_w) + 1);
+ s_w += len;
+ }
+
+ l++;
+ s++;
+ } /* for each word entry */
+ } /* if (full) */
+
+ bcopy(dimming_list, *static_dimming, number_of_words);
+ return (1);
+} /* build_strings */
+
+#define bsfcall callp->param.acall.cargs.bslcvt_arg
+#define bsfret callp->param.aret.rvals.bslcvt_ret
+/*
+ * bslcvtfull - Convert Sensitivity Label and initialize static
+ * information.
+ *
+ * Entry label = Sensitivity Label to convert and get dimming list.
+ * This label should lie within the bounds or the
+ * results may not be meaningful.
+ * bounds = Lower and upper bounds for words lists. Must be
+ * dominated by clearance.
+ * flags = VIEW_INTERNAL, don't promote/demote admin low/high.
+ * VIEW_EXTERNAL, promote/demote admin low/high.
+ *
+ * Exit string = ASCII coded Sensitivity Label.
+ * long_words = Array of pointers to visible long word names.
+ * short_words = Array of pointers to visible short word names.
+ * display = Array of indicators as to whether the word is present
+ * in the converted label (CVT_SET), and/or changeable
+ * (CVT_DIM).
+ * first_compartment = Zero based index of first compartment.
+ * display_size = Number of entries in the display/words lists.
+ *
+ * Returns -1, If unable to access label encodings database, or
+ * invalid label.
+ * 0, If unable to allocate static memory.
+ * 1, If successful.
+ *
+ * Calls RPC - LABELS_BSLCONVERT, STTBLEVEL, SETBSLABEL, TCLNT,
+ * build_strings, clnt_call, clnt_perror.
+ *
+ * Uses sbounds, slrcvt, slrcvtsize, slrdim, slrstring,
+ * slrstringsize.
+ */
+
+int
+bslcvtfull(const bslabel_t *label, const blrange_t *bounds, int flags,
+ char **string, char **long_words[], char **short_words[], char *display[],
+ int *first_compartment, int *display_size)
+{
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize = CALL_SIZE(bslcvt_call_t, 0);
+ int new_words_size;
+ int rval;
+
+ call.callop = BSLCVT;
+ bsfcall.label = *label;
+ bsfcall.bounds.upper_bound = *bounds->upper_bound;
+ bsfcall.bounds.lower_bound = *bounds->lower_bound;
+ bsfcall.flags = LABELS_FULL_CONVERT;
+ set_label_view(&bsfcall.flags, flags);
+
+ if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) {
+#ifdef DEBUG
+ (void) fprintf(stderr, "No label server.\n");
+#endif /* DEBUG */
+ return (-1);
+ } else if (rval != SUCCESS) {
+ return (-1);
+ } else {
+ if (callp->reterr != 0)
+ return (-1);
+ }
+
+ *first_compartment = bsfret.first_comp;
+ *display_size = bsfret.d_len;
+
+ new_words_size = bsfret.l_len + bsfret.s_len + bsfret.d_len +
+ (2 * sizeof (char *)) * bsfret.d_len;
+
+ if (build_strings(&slstringsize, &slstring, &bsfret.buf[bsfret.string],
+ &slcvtsize, new_words_size, &slcvt, &sldim, bsfret.d_len,
+ &bsfret.buf[bsfret.lwords], &bsfret.buf[bsfret.swords],
+ &bsfret.buf[bsfret.dim], 1) != 1) {
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (0);
+ }
+
+ /* save for bslcvt call */
+ sbounds.upper_bound = *bounds->upper_bound;
+ sbounds.lower_bound = *bounds->lower_bound;
+
+ *string = slstring;
+ *display = sldim;
+ /*LINTED*/
+ *long_words = (char **)slcvt;
+ /*LINTED*/
+ *short_words = (char **)(slcvt + *display_size * sizeof (char *));
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (1);
+} /* bslcvtfull */
+#undef bsfcall
+#undef bsfret
+
+#define bsccall callp->param.acall.cargs.bslcvt_arg
+#define bscret callp->param.aret.rvals.bslcvt_ret
+/*
+ * bslcvt - Convert Sensitivity Label and update dimming information.
+ *
+ * Entry label = Sensitivity Label to convert and get dimming list.
+ * This label should lie within the bounds of the
+ * corresponding bslcvtfull call or the results may
+ * not be meaningful.
+ * flags = VIEW_INTERNAL, don't promote/demote admin low/high.
+ * VIEW_EXTERNAL, promote/demote admin low/high.
+ *
+ * Exit string = ASCII coded Sensitivity Label.
+ * display = Array of indicators as to whether the word is present
+ * in the converted label (CVT_SET), and/or changeable
+ * (CVT_DIM).
+ *
+ * Returns -1, If unable to access label encodings database, or
+ * invalid label.
+ * 0, If unable to allocate static memory.
+ * 1, If successful.
+ *
+ * Calls RPC - LABELS_BSLCONVERT, SETBLEVEL, SETBSLABEL, build_strings
+ * clnt_call, clnt_perror.
+ *
+ * Uses sbounds, slrdim, slrstring.
+ */
+
+int
+bslcvt(const bslabel_t *label, int flags, char **string, char *display[])
+{
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize = CALL_SIZE(bslcvt_call_t, 0);
+ int rval;
+
+ if (slcvt == NULL)
+ return (-1); /* conversion not initialized */
+
+ call.callop = BSLCVT;
+ bsccall.label = *label;
+ bsccall.bounds = sbounds; /* save from last bslcvtfull() call */
+ bsccall.flags = 0;
+ set_label_view(&bsccall.flags, flags);
+
+ if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) {
+#ifdef DEBUG
+ (void) fprintf(stderr, "No label server.\n");
+#endif /* DEBUG */
+ return (-1);
+ } else if (rval != SUCCESS) {
+ return (-1);
+ } else {
+ if (callp->reterr != 0)
+ return (-1);
+ }
+
+ if (build_strings(&slstringsize, &slstring, &bscret.buf[bscret.string],
+ &slcvtsize, 0, &slcvt, &sldim, bscret.d_len,
+ &bscret.buf[bscret.lwords], &bscret.buf[bscret.swords],
+ &bscret.buf[bscret.dim], 0) != 1) {
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (0);
+ }
+
+ *string = slstring;
+ *display = sldim;
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (1);
+} /* bslcvt */
+#undef bsccall
+#undef bscret
+
+#define bcfcall callp->param.acall.cargs.bclearcvt_arg
+#define bcfret callp->param.aret.rvals.bclearcvt_ret
+/*
+ * bclearcvtfull - Convert Clearance and initialize static information.
+ *
+ * Entry clearance = Clearance to convert and get dimming list.
+ * This clearance should lie within the bounds or
+ * the results may not be meaningful.
+ * bounds = Lower and upper bounds for words lists. Must be
+ * dominated by clearance.
+ * flags = VIEW_INTERNAL, don't promote/demote admin low/high.
+ * VIEW_EXTERNAL, promote/demote admin low/high.
+ *
+ * Exit string = ASCII coded Clearance.
+ * long_words = Array of pointers to visible long word names.
+ * short_words = Array of pointers to visible short word names.
+ * display = Array of indicators as to whether the word is present
+ * in the converted label (CVT_SET), and/or changeable
+ * (CVT_DIM).
+ * first_compartment = Zero based index of first compartment.
+ * display_size = Number of entries in the display/words lists.
+ *
+ * Returns -1, If unable to access label encodings database, or
+ * invalid label.
+ * 0, If unable to allocate static memory.
+ * 1, If successful.
+ *
+ * Calls RPC - LABELS_BCLEARCONVERT, SETBCLEAR, SETBLEVEL, TCLNT,
+ * build_strings, clnt_call, clnt_perror.
+ *
+ * Uses cbounds, clrcvt, clrcvtsize, clrdim, clrstring,
+ * clrstringsize.
+ */
+
+int
+bclearcvtfull(const bclear_t *clearance, const blrange_t *bounds,
+ int flags, char **string, char **long_words[], char **short_words[],
+ char *display[], int *first_compartment, int *display_size)
+{
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize = CALL_SIZE(bclearcvt_call_t, 0);
+ int new_words_size;
+ int rval;
+
+ call.callop = BCLEARCVT;
+ bcfcall.clear = *clearance;
+ bcfcall.bounds.upper_bound = *bounds->upper_bound;
+ bcfcall.bounds.lower_bound = *bounds->lower_bound;
+ bcfcall.flags = LABELS_FULL_CONVERT;
+ set_label_view(&bcfcall.flags, flags);
+
+ if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) {
+#ifdef DEBUG
+ (void) fprintf(stderr, "No label server.\n");
+#endif /* DEBUG */
+ return (-1);
+ } else if (rval != SUCCESS) {
+ return (-1);
+ } else {
+ if (callp->reterr != 0)
+ return (-1);
+ }
+
+ *first_compartment = bcfret.first_comp;
+ *display_size = bcfret.d_len;
+
+ new_words_size = bcfret.l_len + bcfret.s_len + bcfret.d_len +
+ (2 * sizeof (char *)) * bcfret.d_len;
+
+ if (build_strings(&clrstringsize, &clrstring,
+ &bcfret.buf[bcfret.string],
+ &clrcvtsize, new_words_size, &clrcvt,
+ &clrdim, bcfret.d_len,
+ &bcfret.buf[bcfret.lwords], &bcfret.buf[bcfret.swords],
+ &bcfret.buf[bcfret.dim], 1) != 1) {
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (0);
+ }
+
+ /* save for bclearcvt call */
+ cbounds.upper_bound = *bounds->upper_bound;
+ cbounds.lower_bound = *bounds->lower_bound;
+
+ *string = clrstring;
+ *display = clrdim;
+ /*LINTED*/
+ *long_words = (char **)clrcvt;
+ /*LINTED*/
+ *short_words = (char **)(clrcvt + *display_size * sizeof (char *));
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (1);
+} /* bclearcvtfull */
+#undef bcfcall
+#undef bcfret
+
+#define bcccall callp->param.acall.cargs.bclearcvt_arg
+#define bccret callp->param.aret.rvals.bclearcvt_ret
+/*
+ * bclearcvt - Convert Clearance and update dimming inforamtion.
+ *
+ * Entry clearance = Clearance to convert and get dimming list.
+ * This clearance should lie within the bounds of the
+ * corresponding bclearcvtfull call or the results may
+ * not be meaningful.
+ * flags = VIEW_INTERNAL, don't promote/demote admin low/high.
+ * VIEW_EXTERNAL, promote/demote admin low/high.
+ *
+ * Exit string = ASCII coded Clearance.
+ * display = Array of indicators as to whether the word is present
+ * in the converted label (CVT_SET), and/or changeable
+ * (CVT_DIM).
+ *
+ * Returns -1, If unable to access label encodings database, or
+ * invalid label.
+ * 0, If unable to allocate static memory.
+ * 1, If successful.
+ *
+ * Calls RPC - LABELS_BCLEARCONVERT, SETBCLEAR, SETBLEVEL, build_strings,
+ * clnt_call, clnt_perror.
+ *
+ * Uses cbounds, clrdim, clrstring.
+ */
+
+int
+bclearcvt(const bclear_t *clearance, int flags, char **string,
+ char *display[])
+{
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize = CALL_SIZE(bclearcvt_call_t, 0);
+ int rval;
+
+ if (clrcvt == NULL)
+ return (-1); /* conversion not initialized */
+
+ call.callop = BCLEARCVT;
+ bcccall.clear = *clearance;
+ bcccall.bounds = cbounds; /* save from last bslcvtfull() call */
+ bcccall.flags = 0;
+ set_label_view(&bcccall.flags, flags);
+
+ if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) {
+#ifdef DEBUG
+ (void) fprintf(stderr, "No label server.\n");
+#endif /* DEBUG */
+ return (-1);
+ } else if (rval != SUCCESS) {
+ return (-1);
+ } else {
+ if (callp->reterr != 0)
+ return (-1);
+ }
+
+ if (build_strings(&clrstringsize, &clrstring,
+ &bccret.buf[bccret.string],
+ &clrcvtsize, 0, &clrcvt, &clrdim, bccret.d_len,
+ &bccret.buf[bccret.lwords], &bccret.buf[bccret.swords],
+ &bccret.buf[bccret.dim], 0) != 1) {
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (0);
+ }
+
+ *string = clrstring;
+ *display = clrdim;
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (1);
+} /* bclearcvt */
+#undef bcccall
+#undef bccret
+
+#define lfret callp->param.aret.rvals.fields_ret
+/*
+ * labelfields - Return names for the label fields.
+ *
+ * Entry None
+ *
+ * Exit fields = Updated.
+ *
+ * Returns -1, If unable to access label encodings file, or
+ * labels server failure.
+ * 0, If unable to allocate memory.
+ * 1, If successful.
+ *
+ * Calls __call_labeld(LABELFIELDS).
+ */
+
+int
+labelfields(struct name_fields *fields)
+{
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize = CALL_SIZE(fields_call_t, 0);
+ int rval;
+
+ call.callop = LABELFIELDS;
+
+ if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) {
+
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (-1);
+ }
+
+ /* unpack results */
+
+ if ((fields->class_name = strdup(&lfret.buf[lfret.classi])) == NULL) {
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (0);
+ }
+ if ((fields->comps_name = strdup(&lfret.buf[lfret.compsi])) == NULL) {
+ free(fields->class_name);
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (0);
+ }
+ if ((fields->marks_name = strdup(&lfret.buf[lfret.marksi])) == NULL) {
+ free(fields->class_name);
+ free(fields->comps_name);
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (0);
+ }
+
+ if (callp != &call)
+ /* release return buffer */
+ (void) munmap((void *)callp, bufsize);
+ return (rval);
+} /* labelfields */
+#undef lfret
+
+#define udret callp->param.aret.rvals.udefs_ret
+/*
+ * userdefs - Get default user Sensitivity Label and Clearance.
+ *
+ * Entry None.
+ *
+ * Exit sl = default user Sensitivity Label.
+ * clear = default user Clearance.
+ *
+ * Returns -1, If unable to access label encodings file, or
+ * labels server failure.
+ * 1, If successful.
+ *
+ * Calls __call_labeld(UDEFS).
+ */
+
+int
+userdefs(bslabel_t *sl, bclear_t *clear)
+{
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize = CALL_SIZE(udefs_call_t, 0);
+ int rval;
+
+ call.callop = UDEFS;
+
+ if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) {
+ /* process error */
+
+ return (-1);
+ }
+
+ *sl = udret.sl;
+ *clear = udret.clear;
+ return (rval);
+} /* userdefs */
+#undef udret
diff --git a/usr/src/lib/libtsol/common/privlib.c b/usr/src/lib/libtsol/common/privlib.c
new file mode 100644
index 0000000000..3d1a8023d2
--- /dev/null
+++ b/usr/src/lib/libtsol/common/privlib.c
@@ -0,0 +1,179 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <errno.h>
+#include <priv.h>
+#include <sys/tsol/priv.h>
+#include <sys/varargs.h>
+
+/*
+ * set_effective_priv(op, num_priv, priv_id1, priv_id2, ... )
+ *
+ * Library routine to enable a user process to set its effective
+ * privilege set appropriately using a single call. User is
+ * required to specify the number of privilege ids that follow as
+ * arguments, rather than depending on the compiler to terminate
+ * the argument list with a NULL, which may be compiler-dependent.
+ */
+int
+set_effective_priv(priv_op_t op, int num_priv, ...)
+{
+ priv_set_t *priv_set;
+ priv_t priv_id;
+ va_list ap;
+ int status;
+
+ priv_set = priv_allocset();
+ PRIV_EMPTY(priv_set);
+
+ va_start(ap, num_priv);
+ while (num_priv--) {
+ char *priv_name;
+ /*
+ * Do sanity checking on priv_id's here to assure
+ * valid inputs to privilege macros. This checks
+ * num_priv argument as well.
+ */
+ priv_id = va_arg(ap, priv_t);
+ priv_name = (char *)priv_getbynum((int)(uintptr_t)priv_id);
+ if (priv_name == NULL) {
+ errno = EINVAL;
+ priv_freeset(priv_set);
+ return (-1);
+ }
+ (void) priv_addset(priv_set, priv_name);
+ }
+ va_end(ap);
+
+ /*
+ * Depend on system call to do sanity checking on "op"
+ */
+ status = setppriv(op, PRIV_EFFECTIVE, priv_set);
+ priv_freeset(priv_set);
+ return (status);
+
+} /* set_effective_priv() */
+
+
+
+
+/*
+ * set_inheritable_priv(op, num_priv, priv_id1, priv_id2, ... )
+ *
+ * Library routine to enable a user process to set its inheritable
+ * privilege set appropriately using a single call. User is
+ * required to specify the number of privilege ids that follow as
+ * arguments, rather than depending on the compiler to terminate
+ * the argument list with a NULL, which may be compiler-dependent.
+ */
+int
+set_inheritable_priv(priv_op_t op, int num_priv, ...)
+{
+ priv_set_t *priv_set;
+ priv_t priv_id;
+ va_list ap;
+ int status;
+
+ priv_set = priv_allocset();
+
+ PRIV_EMPTY(priv_set);
+
+ va_start(ap, num_priv);
+ while (num_priv--) {
+ /*
+ * Do sanity checking on priv_id's here to assure
+ * valid inputs to privilege macros. This checks
+ * num_priv argument as well.
+ */
+ priv_id = va_arg(ap, priv_t);
+ if ((char *)priv_getbynum((int)(uintptr_t)priv_id) == NULL) {
+ errno = EINVAL;
+ priv_freeset(priv_set);
+ return (-1);
+ }
+ (void) PRIV_ASSERT(priv_set, priv_id);
+ }
+ va_end(ap);
+
+ /*
+ * Depend on system call to do sanity checking on "op"
+ */
+ status = setppriv(op, PRIV_INHERITABLE, priv_set);
+ priv_freeset(priv_set);
+ return (status);
+
+} /* set_inheritable_priv() */
+
+
+
+
+/*
+ * set_permitted_priv(op, num_priv, priv_id1, priv_id2, ... )
+ *
+ * Library routine to enable a user process to set its permitted
+ * privilege set appropriately using a single call. User is
+ * required to specify the number of privilege ids that follow as
+ * arguments, rather than depending on the compiler to terminate
+ * the argument list with a NULL, which may be compiler-dependent.
+ */
+int
+set_permitted_priv(priv_op_t op, int num_priv, ...)
+{
+ priv_set_t *priv_set;
+ priv_t priv_id;
+ va_list ap;
+ int status;
+
+ priv_set = priv_allocset();
+
+ PRIV_EMPTY(priv_set);
+
+ va_start(ap, num_priv);
+ while (num_priv--) {
+ /*
+ * Do sanity checking on priv_id's here to assure
+ * valid inputs to privilege macros. This checks
+ * num_priv argument as well.
+ */
+ priv_id = va_arg(ap, priv_t);
+ if ((char *)priv_getbynum((int)(uintptr_t)priv_id) == NULL) {
+ errno = EINVAL;
+ priv_freeset(priv_set);
+ return (-1);
+ }
+ (void) PRIV_ASSERT(priv_set, priv_id);
+ }
+ va_end(ap);
+
+ /*
+ * Depend on system call to do sanity checking on "op"
+ */
+ status = setppriv(op, PRIV_PERMITTED, priv_set);
+ priv_freeset(priv_set);
+ return (status);
+
+} /* set_permitted_priv() */
diff --git a/usr/src/lib/libtsol/common/setflabel.c b/usr/src/lib/libtsol/common/setflabel.c
new file mode 100644
index 0000000000..1d645c8d23
--- /dev/null
+++ b/usr/src/lib/libtsol/common/setflabel.c
@@ -0,0 +1,309 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Change the label of a file
+ */
+
+#include <ctype.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <errno.h>
+
+#include <tsol/label.h>
+
+#include "labeld.h"
+#include <sys/tsol/label_macro.h>
+
+#include <sys/types.h>
+
+#include <zone.h>
+#include <sys/zone.h>
+#include <sys/param.h>
+#include <string.h>
+
+static int abspath(char *, const char *, char *);
+
+/*
+ * setflabel(3TSOL) - set file label
+ *
+ * This is the library interface to the door call.
+ */
+
+#define clcall callp->param.acall.cargs.setfbcl_arg
+#define clret callp->param.aret.rvals.setfbcl_ret
+/*
+ *
+ * Exit error = If error reported, the error indicator,
+ * -1, Unable to access label encodings file;
+ * 0, Invalid binary label passed;
+ * >0, Position after the first character in
+ * string of error, 1 indicates entire string.
+ * Otherwise, unchanged.
+ *
+ * Returns 0, If error.
+ * 1, If successful.
+ *
+ * Calls __call_labeld(SETFLABEL)
+ *
+ */
+
+int
+setflabel(const char *path, m_label_t *label)
+{
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize;
+ size_t path_len;
+ static char cwd[MAXPATHLEN];
+ char canon[MAXPATHLEN];
+
+
+ /*
+ * If path is relative and we haven't already determined the current
+ * working directory, do so now. Calculating the working directory
+ * here lets us do the work once, instead of (potentially) repeatedly
+ * in realpath().
+ */
+ if (*path != '/' && cwd[0] == '\0') {
+ if (getcwd(cwd, MAXPATHLEN) == NULL) {
+ cwd[0] = '\0';
+ return (-1);
+ }
+ }
+ /*
+ * Find an absolute pathname in the native file system name space that
+ * corresponds to path, stuffing it into canon.
+ */
+ if (abspath(cwd, path, canon) < 0)
+ return (-1);
+
+ path_len = strlen(canon) + 1;
+
+ datasize = CALL_SIZE(setfbcl_call_t, path_len - BUFSIZE);
+ datasize += 2; /* PAD */
+
+ if (datasize > bufsize) {
+ if ((callp = (labeld_data_t *)malloc(datasize)) == NULL) {
+ return (-1);
+ }
+ bufsize = datasize;
+ }
+
+ callp->callop = SETFLABEL;
+
+ clcall.sl = *label;
+ (void) strcpy(clcall.pathname, canon);
+
+ if (__call_labeld(&callp, &bufsize, &datasize) == SUCCESS) {
+ int err = callp->reterr;
+
+ if (callp != &call) {
+ /* free allocated buffer */
+ free(callp);
+ }
+ /*
+ * reterr == 0, OK,
+ * reterr < 0, invalid binary label,
+ */
+ if (err == 0) {
+ if (clret.status > 0) {
+ errno = clret.status;
+ return (-1);
+ } else {
+ return (0);
+ }
+ } else if (err < 0) {
+ err = 0;
+ }
+ errno = ECONNREFUSED;
+ return (-1);
+ } else {
+ if (callp != &call) {
+ /* free allocated buffer */
+ free(callp);
+ }
+ /* server not present */
+ errno = ECONNREFUSED;
+ return (-1);
+ }
+} /* setflabel */
+
+#undef clcall
+#undef clret
+
+#define clcall callp->param.acall.cargs.zcopy_arg
+#define clret callp->param.aret.rvals.zcopy_ret
+/*
+ *
+ * Exit status = result of zone copy request
+ * -1, Copy not confirmed
+ * Otherwise, unchanged.
+ *
+ * Returns 0, If error.
+ * 1, If successful.
+ *
+ * Calls __call_labeld(ZCOPY)
+ *
+ */
+int
+zonecopy(m_label_t *src_win_sl, char *remote_dir, char *filename,
+ char *local_dir, int transfer_mode)
+{
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize;
+ size_t strings;
+ size_t remote_dir_len;
+ size_t filename_len;
+ size_t local_dir_len;
+ size_t display_len;
+ char *display;
+
+ remote_dir_len = strlen(remote_dir) + 1;
+ filename_len = strlen(filename) + 1;
+ local_dir_len = strlen(local_dir) + 1;
+
+ if ((display = getenv("DISPLAY")) == NULL)
+ display = "";
+ display_len = strlen(display) + 1;
+
+ strings = remote_dir_len + filename_len + local_dir_len + display_len;
+
+ datasize = CALL_SIZE(zcopy_call_t, strings - BUFSIZE);
+
+ datasize += 4; /* PAD */
+
+ if (datasize > bufsize) {
+ if ((callp = (labeld_data_t *)malloc(datasize)) == NULL) {
+ return (NULL);
+ }
+ bufsize = datasize;
+ }
+
+ strings = 0;
+ callp->callop = ZCOPY;
+
+ clcall.src_win_sl = *src_win_sl;
+ clcall.transfer_mode = transfer_mode;
+ clcall.remote_dir = strings;
+ strings += remote_dir_len;
+ clcall.filename = strings;
+ strings += filename_len;
+ clcall.local_dir = strings;
+ strings += local_dir_len;
+ clcall.display = strings;
+
+ (void) strcpy(&clcall.buf[clcall.remote_dir], remote_dir);
+ (void) strcpy(&clcall.buf[clcall.filename], filename);
+ (void) strcpy(&clcall.buf[clcall.local_dir], local_dir);
+ (void) strcpy(&clcall.buf[clcall.display], display);
+
+ if (__call_labeld(&callp, &bufsize, &datasize) == SUCCESS) {
+ int err = callp->reterr;
+
+ if (callp != &call) {
+ /* free allocated buffer */
+ free(callp);
+ }
+ /*
+ * reterr == 0, OK,
+ * reterr < 0, transer not confirmed
+ */
+ if (err == 0) {
+ return (clret.status);
+ } else if (err < 0) {
+ err = 0;
+ }
+ return (PIPEMSG_CANCEL);
+ } else {
+ if (callp != &call) {
+ /* free allocated buffer */
+ free(callp);
+ }
+ /* server not present */
+ return (PIPEMSG_CANCEL);
+ }
+}
+
+/*
+ * Convert the path given in raw to canonical, absolute, symlink-free
+ * form, storing the result in the buffer named by canon, which must be
+ * at least MAXPATHLEN bytes long. If wd is non-NULL, assume that it
+ * points to a path for the current working directory and use it instead
+ * of invoking getcwd; accepting this value as an argument lets our caller
+ * cache the value, so that realpath (called from this routine) doesn't have
+ * to recalculate it each time it's given a relative pathname.
+ *
+ * Return 0 on success, -1 on failure.
+ */
+int
+abspath(char *wd, const char *raw, char *canon)
+{
+ char absbuf[MAXPATHLEN];
+
+ /*
+ * Preliminary sanity check.
+ */
+ if (raw == NULL || canon == NULL)
+ return (-1);
+
+ /*
+ * If the path is relative, convert it to absolute form,
+ * using wd if it's been supplied.
+ */
+ if (raw[0] != '/') {
+ char *limit = absbuf + sizeof (absbuf);
+ char *d;
+
+ /* Fill in working directory. */
+ if (wd != NULL)
+ (void) strncpy(absbuf, wd, sizeof (absbuf));
+ else if (getcwd(absbuf, strlen(absbuf)) == NULL)
+ return (-1);
+
+ /* Add separating slash. */
+ d = absbuf + strlen(absbuf);
+ if (d < limit)
+ *d++ = '/';
+
+ /* Glue on the relative part of the path. */
+ while (d < limit && (*d++ = *raw++))
+ continue;
+
+ raw = absbuf;
+ }
+
+ /*
+ * Call realpath to canonicalize and resolve symlinks.
+ */
+ return (realpath(raw, canon) == NULL ? -1 : 0);
+}
diff --git a/usr/src/lib/libtsol/common/stob.c b/usr/src/lib/libtsol/common/stob.c
new file mode 100644
index 0000000000..e8e6780875
--- /dev/null
+++ b/usr/src/lib/libtsol/common/stob.c
@@ -0,0 +1,312 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * String to binary label translations.
+ */
+
+#include <ctype.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <tsol/label.h>
+
+#include "labeld.h"
+#include <sys/tsol/label_macro.h>
+
+#undef CALL_SIZE
+#define CALL_SIZE(type, buf) (size_t)(sizeof (type) - BUFSIZE + sizeof (int)\
+ + (buf))
+
+#if !defined(TEXT_DOMAIN) /* should be defined by Makefiles */
+#define TEXT_DOMAIN "SYS_TEST"
+#endif /* TEXT_DOMAIN */
+
+/* short hands */
+
+#define IS_ADMIN_LOW(sl) \
+ ((strncasecmp(sl, ADMIN_LOW, (sizeof (ADMIN_LOW) - 1)) == 0))
+
+#define IS_ADMIN_HIGH(sh) \
+ ((strncasecmp(sh, ADMIN_HIGH, (sizeof (ADMIN_HIGH) - 1)) == 0))
+
+#define ISHEX(f, s) \
+ (((((f) & NEW_LABEL) == ((f) | NEW_LABEL)) || \
+ (((f) & NO_CORRECTION) == ((f) | NO_CORRECTION))) && \
+ (((s)[0] == '0') && (((s)[1] == 'x') || ((s)[1] == 'X'))))
+
+#define slcall callp->param.acall.cargs.stobsl_arg
+#define slret callp->param.aret.rvals.stobsl_ret
+/*
+ * stobsl - Translate Sensitivity Label string to a Binary Sensitivity
+ * Label.
+ *
+ * Entry string = Sensitivity Label string to be translated.
+ * label = Address of Binary Sensitivity Label to be initialized or
+ * updated.
+ * flags = Flags to control translation:
+ * NO_CORRECTION implies NEW_LABEL.
+ * NEW_LABEL, Initialize the label to a valid empty
+ * Sensitivity Label structure.
+ * NO_CORRECTION, Initialize the label to a valid
+ * empty Sensitivity Label structure.
+ * Prohibit correction to the Sensitivity Label.
+ * Other, pass existing Sensitivity Label through for
+ * modification.
+ *
+ * Exit label = Translated (updated) Binary Sensitivity Label.
+ * error = If error reported, the error indicator,
+ * -1, Unable to access label encodings file;
+ * 0, Invalid binary label passed;
+ * >0, Position after the first character in
+ * string of error, 1 indicates entire string.
+ * Otherwise, unchanged.
+ *
+ * Returns 0, If error.
+ * 1, If successful.
+ *
+ * Calls __call_labeld(STOBSL), ISHEX, htobsl, strlen,
+ * isspace,
+ * strncasecmp.
+ *
+ * Uses ADMIN_HIGH, ADMIN_LOW.
+ */
+
+int
+stobsl(const char *string, bslabel_t *label, int flags, int *error)
+{
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize = CALL_SIZE(stobsl_call_t, strlen(string) + 1);
+ int rval;
+ char *s = (char *)string;
+
+ while (isspace(*s))
+ s++;
+ /* accept a leading '[' */
+ if (*s == '[') {
+ s++;
+ while (isspace(*s))
+ s++;
+ }
+ if (ISHEX(flags, s)) {
+ if (htobsl(s, label)) {
+ return (1);
+ } else {
+ if (error != NULL)
+ *error = 1;
+ return (0);
+ }
+ }
+
+ if (datasize > bufsize) {
+ if ((callp = malloc(datasize)) == NULL) {
+ if (error != NULL)
+ *error = -1;
+ return (0);
+ }
+ bufsize = datasize;
+ }
+ callp->callop = STOBSL;
+ slcall.flags = (flags&NEW_LABEL) ? LABELS_NEW_LABEL : 0;
+ slcall.flags |= (flags&NO_CORRECTION) ? LABELS_FULL_PARSE : 0;
+ slcall.label = *label;
+ (void) strcpy(slcall.string, string);
+
+ if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) {
+ int err = callp->reterr;
+
+ if (callp != &call) {
+ /* free allocated buffer */
+ free(callp);
+ }
+ /*
+ * reterr == 0, OK,
+ * reterr < 0, invalid binary label,
+ * reterr > 0 error position, 1 == whole string
+ */
+ if (err == 0) {
+ *label = slret.label;
+ return (1);
+ } else if (err < 0) {
+ err = 0;
+ }
+ if (error != NULL)
+ *error = err;
+ return (0);
+ } else if (rval == NOSERVER) {
+ if (callp != &call) {
+ /* free allocated buffer */
+ free(callp);
+ }
+ /* server not present */
+ /* special case Admin High and Admin Low */
+ if (IS_ADMIN_LOW(s)) {
+ BSLLOW(label);
+ } else if (IS_ADMIN_HIGH(s)) {
+ BSLHIGH(label);
+ } else {
+ goto err1;
+ }
+ return (1);
+ }
+ if (callp != &call) {
+ /* free allocated buffer */
+ free(callp);
+ }
+err1:
+ if (error != NULL)
+ *error = -1;
+ return (0);
+} /* stobsl */
+#undef slcall
+#undef slret
+
+#define clrcall callp->param.acall.cargs.stobclear_arg
+#define clrret callp->param.aret.rvals.stobclear_ret
+/*
+ * stobclear - Translate Clearance string to a Binary Clearance.
+ *
+ * Entry string = Clearance string to be translated.
+ * clearance = Address of Binary Clearance to be initialized or
+ * updated.
+ * flags = Flags to control translation:
+ * NO_CORRECTION implies NEW_LABEL.
+ * NEW_LABEL, Initialize the label to a valid empty
+ * Sensitivity Label structure.
+ * NO_CORRECTION, Initialize the label to a valid
+ * empty Sensitivity Label structure.
+ * Prohibit correction to the Sensitivity Label.
+ * Other, pass existing Sensitivity Label through for
+ * modification.
+ *
+ * Exit clearance = Translated (updated) Binary Clearance.
+ * error = If error reported, the error indicator,
+ * -1, Unable to access label encodings file;
+ * 0, Invalid binary label passed;
+ * >0, Position after the first character in
+ * string of error, 1 indicates entire string.
+ * Otherwise, unchanged.
+ *
+ * Returns 0, If error.
+ * 1, If successful.
+ *
+ * Calls __call_labeld(STOBCLEAR), ISHEX, htobsl, strlen,
+ * isspace,
+ * strncasecmp.
+ *
+ * Uses ADMIN_HIGH, ADMIN_LOW.
+ */
+
+int
+stobclear(const char *string, bclear_t *clearance, int flags, int *error)
+{
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize = CALL_SIZE(callp->param.acall, strlen(string) + 1);
+ int rval;
+
+ if (ISHEX(flags, string)) {
+ if (htobclear(string, clearance)) {
+ return (1);
+ } else {
+ if (error != NULL)
+ *error = 1;
+ return (0);
+ }
+ }
+
+ if (datasize > bufsize) {
+ if ((callp = malloc(datasize)) == NULL) {
+ if (error != NULL)
+ *error = -1;
+ return (0);
+ }
+ bufsize = datasize;
+ }
+ callp->callop = STOBCLEAR;
+ clrcall.flags = (flags&NEW_LABEL) ? LABELS_NEW_LABEL : 0;
+ clrcall.flags |= (flags&NO_CORRECTION) ? LABELS_FULL_PARSE : 0;
+ clrcall.clear = *clearance;
+ (void) strcpy(clrcall.string, string);
+
+ if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) {
+ int err = callp->reterr;
+
+ if (callp != &call) {
+ /* free allocated buffer */
+ free(callp);
+ }
+ /*
+ * reterr == 0, OK,
+ * reterr < 0, invalid binary label,
+ * reterr > 0 error position, 1 == whole string
+ */
+ if (err == 0) {
+ *clearance = clrret.clear;
+ return (1);
+ } else if (err < 0) {
+ err = 0;
+ }
+ if (error != NULL)
+ *error = err;
+ return (0);
+ } else if (rval == NOSERVER) {
+ char *s = (char *)string;
+
+ if (callp != &call) {
+ /* free allocated buffer */
+ free(callp);
+ }
+ /* server not present */
+ /* special case Admin High and Admin Low */
+ while (isspace(*s))
+ s++;
+ if (IS_ADMIN_LOW(s)) {
+ BCLEARLOW(clearance);
+ } else if (IS_ADMIN_HIGH(s)) {
+ BCLEARHIGH(clearance);
+ } else {
+ goto err1;
+ }
+ return (1);
+ }
+ if (callp != &call) {
+ /* free allocated buffer */
+ free(callp);
+ }
+err1:
+ if (error != NULL)
+ *error = -1;
+ return (0);
+} /* stobclear */
+#undef clrcall
+#undef clrret
diff --git a/usr/src/lib/libtsol/common/stol.c b/usr/src/lib/libtsol/common/stol.c
new file mode 100644
index 0000000000..2a951b3907
--- /dev/null
+++ b/usr/src/lib/libtsol/common/stol.c
@@ -0,0 +1,394 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+
+#include <sys/mman.h>
+#include <sys/tsol/label_macro.h>
+
+#include <tsol/label.h>
+
+#include "clnt.h"
+#include "labeld.h"
+
+#define IS_LOW(s) \
+ ((strncasecmp(s, ADMIN_LOW, (sizeof (ADMIN_LOW) - 1)) == 0) && \
+ (s[sizeof (ADMIN_LOW) - 1] == '\0'))
+#define IS_HIGH(s) \
+ ((strncasecmp(s, ADMIN_HIGH, (sizeof (ADMIN_HIGH) - 1)) == 0) && \
+ (s[sizeof (ADMIN_HIGH) - 1] == '\0'))
+#define IS_HEX(f, s) \
+ (((((f) == L_NO_CORRECTION)) || ((f) == L_DEFAULT)) && \
+ (((s)[0] == '0') && (((s)[1] == 'x') || ((s)[1] == 'X'))))
+
+static boolean_t
+unhex(char **h, uchar_t *l, int len)
+{
+ char *hx = *h;
+ char ch;
+ uchar_t byte;
+
+ for (; len--; ) {
+ ch = *hx++;
+ if (!isxdigit(ch))
+ return (B_FALSE);
+ if (isdigit(ch))
+ byte = ch - '0';
+ else
+ byte = ch - (isupper(ch) ? 'A' - 10 : 'a' - 10);
+ byte <<= 4;
+ ch = *hx++;
+ if (isdigit(ch))
+ byte |= ch - '0';
+ else
+ byte |= ch - (isupper(ch) ? 'A' - 10 : 'a' - 10);
+ *l++ = byte;
+ }
+ *h = hx;
+ return (B_TRUE);
+}
+
+/*
+ * Formats accepted:
+ * 0x + 4 class + 64 comps + end of string
+ * 0x + 4 class + '-' + ll + '-' + comps + end of string
+ * ll = number of words to fill out the entire comps field
+ * presumes trailing zero for comps
+ *
+ * So in the case of 256 comps (i.e., 8 compartment words):
+ * 0x0006-08-7ff3f
+ * 0x + Classification + Compartments + end of string
+ * 0[xX]hhh...
+ */
+
+static int
+htol(char *s, m_label_t *l)
+{
+ char *h = &s[2]; /* skip 0[xX] */
+ uchar_t *lp = (uchar_t *)&(((_mac_label_impl_t *)l)->_lclass);
+ size_t len = sizeof (_mac_label_impl_t) - 4;
+ int bytes;
+
+ /* unpack classification */
+ if (!unhex(&h, lp, 2)) {
+ goto error;
+ }
+ lp = (uchar_t *)&(((_mac_label_impl_t *)l)->_comps);
+ if (LCLASS(l) < LOW_CLASS ||
+ LCLASS(l) > HIGH_CLASS) {
+ goto error;
+ }
+ if (h[0] == '-' && h[3] == '-') {
+ uchar_t size;
+
+ /* length specified of internal text label */
+ h++; /* skip '-' */
+ if (!unhex(&h, &size, 1)) {
+ goto error;
+ }
+ size *= sizeof (uint32_t); /* words to bytes */
+ if (size > len) {
+ /*
+ * internal label greater than will fit in current
+ * binary.
+ */
+ goto error;
+ }
+ bzero(lp, len);
+ h++; /* skip '-' */
+ bytes = strlen(h)/2;
+ } else {
+ bytes = (strlen(h) + 1)/2;
+ }
+ if ((bytes > len) || !unhex(&h, lp, bytes)) {
+ goto error;
+ }
+ return (0);
+error:
+ errno = EINVAL;
+ return (-1);
+}
+
+static int
+convert_id(m_label_type_t t)
+{
+ switch (t) {
+ case MAC_LABEL:
+ return (SUN_MAC_ID);
+ case USER_CLEAR:
+ return (SUN_UCLR_ID);
+ default:
+ return (-1);
+ }
+}
+
+/*
+ * str_to_label -- parse a string into the requested label type.
+ *
+ * Entry s = string to parse.
+ * l = label to create or modify.
+ * t = label type (MAC_LABEL, USER_CLEAR).
+ * f = flags
+ * L_DEFAULT,
+ * L_MODIFY_EXISTING, use the existing label as a basis for
+ * the parse string.
+ * L_NO_CORRECTION, s must be correct and full by the
+ * label_encoding rules.
+ *
+ * Exit l = parsed label value.
+ * e = index into string of error.
+ * = M_BAD_STRING (-1) or could be zero, indicates entire string,
+ * e = M_BAD_LABEL (-3), problems with l
+ *
+ * Returns 0, success.
+ * -1, failure
+ * errno = ENOTSUP, the underlying label mechanism
+ * does not support label parsing.
+ * ENOMEM, unable to allocate memory for l.
+ * EINVAL, invalid argument, l != NULL or
+ * invalid label type for the underlying
+ * label mechanism.
+ */
+#define _M_GOOD_LABEL -1 /* gfi L_GOOD_LABEL */
+int
+str_to_label(const char *str, m_label_t **l, const m_label_type_t t, uint_t f,
+ int *e)
+{
+ char *s = (char *)str;
+ char *p;
+ labeld_data_t call;
+ labeld_data_t *callp = &call;
+ size_t bufsize = sizeof (labeld_data_t);
+ size_t datasize;
+ int err;
+ int id = convert_id(t);
+ boolean_t new = B_FALSE;
+
+ if (*l == NULL) {
+ if ((*l = m_label_alloc(t)) == NULL) {
+ return (-1);
+ }
+ if (id == -1) {
+ goto badlabel;
+ }
+ _LOW_LABEL(*l, id);
+ new = B_TRUE;
+ } else if (_MTYPE(*l, SUN_INVALID_ID) &&
+ ((f == L_NO_CORRECTION) || (f == L_DEFAULT))) {
+ _LOW_LABEL(*l, id);
+ new = B_TRUE;
+ } else if (!(_MTYPE(*l, SUN_MAC_ID) || _MTYPE(*l, SUN_CLR_ID))) {
+ goto badlabel;
+ }
+
+ if (new == B_FALSE && id == -1) {
+ goto badlabel;
+ }
+
+ /* get to the beginning of the string to parse */
+ while (isspace(*s)) {
+ s++;
+ }
+
+ /* accept a leading '[' and trailing ']' for old times sake */
+ if (*s == '[') {
+ s++;
+ while (isspace(*s)) {
+ s++;
+ }
+ }
+ p = s;
+ while (*p != '\0' && *p != ']') {
+ p++;
+ }
+
+ /* strip trailing spaces */
+ while (p != s && isspace(*(p-1))) {
+ --p;
+ }
+ *p = '\0'; /* end of string */
+
+ /* translate hex, admin_low and admin_high */
+ id = _MGETTYPE(*l);
+ if (IS_LOW(s)) {
+ _LOW_LABEL(*l, id);
+ return (0);
+ } else if (IS_HIGH(s)) {
+ _HIGH_LABEL(*l, id);
+ return (0);
+ } else if (IS_HEX(f, s)) {
+ int herr;
+
+ herr = htol(s, *l);
+ return (herr);
+ }
+#define slcall callp->param.acall.cargs.sl_arg
+#define slret callp->param.aret.rvals.sl_ret
+ /* now try label server */
+
+ datasize = CALL_SIZE(sl_call_t, strlen(str) + 1);
+ if (datasize > bufsize) {
+ if ((callp = malloc(datasize)) == NULL) {
+ return (-1);
+ }
+ bufsize = datasize;
+ }
+ callp->callop = STOL;
+ slcall.label = **l;
+ slcall.flags = f;
+ if (new)
+ slcall.flags |= L_NEW_LABEL;
+ (void) strcpy(slcall.string, str);
+ /*
+ * callp->reterr = L_GOOD_LABEL (-1) == OK;
+ * L_BAD_CLASSIFICATION (-2) == bad input
+ * classification: class
+ * L_BAD_LABEL (-3) == either sring or input label bad
+ * O'E == offset in string 0 == entire string.
+ */
+ if (__call_labeld(&callp, &bufsize, &datasize) == SUCCESS) {
+
+ err = callp->reterr;
+ if (callp != &call) {
+ /* free allocated buffer */
+ (void) free(callp);
+ }
+ switch (err) {
+ case _M_GOOD_LABEL: /* L_GOOD_LABEL */
+ **l = slret.label;
+ return (0);
+ case M_BAD_LABEL: /* L_BAD_CLASSIFICATION */
+ case M_BAD_STRING: /* L_BAD_LABEL */
+ default:
+ errno = EINVAL;
+ if (e != NULL)
+ *e = err;
+ return (-1);
+ }
+ }
+ switch (callp->reterr) {
+ case NOSERVER:
+ errno = ENOTSUP;
+ break;
+ default:
+ errno = EINVAL;
+ break;
+ }
+ return (-1);
+
+badlabel:
+ errno = EINVAL;
+ if (e != NULL)
+ *e = M_BAD_LABEL;
+ return (-1);
+}
+#undef slcall
+#undef slret
+
+/*
+ * m_label_alloc -- allocate a label structure
+ *
+ * Entry t = label type (MAC_LABEL, USER_CLEAR).
+ *
+ * Exit If error, NULL, errno set to ENOMEM
+ * Otherwise, pointer to m_label_t memory
+ */
+
+/* ARGUSED */
+m_label_t *
+m_label_alloc(const m_label_type_t t)
+{
+ m_label_t *l;
+
+ switch (t) {
+ case MAC_LABEL:
+ case USER_CLEAR:
+ if ((l = malloc(sizeof (_mac_label_impl_t))) == NULL) {
+ return (NULL);
+ }
+ _MSETTYPE(l, SUN_INVALID_ID);
+ break;
+ default:
+ errno = EINVAL;
+ return (NULL);
+ }
+ return (l);
+}
+
+/*
+ * m_label_dup -- make a duplicate copy of the given label.
+ *
+ * Entry l = label to duplicate.
+ *
+ * Exit d = duplicate copy of l.
+ *
+ * Returns 0, success
+ * -1, if error.
+ * errno = ENOTSUP, the underlying label mechanism
+ * does not support label duplication.
+ * ENOMEM, unable to allocate memory for d.
+ * EINVAL, invalid argument, l == NULL or
+ * invalid label type for the underlying
+ * label mechanism.
+ */
+
+int
+m_label_dup(m_label_t **d, const m_label_t *l)
+{
+ if (d == NULL || *d != NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+ if ((*d = malloc(sizeof (_mac_label_impl_t))) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ }
+
+ (void) memcpy(*d, l, sizeof (_mac_label_impl_t));
+ return (0);
+}
+
+/*
+ * m_label_free -- free label structure
+ *
+ * Entry l = label to free.
+ *
+ * Exit memory freed.
+ *
+ */
+
+void
+m_label_free(m_label_t *l)
+{
+ if (l)
+ free(l);
+}
diff --git a/usr/src/lib/libtsol/common/zone.c b/usr/src/lib/libtsol/common/zone.c
new file mode 100644
index 0000000000..6e4b2970a2
--- /dev/null
+++ b/usr/src/lib/libtsol/common/zone.c
@@ -0,0 +1,272 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+#include <strings.h>
+#include <zone.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/tsol/label_macro.h>
+
+/*
+ * Get label from zone name
+ */
+m_label_t *
+getzonelabelbyname(const char *zone)
+{
+ zoneid_t zoneid;
+
+ if ((zoneid = getzoneidbyname(zone)) == -1) {
+ errno = EINVAL;
+ return (NULL);
+ }
+ return (getzonelabelbyid(zoneid));
+}
+
+/*
+ * Get label from zone id
+ */
+m_label_t *
+getzonelabelbyid(zoneid_t zoneid)
+{
+ m_label_t *slabel;
+
+ if ((slabel = m_label_alloc(MAC_LABEL)) == NULL)
+ return (NULL);
+
+ if (zone_getattr(zoneid, ZONE_ATTR_SLBL, slabel,
+ sizeof (m_label_t)) < 0) {
+ m_label_free(slabel);
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ return (slabel);
+}
+
+/*
+ * Get zone id from label
+ */
+
+zoneid_t
+getzoneidbylabel(const m_label_t *label)
+{
+ m_label_t admin_low;
+ m_label_t admin_high;
+ zoneid_t zoneid;
+ zoneid_t *zids;
+ uint_t nzents;
+ uint_t nzents_saved;
+ int i;
+
+ bsllow(&admin_low);
+ bslhigh(&admin_high);
+
+ /* Check for admin_low or admin_high; both are global zone */
+ if (blequal(label, &admin_low) || blequal(label, &admin_high))
+ return (GLOBAL_ZONEID);
+
+ nzents = 0;
+ if (zone_list(NULL, &nzents) != 0)
+ return (-1);
+
+again:
+ if (nzents == 0) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ /*
+ * Add a small amount of padding here to avoid spinning in a tight loop
+ * if there's a process running somewhere that's creating lots of zones
+ * all at once.
+ */
+ nzents += 8;
+ if ((zids = malloc(nzents * sizeof (zoneid_t))) == NULL)
+ return (-1);
+ nzents_saved = nzents;
+
+ if (zone_list(zids, &nzents) != 0) {
+ free(zids);
+ return (-1);
+ }
+ if (nzents > nzents_saved) {
+ /* list changed, try again */
+ free(zids);
+ goto again;
+ }
+
+ for (i = 0; i < nzents; i++) {
+ m_label_t test_sl;
+
+ if (zids[i] == GLOBAL_ZONEID)
+ continue;
+
+ if (zone_getattr(zids[i], ZONE_ATTR_SLBL, &test_sl,
+ sizeof (m_label_t)) < 0)
+ continue; /* Badly configured zone info */
+
+ if (blequal(label, &test_sl) != 0) {
+ zoneid = zids[i];
+ free(zids);
+ return (zoneid);
+ }
+ }
+ free(zids);
+ errno = EINVAL;
+ return (-1);
+}
+
+/*
+ * Get zoneroot for a zoneid
+ */
+
+char *
+getzonerootbyid(zoneid_t zoneid)
+{
+ char zoneroot[MAXPATHLEN];
+
+ if (zone_getattr(zoneid, ZONE_ATTR_ROOT, zoneroot,
+ sizeof (zoneroot)) == -1) {
+ return (NULL);
+ }
+
+ return (strdup(zoneroot));
+}
+
+/*
+ * Get zoneroot for a zonename
+ */
+
+char *
+getzonerootbyname(const char *zone)
+{
+ zoneid_t zoneid;
+
+ if ((zoneid = getzoneidbyname(zone)) == -1)
+ return (NULL);
+ return (getzonerootbyid(zoneid));
+}
+
+/*
+ * Get zoneroot for a label
+ */
+
+char *
+getzonerootbylabel(const m_label_t *label)
+{
+ zoneid_t zoneid;
+
+ if ((zoneid = getzoneidbylabel(label)) == -1)
+ return (NULL);
+ return (getzonerootbyid(zoneid));
+}
+
+/*
+ * Get label of path relative to global zone
+ *
+ * This function must be called from the global zone
+ */
+
+m_label_t *
+getlabelbypath(const char *path)
+{
+ m_label_t *slabel;
+ zoneid_t *zids;
+ uint_t nzents;
+ uint_t nzents_saved;
+ int i;
+
+ if (getzoneid() != GLOBAL_ZONEID) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ nzents = 0;
+ if (zone_list(NULL, &nzents) != 0)
+ return (NULL);
+
+again:
+ /* Add a small amount of padding to avoid loops */
+ nzents += 8;
+ zids = malloc(nzents * sizeof (zoneid_t));
+ if (zids == NULL)
+ return (NULL);
+
+ nzents_saved = nzents;
+
+ if (zone_list(zids, &nzents) != 0) {
+ free(zids);
+ return (NULL);
+ }
+ if (nzents > nzents_saved) {
+ /* list changed, try again */
+ free(zids);
+ goto again;
+ }
+
+ slabel = m_label_alloc(MAC_LABEL);
+ if (slabel == NULL) {
+ free(zids);
+ return (NULL);
+ }
+
+ for (i = 0; i < nzents; i++) {
+ char zoneroot[MAXPATHLEN];
+ int zonerootlen;
+
+ if (zids[i] == GLOBAL_ZONEID)
+ continue;
+
+ if (zone_getattr(zids[i], ZONE_ATTR_ROOT, zoneroot,
+ sizeof (zoneroot)) == -1)
+ continue; /* Badly configured zone info */
+
+ /*
+ * Need to handle the case for the /dev directory which is
+ * parallel to the zone's root directory. So we back up
+ * 4 bytes - the strlen of "root".
+ */
+ if ((zonerootlen = strlen(zoneroot)) <= 4)
+ continue; /* Badly configured zone info */
+ if (strncmp(path, zoneroot, zonerootlen - 4) == 0) {
+ /*
+ * If we get a match, the file is in a labeled zone.
+ * Return the label of that zone.
+ */
+ if (zone_getattr(zids[i], ZONE_ATTR_SLBL, slabel,
+ sizeof (m_label_t)) < 0)
+ continue; /* Badly configured zone info */
+
+ free(zids);
+ return (slabel);
+ }
+ }
+ free(zids);
+ bsllow(slabel);
+ return (slabel);
+}
diff --git a/usr/src/lib/libtsol/i386/Makefile b/usr/src/lib/libtsol/i386/Makefile
new file mode 100644
index 0000000000..fb5e32504a
--- /dev/null
+++ b/usr/src/lib/libtsol/i386/Makefile
@@ -0,0 +1,30 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#/
+
+#ident "%Z%%M% %I% %E% SMI"
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
diff --git a/usr/src/lib/libtsol/sparc/Makefile b/usr/src/lib/libtsol/sparc/Makefile
new file mode 100644
index 0000000000..4addab0cae
--- /dev/null
+++ b/usr/src/lib/libtsol/sparc/Makefile
@@ -0,0 +1,30 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+include ../Makefile.com
+
+install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
diff --git a/usr/src/lib/libtsol/sparcv9/Makefile b/usr/src/lib/libtsol/sparcv9/Makefile
new file mode 100644
index 0000000000..69cf39010b
--- /dev/null
+++ b/usr/src/lib/libtsol/sparcv9/Makefile
@@ -0,0 +1,31 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#ident "%Z%%M% %I% %E% SMI"
+
+include ../Makefile.com
+include ../../Makefile.lib.64
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
diff --git a/usr/src/lib/libtsol/spec/Makefile b/usr/src/lib/libtsol/spec/Makefile
new file mode 100644
index 0000000000..835bbc66f1
--- /dev/null
+++ b/usr/src/lib/libtsol/spec/Makefile
@@ -0,0 +1,28 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include $(SRC)/lib/Makefile.spec.arch
diff --git a/usr/src/lib/libtsol/spec/Makefile.targ b/usr/src/lib/libtsol/spec/Makefile.targ
new file mode 100644
index 0000000000..e76d79a49d
--- /dev/null
+++ b/usr/src/lib/libtsol/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 (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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+LIBRARY = libtsol.a
+VERS = .2
+OBJECTS = obsolete.o \
+ private.o \
+ tsol.o
+SPECCPP = -I../../common
diff --git a/usr/src/lib/libtsol/spec/amd64/Makefile b/usr/src/lib/libtsol/spec/amd64/Makefile
new file mode 100644
index 0000000000..03d9b122a2
--- /dev/null
+++ b/usr/src/lib/libtsol/spec/amd64/Makefile
@@ -0,0 +1,33 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+include $(SRC)/lib/Makefile.spec
diff --git a/usr/src/lib/libtsol/spec/i386/Makefile b/usr/src/lib/libtsol/spec/i386/Makefile
new file mode 100644
index 0000000000..7aab1a07a8
--- /dev/null
+++ b/usr/src/lib/libtsol/spec/i386/Makefile
@@ -0,0 +1,32 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.spec
diff --git a/usr/src/lib/libtsol/spec/obsolete.spec b/usr/src/lib/libtsol/spec/obsolete.spec
new file mode 100644
index 0000000000..ccebc2f8b9
--- /dev/null
+++ b/usr/src/lib/libtsol/spec/obsolete.spec
@@ -0,0 +1,122 @@
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# Obsolete interfaces to be removed from a future release.
+# Retained to aid 3rd party initial porting from TS8.
+#
+# 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
+# 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"
+#
+
+function bcleartoh_r
+include <tsol/label.h>
+declaration char *bcleartoh_r(const bclear_t *clearance, char *hex);
+version SUNWprivate_1.1
+end
+
+function bcleartoh
+include <tsol/label.h>
+declaration char *bcleartoh(const bclear_t *clearance);
+version SUNWprivate_1.1
+end
+
+function bltocolor
+include <tsol/label.h>
+declaration char *bltocolor(const blevel_t *label);
+version SUNWprivate_1.1
+end
+
+function bltocolor_r
+include <tsol/label.h>
+declaration char *bltocolor_r(const blevel_t *label, int size, \
+ char *color_name);
+version SUNWprivate_1.1
+end
+
+function bsltoh
+include <tsol/label.h>
+declaration char *bsltoh(const bslabel_t *label);
+version SUNWprivate_1.1
+end
+
+function bsltoh_r
+include <tsol/label.h>
+declaration char *bsltoh_r(const bslabel_t *label, char *hex);
+version SUNWprivate_1.1
+end
+
+function bsltos
+include <tsol/label.h>
+declaration ssize_t bsltos(const bslabel_t *label, char **string, \
+ size_t str_len, int flags);
+version SUNWprivate_1.1
+end
+
+function h_alloc
+include <tsol/label.h>
+declaration char *h_alloc(unsigned char id);
+version SUNWprivate_1.1
+end
+
+function h_free
+include <tsol/label.h>
+declaration void h_free(char *hex);
+version SUNWprivate_1.1
+end
+
+function htobclear
+include <tsol/label.h>
+declaration int htobclear(const char *s, bclear_t *clearance);
+version SUNWprivate_1.1
+end
+
+function htobsl
+include <tsol/label.h>
+declaration int htobsl(const char *s, bslabel_t *label);
+version SUNWprivate_1.1
+end
+
+function sbcleartos
+include <tsol/label.h>
+declaration char *sbcleartos(const bclear_t *clearance, int len);
+version SUNWprivate_1.1
+end
+
+function sbsltos
+include <tsol/label.h>
+declaration char *sbsltos(const bslabel_t *label, int len);
+version SUNWprivate_1.1
+end
+
+function stobclear
+include <tsol/label.h>
+declaration int stobclear(const char *string, bclear_t *clearance, \
+ int flags, int *error);
+version SUNWprivate_1.1
+end
+
+function stobsl
+include <tsol/label.h>
+declaration int stobsl(const char *string, bslabel_t *label, int flags, \
+ int *error);
+version SUNWprivate_1.1
+end
diff --git a/usr/src/lib/libtsol/spec/private.spec b/usr/src/lib/libtsol/spec/private.spec
new file mode 100644
index 0000000000..c5e66ea7b6
--- /dev/null
+++ b/usr/src/lib/libtsol/spec/private.spec
@@ -0,0 +1,239 @@
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# Project Private to the Trusted eXtensions project.
+# Not for public consumption or to be documented.
+#
+# 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
+# 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"
+#
+
+function bclearhigh
+include <tsol/label.h>
+declaration void bclearhigh(bclear_t *clearance);
+version SUNWprivate_1.1
+end
+
+function bclearlow
+include <tsol/label.h>
+declaration void bclearlow(bclear_t *clearance);
+version SUNWprivate_1.1
+end
+
+function bcleartos
+include <tsol/label.h>
+declaration ssize_t bcleartos(const bclear_t *clearance, char **string, \
+ size_t str_len, int flags);
+version SUNWprivate_1.1
+end
+
+function bclearundef
+include <tsol/label.h>
+declaration void bclearundef(bclear_t *clearance);
+version SUNWprivate_1.1
+end
+
+function bclearvalid
+include <tsol/label.h>
+declaration int bclearvalid(const bclear_t *clearance);
+version SUNWprivate_1.1
+end
+
+function bclearcvtfull
+include <tsol/label.h>
+declaration int bclearcvtfull(const bclear_t *clearance, \
+ const blrange_t *bounds, int flags, char **string, \
+ char **long_words[], char **short_words[], \
+ char *display[], int *first_compartment, \
+ int *display_size);
+version SUNWprivate_1.1
+end
+
+function bclearcvt
+include <tsol/label.h>
+declaration int bclearcvt(const bclear_t *clearance, int flags, \
+ char **string, char *display[]);
+version SUNWprivate_1.1
+end
+
+function blinrange
+include <tsol/label.h>
+declaration int blinrange(const blevel_t *label, const blrange_t *range);
+version SUNWprivate_1.1
+end
+
+function blinset
+include <tsol/label.h>
+declaration int blinset(const bslabel_t *label, const set_id *id);
+version SUNWprivate_1.1
+end
+
+function blmaximum
+include <tsol/label.h>
+declaration void blmaximum(blevel_t *label1, const blevel_t *label2);
+version SUNWprivate_1.1
+end
+
+function blminimum
+include <tsol/label.h>
+declaration void blminimum(blevel_t *label1, const blevel_t *label2);
+version SUNWprivate_1.1
+end
+
+function bltype
+include <tsol/label.h>
+declaration int bltype(const void *label, uint8_t type);
+version SUNWprivate_1.1
+end
+
+function bslcvtfull
+include <tsol/label.h>
+declaration int bslcvtfull(const bslabel_t *label,
+ const blrange_t *bounds, \
+ int flags, char **string, char **long_words[], \
+ char **short_words[], char *display[], \
+ int *first_compartment, int *display_size);
+version SUNWprivate_1.1
+end
+
+function bslcvt
+include <tsol/label.h>
+declaration int bslcvt(const bslabel_t *label, int flags, char **string, \
+ char *display[]);
+version SUNWprivate_1.1
+end
+
+function bslhigh
+include <tsol/label.h>
+declaration void bslhigh(bslabel_t *label);
+version SUNWprivate_1.1
+end
+
+function bsllow
+include <tsol/label.h>
+declaration void bsllow(bslabel_t *label);
+version SUNWprivate_1.1
+end
+
+function bslundef
+include <tsol/label.h>
+declaration void bslundef(bslabel_t *label);
+version SUNWprivate_1.1
+end
+
+function bslvalid
+include <tsol/label.h>
+declaration int bslvalid(const bslabel_t *label);
+version SUNWprivate_1.1
+end
+
+function labelinfo
+include <tsol/label.h>
+declaration int labelinfo(struct label_info *info);
+version SUNWprivate_1.1
+end
+
+function labelfields
+include <tsol/label.h>
+declaration int labelfields(struct name_fields *fields);
+version SUNWprivate_1.1
+end
+
+function labelvers
+include <tsol/label.h>
+declaration ssize_t labelvers(char **version, int len);
+version SUNWprivate_1.1
+end
+
+function getpathbylabel
+include <tsol/label.h>
+declaration char *getpathbylabel(const char *path_name, \
+ char *resolved_path, size_t bufsize, const bslabel_t *sl);
+version SUNWprivate_1.1
+end
+
+function getlabelbypath
+include <tsol/label.h>
+declaration m_label_t *getlabelbypath(char *path);
+version SUNWprivate_1.1
+end
+
+function blabel_alloc
+include <tsol/label.h>
+declaration blevel_t *blabel_alloc(void);
+version SUNWprivate_1.1
+end
+
+function blabel_free
+include <tsol/label.h>
+declaration void blabel_free(blevel_t *label_p);
+version SUNWprivate_1.1
+end
+
+function blabel_size
+include <tsol/label.h>
+declaration size_t blabel_size(void);
+version SUNWprivate_1.1
+end
+
+function setbltype
+include <tsol/label.h>
+declaration void setbltype(void *label, uint8_t type);
+version SUNWprivate_1.1
+end
+
+function bisinvalid
+include <tsol/label.h>
+declaration boolean_t bisinvalid(const void *label);
+version SUNWprivate_1.1
+end
+
+function set_effective_priv
+include <tsol/label.h>
+declaration int set_effective_priv(priv_op_t op, int num_priv, ...);
+version SUNWprivate_1.1
+end
+
+function set_inheritable_priv
+include <tsol/label.h>
+declaration int set_inheritable_priv(priv_op_t op, int num_priv, ...);
+version SUNWprivate_1.1
+end
+
+function set_permitted_priv
+include <tsol/label.h>
+declaration int set_permitted_priv(priv_op_t op, int num_priv, ...);
+version SUNWprivate_1.1
+end
+
+function userdefs
+include <tsol/label.h>
+declaration int userdefs(bslabel_t *sl, bclear_t *clear);
+version SUNWprivate_1.1
+end
+
+function zonecopy
+include <tsol/label.h>
+declaration int zonecopy(bslabel_t *src_win_sl, char *remote_dir, \
+ char *filename, char *local_dir, int transfer_mode);
+version SUNWprivate_1.1
+end
diff --git a/usr/src/lib/libtsol/spec/sparc/Makefile b/usr/src/lib/libtsol/spec/sparc/Makefile
new file mode 100644
index 0000000000..7aab1a07a8
--- /dev/null
+++ b/usr/src/lib/libtsol/spec/sparc/Makefile
@@ -0,0 +1,32 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.spec
diff --git a/usr/src/lib/libtsol/spec/sparcv9/Makefile b/usr/src/lib/libtsol/spec/sparcv9/Makefile
new file mode 100644
index 0000000000..03d9b122a2
--- /dev/null
+++ b/usr/src/lib/libtsol/spec/sparcv9/Makefile
@@ -0,0 +1,33 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+include $(SRC)/lib/Makefile.lib
+include $(SRC)/lib/Makefile.lib.64
+include $(SRC)/lib/Makefile.spec
diff --git a/usr/src/lib/libtsol/spec/tsol.spec b/usr/src/lib/libtsol/spec/tsol.spec
new file mode 100644
index 0000000000..089f5eb2ec
--- /dev/null
+++ b/usr/src/lib/libtsol/spec/tsol.spec
@@ -0,0 +1,143 @@
+#
+# Copyright 2006 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 (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"
+#
+
+function label_to_str
+include <tsol/label.h>
+declaration int label_to_str(const m_label_t *label, char **string, \
+ const m_label_str_t conversion_type, uint_t flags);
+version SUNW_2.1
+end
+
+function m_label_alloc
+include <tsol/label.h>
+declaration m_label_t m_label_dup(const m_label_type_t *type);
+version SUNW_2.1
+end
+
+function m_label_dup
+include <tsol/label.h>
+declaration int m_label_dup(m_label_t **dst, const m_label_t *src);
+version SUNW_2.1
+end
+
+function m_label_free
+include <tsol/label.h>
+declaration void m_label_free(m_label_t *label);
+version SUNW_2.1
+end
+
+function str_to_label
+include <tsol/label.h>
+declaration int str_to_label(const char *str, m_label_t **label, \
+ const m_label_type_t type, unit_t flags, int *error);
+version SUNW_2.1
+end
+
+function bldominates
+include <tsol/label.h>
+declaration int bldominates(const m_label_t *label1, \
+ const m_label_t *label2);
+version SUNW_2.1
+end
+
+function blequal
+include <tsol/label.h>
+declaration int blequal(const m_label_t *label1, const m_label_t *label2);
+version SUNW_2.1
+end
+
+function blstrictdom
+include <tsol/label.h>
+declaration int blstrictdom(const m_label_t *label1, \
+ const m_label_t *label2);
+version SUNW_2.1
+end
+
+function getlabel
+include <tsol/label.h>
+declaration int getlabel(const char *path, m_label_t *label);
+version SUNW_2.1
+end
+
+function fgetlabel
+include <tsol/label.h>
+declaration int fgetlabel(int fd, m_label_t *label);
+version SUNW_2.1
+end
+
+function getplabel
+include <tsol/label.h>
+declaration int getplabel(m_label_t *label_p);
+version SUNW_2.1
+end
+
+function getzoneidbylabel
+include <tsol/label.h>
+declaration zoneid_t getzoneidbylabel(const m_label_t *label);
+version SUNW_2.1
+end
+
+function getzonelabelbyid
+include <tsol/label.h>
+declaration m_label_t *getzonelabelbyid(zoneid_t zoneid);
+version SUNW_2.1
+end
+
+function getzonelabelbyname
+include <tsol/label.h>
+declaration m_label_t *getzonelabelbyname(char *zone);
+version SUNW_2.1
+end
+
+function getzonerootbyid
+include <tsol/label.h>
+declaration char *getzonerootbyid(zoneid_t zoneid);
+version SUNW_2.1
+end
+
+function getzonerootbylabel
+include <tsol/label.h>
+declaration char *getzonerootbylabel(m_label_t *label);
+version SUNW_2.1
+end
+
+function getzonerootbyname
+include <tsol/label.h>
+declaration char *getzonerootbyname(char *zone);
+version SUNW_2.1
+end
+
+function setflabel
+include <tsol/label.h>
+declaration int setflabel(const char *path, m_label_t *label);
+version SUNW_2.1
+end
+
+function getuserrange
+include <tsol/label.h>
+declaration m_range_t *getuserrange(const char *username);
+version SUNW_2.1
+end
diff --git a/usr/src/lib/libtsol/spec/versions b/usr/src/lib/libtsol/spec/versions
new file mode 100644
index 0000000000..40f1cccb72
--- /dev/null
+++ b/usr/src/lib/libtsol/spec/versions
@@ -0,0 +1,45 @@
+#
+# 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
+# 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 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# vers file for libtsol
+#
+
+sparc {
+ SUNW_2.1;
+ SUNWprivate_1.1;
+}
+i386 {
+ SUNW_2.1;
+ SUNWprivate_1.1;
+}
+sparcv9 {
+ SUNW_2.1;
+ SUNWprivate_1.1;
+}
+amd64 {
+ SUNW_2.1;
+ SUNWprivate_1.1;
+}
diff --git a/usr/src/lib/libzonecfg/common/libzonecfg.c b/usr/src/lib/libzonecfg/common/libzonecfg.c
index 36862ce976..cede45643a 100644
--- a/usr/src/lib/libzonecfg/common/libzonecfg.c
+++ b/usr/src/lib/libzonecfg/common/libzonecfg.c
@@ -49,8 +49,6 @@
#include <arpa/inet.h>
#include <netdb.h>
-#include <priv.h>
-
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
@@ -125,8 +123,8 @@
#define ATTACH_FORCED "SUNWattached.xml"
#define PKG_PATH "/var/sadm/pkg"
#define CONTENTS_FILE "/var/sadm/install/contents"
-#define ALL_ZONES "SUNW_PKG_ALLZONES=true\n"
-#define THIS_ZONE "SUNW_PKG_THISZONE=true\n"
+#define SUNW_PKG_ALL_ZONES "SUNW_PKG_ALLZONES=true\n"
+#define SUNW_PKG_THIS_ZONE "SUNW_PKG_THISZONE=true\n"
#define VERSION "VERSION="
#define PATCHLIST "PATCHLIST="
#define PATCHINFO "PATCH_INFO_"
@@ -3417,7 +3415,9 @@ static const char *default_priv_list[] = {
PRIV_IPC_DAC_READ,
PRIV_IPC_DAC_WRITE,
PRIV_IPC_OWNER,
+ PRIV_NET_BINDMLP,
PRIV_NET_ICMPACCESS,
+ PRIV_NET_MAC_AWARE,
PRIV_NET_PRIVADDR,
PRIV_PROC_CHROOT,
PRIV_SYS_AUDIT,
@@ -5294,10 +5294,10 @@ get_pkginfo(char *pkginfo, struct zone_pkginfo *infop)
len = strlen(infop->zpi_version);
*(infop->zpi_version + len - 1) = 0;
- } else if (strcmp(buf, ALL_ZONES) == 0) {
+ } else if (strcmp(buf, SUNW_PKG_ALL_ZONES) == 0) {
infop->zpi_all_zones = B_TRUE;
- } else if (strcmp(buf, THIS_ZONE) == 0) {
+ } else if (strcmp(buf, SUNW_PKG_THIS_ZONE) == 0) {
infop->zpi_this_zone = B_TRUE;
} else if (strncmp(buf, PATCHINFO, sizeof (PATCHINFO) - 1)
diff --git a/usr/src/lib/nsswitch/files/Makefile.com b/usr/src/lib/nsswitch/files/Makefile.com
index e71a2db442..f6105144d7 100644
--- a/usr/src/lib/nsswitch/files/Makefile.com
+++ b/usr/src/lib/nsswitch/files/Makefile.com
@@ -2,9 +2,8 @@
# 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.
+# 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
# or http://www.opensolaris.org/os/licensing.
@@ -18,6 +17,8 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
+
+
#
#
# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
@@ -49,7 +50,9 @@ OBJECTS = bootparams_getbyname.o \
getexecattr.o \
getuserattr.o \
getauuser.o \
- netmasks.o
+ netmasks.o \
+ tsol_getrhent.o \
+ tsol_gettpent.o
# include common nsswitch library definitions.
include ../../Makefile.com
diff --git a/usr/src/lib/nsswitch/files/common/mapfile-vers b/usr/src/lib/nsswitch/files/common/mapfile-vers
index a4c6b1b67f..7210caf3d7 100644
--- a/usr/src/lib/nsswitch/files/common/mapfile-vers
+++ b/usr/src/lib/nsswitch/files/common/mapfile-vers
@@ -1,15 +1,14 @@
#
#ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 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.
+# 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
# or http://www.opensolaris.org/os/licensing.
@@ -59,6 +58,8 @@ SUNWprivate_1.1 {
_nss_files_services_constr;
_nss_files_shadow_constr;
_nss_files_user_attr_constr;
+ _nss_files_tnrhdb_constr;
+ _nss_files_tnrhtp_constr;
local:
*;
};
diff --git a/usr/src/lib/nsswitch/files/common/tsol_getrhent.c b/usr/src/lib/nsswitch/files/common/tsol_getrhent.c
new file mode 100644
index 0000000000..f41f606034
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/tsol_getrhent.c
@@ -0,0 +1,73 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "files_common.h"
+#include <string.h>
+#include <libtsnet.h>
+
+/*
+ * files/tsol_getrhent.c --
+ * "files" backend for nsswitch "tnrhdb" database
+ */
+static int
+check_addr(nss_XbyY_args_t *args)
+{
+ tsol_rhstr_t *rhstrp = (tsol_rhstr_t *)args->returnval;
+
+ if ((args->key.hostaddr.type == rhstrp->family) &&
+ (strcmp(args->key.hostaddr.addr, rhstrp->address) == 0))
+ return (1);
+
+ return (0);
+}
+
+static nss_status_t
+getbyaddr(files_backend_ptr_t be, void *a)
+{
+ nss_XbyY_args_t *argp = a;
+
+ return (_nss_files_XY_all(be, argp, 1,
+ argp->key.hostaddr.addr, check_addr));
+}
+
+static files_backend_op_t tsol_rh_ops[] = {
+ _nss_files_destr,
+ _nss_files_endent,
+ _nss_files_setent,
+ _nss_files_getent_netdb,
+ getbyaddr
+};
+
+/* ARGSUSED */
+nss_backend_t *
+_nss_files_tnrhdb_constr(const char *dummy1, const char *dummy2,
+ const char *dummy3)
+{
+ return (_nss_files_constr(tsol_rh_ops,
+ sizeof (tsol_rh_ops) / sizeof (tsol_rh_ops[0]), TNRHDB_PATH,
+ NSS_LINELEN_TSOL_RH, NULL));
+}
diff --git a/usr/src/lib/nsswitch/files/common/tsol_gettpent.c b/usr/src/lib/nsswitch/files/common/tsol_gettpent.c
new file mode 100644
index 0000000000..ae5e9ca2be
--- /dev/null
+++ b/usr/src/lib/nsswitch/files/common/tsol_gettpent.c
@@ -0,0 +1,75 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "files_common.h"
+#include <sys/tsol/tndb.h>
+#include <string.h>
+
+/*
+ * files/tsol_gettpent.c --
+ * "files" backend for nsswitch "tnrhtp" database
+ */
+static int
+check_name(nss_XbyY_args_t *args)
+{
+ tsol_tpstr_t *tpstrp = (tsol_tpstr_t *)args->returnval;
+ const char *name = args->key.name;
+
+ if (strcmp(tpstrp->template, name) == 0)
+ return (1);
+
+ return (0);
+}
+
+static nss_status_t
+getbyname(be, a)
+ files_backend_ptr_t be;
+ void *a;
+{
+ nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a;
+
+ return (_nss_files_XY_all(be, argp, 1, argp->key.name, check_name));
+}
+
+static files_backend_op_t tsol_tp_ops[] = {
+ _nss_files_destr,
+ _nss_files_endent,
+ _nss_files_setent,
+ _nss_files_getent_netdb,
+ getbyname
+};
+
+nss_backend_t *
+_nss_files_tnrhtp_constr(dummy1, dummy2, dummy3)
+ const char *dummy1, *dummy2, *dummy3;
+{
+ return (_nss_files_constr(tsol_tp_ops,
+ sizeof (tsol_tp_ops) / sizeof (tsol_tp_ops[0]),
+ "/etc/security/tsol/tnrhtp",
+ NSS_LINELEN_TSOL_TP,
+ NULL));
+}
diff --git a/usr/src/lib/nsswitch/ldap/Makefile.com b/usr/src/lib/nsswitch/ldap/Makefile.com
index 03d14aa6a7..031dd04f46 100644
--- a/usr/src/lib/nsswitch/ldap/Makefile.com
+++ b/usr/src/lib/nsswitch/ldap/Makefile.com
@@ -2,9 +2,8 @@
# 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.
+# 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
# or http://www.opensolaris.org/os/licensing.
@@ -18,12 +17,14 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
+
+
#
#
#ident "%Z%%M% %I% %E% SMI"
#
-# Copyright (c) 1999-2001 by Sun Microsystems, Inc.
-# All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
#
# lib/nsswitch/ldap/Makefile.com
@@ -51,6 +52,8 @@ OBJECTS = getauthattr.o \
getservent.o \
getspent.o \
getuserattr.o \
+ tsol_getrhent.o \
+ tsol_gettpent.o \
ldap_common.o \
ldap_utils.o
diff --git a/usr/src/lib/nsswitch/ldap/common/ldap_common.c b/usr/src/lib/nsswitch/ldap/common/ldap_common.c
index 06acfe2e9b..9d961d9d1d 100644
--- a/usr/src/lib/nsswitch/ldap/common/ldap_common.c
+++ b/usr/src/lib/nsswitch/ldap/common/ldap_common.c
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -55,6 +54,9 @@
#define _F_GETSPENT "(objectclass=shadowAccount)"
#define _F_GETUSERNAME "(objectClass=SolarisUserAttr)"
#define _F_GETPROJENT "(objectClass=SolarisProject)"
+#define _F_GETTNRHDB "(objectClass=ipTnetHost)"
+#define _F_GETTNRHTP "(&(objectClass=ipTnetTemplate)"\
+ "(SolarisAttrKeyValue=*))"
#define _F_GETENT_SSD "(%s)"
static struct gettablefilter {
@@ -77,6 +79,8 @@ static struct gettablefilter {
{(char *)_USERATTR, (char *)_F_GETUSERNAME},
{(char *)_PROJECT, (char *)_F_GETPROJENT},
{(char *)_PRINTERS, (char *)_F_GETPRINTERENT},
+ {(char *)_TNRHDB, (char *)_F_GETTNRHDB},
+ {(char *)_TNRHTP, (char *)_F_GETTNRHTP},
{(char *)NULL, (char *)NULL}
};
diff --git a/usr/src/lib/nsswitch/ldap/common/ldap_common.h b/usr/src/lib/nsswitch/ldap/common/ldap_common.h
index 292abfba54..23d5e2b1ae 100644
--- a/usr/src/lib/nsswitch/ldap/common/ldap_common.h
+++ b/usr/src/lib/nsswitch/ldap/common/ldap_common.h
@@ -2,9 +2,8 @@
* 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.
+ * 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
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -68,6 +67,8 @@ extern "C" {
#define _SERVICES "services"
#define _SHADOW "shadow"
#define _USERATTR "user_attr"
+#define _TNRHDB "tnrhdb"
+#define _TNRHTP "tnrhtp"
#define NSS_STR_PARSE_NO_ADDR (NSS_STR_PARSE_ERANGE + 100)
diff --git a/usr/src/lib/nsswitch/ldap/common/mapfile-vers b/usr/src/lib/nsswitch/ldap/common/mapfile-vers
index 9daed00900..ae31444846 100644
--- a/usr/src/lib/nsswitch/ldap/common/mapfile-vers
+++ b/usr/src/lib/nsswitch/ldap/common/mapfile-vers
@@ -1,15 +1,14 @@
#
#ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 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.
+# 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
# or http://www.opensolaris.org/os/licensing.
@@ -61,6 +60,8 @@ SUNWprivate_1.1 {
_nss_ldap_shadow_constr;
_nss_ldap_publickey_constr;
_nss_ldap_user_attr_constr;
+ _nss_ldap_tnrhdb_constr;
+ _nss_ldap_tnrhtp_constr;
local:
*;
};
diff --git a/usr/src/lib/nsswitch/ldap/common/tsol_getrhent.c b/usr/src/lib/nsswitch/ldap/common/tsol_getrhent.c
new file mode 100644
index 0000000000..90a21988a2
--- /dev/null
+++ b/usr/src/lib/nsswitch/ldap/common/tsol_getrhent.c
@@ -0,0 +1,183 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <netdb.h>
+#include "ldap_common.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/tsol/tndb.h>
+
+/* tnrhdb attributes filters */
+#define _TNRHDB_ADDR "ipTnetNumber"
+#define _TNRHDB_TNAME "ipTnetTemplateName"
+#define _F_GETTNDBBYADDR "(&(objectClass=ipTnetHost)(ipTnetNumber=%s))"
+#define _F_GETTNDBBYADDR_SSD "(&(%%s)(ipTnetNumber=%s))"
+
+static const char *tnrhdb_attrs[] = {
+ _TNRHDB_ADDR,
+ _TNRHDB_TNAME,
+ NULL
+};
+
+static int
+_nss_ldap_tnrhdb2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp)
+{
+ int i, nss_result;
+ int len = 0;
+ int buflen = 0;
+ char *buffer = NULL;
+ char *ceiling = NULL;
+ ns_ldap_attr_t *attrptr;
+ ns_ldap_result_t *result = be->result;
+ tsol_rhstr_t *rhstrp;
+
+ buffer = argp->buf.buffer;
+ buflen = argp->buf.buflen;
+ if (argp->buf.result == NULL) {
+ nss_result = NSS_STR_PARSE_ERANGE;
+ goto result_tnrhdb2ent;
+ }
+ rhstrp = (tsol_rhstr_t *)(argp->buf.result);
+ rhstrp->family = 0;
+ rhstrp->address = rhstrp->template = NULL;
+ ceiling = buffer + buflen;
+ (void) memset(argp->buf.buffer, 0, buflen);
+ attrptr = getattr(result, 0);
+ if (attrptr == NULL) {
+ nss_result = NSS_STR_PARSE_PARSE;
+ goto result_tnrhdb2ent;
+ }
+ for (i = 0; i < result->entry->attr_count; i++) {
+ attrptr = getattr(result, i);
+ if (attrptr == NULL) {
+ nss_result = NSS_STR_PARSE_PARSE;
+ goto result_tnrhdb2ent;
+ }
+ if (strcasecmp(attrptr->attrname, _TNRHDB_ADDR) == 0) {
+ len = strlen(attrptr->attrvalue[0]);
+ if (len < 1 || (attrptr->attrvalue[0] == '\0')) {
+ nss_result = NSS_STR_PARSE_PARSE;
+ goto result_tnrhdb2ent;
+ }
+ rhstrp->address = buffer;
+ buffer += len + 1;
+ if (buffer >= ceiling) {
+ nss_result = (int)NSS_STR_PARSE_ERANGE;
+ goto result_tnrhdb2ent;
+ }
+ (void) strcpy(rhstrp->address, attrptr->attrvalue[0]);
+ continue;
+ }
+ if (strcasecmp(attrptr->attrname, _TNRHDB_TNAME) == 0) {
+ len = strlen(attrptr->attrvalue[0]);
+ if (len < 1 || (attrptr->attrvalue[0] == '\0')) {
+ nss_result = NSS_STR_PARSE_PARSE;
+ goto result_tnrhdb2ent;
+ }
+ rhstrp->template = buffer;
+ buffer += len + 1;
+ if (buffer >= ceiling) {
+ nss_result = (int)NSS_STR_PARSE_ERANGE;
+ goto result_tnrhdb2ent;
+ }
+ (void) strcpy(rhstrp->template, attrptr->attrvalue[0]);
+ continue;
+ }
+ }
+ nss_result = NSS_STR_PARSE_SUCCESS;
+
+#ifdef DEBUG
+ (void) printf("\n[tsol_getrhent.c: _nss_ldap_tnrhdb2ent]\n");
+ (void) printf(" address: [%s]\n",
+ rhstrp->address ? rhstrp->address : "NULL");
+ (void) printf("template: [%s]\n",
+ rhstrp->template ? rhstrp->template : "NULL");
+#endif /* DEBUG */
+
+result_tnrhdb2ent:
+ (void) __ns_ldap_freeResult(&be->result);
+ return (nss_result);
+}
+
+
+static nss_status_t
+getbyaddr(ldap_backend_ptr be, void *a)
+{
+ char searchfilter[SEARCHFILTERLEN];
+ char userdata[SEARCHFILTERLEN];
+ nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a;
+ struct in_addr addr;
+ char buf[18];
+ extern char *inet_ntoa_r();
+
+#ifdef DEBUG
+ (void) fprintf(stdout, "\n[tsol_getrhent.c: getbyaddr]\n");
+#endif /* DEBUG */
+
+ (void) memcpy(&addr, argp->key.hostaddr.addr, sizeof (addr));
+ (void) inet_ntoa_r(addr, buf);
+
+ if (snprintf(searchfilter, sizeof (searchfilter), _F_GETTNDBBYADDR,
+ buf) < 0)
+ return ((nss_status_t)NSS_NOTFOUND);
+
+ if (snprintf(userdata, sizeof (userdata), _F_GETTNDBBYADDR_SSD,
+ buf) < 0)
+ return ((nss_status_t)NSS_NOTFOUND);
+
+ return (_nss_ldap_lookup(be, argp, _TNRHDB, searchfilter, NULL,
+ _merge_SSD_filter, userdata));
+}
+
+
+static ldap_backend_op_t tnrhdb_ops[] = {
+ _nss_ldap_destr,
+ _nss_ldap_endent,
+ _nss_ldap_setent,
+ _nss_ldap_getent,
+ getbyaddr
+};
+
+
+/* ARGSUSED */
+nss_backend_t *
+_nss_ldap_tnrhdb_constr(const char *dummy1,
+ const char *dummy2,
+ const char *dummy3,
+ const char *dummy4,
+ const char *dummy5)
+{
+#ifdef DEBUG
+ (void) fprintf(stdout,
+ "\n[tsol_getrhent.c: _nss_ldap_tnrhdb_constr]\n");
+#endif
+ return ((nss_backend_t *)_nss_ldap_constr(tnrhdb_ops,
+ sizeof (tnrhdb_ops)/sizeof (tnrhdb_ops[0]), _TNRHDB,
+ tnrhdb_attrs, _nss_ldap_tnrhdb2ent));
+}
diff --git a/usr/src/lib/nsswitch/ldap/common/tsol_gettpent.c b/usr/src/lib/nsswitch/ldap/common/tsol_gettpent.c
new file mode 100644
index 0000000000..b7f5423f6f
--- /dev/null
+++ b/usr/src/lib/nsswitch/ldap/common/tsol_gettpent.c
@@ -0,0 +1,182 @@
+/*
+ * 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
+ * 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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include "ldap_common.h"
+#include <sys/tsol/tndb.h>
+
+/* tnrhtp attributes filters */
+#define _TNRHTP_NAME "ipTnetTemplateName"
+#define _TNRHTP_ATTRS "SolarisAttrKeyValue"
+#define _F_GETTNTPBYNAME "(&(objectClass=ipTnetTemplate)"\
+ "(ipTnetTemplateName=%s))"
+#define _F_GETTNTPBYNAME_SSD "(&(%%s)(ipTnetTemplateName=%s))"
+
+static const char *tnrhtp_attrs[] = {
+ _TNRHTP_NAME,
+ _TNRHTP_ATTRS,
+ NULL
+};
+
+static int
+_nss_ldap_tnrhtp2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp)
+{
+ int i, nss_result;
+ int len = 0;
+ int buflen = 0;
+ char *buffer = NULL;
+ char *ceiling = NULL;
+ ns_ldap_attr_t *attrptr;
+ ns_ldap_result_t *result = be->result;
+ tsol_tpstr_t *tpstrp;
+
+ buffer = argp->buf.buffer;
+ buflen = argp->buf.buflen;
+ if (argp->buf.result == NULL) {
+ nss_result = (int)NSS_STR_PARSE_ERANGE;
+ goto result_tnrhtp2ent;
+ }
+ tpstrp = (tsol_tpstr_t *)(argp->buf.result);
+ tpstrp->template = tpstrp->attrs = NULL;
+ ceiling = buffer + buflen;
+ (void) memset(argp->buf.buffer, 0, buflen);
+ attrptr = getattr(result, 0);
+ if (attrptr == NULL) {
+ nss_result = NSS_STR_PARSE_PARSE;
+ goto result_tnrhtp2ent;
+ }
+ for (i = 0; i < result->entry->attr_count; i++) {
+ attrptr = getattr(result, i);
+ if (attrptr == NULL) {
+ nss_result = (int)NSS_STR_PARSE_PARSE;
+ goto result_tnrhtp2ent;
+ }
+#ifdef DEBUG
+ (void) fprintf(stdout,
+ "\n[tsol_gettpent.c: _nss_ldap_tnrhtp2ent %d]\n", i);
+ (void) fprintf(stdout, " entry value count %d: %s:%s\n",
+ attrptr->value_count,
+ attrptr->attrname ? attrptr->attrname : "NULL",
+ attrptr->attrvalue[0] ? attrptr->attrvalue[0] : "NULL");
+#endif /* DEBUG */
+ if (strcasecmp(attrptr->attrname, _TNRHTP_NAME) == 0) {
+ len = strlen(attrptr->attrvalue[0]);
+ if (len < 1 || (attrptr->attrvalue[0] == '\0')) {
+ nss_result = (int)NSS_STR_PARSE_PARSE;
+ goto result_tnrhtp2ent;
+ }
+ tpstrp->template = buffer;
+ buffer += len + 1;
+ if (buffer >= ceiling) {
+ nss_result = (int)NSS_STR_PARSE_ERANGE;
+ goto result_tnrhtp2ent;
+ }
+ (void) strcpy(tpstrp->template, attrptr->attrvalue[0]);
+ continue;
+ }
+ if (strcasecmp(attrptr->attrname, _TNRHTP_ATTRS) == 0) {
+ len = strlen(attrptr->attrvalue[0]);
+ if (len < 1 || (attrptr->attrvalue[0] == '\0')) {
+ nss_result = (int)NSS_STR_PARSE_PARSE;
+ goto result_tnrhtp2ent;
+ }
+ tpstrp->attrs = buffer;
+ buffer += len + 1;
+ if (buffer >= ceiling) {
+ nss_result = (int)NSS_STR_PARSE_PARSE;
+ goto result_tnrhtp2ent;
+ }
+ (void) strcpy(tpstrp->attrs, attrptr->attrvalue[0]);
+ continue;
+ }
+ }
+ if (tpstrp->attrs == NULL)
+ nss_result = NSS_STR_PARSE_PARSE;
+ else
+ nss_result = NSS_STR_PARSE_SUCCESS;
+
+#ifdef DEBUG
+ (void) fprintf(stdout, "\n[tsol_gettpent.c: _nss_ldap_tnrhtp2ent]\n");
+ (void) fprintf(stdout, " template: [%s]\n",
+ tpstrp->template ? tpstrp->template : "NULL");
+ (void) fprintf(stdout, " attrs: [%s]\n",
+ tpstrp->attrs ? tpstrp->attrs : "NULL");
+#endif /* DEBUG */
+
+result_tnrhtp2ent:
+ (void) __ns_ldap_freeResult(&be->result);
+ return (nss_result);
+}
+
+
+static nss_status_t
+getbyname(ldap_backend_ptr be, void *a)
+{
+ char searchfilter[SEARCHFILTERLEN];
+ char userdata[SEARCHFILTERLEN];
+ nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a;
+
+#ifdef DEBUG
+ (void) fprintf(stdout, "\n[tsol_gettpent.c: getbyname]\n");
+#endif /* DEBUG */
+
+ if (snprintf(searchfilter, SEARCHFILTERLEN, _F_GETTNTPBYNAME,
+ argp->key.name) < 0)
+ return ((nss_status_t)NSS_NOTFOUND);
+
+ if (snprintf(userdata, sizeof (userdata), _F_GETTNTPBYNAME_SSD,
+ argp->key.name) < 0)
+ return ((nss_status_t)NSS_NOTFOUND);
+
+ return (_nss_ldap_lookup(be, argp, _TNRHTP, searchfilter, NULL,
+ _merge_SSD_filter, userdata));
+}
+
+
+static ldap_backend_op_t tnrhtp_ops[] = {
+ _nss_ldap_destr,
+ _nss_ldap_endent,
+ _nss_ldap_setent,
+ _nss_ldap_getent,
+ getbyname
+};
+
+
+nss_backend_t *
+_nss_ldap_tnrhtp_constr(const char *dummy1,
+ const char *dummy2,
+ const char *dummy3,
+ const char *dummy4,
+ const char *dummy5)
+{
+#ifdef DEBUG
+ (void) fprintf(stdout,
+ "\n[gettnrhtpattr.c: _nss_ldap_tnrhtp_constr]\n");
+#endif
+ return ((nss_backend_t *)_nss_ldap_constr(tnrhtp_ops,
+ sizeof (tnrhtp_ops)/sizeof (tnrhtp_ops[0]), _TNRHTP,
+ tnrhtp_attrs, _nss_ldap_tnrhtp2ent));
+}