summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/Targetdirs5
-rw-r--r--usr/src/cmd/Makefile6
-rw-r--r--usr/src/cmd/Makefile.cmd35
-rw-r--r--usr/src/cmd/allocate/Makefile47
-rw-r--r--usr/src/cmd/allocate/add_allocatable.c505
-rw-r--r--usr/src/cmd/allocate/audio_clean_wrapper.sh164
-rw-r--r--usr/src/cmd/allocate/devalloc_defaults46
-rw-r--r--usr/src/cmd/allocate/disk_clean.sh542
-rw-r--r--usr/src/cmd/allocate/mkdevalloc.c47
-rw-r--r--usr/src/cmd/allocate/wdwmsg.sh51
-rw-r--r--usr/src/cmd/allocate/wdwwrapper.sh75
-rw-r--r--usr/src/cmd/bsmconv/bsmconv.sh18
-rw-r--r--usr/src/cmd/devfsadm/devfsadm.c26
-rw-r--r--usr/src/cmd/lp/filter/postscript/postscript/Makefile12
-rw-r--r--usr/src/cmd/lp/filter/postscript/postscript/tsol_banner.ps30
-rw-r--r--usr/src/cmd/lp/filter/postscript/postscript/tsol_separator.ps687
-rw-r--r--usr/src/cmd/lp/filter/postscript/postscript/tsol_trailer.ps29
-rw-r--r--usr/src/cmd/lp/model/Makefile6
-rw-r--r--usr/src/cmd/lp/model/lp.tsol_separator.c528
-rw-r--r--usr/src/cmd/lp/model/tsol_netstandard751
-rw-r--r--usr/src/cmd/lp/model/tsol_netstandard_foomatic788
-rw-r--r--usr/src/cmd/lp/model/tsol_standard1162
-rw-r--r--usr/src/cmd/lp/model/tsol_standard_foomatic1190
-rw-r--r--usr/src/cmd/tsol/Makefile95
-rw-r--r--usr/src/cmd/tsol/Makefile.targ77
-rw-r--r--usr/src/cmd/tsol/atohexlabel/Makefile49
-rw-r--r--usr/src/cmd/tsol/atohexlabel/atohexlabel.c161
-rw-r--r--usr/src/cmd/tsol/demo/Makefile67
-rw-r--r--usr/src/cmd/tsol/demo/clonebylabel.sh107
-rw-r--r--usr/src/cmd/tsol/demo/getmounts.sh30
-rw-r--r--usr/src/cmd/tsol/demo/runinzone.ksh41
-rw-r--r--usr/src/cmd/tsol/demo/runwlabel.ksh50
-rw-r--r--usr/src/cmd/tsol/demo/waitforzone.ksh42
-rw-r--r--usr/src/cmd/tsol/getlabel/Makefile49
-rw-r--r--usr/src/cmd/tsol/getlabel/getlabel.c152
-rw-r--r--usr/src/cmd/tsol/getzonepath/Makefile49
-rw-r--r--usr/src/cmd/tsol/getzonepath/getzonepath.c111
-rw-r--r--usr/src/cmd/tsol/hextoalabel/Makefile51
-rw-r--r--usr/src/cmd/tsol/hextoalabel/hextoalabel.c161
-rw-r--r--usr/src/cmd/tsol/labeld/Makefile58
-rw-r--r--usr/src/cmd/tsol/labeld/labeld.xml83
-rw-r--r--usr/src/cmd/tsol/labeld/svc-labeld282
-rw-r--r--usr/src/cmd/tsol/lslabels/Makefile52
-rw-r--r--usr/src/cmd/tsol/lslabels/lslabels.c214
-rwxr-xr-xusr/src/cmd/tsol/misc/Makefile53
-rw-r--r--usr/src/cmd/tsol/misc/relabel.sh77
-rw-r--r--usr/src/cmd/tsol/misc/txzonemgr.sh778
-rw-r--r--usr/src/cmd/tsol/plabel/Makefile52
-rw-r--r--usr/src/cmd/tsol/plabel/plabel.c236
-rw-r--r--usr/src/cmd/tsol/setlabel/Makefile50
-rw-r--r--usr/src/cmd/tsol/setlabel/setlabel.c175
-rw-r--r--usr/src/cmd/tsol/tnchkdb/Makefile47
-rw-r--r--usr/src/cmd/tsol/tnchkdb/tnchkdb.c642
-rw-r--r--usr/src/cmd/tsol/tnctl/Makefile58
-rw-r--r--usr/src/cmd/tsol/tnctl/svc-tnctl34
-rw-r--r--usr/src/cmd/tsol/tnctl/tnctl.c597
-rw-r--r--usr/src/cmd/tsol/tnctl/tnctl.xml90
-rw-r--r--usr/src/cmd/tsol/tnctl/tnrhdb41
-rw-r--r--usr/src/cmd/tsol/tnctl/tnrhtp34
-rw-r--r--usr/src/cmd/tsol/tnctl/tnzonecfg60
-rw-r--r--usr/src/cmd/tsol/tnd/Makefile62
-rw-r--r--usr/src/cmd/tsol/tnd/svc-tnd46
-rw-r--r--usr/src/cmd/tsol/tnd/tnd.c1920
-rw-r--r--usr/src/cmd/tsol/tnd/tnd.h138
-rw-r--r--usr/src/cmd/tsol/tnd/tnd.xml127
-rw-r--r--usr/src/cmd/tsol/tninfo/Makefile49
-rw-r--r--usr/src/cmd/tsol/tninfo/tninfo.c339
-rw-r--r--usr/src/cmd/tsol/tsol-zones/Makefile65
-rw-r--r--usr/src/cmd/tsol/tsol-zones/svc-tsol-zones45
-rw-r--r--usr/src/cmd/tsol/tsol-zones/tsol-zones.xml82
-rw-r--r--usr/src/cmd/tsol/updatehome/Makefile57
-rw-r--r--usr/src/cmd/tsol/updatehome/setupfiles.c517
-rw-r--r--usr/src/cmd/tsol/updatehome/setupfiles.h55
-rw-r--r--usr/src/cmd/tsol/updatehome/updatehome.c193
-rw-r--r--usr/src/cmd/tsol/zones/Makefile62
-rw-r--r--usr/src/cmd/tsol/zones/SUNWtsoldef.xml41
-rw-r--r--usr/src/cmd/tsol/zones/zoneshare.sh81
-rw-r--r--usr/src/cmd/tsol/zones/zoneunshare.sh77
-rw-r--r--usr/src/lib/libbsm/common/devalloc.h1
-rw-r--r--usr/src/lib/libpam/pam.conf35
-rw-r--r--usr/src/lib/libsecdb/auth_attr.txt25
-rw-r--r--usr/src/lib/libsecdb/exec_attr.txt3
-rw-r--r--usr/src/lib/libsecdb/help/auths/FileChown.html35
-rw-r--r--usr/src/lib/libsecdb/help/auths/FileHeader.html35
-rw-r--r--usr/src/lib/libsecdb/help/auths/FileOwner.html39
-rw-r--r--usr/src/lib/libsecdb/help/auths/LabelFileDowngrade.html36
-rw-r--r--usr/src/lib/libsecdb/help/auths/LabelFileUpgrade.html36
-rw-r--r--usr/src/lib/libsecdb/help/auths/LabelHeader.html36
-rw-r--r--usr/src/lib/libsecdb/help/auths/LabelPrint.html35
-rw-r--r--usr/src/lib/libsecdb/help/auths/LabelRange.html40
-rw-r--r--usr/src/lib/libsecdb/help/auths/LabelServer.html35
-rw-r--r--usr/src/lib/libsecdb/help/auths/LabelWinDowngrade.html37
-rw-r--r--usr/src/lib/libsecdb/help/auths/LabelWinNoView.html36
-rw-r--r--usr/src/lib/libsecdb/help/auths/LabelWinUpgrade.html37
-rw-r--r--usr/src/lib/libsecdb/help/auths/Makefile24
-rw-r--r--usr/src/lib/libsecdb/help/auths/PrintAdmin.html36
-rw-r--r--usr/src/lib/libsecdb/help/auths/PrintCancel.html35
-rw-r--r--usr/src/lib/libsecdb/help/auths/PrintHeader.html36
-rw-r--r--usr/src/lib/libsecdb/help/auths/PrintList.html35
-rw-r--r--usr/src/lib/libsecdb/help/auths/PrintNoBanner.html37
-rw-r--r--usr/src/lib/libsecdb/help/auths/PrintPs.html35
-rw-r--r--usr/src/lib/libsecdb/help/auths/PrintUnlabeled.html37
-rw-r--r--usr/src/lib/libsecdb/help/auths/TNDaemon.html35
-rw-r--r--usr/src/lib/libsecdb/help/auths/TNctl.html35
-rw-r--r--usr/src/lib/libsecdb/help/auths/ValueTND.html35
-rw-r--r--usr/src/lib/libsecdb/help/profiles/Makefile3
-rw-r--r--usr/src/lib/libsecdb/help/profiles/RtInfoSec.html39
-rw-r--r--usr/src/lib/libsecdb/help/profiles/RtObjectLabelMngmnt.html37
-rw-r--r--usr/src/lib/libsecdb/help/profiles/RtOutsideAccred.html37
-rw-r--r--usr/src/lib/libsecdb/prof_attr.txt16
-rw-r--r--usr/src/lib/libsecdb/user_attr.txt2
-rw-r--r--usr/src/lib/pam_modules/Makefile1
-rw-r--r--usr/src/lib/pam_modules/tsol_acct/Makefile50
-rw-r--r--usr/src/lib/pam_modules/tsol_acct/Makefile.com43
-rw-r--r--usr/src/lib/pam_modules/tsol_acct/amd64/Makefile36
-rw-r--r--usr/src/lib/pam_modules/tsol_acct/i386/Makefile30
-rw-r--r--usr/src/lib/pam_modules/tsol_acct/mapfile-vers33
-rw-r--r--usr/src/lib/pam_modules/tsol_acct/sparc/Makefile30
-rw-r--r--usr/src/lib/pam_modules/tsol_acct/sparcv9/Makefile31
-rw-r--r--usr/src/lib/pam_modules/tsol_acct/tsol_acct.c145
-rw-r--r--usr/src/pkgdefs/Makefile3
-rw-r--r--usr/src/pkgdefs/SUNW0on/prototype_com26
-rw-r--r--usr/src/pkgdefs/SUNWtsg/Makefile39
-rw-r--r--usr/src/pkgdefs/SUNWtsg/pkginfo.tmpl55
-rw-r--r--usr/src/pkgdefs/SUNWtsg/postinstall57
-rw-r--r--usr/src/pkgdefs/SUNWtsg/prototype_com106
-rw-r--r--usr/src/pkgdefs/SUNWtsg/prototype_i38650
-rw-r--r--usr/src/pkgdefs/SUNWtsg/prototype_sparc50
-rw-r--r--usr/src/pkgdefs/SUNWtsr/Makefile36
-rw-r--r--usr/src/pkgdefs/SUNWtsr/depend47
-rw-r--r--usr/src/pkgdefs/SUNWtsr/pkginfo.tmpl55
-rw-r--r--usr/src/pkgdefs/SUNWtsr/prototype_com56
-rw-r--r--usr/src/pkgdefs/SUNWtsr/prototype_i38650
-rw-r--r--usr/src/pkgdefs/SUNWtsr/prototype_sparc50
-rw-r--r--usr/src/pkgdefs/SUNWtsu/Makefile39
-rw-r--r--usr/src/pkgdefs/SUNWtsu/depend44
-rw-r--r--usr/src/pkgdefs/SUNWtsu/pkginfo.tmpl55
-rw-r--r--usr/src/pkgdefs/SUNWtsu/prototype_com137
-rw-r--r--usr/src/pkgdefs/SUNWtsu/prototype_i38651
-rw-r--r--usr/src/pkgdefs/SUNWtsu/prototype_sparc51
-rw-r--r--usr/src/pkgdefs/common_files/i.devallocdefs264
-rw-r--r--usr/src/pkgdefs/common_files/i.pamconf63
-rw-r--r--usr/src/pkgdefs/common_files/r.renamenew36
-rw-r--r--usr/src/tools/scripts/bfu.sh12
-rw-r--r--usr/src/uts/common/os/tlabel.c11
145 files changed, 18505 insertions, 63 deletions
diff --git a/usr/src/Targetdirs b/usr/src/Targetdirs
index d0af19a936..6e65581c25 100644
--- a/usr/src/Targetdirs
+++ b/usr/src/Targetdirs
@@ -102,6 +102,7 @@ ROOT.SYS= \
/etc/iscsi \
/etc/rpcsec \
/etc/security \
+ /etc/security/tsol \
/etc/gss \
/etc/init.d \
/etc/dhcp \
@@ -179,7 +180,9 @@ ROOT.SYS= \
/var/svc/manifest/platform/sun4u \
/var/svc/manifest/platform/sun4v \
/var/svc/manifest/site \
- /var/svc/profile
+ /var/svc/profile \
+ /var/tsol \
+ /var/tsol/doors
# EXPORT DELETE START
XROOT.BIN= \
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile
index 420cb93003..4c8f29506e 100644
--- a/usr/src/cmd/Makefile
+++ b/usr/src/cmd/Makefile
@@ -386,6 +386,7 @@ COMMON_SUBDIRS= \
troff \
true \
truss \
+ tsol \
tty \
ttymon \
uadmin \
@@ -667,6 +668,7 @@ MSGSUBDIRS= \
touch \
tput \
troff \
+ tsol \
tty \
ttymon \
ul \
@@ -824,6 +826,10 @@ MANIFEST_SUBDIRS= \
cmd-inet/usr.sbin/in.routed \
cmd-inet/usr.sbin/in.talkd \
cmd-inet/usr.sbin/routeadm \
+ cmd/tsol/labeld \
+ cmd/tsol/tnctl \
+ cmd/tsol/tnd \
+ cmd/tsol/tsol-zones \
dcs/sparc/sun4u \
fs.d/autofs \
fs.d/cachefs \
diff --git a/usr/src/cmd/Makefile.cmd b/usr/src/cmd/Makefile.cmd
index 5d6edbf8e2..6a3cccfdb6 100644
--- a/usr/src/cmd/Makefile.cmd
+++ b/usr/src/cmd/Makefile.cmd
@@ -55,12 +55,19 @@ ROOTBIN= $(ROOT)/usr/bin
ROOTLIB= $(ROOT)/usr/lib
ROOTLIBSVCBIN= $(ROOT)/lib/svc/bin
ROOTLIBSVCMETHOD= $(ROOT)/lib/svc/method
+ROOTLIBZONES= $(ROOT)/lib/zones
ROOTSHLIB= $(ROOT)/usr/share/lib
ROOTSHLIBCCS= $(ROOTSHLIB)/ccs
ROOTSBIN= $(ROOT)/sbin
ROOTUSRSBIN= $(ROOT)/usr/sbin
ROOTETC= $(ROOT)/etc
+
+ROOTETCSECURITY= $(ROOTETC)/security
+ROOTETCTSOL= $(ROOTETCSECURITY)/tsol
+ROOTETCSECLIB= $(ROOTETCSECURITY)/lib
+ROOTETCZONES= $(ROOTETC)/zones
+
ROOTCCSBIN= $(ROOT)/usr/ccs/bin
ROOTCCSBIN64= $(ROOTCCSBIN)/$(MACH64)
ROOTCCSBINLINKDIR= $(ROOT)/../../bin
@@ -151,6 +158,7 @@ ROOTLIBSHFILES= $(SHFILES:%=$(ROOTLIB)/%)
ROOTSHLIBPROG= $(PROG:%=$(ROOTSHLIB)/%)
ROOTSBINPROG= $(PROG:%=$(ROOTSBIN)/%)
ROOTUSRSBINPROG=$(PROG:%=$(ROOTUSRSBIN)/%)
+ROOTUSRSBINSCRIPT=$(SCRIPT:%=$(ROOTUSRSBIN)/%)
ROOTETCPROG= $(PROG:%=$(ROOTETC)/%)
ROOTCCSBINPROG= $(PROG:%=$(ROOTCCSBIN)/%)
ROOTCCSBINPROG64= $(PROG:%=$(ROOTCCSBIN64)/%)
@@ -198,6 +206,21 @@ $(ROOTETCDEFAULTFILES) := OWNER = root
$(ROOTETCDEFAULTFILES) := GROUP = sys
$(ROOTETCDEFAULTFILES) := FILEMODE = 0644
+ROOTETCSECFILES= $(ETCSECFILES:%=$(ROOTETCSECURITY)/%)
+$(ROOTETCSECFILES) := FILEMODE = 0644
+
+ROOTETCTSOLFILES= $(ETCTSOLFILES:%=$(ROOTETCTSOL)/%)
+$(ROOTETCTSOLFILES) := FILEMODE = 0644
+
+ROOTETCSECLIBFILES= $(ETCSECLIBFILES:%=$(ROOTETCSECLIB)/%)
+
+ROOTETCZONESFILES= $(ETCZONESFILES:%=$(ROOTETCZONES)/%)
+$(ROOTETCZONESFILES) := FILEMODE = 0444
+
+ROOTLIBZONESFILES= $(LIBZONESFILES:%=$(ROOTLIBZONES)/%)
+$(ROOTLIBZONESFILES) := FILEMODE = 0555
+
+
#
# Directories for smf(5) service manifests and profiles.
#
@@ -306,6 +329,18 @@ $(ROOTETC)/%: %
$(ROOTETCDEFAULT)/%: %.dfl
$(INS.rename)
+$(ROOTETCTSOL)/%: %
+ $(INS.file)
+
+$(ROOTETCSECLIB)/%: %
+ $(INS.file)
+
+$(ROOTETCZONES)/%: %
+ $(INS.file)
+
+$(ROOTLIBZONES)/%: %
+ $(INS.file)
+
$(ROOTUSRKVM)/%: %
$(INS.file)
diff --git a/usr/src/cmd/allocate/Makefile b/usr/src/cmd/allocate/Makefile
index 8fc40750cc..005b180983 100644
--- a/usr/src/cmd/allocate/Makefile
+++ b/usr/src/cmd/allocate/Makefile
@@ -20,12 +20,14 @@
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
#
+ETCTSOLFILES = devalloc_defaults
+
include ../Makefile.cmd
ROOTSEC = $(ROOTETC)/security
@@ -34,18 +36,28 @@ ROOTSECLIB = $(ROOTSEC)/lib
ROOTDIRS = $(ROOTSECDEV) $(ROOTSECLIB)
RTLCKS = audio fd0 sr0 st0 st1
-SCRIPTS = fd_clean sr_clean st_clean
+CLEANfd = fd_clean
+CLEANsr = sr_clean
+CLEANst = st_clean
+CLEANaudio = audio_clean_wrapper
+CLEANdisk = disk_clean
+CLEAN_SCRIPTS = $(CLEANfd) $(CLEANsr) $(CLEANst) $(CLEANaudio) $(CLEANdisk)
+WDW_SCRIPTS = wdwmsg wdwwrapper
+WDW_LINKS = $(CLEANaudio) $(CLEANdisk) $(CLEANst)
+SCRIPTS = $(CLEAN_SCRIPTS) $(WDW_SCRIPTS)
ALLSCRIPTS = allscripts.sh
PROGalloc = allocate
PROGmkdevalloc = mkdevalloc
PROGdminfo = dminfo
PROGaudio = audio_clean
-PROG = $(PROGalloc) $(PROGmkdevalloc) $(PROGdminfo) $(PROGaudio)
+PROGaddalloc = add_allocatable
+PROG = $(PROGalloc) $(PROGmkdevalloc) $(PROGdminfo) \
+ $(PROGaudio) $(PROGaddalloc)
LINKPROGalloc = deallocate list_devices
LINKPROGmkdevalloc = mkdevmaps
-
+LINKPROGaddalloc = remove_allocatable
POFILE = allocate_all.po
POFILES = $(OBJS:%.o=%.po) $(ALLSCRIPTS:%.sh=%.po)
@@ -55,24 +67,29 @@ CPPFLAGS += $(DFLAGS)
ROOTLOCKS = $(RTLCKS:%=$(ROOTSECDEV)/%)
ROOTSCRIPTS = $(SCRIPTS:%=$(ROOTSECLIB)/%)
+ROOTWDWLINKS = $(WDW_LINKS:%=$(ROOTSECLIB)/%.windowing)
ROOTPROG = $(PROGallocate:%=$(ROOTUSRSBIN)/%) \
$(PROGmkdevalloc:%=$(ROOTUSRSBIN)/%) \
$(PROGdminfo:%=$(ROOTUSRSBIN)/%) \
- $(PROGaudio:%=$(ROOTSECLIB)/%)
+ $(PROGaudio:%=$(ROOTSECLIB)/%) \
+ $(PROGaddaloc:%=$(ROOTUSRSBIN)/%)
ROOTLINKalloc = $(LINKPROGalloc:%=$(ROOTUSRSBIN)/%)
ROOTLINKmkdevalloc = $(LINKPROGmkdevalloc:%=$(ROOTUSRSBIN)/%)
-ROOTLINKS = $(ROOTLINKalloc) $(ROOTLINKmkdevalloc)
+ROOTLINKaddalloc = $(LINKPROGaddalloc:%=$(ROOTUSRSBIN)/%)
+ROOTLINKS = $(ROOTLINKalloc) $(ROOTLINKmkdevalloc) $(ROOTLINKaddalloc)
PROGallocOBJS = allocate.o allocate3.o
PROGmkdevallocOBJS = mkdevalloc.o
PROGdminfoOBJS = dminfo.o
PROGaudioOBJS = audio_clean.o
+PROGaddallocOBJS = add_allocatable.o
OBJS = $(PROGallocOBJS) \
$(PROGmkdevallocOBJS) \
$(PROGdminfoOBJS) \
- $(PROGaudioOBJS)
+ $(PROGaudioOBJS) \
+ $(PROGaddallocOBJS)
SRCS = $(OBJS:%.o=%.c)
@@ -93,6 +110,7 @@ $(PROGalloc) := LDLIBS += -lbsm -lsec -lsecdb -ldevinfo $(LAZYLIBS)
$(PROGmkdevalloc) := LDLIBS += -lbsm
$(PROGdminfo) := LDLIBS += -lbsm
$(PROGaudio) := LDLIBS += -lbsm
+$(PROGaddalloc) := LDLIBS += -lbsm -lsecdb $(LAZYLIBS)
CLOBBERFILES += $(SCRIPTS)
@@ -101,7 +119,7 @@ CLOBBERFILES += $(SCRIPTS)
all : $(PROG) $(RTLCKS) $(SCRIPTS)
install : $(PROG) $(ROOTDIRS) $(ROOTPROG) $(ROOTLOCKS) \
- $(ROOTSCRIPTS) $(ROOTLINKS)
+ $(ROOTSCRIPTS) $(ROOTLINKS) $(ROOTWDWLINKS) $(ROOTETCTSOLFILES)
$(RTLCKS):
$(TOUCH) $@
@@ -113,6 +131,10 @@ $(PROGalloc) : $(PROGallocOBJS)
$(LINK.c) $(PROGallocOBJS) -o $@ $(LDLIBS)
$(POST_PROCESS)
+$(PROGaddalloc) : $(PROGaddallocOBJS)
+ $(LINK.c) $(PROGaddallocOBJS) -o $@ $(LDLIBS)
+ $(POST_PROCESS)
+
$(PROGmkdevalloc) : $(PROGmkdevallocOBJS)
$(LINK.c) $(PROGmkdevallocOBJS) -o $@ $(LDLIBS)
$(POST_PROCESS)
@@ -143,10 +165,19 @@ $(ROOTLINKalloc) : $(PROGalloc:%=$(ROOTUSRSBIN)/%)
$(RM) $@
$(LN) $(PROGalloc:%=$(ROOTUSRSBIN)/%) $@
+$(ROOTLINKaddalloc) : $(PROGaddalloc:%=$(ROOTUSRSBIN)/%)
+ $(RM) $@
+ $(LN) $(PROGaddalloc:%=$(ROOTUSRSBIN)/%) $@
+
$(ROOTLINKmkdevalloc) : $(PROGmkdevalloc:%=$(ROOTUSRSBIN)/%)
$(RM) $@
$(LN) $(PROGmkdevalloc:%=$(ROOTUSRSBIN)/%) $@
+
+$(ROOTETCSECLIB)/%.windowing: %
+ $(RM) $@
+ $(SYMLINK) $< $@
+
$(POFILE): $(POFILES)
$(RM) $@
$(CAT) $(POFILES) > $@
diff --git a/usr/src/cmd/allocate/add_allocatable.c b/usr/src/cmd/allocate/add_allocatable.c
new file mode 100644
index 0000000000..759d1ed1e9
--- /dev/null
+++ b/usr/src/cmd/allocate/add_allocatable.c
@@ -0,0 +1,505 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * add_allocatable -
+ * a command-line interface to add device to device_allocate and
+ * device_maps.
+ */
+
+#ifndef __EXTENSIONS__
+#define __EXTENSIONS__ /* needed for _strtok_r */
+#endif
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <string.h>
+#include <locale.h>
+#include <libintl.h>
+#include <pwd.h>
+#include <nss_dbdefs.h>
+#include <auth_attr.h>
+#include <auth_list.h>
+#include <zone.h>
+#include <tsol/label.h>
+#include <bsm/devices.h>
+#include <bsm/devalloc.h>
+
+#define NO_OVERRIDE -1
+
+int check_args(da_args *);
+int process_args(int, char **, da_args *, char *);
+int scan_label(char *, char *);
+void usage(da_args *, char *);
+
+int system_labeled = 0;
+
+int
+main(int argc, char *argv[])
+{
+ int rc;
+ uid_t uid;
+ char *progname;
+ char pwbuf[NSS_LINELEN_PASSWD];
+ struct passwd pwd;
+ da_args dargs;
+ devinfo_t devinfo;
+
+ (void) setlocale(LC_ALL, "");
+#if !defined(TEXT_DOMAIN)
+#define TEXT_DOMAIN "SYS_TEST"
+#endif
+ (void) textdomain(TEXT_DOMAIN);
+ if ((progname = strrchr(argv[0], '/')) == NULL)
+ progname = argv[0];
+ else
+ progname++;
+
+ system_labeled = is_system_labeled();
+ if (system_labeled) {
+ /*
+ * this command can be run only in the global zone.
+ */
+ if (getzoneid() != GLOBAL_ZONEID) {
+ (void) fprintf(stderr, "%s%s", progname,
+ gettext(" : must be run in global zone\n"));
+ exit(1);
+ }
+ } else {
+ /*
+ * this command works in Trusted Extensions only.
+ */
+ (void) fprintf(stderr, "%s%s", progname,
+ gettext(" : need to install Trusted Extensions\n"));
+ exit(1);
+ }
+
+ dargs.optflag = 0;
+ dargs.rootdir = NULL;
+ dargs.devnames = NULL;
+ dargs.devinfo = &devinfo;
+
+ if (strcmp(progname, "add_allocatable") == 0) {
+ dargs.optflag |= DA_ADD;
+ } else if (strcmp(progname, "remove_allocatable") == 0) {
+ dargs.optflag |= DA_REMOVE;
+ } else {
+ usage(&dargs, progname);
+ exit(1);
+ }
+
+ uid = getuid();
+ if ((getpwuid_r(uid, &pwd, pwbuf, sizeof (pwbuf))) == NULL) {
+ (void) fprintf(stderr, "%s%s", progname,
+ gettext(" : getpwuid_r failed: "));
+ (void) fprintf(stderr, "%s\n", strerror(errno));
+ exit(2);
+ }
+
+ if (chkauthattr(DEVICE_CONFIG_AUTH, pwd.pw_name) != 1) {
+ (void) fprintf(stderr, "%s%s%s", progname,
+ gettext(" : user lacks authorization: \n"),
+ DEVICE_CONFIG_AUTH);
+ exit(4);
+ }
+
+ if (process_args(argc, argv, &dargs, progname) != 0) {
+ usage(&dargs, progname);
+ exit(1);
+ }
+
+ if (dargs.optflag & DA_ADD) {
+ if (check_args(&dargs) == NO_OVERRIDE) {
+ (void) fprintf(stderr, "%s%s%s%s", progname,
+ gettext(" : entry exists for "),
+ dargs.devinfo->devname, gettext("\n"));
+ usage(&dargs, progname);
+ exit(3);
+ }
+ }
+
+ if (dargs.optflag & DA_DEFATTRS)
+ rc = da_update_defattrs(&dargs);
+ else
+ rc = da_update_device(&dargs);
+
+ if ((rc != 0) && (!(dargs.optflag & DA_SILENT))) {
+ if (rc == -2)
+ (void) fprintf(stderr, "%s%s", progname,
+ gettext(" : device name/type/list missing\n"));
+ else if (dargs.optflag & DA_ADD)
+ (void) fprintf(stderr, "%s%s", progname,
+ gettext(" : error adding/updating device\n"));
+ else if (dargs.optflag & DA_REMOVE)
+ (void) fprintf(stderr, "%s%s", progname,
+ gettext(" : error removing device\n"));
+ rc = 2; /* exit code for 'Unknown system error' in man page */
+ }
+
+ return (rc);
+}
+
+int
+process_args(int argc, char **argv, da_args *dargs, char *progname)
+{
+ int c;
+ int aflag, cflag, dflag, fflag, lflag, nflag, oflag, tflag;
+ extern char *optarg;
+ devinfo_t *devinfo;
+
+ devinfo = dargs->devinfo;
+ aflag = cflag = dflag = fflag = lflag = nflag = oflag = tflag = 0;
+ devinfo->devname = devinfo->devtype = devinfo->devauths =
+ devinfo->devexec = devinfo->devopts = devinfo->devlist = NULL;
+ devinfo->instance = 0;
+
+ while ((c = getopt(argc, argv, "a:c:dfl:n:o:st:")) != EOF) {
+ switch (c) {
+ case 'a':
+ devinfo->devauths = optarg;
+ aflag++;
+ break;
+ case 'c':
+ devinfo->devexec = optarg;
+ if (strlen(devinfo->devexec) == 0) {
+ if (!(dargs->optflag & DA_SILENT))
+ (void) fprintf(stderr, "%s%s", progname,
+ gettext(" : device clean program"
+ " name not found\n"));
+ return (1);
+ }
+ cflag++;
+ break;
+ case 'd':
+ dargs->optflag |= DA_DEFATTRS;
+ dflag++;
+ break;
+ case 'l':
+ devinfo->devlist = optarg;
+ if (strlen(devinfo->devlist) == 0) {
+ if (!(dargs->optflag & DA_SILENT))
+ (void) fprintf(stderr, "%s%s", progname,
+ gettext(" : device file list"
+ " not found\n"));
+ return (1);
+ }
+ lflag++;
+ break;
+ case 'f':
+ dargs->optflag |= DA_FORCE;
+ fflag++;
+ break;
+ case 'n':
+ devinfo->devname = optarg;
+ if (strlen(devinfo->devname) == 0) {
+ if (!(dargs->optflag & DA_SILENT))
+ (void) fprintf(stderr, "%s%s", progname,
+ gettext(" : device name "
+ "not found\n"));
+ return (1);
+ }
+ nflag++;
+ break;
+ case 'o':
+ /* check for field delimiters in the option */
+ if (strpbrk(optarg, ":;=") == NULL) {
+ if (!(dargs->optflag & DA_SILENT)) {
+ (void) fprintf(stderr, "%s%s%s",
+ progname,
+ gettext(" : invalid "
+ "key=val string: "),
+ optarg);
+ (void) fprintf(stderr, "%s",
+ gettext("\n"));
+ }
+ return (1);
+ }
+ devinfo->devopts = optarg;
+ if (dargs->optflag & DA_ADD) {
+ if (scan_label(devinfo->devopts, progname) != 0)
+ return (1);
+ }
+ oflag++;
+ break;
+ case 's':
+ dargs->optflag |= DA_SILENT;
+ break;
+ case 't':
+ devinfo->devtype = optarg;
+ if (strlen(devinfo->devtype) == 0) {
+ if (!(dargs->optflag & DA_SILENT))
+ (void) fprintf(stderr, "%s%s", progname,
+ gettext(" : device type "
+ "not found\n"));
+ return (1);
+ }
+ tflag++;
+ break;
+ default :
+ return (1);
+ }
+ }
+
+
+ if (dargs->optflag & DA_ADD) {
+ if (dflag) {
+ /* -d requires -t, but does not like -n */
+ if (nflag || tflag == 0)
+ return (1);
+ } else if (nflag == 0 && tflag == 0 && lflag == 0) {
+ /* require at least -n or -t or -l to be specified */
+ if (!(dargs->optflag & DA_SILENT))
+ (void) fprintf(stderr, "%s%s", progname,
+ gettext(" : required options missing\n"));
+ return (1);
+ }
+ } else if (dargs->optflag & DA_REMOVE) {
+ if (dflag) {
+ /* -d requires -t, but does not like -n */
+ if (nflag || tflag == 0)
+ return (1);
+ } else if (nflag == 0 && tflag == 0) {
+ /* require at least -n or -t to be specified */
+ if (!(dargs->optflag & DA_SILENT))
+ (void) fprintf(stderr, "%s%s", progname,
+ gettext(" : required options missing\n"));
+ return (1);
+ }
+ /* there's a bunch not accepted by remove_allocatable */
+ if (aflag || cflag || lflag || oflag)
+ return (1);
+ } else {
+ return (1);
+ }
+
+ /* check for option specified more than once */
+ if (aflag > 1 || cflag > 1 || lflag > 1 || fflag > 1 ||
+ nflag > 1 || tflag > 1) {
+ if (!(dargs->optflag & DA_SILENT))
+ (void) fprintf(stderr, "%s%s", progname,
+ gettext(" : multiple-defined options\n"));
+ return (1);
+ }
+
+ return (0);
+}
+
+int
+verify_label(char *token, char *progname)
+{
+ int error = 0;
+ char *p, *val, *str;
+
+ if ((strstr(token, DAOPT_MINLABEL) == NULL) &&
+ (strstr(token, DAOPT_MAXLABEL) == NULL)) {
+ /* no label specified */
+ return (0);
+ }
+ if ((val = strchr(token, '=')) == NULL)
+ return (1);
+ val++;
+ /*
+ * if non-default labels are specified, check if they are correct
+ */
+ if ((strcmp(val, DA_DEFAULT_MIN) != 0) &&
+ (strcmp(val, DA_DEFAULT_MAX) != 0)) {
+ m_label_t *slabel = NULL;
+
+ str = strdup(val);
+ /* get rid of double quotes if they exist */
+ while (*str == '"')
+ str++;
+ if ((p = strchr(str, '"')) != NULL)
+ *p = '\0';
+ if (str_to_label(str, &slabel, MAC_LABEL, L_NO_CORRECTION,
+ &error) == -1) {
+ (void) fprintf(stderr, "%s%s%s", progname,
+ gettext(" : bad label input: "),
+ val);
+ (void) fprintf(stderr, "%s", gettext("\n"));
+ free(str);
+ m_label_free(slabel);
+ return (1);
+ }
+ free(str);
+ m_label_free(slabel);
+ }
+
+ return (0);
+}
+
+int
+scan_label(char *devopts, char *progname)
+{
+ char *tok = NULL;
+ char *lasts, *optsarg;
+
+ if (devopts == NULL)
+ return (0);
+
+ if ((optsarg = strdup(devopts)) == NULL)
+ return (1);
+
+ if ((tok = strtok_r(optsarg, KV_TOKEN_DELIMIT, &lasts)) == NULL)
+ return (1);
+
+ if (verify_label(tok, progname) != 0) {
+ free(optsarg);
+ return (1);
+ }
+
+ while ((tok = strtok_r(NULL, KV_TOKEN_DELIMIT, &lasts)) != NULL) {
+ if (verify_label(tok, progname) != 0) {
+ free(optsarg);
+ return (1);
+ }
+ }
+
+ return (0);
+}
+
+int
+check_args(da_args *dargs)
+{
+ int nlen;
+ char *kval, *nopts, *ntok, *nstr,
+ *defmin, *defmax, *defauths, *defexec;
+ kva_t *kva;
+ devinfo_t *devinfo;
+ devalloc_t *da = NULL;
+ da_defs_t *da_defs = NULL;
+
+ devinfo = dargs->devinfo;
+ /*
+ * check if we're updating an existing entry without -f
+ */
+ setdaent();
+ da = getdanam(devinfo->devname);
+ enddaent();
+ if (da && !(dargs->optflag & DA_FORCE)) {
+ freedaent(da);
+ return (NO_OVERRIDE);
+ }
+ if ((devinfo->devopts == NULL) ||
+ (strstr(devinfo->devopts, DAOPT_MINLABEL) == NULL) ||
+ (strstr(devinfo->devopts, DAOPT_MAXLABEL) == NULL) ||
+ (devinfo->devauths == NULL) ||
+ (devinfo->devexec == NULL)) {
+ /* fill in defaults as required */
+ defmin = DA_DEFAULT_MIN;
+ defmax = DA_DEFAULT_MAX;
+ defauths = DEFAULT_DEV_ALLOC_AUTH;
+ defexec = DA_DEFAULT_CLEAN;
+ setdadefent();
+ if (da_defs = getdadeftype(devinfo->devtype)) {
+ kva = da_defs->devopts;
+ if ((kval = kva_match(kva, DAOPT_MINLABEL)) != NULL)
+ defmin = strdup(kval);
+ if ((kval = kva_match(kva, DAOPT_MAXLABEL)) != NULL)
+ defmax = strdup(kval);
+ if ((kval = kva_match(kva, DAOPT_AUTHS)) != NULL)
+ defauths = strdup(kval);
+ if ((kval = kva_match(kva, DAOPT_CSCRIPT)) != NULL)
+ defexec = strdup(kval);
+ freedadefent(da_defs);
+ }
+ enddadefent();
+ if (devinfo->devauths == NULL)
+ devinfo->devauths = defauths;
+ if (devinfo->devexec == NULL)
+ devinfo->devexec = defexec;
+ if (devinfo->devopts == NULL) {
+ /* add default minlabel and maxlabel */
+ nlen = strlen(DAOPT_MINLABEL) + strlen(KV_ASSIGN) +
+ strlen(defmin) + strlen(KV_TOKEN_DELIMIT) +
+ strlen(DAOPT_MAXLABEL) + strlen(KV_ASSIGN) +
+ strlen(defmax) + 1; /* +1 for terminator */
+ if (nopts = (char *)malloc(nlen)) {
+ (void) snprintf(nopts, nlen, "%s%s%s%s%s%s%s",
+ DAOPT_MINLABEL, KV_ASSIGN, defmin,
+ KV_TOKEN_DELIMIT,
+ DAOPT_MAXLABEL, KV_ASSIGN, defmax);
+ devinfo->devopts = nopts;
+ }
+ } else {
+ if (strstr(devinfo->devopts, DAOPT_MINLABEL) == NULL) {
+ /* add default minlabel */
+ ntok = DAOPT_MINLABEL;
+ nstr = defmin;
+ nlen = strlen(devinfo->devopts) +
+ strlen(KV_TOKEN_DELIMIT) +
+ strlen(ntok) + strlen(KV_ASSIGN) +
+ strlen(nstr) + 1;
+ if (nopts = (char *)malloc(nlen)) {
+ (void) snprintf(nopts, nlen,
+ "%s%s%s%s%s",
+ devinfo->devopts, KV_TOKEN_DELIMIT,
+ ntok, KV_ASSIGN, nstr);
+ devinfo->devopts = nopts;
+ }
+ }
+ if (strstr(devinfo->devopts, DAOPT_MAXLABEL) == NULL) {
+ /* add default maxlabel */
+ ntok = DAOPT_MAXLABEL;
+ nstr = defmax;
+ nlen = strlen(devinfo->devopts) +
+ strlen(KV_TOKEN_DELIMIT) +
+ strlen(ntok) + strlen(KV_ASSIGN) +
+ strlen(nstr) + 1;
+ if (nopts = (char *)malloc(nlen)) {
+ (void) snprintf(nopts, nlen,
+ "%s%s%s%s%s",
+ devinfo->devopts, KV_TOKEN_DELIMIT,
+ ntok, KV_ASSIGN, nstr);
+ devinfo->devopts = nopts;
+ }
+ }
+ }
+ }
+
+ return (0);
+}
+
+void
+usage(da_args *dargs, char *progname)
+{
+ if (dargs->optflag & DA_SILENT)
+ return;
+ if (dargs->optflag & DA_ADD)
+ (void) fprintf(stderr, "%s%s%s", gettext("Usage: "), progname,
+ gettext(" [-f][-s][-d] -n name -t type -l device-list"
+ "\n\t[-a authorization] [-c cleaning program] "
+ "[-o key=value]\n"));
+ else if (dargs->optflag & DA_REMOVE)
+ (void) fprintf(stderr, "%s%s%s", gettext("Usage: "), progname,
+ gettext(" [-f][-s][-d] [-n name|-t type]\n"));
+ else
+ (void) fprintf(stderr, gettext("Invalid usage\n"), progname);
+}
diff --git a/usr/src/cmd/allocate/audio_clean_wrapper.sh b/usr/src/cmd/allocate/audio_clean_wrapper.sh
new file mode 100644
index 0000000000..2a7820c098
--- /dev/null
+++ b/usr/src/cmd/allocate/audio_clean_wrapper.sh
@@ -0,0 +1,164 @@
+#! /bin/sh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# This is a wrapper for the audio_clean program.
+#
+# Following is the syntax for calling the script:
+# scriptname [-s|-f|-i|-I] devicename [-A|-D] [username] [zonename]
+# [zonepath]
+#
+# $1: -s for standard cleanup by a user
+# -f for forced cleanup by an administrator
+# -i for boot-time initialization (when the system is booted with -r)
+# -I to suppress error/warning messages; the script is run in the '-i'
+# mode
+#
+# $2: devicename - device to be allocated/deallocated, e.g., sr0
+#
+# $3: -A if cleanup is for allocation, or -D if cleanup is for deallocation.
+#
+# $4: username - run the script as this user, rather than as the caller.
+#
+# $5: zonename - zone in which device to be allocated/deallocated
+#
+# $6: zonepath - root path of zonename
+#
+# Unless the clean script is being called for boot-time
+# initialization, it may communicate with the user via stdin and
+# stdout. To communicate with the user via CDE dialogs, create a
+# script or link with the same name, but with ".windowing" appended.
+# For example, if the clean script specified in device_allocate is
+# /etc/security/xyz_clean, that script must use stdin/stdout. If a
+# script named /etc/security/xyz_clean.windowing exists, it must use
+# dialogs. To present dialogs to the user, the dtksh script
+# /etc/security/lib/wdwmsg may be used.
+#
+# This particular script, audio_clean_wrapper, will work using stdin/stdout, or
+# using dialogs. A symbolic link audio_clean_wrapper.windowing points to
+# audio_clean_wrapper.
+
+
+trap "" INT TERM QUIT TSTP ABRT
+
+USAGE="usage: $0 [-s|-f|-i|-I] devicename [-A|-D][username][zonename][zonepath]"
+PATH="/usr/bin:/usr/sbin"
+CLEAN_PROG="/etc/security/lib/audio_clean"
+WDWMSG="/etc/security/lib/wdwmsg"
+MODE="allocate"
+
+if [ `basename $0` != `basename $0 .windowing` ]; then
+ WINDOWING="yes"
+else
+ WINDOWING="no"
+fi
+
+#
+# *** Shell Function Declarations ***
+#
+
+msg() {
+ if [ "$WINDOWING" = "yes" ]; then
+ if [ $MODE = "allocate" ]; then
+ TITLE="Audio Device Allocation"
+ else
+ TITLE="Audio Device Dellocation"
+ fi
+ $WDWMSG "$*" "$TITLE" OK
+ else
+ echo "$*"
+ fi
+}
+
+alloc_msg() {
+ msg "Audio device allocated in zone $ZONENAME." \
+ "\nTurn on microphone if audio recording is to be performed." \
+ "\nTurn microphone off when not recording."
+}
+
+dealloc_msg() {
+ msg "Please make sure the microphone is turned off."
+}
+
+fail_msg() {
+ if [ "$MODE" = "allocate" ]; then
+ msg "$0: Allocate of $DEVICE failed."
+ else
+ msg "$0: Deallocate of $DEVICE failed."
+ fi
+}
+
+#
+# Main program
+#
+
+# Check syntax, parse arguments.
+
+while getopts ifsI c
+do
+ case $c in
+ i)
+ FLAG=$c;;
+ f)
+ FLAG=$c;;
+ s)
+ FLAG=$c;;
+ I)
+ FLAG=i
+ silent=y;;
+ \?) msg $USAGE
+ exit 1;;
+ esac
+done
+
+shift `expr $OPTIND - 1`
+
+DEVICE=$1
+if [ "$2" = "-A" ]; then
+ MODE="allocate"
+elif [ "$2" = "-D" ]; then
+ MODE="deallocate"
+fi
+if [ "$MODE" != "allocate" -a "$MODE" != "deallocate" ]; then
+ msg $USAGE
+ exit 1
+fi
+ZONENAME=$4
+ZONEPATH=$5
+
+$CLEAN_PROG -$FLAG $DEVICE
+
+if [ $? -ne 0 ]; then
+ fail_msg
+ exit 1
+fi
+
+if [ "$MODE" = "allocate" ]; then
+ alloc_msg
+else
+ dealloc_msg
+fi
+
+exit 0
diff --git a/usr/src/cmd/allocate/devalloc_defaults b/usr/src/cmd/allocate/devalloc_defaults
new file mode 100644
index 0000000000..56ef8ce53a
--- /dev/null
+++ b/usr/src/cmd/allocate/devalloc_defaults
@@ -0,0 +1,46 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# Default device_allocation attributes for device types.
+# Device types supported -
+# audio, fd, sr, st, rmdisk
+#
+# Syntax -
+# device-type:\
+# minlabel=<ascii string for minimum label>;\
+# maxlabel=<ascii string for maximum label>;\
+# auths=<comma separated list of device authorizations>;\
+# cleanscript=<full path to clean script for this type>
+#
+# Multi-word strings above should be in double quotes.
+# e.g.: minlabel="TS A B";maxlabel="TS AB";auths=solaris.device.allocate;\
+# cleanscript=/bin/true
+#
+audio:minlabel=admin_low;maxlabel=admin_high;auths=solaris.device.allocate;cleanscript=/etc/security/lib/audio_clean_wrapper
+fd:minlabel=admin_low;maxlabel=admin_high;auths=solaris.device.allocate;cleanscript=/etc/security/lib/disk_clean
+sr:minlabel=admin_low;maxlabel=admin_high;auths=solaris.device.allocate;cleanscript=/etc/security/lib/disk_clean
+st:minlabel=admin_low;maxlabel=admin_high;auths=solaris.device.allocate;cleanscript=/etc/security/lib/tape_clean
+rmdisk:minlabel=admin_low;maxlabel=admin_high;auths=solaris.device.allocate;cleanscript=/etc/security/lib/disk_clean
diff --git a/usr/src/cmd/allocate/disk_clean.sh b/usr/src/cmd/allocate/disk_clean.sh
new file mode 100644
index 0000000000..e424d20287
--- /dev/null
+++ b/usr/src/cmd/allocate/disk_clean.sh
@@ -0,0 +1,542 @@
+#! /usr/bin/sh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+#
+# This is a clean script for removable disks
+#
+# Following is the syntax for calling the script:
+# scriptname [-s|-f|-i|-I] devicename [-A|-D] username zonename zonepath
+#
+# -s for standard cleanup by a user
+# -f for forced cleanup by an administrator
+# -i for boot-time initialization (when the system is booted with -r)
+# -I to suppress error/warning messages; the script is run in the '-i'
+# mode
+#
+# $1: devicename - device to be allocated/deallocated, e.g., sr0
+#
+# $2: -A if cleanup is for allocation, or -D if cleanup is for deallocation.
+#
+# $3: username - run the script as this user, rather than as the caller.
+#
+# $4: zonename - zone in which device to be allocated/deallocated
+#
+# $5: zonepath - root path of zonename
+#
+# A clean script for a removable media device should prompt the user to
+# insert correctly labeled media at allocation time, and ensure that the
+# media is ejected at deallocation time.
+#
+# Unless the clean script is being called for boot-time
+# initialization, it may communicate with the user via stdin and
+# stdout. To communicate with the user via CDE dialogs, create a
+# script or link with the same name, but with ".windowing" appended.
+# For example, if the clean script specified in device_allocate is
+# /etc/security/xyz_clean, that script must use stdin/stdout. If a
+# script named /etc/security/xyz_clean.windowing exists, it must use
+# dialogs. To present dialogs to the user, the dtksh script
+# /etc/security/lib/wdwmsg may be used.
+#
+# This particular script, disk_clean, will work using stdin/stdout, or
+# using dialogs. A symbolic link disk_clean.windowing points to
+# disk_clean.
+#
+
+# ####################################################
+# ################ Local Functions #################
+# ####################################################
+
+#
+# Set up for windowing and non-windowing messages
+#
+msg_init()
+{
+ if [ `basename $0` != `basename $0 .windowing` ]; then
+ WINDOWING="yes"
+ case $VOLUME_MEDIATYPE in
+ cdrom) TITLE="CD-ROM";;
+ rmdisk) TITLE="Removable Disk";;
+ floppy) TITLE="Floppy";;
+ *) TITLE="Disk";;
+ esac
+
+ if [ "$MODE" = "allocate" ]; then
+ TITLE="$TITLE Allocation"
+ else
+ TITLE="$TITLE Deallocation"
+ fi
+ else
+ WINDOWING="no"
+ fi
+}
+
+#
+# Display a message for the user. For windowing, user must press OK button
+# to continue. For non-windowing, no response is required.
+#
+msg() {
+ if [ "$WINDOWING" = "yes" ]; then
+ $WDWMSG "$*" "$TITLE" OK
+ elif [ "$silent" != "y" ]; then
+ echo "$*" > /dev/${MSGDEV}
+ fi
+}
+
+ok_msg() {
+ if [ "$WINDOWING" = "yes" ]; then
+ $WDWMSG "$*" "$TITLE" READY
+ else
+ form=`gettext "Media in %s is ready. Please store safely."`
+ printf "${form}\n" $PROG $DEVICE > /dev/{MSGDEV}
+ fi
+}
+
+error_msg() {
+ if [ "$WINDOWING" = "yes" ]; then
+ $WDWMSG "$*" "$TITLE" ERROR
+ else
+ form=`gettext "%s: Error cleaning up device %s."`
+ printf "${form}\n" $PROG $DEVICE > /dev/${MSGDEV}
+ fi
+}
+
+#
+# Ask the user an OK/Cancel question. Return 0 for OK, 1 for Cancel.
+#
+okcancel() {
+ if [ "$WINDOWING" = "yes" ]; then
+ $WDWMSG "$*" "$TITLE" OK Cancel
+ elif [ "$silent" != "y" ]; then
+ get_reply "$* (y to continue, n to cancel) \c" y n
+ fi
+}
+
+#
+# Ask the user an Yes/No question. Return 0 for Yes, 1 for No
+#
+yesno() {
+ if [ "$WINDOWING" = "yes" ]; then
+ $WDWMSG "$*" "$TITLE" Yes No
+ elif [ "$silent" != "y" ]; then
+ get_reply "$* (y/n) \c" y n
+ fi
+}
+
+#
+# Display an error message, put the device in the error state, and exit.
+#
+error_exit() {
+ if [ "$silent" != "y" ]; then
+ msg "$2" "$3" \
+ "\n\nDevice has been placed in allocation error state." \
+ "\nPlease inform system administrator."
+ fi
+ exit 1
+}
+
+#
+# get_reply prompt choice ...
+#
+get_reply() {
+ prompt=$1; shift
+ while true
+ do
+ echo $prompt > /dev/tty
+ read reply
+ i=0
+ for choice in $*
+ do
+ if [ "$choice" = "$reply" ]
+ then
+ return $i
+ else
+ i=`expr $i + 1`
+ fi
+ done
+ done
+}
+
+#
+# Find the first disk slice containing a HSFS file system
+#
+find_fs()
+{
+ for DEVn in $FILES ; do
+ x="`labelit -F hsfs $DEVn 2>&1| grep 'Volume id'`"
+ if [ $? = 0 ]; then
+ FSPATH=$DEVn
+ if [ "$x" != "" ]; then
+ y="`echo $x|cut -f3- -d' '|\
+ /usr/xpg4/bin/tr '[:upper:] ' '[:lower:]_'`"
+ FSNAME=$y
+ fi
+ return
+ fi
+ done
+}
+
+#
+# Find all mountpoints in use for a set of device special files.
+# Usage: findmounts devpath ...
+#
+
+findmounts() {
+ nawk -f - -v vold_root="$VOLD_ROOT" -v devs="$*" /etc/mnttab <<\
+ "ENDOFAWKPGM"
+ BEGIN {
+ split(devs, devlist, " ");
+ for (devN in devlist) {
+ dev = devlist[devN];
+ realdevlist[dev] = 1;
+ sub(/.*\//, "", dev);
+ sub(/s[0-9]$/, "", dev);
+ if (vold_root != "") {
+ vold_dir[vold_root "/dev/dsk/" dev] = 1;
+ vold_dir[vold_root "/dev/rdsk/" dev] = 1;
+ }
+ }
+ }
+
+ {
+ for (dev in realdevlist) {
+ if ($1 == dev) {
+ mountpoint = $2;
+ print mountpoint;
+ }
+ }
+ for (dev in vold_dir) {
+ if (substr($1, 1, length(dev)) == dev) {
+ mountpoint = $2;
+ print mountpoint;
+ }
+ }
+ }
+ENDOFAWKPGM
+}
+
+#
+# Allocate a device.
+# Ask the user to make sure the disk is properly labeled.
+# Ask if the disk should be mounted.
+#
+do_allocate()
+{
+ if [ $VOLUME_MEDIATYPE = floppy ]; then
+ # Determine if media is in drive
+ eject_msg="`eject -q $DEVFILE 2>&1`"
+ eject_status="$?"
+ case $eject_status in
+ 1) # Media is not in drive
+ okcancel "Insert disk in $DEVICE."
+ if [ $? != 0 ]; then
+ exit 0
+ fi;;
+ 3) # Error
+ error_exit $DEVICE \
+ "Error checking for media in drive.";;
+ esac
+ else
+ okcancel "Insert disk in $DEVICE."
+ if [ $? != 0 ]; then
+ exit 0
+ fi
+ fi
+
+ yesno "Do you want $DEVICE mounted?"
+ if [ $? != 0 ]; then
+ exit 0
+ fi
+
+ if [ $VOLUME_MEDIATYPE = cdrom -o $VOLUME_MEDIATYPE = rmdisk ]; then
+ # Get the device path and volume name of a partition
+ find_fs
+ if [ "$FSPATH" != "" ]; then
+ VOLUME_PATH=$FSPATH
+ fi
+ if [ "$FSNAME" != "" ]; then
+ VOLUME_NAME=$FSNAME
+ fi
+ fi
+ VOLUME_ACTION=insert
+
+ # Give ourself write permission on device file so file system gets
+ # mounted read/write if possible.
+ # rmmount only cares about permissions not user...
+ chown $VOLUME_USER $VOLUME_PATH
+ chmod 700 $VOLUME_PATH
+
+ # Do the actual mount. VOLUME_* environment variables are inputs to
+ # rmmount.
+ rmmount_msg="`/usr/sbin/rmmount 2>&1`"
+ rmmount_status="$?"
+ if [ $rmmount_status -eq 0 ]; then
+ EXIT_STATUS=$CLEAN_MOUNT
+ elif [ $rmmount_status -gt 0 -a $VOLUME_MEDIATYPE != cdrom ]; then
+ # Try again in readonly mode. cdrom is always mounted ro, so
+ # no need to try again.
+ echo "Read-write mount of $DEVICE failed. Mounting read-only."
+ VOLUME_ACTION=remount; export VOLUME_ACTION
+ VOLUME_MOUNT_MODE=ro; export VOLUME_MOUNT_MODE
+ `/usr/sbin/rmmount`
+ if [ $? -eq 0 ]; then
+ EXIT_STATUS=$CLEAN_MOUNT
+ fi
+ fi
+
+ # Set permissions on directory used by vold, sdtvolcheck, etc.
+ if [ -d /tmp/.removable ]; then
+ chown root /tmp/.removable
+ chmod 777 /tmp/.removable
+ fi
+}
+
+
+do_deallocate()
+{
+ if [ $VOLUME_MEDIATYPE = cdrom -o $VOLUME_MEDIATYPE = rmdisk ]; then
+ # Get the device path and volume name of a partition
+ find_fs
+ if [ "$FSPATH" != "" ]; then
+ VOLUME_PATH=$FSPATH
+ fi
+ if [ "$FSNAME" != "" ]; then
+ VOLUME_NAME=$FSNAME
+ fi
+ fi
+ VOLUME_ACTION=eject
+
+ # Do the actual unmount. VOLUME_* environment variables are inputs to
+ # rmmount.
+ rmmount_msg="`/usr/sbin/rmmount 2>&1`"
+ rmmount_status="$?"
+
+ # Remove symbolic links to mount point
+ for name in $VOLUME_ZONE_PATH/$VOLUME_MEDIATYPE/*; do
+ if [ -h $name ]; then
+ target=`ls -l $name | awk '{ print $NF; }'`
+ target_dir=`dirname $target`
+ target_device=`echo $target_dir | \
+ sed -e 's/^.*-\(.*\)$/\1/'`
+ if [ "$target_device" = "$DEVICE" ]; then
+ rm -f $name
+ fi
+ fi
+ done
+
+ case $rmmount_status in
+ 1) # still mounted
+ error_exit $DEVICE "Error unmounting $DEVICE" "$rmmount_msg";;
+ 0) # not mounted
+ # Eject the media
+ if [ "$FLAG" = "f" ] ; then
+ eject_msg="`eject -f $DEVFILE 2>&1`"
+ else
+ eject_msg="`eject $DEVFILE 2>&1`"
+ fi
+ eject_status="$?"
+ case $eject_status in
+ 0|4) # Media has been ejected
+ case $VOLUME_MEDIATYPE in
+ floppy|cdrom|rmdisk)
+ msg "Please remove the disk from $DEVICE.";;
+ esac;;
+ 1|3) # Media didn't eject
+ EXIT_STATUS=2
+ msg $DEVICE "Error ejecting disk from $DEVICE" \
+ "$eject_msg";;
+ esac
+ esac
+}
+
+#
+# Reclaim a device
+#
+do_init()
+{
+ eject_msg="`eject -f $DEVFILE 2>&1`"
+ eject_status="$?"
+
+ case $eject_status in
+ 0) # Media has been ejected
+ if [ "$silent" != "y" ]; then
+ ok_msg
+ fi
+ exit 0;;
+ 1) # Media not ejected
+ if [ "$silent" != "y" ]; then
+ error_msg
+ fi
+ exit 0;;
+ 3) # Error
+ if [ "$silent" != "y" ]; then
+ error_msg
+ fi
+ msg $DEVICE "Error ejecting disk from $DEVICE" \
+ "$eject_msg"
+ exit 2;;
+ esac
+}
+
+
+# ####################################################
+# ################ Begin main program ################
+# ####################################################
+
+trap "" INT TERM QUIT TSTP ABRT
+
+PATH="/usr/bin:/usr/sbin"
+MODE="allocate"
+SILENT=n
+WDWMSG="/etc/security/lib/wdwmsg"
+VOLUME_ZONE_PATH="/"
+USAGE="Usage: disk_clean [-s|-f|-i|-I] devicename -[A|D] [username] [zonename] [zonepath]"
+EXIT_STATUS=0
+CLEAN_MOUNT=4
+MACH=`uname -p`
+FLAG=i
+#
+# Parse the command line arguments
+#
+while getopts ifsI c
+do
+ case $c in
+ i)
+ FLAG=$c;;
+ f)
+ FLAG=$c;;
+ s)
+ FLAG=$c;;
+ I)
+ FLAG=i
+ silent=y;;
+ \?)
+ echo $USAGE
+ exit 1;;
+ esac
+done
+
+shift `expr $OPTIND - 1`
+
+DEVICE=$1
+MODE="deallocate"
+if [ "$2" = "-A" ]; then
+ MODE="allocate"
+elif [ "$2" = "-D" ]; then
+ MODE="deallocate"
+fi
+
+#get the device_maps information
+MAP=`/usr/sbin/list_devices -s -l $DEVICE`
+FILES=`echo $MAP | cut -f4 -d:` # e.g., /dev/dsk/c0t6d0s0 /dev/dsk/c0t6d0s1 ...
+DEVFILE=`echo $FILES | cut -f1 -d" "` # e.g., "/dev/dsk/c0t6d0s0"
+
+# Set VOLUME_ variables that are inputs to rmmount
+
+VOLUME_DEVICE=`echo $FILES | cut -f2 -d" "` # e.g., "/dev/dsk/c0t6d0s1"
+MEDIATYPE=`echo $MAP | cut -f3 -d: | cut -f2 -d" "`
+ # e.g., "cdrom" or "floppy"
+if [ "$MEDIATYPE" = "sr" ]; then
+ VOLUME_MEDIATYPE="cdrom"
+elif [ "$MEDIATYPE" = "fd" ]; then
+ VOLUME_MEDIATYPE="floppy"
+elif [ "$MEDIATYPE" = "rmdisk" ]; then
+ VOLUME_MEDIATYPE="rmdisk"
+fi
+
+VOLUME_PATH=$DEVFILE # e.g., "/dev/dsk/c0t6d0s0"
+if [ "$MACH" = "i386" ] && [ "$MEDIATYPE" = "rmdisk" ]; then
+ VOLUME_PATH=`echo $DEVFILE | sed -e 's/s0/p0/'`
+fi
+
+SYMDEV=`echo $DEVICE | sed -e 's/_//'` # e.g., "cdrom" or "floppy"
+SYMNUM=`echo $SYMDEV | sed -e 's/[a-z]*//g'`
+SYMDEV=`echo $SYMDEV | sed -e 's/[0-9]*//g'`
+if [ "$SYMDEV" = "sr" ]; then
+ VOLUME_SYMDEV="cdrom"$SYMNUM
+elif [ "$SYMDEV" = "fd" ]; then
+ VOLUME_SYMDEV="floppy"$SYMNUM
+elif [ "$SYMDEV" = "rmdisk" ]; then
+ VOLUME_SYMDEV="rmdisk"$SYMNUM
+else
+ VOLUME_SYMDEV=$SYMDEV$SYMNUM
+fi
+
+VOLUME_ZONE_NAME=$4
+
+VOLUME_ZONE_PATH=$5
+
+if [ "$MODE" = "allocate" ]; then
+ if [ -n "$3" ]; then # e.g., "joeuser"
+ VOLUME_USER=$3
+ else
+ VOLUME_USER=`/usr/xpg4/bin/id -u -nr`
+ fi
+else
+ # If there's a directory for the device under /<mediatype>, get the
+ # user name from there, to use in cleaning up that directory. Otherwise,
+ # the user name isn't actually used in deallocation.
+ if [ -d ${VOLUME_ZONE_PATH}/${VOLUME_MEDIATYPE}/*-${DEVICE} ]; then
+ VOLUME_USER=`ls -ld ${VOLUME_ZONE_PATH}/${VOLUME_MEDIATYPE}/*-${DEVICE} | awk '/^d/{print $3}'`
+ else
+ if [ -n "$3" ]; then
+ VOLUME_USER=$3
+ else
+ VOLUME_USER=`/usr/xpg4/bin/id -u -nr`
+ fi
+ fi
+fi
+
+VOLUME_NAME=unnamed_${VOLUME_MEDIATYPE}
+ # e.g., "joeuser-cdrom0/unnamed_cdrom"
+
+if [ "$VOLUME_MEDIATYPE" = "rmdisk" ]; then
+ VOLUME_PCFS_ID=c
+else
+ VOLUME_PCFS_ID=
+fi
+
+export VOLUME_ACTION VOLUME_DEVICE VOLUME_MEDIATYPE VOLUME_NAME VOLUME_PCFS_ID
+export VOLUME_PATH VOLUME_SYMDEV VOLUME_USER VOLUME_ZONE_NAME VOLUME_ZONE_PATH
+
+USERDIR=${VOLUME_USER}-${DEVICE} # e.g., "joeusr-cdrom0"
+
+msg_init
+
+if [ "$MODE" = "allocate" ]; then
+ MSGDEV=tty
+ do_allocate
+else
+ if [ "$FLAG" = "i" ] ; then
+ MSGDEV=console
+ do_init
+ else
+ MSGDEV=tty
+ do_deallocate
+ fi
+fi
+
+exit $EXIT_STATUS
diff --git a/usr/src/cmd/allocate/mkdevalloc.c b/usr/src/cmd/allocate/mkdevalloc.c
index a7d2febcc5..750b1eeb9a 100644
--- a/usr/src/cmd/allocate/mkdevalloc.c
+++ b/usr/src/cmd/allocate/mkdevalloc.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -68,6 +68,7 @@
#include <libintl.h>
#include <libdevinfo.h>
#include <secdb.h>
+#include <deflt.h>
#include <auth_attr.h>
#include <auth_list.h>
#include <bsm/devices.h>
@@ -163,7 +164,6 @@ main(int argc, char **argv)
{
int cd_count = 0;
char *progname;
- struct stat tx_stat;
(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);
@@ -181,25 +181,34 @@ main(int argc, char **argv)
system_labeled = is_system_labeled();
+ if (!system_labeled) {
+ /*
+ * is_system_labeled() will return false in case we are
+ * starting before the first reboot after Trusted Extensions
+ * is enabled. Check the setting in /etc/system to see if
+ * TX is enabled (even if not yet booted).
+ */
+ if (defopen("/etc/system") == 0) {
+ if (defread("set sys_labeling=1") != NULL)
+ system_labeled = 1;
+
+ /* close defaults file */
+ (void) defopen(NULL);
+ }
+ }
+
+#ifdef DEBUG
/* test hook: see also devfsadm.c and allocate.c */
if (!system_labeled) {
+ struct stat tx_stat;
+
system_labeled = is_system_labeled_debug(&tx_stat);
if (system_labeled) {
fprintf(stderr, "/ALLOCATE_FORCE_LABEL is set,\n"
"forcing system label on for testing...\n");
}
}
-
- if (system_labeled == 0) {
- /*
- * is_system_labeled() will return false in case we are
- * starting before the first reboot after Trusted Extensions
- * is installed. we check for a well known TX binary to
- * to see if TX is installed.
- */
- if (stat(DA_LABEL_CHECK, &tx_stat) == 0)
- system_labeled = 1;
- }
+#endif
if (system_labeled && do_devalloc && (argc == 2) &&
(strcmp(argv[1], DA_IS_LABELED) == 0)) {
@@ -261,7 +270,7 @@ dotape()
if (i == ntape) {
/* will exit(1) if insufficient memory */
ntape = expandmem(i, (void **)&tape,
- sizeof (struct tape));
+ sizeof (struct tape));
}
/* save name (/dev + / + d_name + \0) */
@@ -282,7 +291,7 @@ dotape()
/* get name from symbolic link */
if ((sz = readlink(tape[i].name, linkvalue,
- sizeof (linkvalue))) < 0)
+ sizeof (linkvalue))) < 0)
continue;
nm = (char *)malloc(sz + 1);
if (nm == NULL)
@@ -319,7 +328,7 @@ dotape()
if (i == ntape) {
/* will exit(1) if insufficient memory */
ntape = expandmem(i, (void **)&tape,
- sizeof (struct tape));
+ sizeof (struct tape));
}
/* save name (/dev/rmt + / + d_name + \0) */
@@ -468,7 +477,7 @@ doaudio()
if (i == naudio) {
/* will exit(1) if insufficient memory */
naudio = expandmem(i, (void **)&audio,
- sizeof (struct audio));
+ sizeof (struct audio));
}
/* save name (/dev + 1 + d_name + \0) */
@@ -489,7 +498,7 @@ doaudio()
/* get name from symbolic link */
if ((sz = readlink(audio[i].name, linkvalue,
- sizeof (linkvalue))) < 0)
+ sizeof (linkvalue))) < 0)
continue;
nm = (char *)malloc(sz + 1);
if (nm == NULL)
@@ -520,7 +529,7 @@ doaudio()
if (i == naudio) {
/* will exit(1) if insufficient memory */
naudio = expandmem(i, (void **)&audio,
- sizeof (struct audio));
+ sizeof (struct audio));
}
/* save name (/dev/sound + / + d_name + \0) */
diff --git a/usr/src/cmd/allocate/wdwmsg.sh b/usr/src/cmd/allocate/wdwmsg.sh
new file mode 100644
index 0000000000..f049f7c45e
--- /dev/null
+++ b/usr/src/cmd/allocate/wdwmsg.sh
@@ -0,0 +1,51 @@
+#! /bin/ksh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+
+################## Check parameters #################################
+
+if [ $# -lt 3 -o $# -gt 4 ]; then
+ echo "Usage: `basename $0` TITLE OKBUTTONTEXT [CANCELBUTTONTEXT]"
+ exit 127
+fi
+
+################## Create the Main UI #################################
+
+messageString="$1"
+dialogTitle="$2"
+
+if [ $# -eq 4 -a "$4" != "" ];then
+ type="--question"
+else
+ type="--info"
+fi
+
+reply=$(/usr/bin/zenity $type \
+ --title="$dialogTitle" \
+ --height=100 \
+ --width=200 \
+ --text="$messageString")
+exit $reply
diff --git a/usr/src/cmd/allocate/wdwwrapper.sh b/usr/src/cmd/allocate/wdwwrapper.sh
new file mode 100644
index 0000000000..2273d63049
--- /dev/null
+++ b/usr/src/cmd/allocate/wdwwrapper.sh
@@ -0,0 +1,75 @@
+#! /bin/ksh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+
+
+# Script to wrap a non-windowing clean script to provide a prompt
+# before the dtterm window closes, and to catch abnormal terminations.
+
+# For any abnormal termination of the clean script, kill our parent
+# process so that our grandparent will know that the script did not
+# terminate normally. (We expect our parent to be dtterm, and our
+# grandparent to be allocate.)
+
+# Trap any signal that would cause abnormal termination of the script,
+# This catches use of ^C, ^Z, etc., and it also catches the HUP signal
+# when the dtterm window is closed before the script is finished.
+
+PARENT_KILLED=no
+
+killparent() {
+ if [ $PARENT_KILLED = "no" ]; then
+ PARENT_KILLED=yes
+ kill -9 $PPID
+ fi
+}
+
+trap "killparent" HUP INT TERM QUIT TSTP ABRT
+
+SCRIPT=$1
+shift
+
+if [ ! -e $SCRIPT ]; then
+ echo **** Clean script $SCRIPT not found ****
+ echo "**** Press RETURN to close window ****"
+ read
+ kill -9 $PPID
+fi
+
+echo "**** Device cleanup for $2 ****\n"
+
+$SCRIPT "$@"
+STAT=$?
+
+echo "\n**** Press RETURN to close window ****"
+read
+
+# If the script returned a non-zero exit status, kill our dtterm
+# parent process.
+
+if [ $STAT != 0 ]; then
+ killparent
+fi
diff --git a/usr/src/cmd/bsmconv/bsmconv.sh b/usr/src/cmd/bsmconv/bsmconv.sh
index 3609293b9b..304b0a452c 100644
--- a/usr/src/cmd/bsmconv/bsmconv.sh
+++ b/usr/src/cmd/bsmconv/bsmconv.sh
@@ -20,7 +20,7 @@
#
# CDDL HEADER END
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -158,10 +158,18 @@ fi
form=`gettext "%s: INFO: initializing device allocation."`
printf "${form}\n" $PROG
-if [ -x /usr/bin/plabel ]
-then
- # Trusted Extensions is installed. This is not currently done
- # for alternate boot environments.
+
+# Need to determine if Trusted Extensions is enabled. This is tricky
+# because we need to know if TX will be active on the boot following
+# bsmconv. Check the setting in etc/system (other methods won't work
+# because TX is likely not yet fully active.)
+#
+grep "^[ ]*set[ ][ ]*sys_labeling[ ]*=[ ]*1" \
+ $ROOT/etc/system > /dev/null 2>&1
+
+if [ $? = 0 ]; then
+ # Trusted Extensions is enabled (but possibly not yet booted).
+ # This is not currently done for alternate boot environments.
if [ -z "$ROOT" -o "$ROOT" = "/" ]
then
/usr/sbin/devfsadm -e
diff --git a/usr/src/cmd/devfsadm/devfsadm.c b/usr/src/cmd/devfsadm/devfsadm.c
index deef0d2730..7fd0a792f4 100644
--- a/usr/src/cmd/devfsadm/devfsadm.c
+++ b/usr/src/cmd/devfsadm/devfsadm.c
@@ -37,6 +37,7 @@
*/
#include <string.h>
+#include <deflt.h>
#include <tsol/label.h>
#include <bsm/devices.h>
#include <bsm/devalloc.h>
@@ -254,7 +255,6 @@ static void process_syseventq();
int
main(int argc, char *argv[])
{
- struct stat tx_stat;
struct passwd *pw;
struct group *gp;
pid_t pid;
@@ -301,17 +301,27 @@ main(int argc, char *argv[])
/*
* is_system_labeled() will return false in case we are
* starting before the first reboot after Trusted Extensions
- * is installed. we check for a well known TX binary to
- * to see if TX is installed.
+ * is enabled. Check the setting in /etc/system to see if
+ * TX is enabled (even if not yet booted).
*/
- if (stat(DA_LABEL_CHECK, &tx_stat) == 0)
- system_labeled = TRUE;
- else {
- /* test hook: see also mkdevalloc.c and allocate.c */
- system_labeled = is_system_labeled_debug(&tx_stat);
+ if (defopen("/etc/system") == 0) {
+ if (defread("set sys_labeling=1") != NULL)
+ system_labeled = TRUE;
+
+ /* close defaults file */
+ (void) defopen(NULL);
}
}
+#ifdef DEBUG
+ if (system_labeled == FALSE) {
+ struct stat tx_stat;
+
+ /* test hook: see also mkdevalloc.c and allocate.c */
+ system_labeled = is_system_labeled_debug(&tx_stat);
+ }
+#endif
+
parse_args(argc, argv);
(void) sema_init(&dev_sema, 1, USYNC_THREAD, NULL);
diff --git a/usr/src/cmd/lp/filter/postscript/postscript/Makefile b/usr/src/cmd/lp/filter/postscript/postscript/Makefile
index 6f12d7ee36..92fff2d723 100644
--- a/usr/src/cmd/lp/filter/postscript/postscript/Makefile
+++ b/usr/src/cmd/lp/filter/postscript/postscript/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.
@@ -22,7 +21,7 @@
#
# ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 1989-2002 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# cmd/lp/filter/postscript/postscript/Makefile
@@ -49,7 +48,10 @@ FILES = \
postplot.ps \
postprint.ps \
posttek.ps \
- ps.requests
+ ps.requests \
+ tsol_banner.ps \
+ tsol_separator.ps \
+ tsol_trailer.ps
ROOTPOSTFILES= $(FILES:%=$(ROOTLIBLPPOST)/%)
diff --git a/usr/src/cmd/lp/filter/postscript/postscript/tsol_banner.ps b/usr/src/cmd/lp/filter/postscript/postscript/tsol_banner.ps
new file mode 100644
index 0000000000..babf5df1c5
--- /dev/null
+++ b/usr/src/cmd/lp/filter/postscript/postscript/tsol_banner.ps
@@ -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 2007 Sun Microsystems, Inc. All rights reserved.
+% Use is subject to license terms.
+%
+%ident "%Z%%M% %I% %E% SMI"
+%
+% works in conjunction with tsol_separator.ps to do a banner page
+%
+
+SeparatorPagesDict /Banner get exec
diff --git a/usr/src/cmd/lp/filter/postscript/postscript/tsol_separator.ps b/usr/src/cmd/lp/filter/postscript/postscript/tsol_separator.ps
new file mode 100644
index 0000000000..50c4820551
--- /dev/null
+++ b/usr/src/cmd/lp/filter/postscript/postscript/tsol_separator.ps
@@ -0,0 +1,687 @@
+%
+% 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 2007 Sun Microsystems, Inc. All rights reserved.
+% Use is subject to license terms.
+%
+%ident "%Z%%M% %I% %E% SMI"
+%
+%% This PostScript file is normally used as input to the lp.tsol_separator
+%% program, which will prepend code to set the values of a number of
+%% variables. lp.tsol_separator is called by the printer interface script.
+
+%% This PostScript file may be modified for local customizations or
+%% internationalization. Comments marked "INTERNATIONALIZE:" show
+%% places where changes may be made for internationalization. Comments
+%% marked "CUSTOMIZE:" show places where some typical customization
+%% changes may be made.
+
+
+%% The following comments describe variables set by lp.tsol_separator
+
+%% These variables are from the print job information that can be
+%% displayed with lpstat or lpq.
+%%
+%% /Job_Classification The classification (from the sensitivity label) to
+%% be displayed at the top and bottom of the banner
+%% /Job_Printer Printer Name
+%% /Job_Host Host job was submitted from
+%% /Job_User User who submitted the job
+%% /Job_JobID Job number
+%% /Job_Title Job title
+%%
+%%
+%% This variable is NO if an authorized user used the lp -o nobanner option
+%% and the printer was set up to allow bannerless jobs. Otherwise it is YES.
+%%
+%% /Job_DoPageLabels Print page labels YES/NO.
+%%
+%% These variables are generated from the system clock value.
+%%
+%% /Job_Date Date and time the job is being printed, in the
+%% locale's default format
+%% /Job_Hash A randomly generatred identifying number for
+%% matching up the banner and trailer pages of the job
+%%
+%%
+%% The following variables are the job's labels
+%% as interpreted by the bcltobanner(3TSOL) library routine.
+%%
+%% /Job_Classification The classification (from the sensitivity label) to be
+%% displayed at the top and bottom of the banner page.
+%% /Job_Protect The sensitivity label to be displayed in the protect-as
+%% field.
+%% /Job_Caveats The caveats from the sesitivity label.
+%% /Job_Channels The channels from the sesitivity label.
+%%
+%%
+%% The following variables are the job's Sensitivity Label and
+%% Information Label as interpreted by the bsltos and biltos library
+%% routines.
+%%
+%% /Job_SL_Internal The sensitivity label in internal view format.
+%% /Job_SL_External The sensitivity label in external view format.
+
+/SeparatorPagesDict 100 dict def
+userdict /JobDict known not {
+ userdict /JobDict 100 dict put
+} if
+
+SeparatorPagesDict
+begin
+
+ %% CUSTOMIZE: To print header page label left-justified, set this to false
+ /center_label true def
+
+ /center_show where {
+ pop
+ } {
+ userdict /center_show
+ {
+ dup stringwidth exch
+ 2 div neg exch rmoveto show
+ } put
+ } ifelse
+
+ /append where
+ { pop }
+ {
+ /append
+ {
+ 1 index length 1 index length add
+ 1 index dup type /dicttype eq
+ {
+ pop dict
+ begin
+ exch { def } forall
+ { def } forall
+ currentdict
+ end
+ }
+ {
+ /arraytype eq { array } { string } ifelse
+ dup 4 -1 roll 1 index copy length 4 -1 roll putinterval
+ }
+ ifelse
+ } def
+ } ifelse
+
+ /fontheight
+ systemdict /fontheight known
+ { systemdict /fontheight get }
+ {
+ {
+ gsave
+ setfont (qf) true charpath flattenpath pathbbox
+ 4 -1 roll pop exch pop exch sub
+ grestore
+ }
+ } ifelse
+ def
+
+ /m { moveto } def
+ /r { rmoveto } def
+ /rl { rlineto } def
+
+ /NewLine {
+ currentpoint exch pop
+ currentfont fontheight sub errorx0 exch moveto
+ } def
+
+ /clipSL {
+ /MaxWidth exch def
+ dup stringwidth pop MaxWidth gt {
+ {
+ dup stringwidth pop (<-) stringwidth pop add MaxWidth le {exit} if
+ dup 0 exch length 1 sub getinterval
+ } loop
+ (<-)
+ %% Concatenate strings
+ dup length 2 index length add 1 index pop string
+ dup 0 4 index putinterval
+ dup 4 -1 roll length 4 -1 roll putinterval
+ } if
+ } def
+
+ /BreakWithBlanks {
+
+ {restoftext ( ) search
+ {
+ /blank_nextword exch def pop
+ /blank_restoftext exch def
+ /blank_wordwidth blank_nextword stringwidth pop def
+
+ restoftext (/) search
+ {
+ /slash_nextword exch def pop
+ /slash_restoftext exch def
+ /slash_wordwidth slash_nextword stringwidth pop def
+
+ blank_wordwidth slash_wordwidth lt
+ {
+ /nextword blank_nextword def
+ /restoftext blank_restoftext def
+ /wordwidth blank_wordwidth def
+ /breakwidth ( ) stringwidth pop def
+ }
+ {
+ /nextword slash_nextword def
+ /restoftext slash_restoftext def
+ /wordwidth slash_wordwidth def
+ /breakwidth (/) stringwidth pop def
+ }ifelse
+ }
+ {
+ pop
+ /nextword blank_nextword def
+ /restoftext blank_restoftext def
+ /wordwidth blank_wordwidth def
+ /breakwidth ( ) stringwidth pop def
+ }ifelse
+
+ curwidth wordwidth add linewidth gt
+ {textstring startchar
+ lastwordbreak startchar sub
+ getinterval proc
+ /startchar lastwordbreak def
+ /curwidth wordwidth breakwidth add def }
+
+ {/curwidth curwidth wordwidth add
+ breakwidth add def
+ } ifelse
+ /lastwordbreak lastwordbreak
+ nextword length add 1 add def
+ }
+ {pop BreakWithSlashes exit}
+ ifelse
+ }loop
+}def
+
+ /BreakWithSlashes
+ {
+ /breakchar (/) def
+ /breakwidth breakchar stringwidth pop def
+ {restoftext breakchar search
+ {/nextword exch def pop
+ /restoftext exch def
+ /wordwidth nextword stringwidth pop def
+
+ curwidth wordwidth add linewidth gt
+ {textstring startchar
+ lastwordbreak startchar sub
+ getinterval proc
+ /startchar lastwordbreak def
+ /curwidth wordwidth breakwidth add def }
+
+ {/curwidth curwidth wordwidth add
+ breakwidth add def
+ } ifelse
+ /lastwordbreak lastwordbreak
+ nextword length add 1 add def
+ }
+ {pop exit}
+ ifelse
+ }loop
+ }def
+
+ /BreakIntoLines
+ {/proc exch def
+ /linewidth exch 40 sub def
+ /textstring exch def
+
+ /curwidth 0 def
+ /lastwordbreak 0 def
+ /startchar 0 def
+ /restoftext textstring def
+
+ % begin scale the font if necessary
+
+ /allowedarea linewidth fbh 10 div mul def
+ /currentarea currentfont fontheight textstring stringwidth pop mul def
+
+ currentarea allowedarea gt
+ {
+ currentfont allowedarea currentarea div scalefont setfont
+ }if
+
+ % end scale the font if necessary
+
+ BreakWithBlanks
+ /lastchar textstring length def
+ textstring startchar lastchar startchar sub
+ getinterval proc
+ }def
+
+
+ /ShowBanner {
+ JobDict /Job_Proclam? get {
+ systemdict /showpage get cvx exec
+ } if
+ } def
+
+ /Init {
+
+ initgraphics
+ /#copies 1 def
+ initmatrix
+ erasepage
+
+ clippath pathbbox /fbh exch def
+ /fbw exch def
+ pop pop newpath
+ 0 0 moveto
+ 0 fbh translate
+ 0 0 moveto
+
+ /margin fbh 20 div def
+ /imargin margin 1.1 mul def
+ /errorx0 imargin def
+ /errorx1 fbw imargin sub def
+ /errory1 imargin def
+
+ gsave
+ } def
+
+% this stuff is lpd dependant.
+
+ /lpdglue {
+ userdict
+ begin
+ JobDict
+ begin
+ % If Job_Printer is defined, assume the others are too,
+ /Job_Printer where
+ {
+ pop
+ /Job_Proclam? true def
+ /Job_Endclam? true def
+
+ /Printer Job_Printer def
+ /Host Job_Host def
+ /User Job_User def
+ /Title Job_Title def
+ /JobID Job_JobID def
+ /Date Job_Date def
+
+ %% CUSTOMIZE: To use a different string at the top and
+ %% bottom of each page, change the following line. For
+ %% instance, to use the sensitivity label in external view
+ %% format, change the line to: /PageLabel Job_SL_External def
+ %% To eliminate page labels completely, change this line to
+ %% set the page label to an empty string: /PageLabel () def
+ /PageLabel Job_SL_Internal def
+ Job_Protect () eq
+ {
+ %% Job_Protect is empty because SLs are turned
+ %% off in secconf. (Turning off SLs is actually not yet
+ %% supported by the system.)
+ /Protect () def
+ /Protect_Text1 () def
+ /Protect_Text2 () def
+ }
+ {
+ %% INTERNATIONALIZE/CUSTOMIZE: Replace the text between
+ %% parentheses with the appropriate text to display
+ %% above and below the SL.
+ /Protect Job_Protect def
+ /Protect_Text1 (This output must be protected as:) def
+ /Protect_Text2 (unless manually reviewed and downgraded.) def
+ }
+ ifelse
+
+ %% CUSTOMIZE: To not print the caveats, change
+ %% this line to /Caveats () def
+ /Caveats Job_Caveats def
+ %% CUSTOMIZE: To not print the channels, change
+ %% this line to /Channels () def
+ /Channels Job_Channels def
+
+ %% CUSTOMIZE: To not print the hash number, change
+ %% this line to /Hash () def
+ /Hash Job_Hash def
+
+ %% CUSTOMIZE: To not print the head label, change
+ %% this line to /HeadLabel () def
+ %% You may also substitute another string. For example, to use
+ %% the SL in internal view format: /HeadLabel Job_SL_Internal def
+ /HeadLabel Job_Classification def
+ } {
+ /Job_Proclam? false def
+ /Job_Endclam? false def
+ } ifelse
+ end
+ end
+ } def
+
+ /border {
+ gsave
+ setlinewidth
+ setgray
+ 30 -20 moveto
+ 0 60 fbh sub rlineto
+ fbw 60 sub 0 rlineto
+ 0 fbh 60 sub rlineto
+ 60 currentlinewidth 2 div sub fbw sub 0 rlineto
+ stroke
+ grestore
+ } def
+
+ /TSOLJobInfo {
+ gsave
+
+ /fontscale fbh 50 div def
+ /Courier-Bold findfont fontscale scalefont setfont
+ /ClippedLabel
+ JobDict /HeadLabel get
+ SeparatorPagesDict /fbw get 90 sub
+ SeparatorPagesDict /clipSL get exec
+ def
+
+ /head_len {
+ ClippedLabel stringwidth pop 5 add
+ HeadLabel () eq { pop 0 } if
+ } def
+ 15 setlinewidth
+ fbw 2 div head_len 2 div sub -20 moveto
+ head_len 0 rlineto stroke
+ 1 setgray
+ fbw 10 div -25 m gsave ClippedLabel
+ currentpoint exch pop fbw 2 div exch moveto
+ center_show NewLine grestore
+
+ 0 setgray
+ /fontscale fbh 70 div def
+
+ /Helvetica findfont fontscale scalefont setfont
+ 0 fbh 8 div neg r Protect_Text1
+ currentpoint exch pop
+ center_label {
+ fbw 2 div exch moveto center_show
+ }
+ {
+ fbw 10 div exch moveto show
+ }
+ ifelse
+ /fontscale fbh 60 div def
+ /Helvetica-Bold findfont fontscale scalefont setfont
+
+ 0 fbh 150 div neg r
+ Protect
+ fbw errorx0 3 mul sub % width minus margins
+
+ center_label {
+ {NewLine currentpoint exch pop fbw 2 div exch moveto center_show}
+ BreakIntoLines
+ }
+ {
+ {NewLine currentpoint exch pop fbw 10 div exch moveto show}
+ BreakIntoLines
+ }
+ ifelse
+
+ /fontscale fbh 70 div def
+ /Helvetica findfont fontscale scalefont setfont
+ 0 fbh 50 div neg r Protect_Text2
+ currentpoint exch pop
+ center_label {
+ fbw 2 div exch moveto center_show
+ }
+ {
+ fbw 10 div exch moveto show
+ }
+ ifelse
+
+ /fontscale fbh 60 div def
+ /Helvetica-Bold findfont fontscale scalefont setfont
+ 0 fbh 200 div neg r
+
+ 0 fbh 10 div neg r
+
+ /fontscale fbh 40 div def
+ /Helvetica-Bold findfont fontscale scalefont setfont
+
+ 0 fbh 30 div neg r gsave
+ %% INTERNATIONALIZE: Replace the text between
+ %% parentheses with the appropriate text.
+ (User: ) User (@) Host append append append
+ currentpoint exch pop fbw 2 div exch moveto center_show
+ NewLine grestore
+ 0 fbh 30 div neg r gsave
+ %% INTERNATIONALIZE: Replace the text between
+ %% parentheses with the appropriate text.
+ (Job: ) JobID append
+ currentpoint exch pop fbw 2 div exch moveto center_show
+ NewLine grestore
+ 0 fbh 30 div neg r gsave
+ Title
+ currentpoint exch pop fbw 2 div exch moveto center_show
+ NewLine grestore
+ /fontscale fbh 70 div def
+ /Helvetica findfont fontscale scalefont setfont
+ 0 fbh 30 div neg r gsave
+ %% INTERNATIONALIZE: Replace the text between
+ %% parentheses with the appropriate text.
+ (Printed at: ) Date append
+ currentpoint exch pop fbw 2 div exch moveto center_show
+ NewLine grestore
+ 0 fbh 30 div neg r gsave
+ %% INTERNATIONALIZE: Replace the text between
+ %% parentheses with the appropriate text.
+ (Printer queue: ) Printer append
+ currentpoint exch pop fbw 2 div exch moveto center_show
+ NewLine grestore
+
+ /Helvetica-Bold findfont fontscale scalefont setfont
+ 0 fbh 20 div neg r
+ Caveats
+ fbw errorx0 3 mul sub % width minus margins
+ {NewLine currentpoint exch pop fbw 2 div exch moveto center_show}
+ BreakIntoLines
+
+ 0 fbh 30 div neg r
+ Channels
+ fbw errorx0 3 mul sub % width minus margins
+ {NewLine currentpoint exch pop fbw 2 div exch moveto center_show}
+ BreakIntoLines
+
+ /fontscale fbh 50 div def
+ /Courier-Bold findfont fontscale scalefont setfont
+ 15 setlinewidth
+ fbw 2 div head_len 2 div sub 40 fbh sub moveto
+ head_len 0 rlineto stroke
+ 1 setgray
+ fbw 10 div 35 fbh sub m gsave ClippedLabel
+ currentpoint exch pop fbw 2 div exch moveto center_show
+ NewLine grestore
+
+ grestore
+ } def
+
+ /JobHashInfo {
+ gsave
+ 0 setgray
+ /fontscale fbh 50 div def
+ /Helvetica-Bold findfont fontscale scalefont setfont
+
+ %% Upper left corner
+ Hash
+ fbw 12 div 50 neg m gsave show grestore
+
+ %% Lower left corner
+ Hash
+ fbw 12 div fbh 60 sub neg m gsave show grestore
+
+ %% Lower right corner
+ Hash dup stringwidth pop
+ fbw 11 mul 12 div exch sub fbh 60 sub neg m gsave show grestore
+
+ %% Upper right corner
+ Hash dup stringwidth pop
+ fbw 11 mul 12 div exch sub 50 neg m gsave show grestore
+
+ /fontscale fbh 40 div def
+ /Helvetica-Bold findfont fontscale scalefont setfont
+ fbw 10 div 120 fbh sub m gsave
+ currentpoint exch pop fbw 2 div exch moveto center_show
+
+ grestore
+ } def
+
+
+ /jobproclam {
+ JobDict
+ begin
+ Job_Proclam?
+ %% INTERNATIONALIZE: Replace the text between
+ %% parentheses with the appropriate text.
+ { TSOLJobInfo (JOB START) JobHashInfo}
+ { 0 -100 rmoveto }
+ ifelse
+ end
+ } def
+
+ /jobendclam {
+ JobDict
+ begin
+ Job_Endclam?
+ %% INTERNATIONALIZE: Replace the text between
+ %% parentheses with the appropriate text.
+ { TSOLJobInfo (JOB END) JobHashInfo}
+ { 0 -100 rmoveto }
+ ifelse
+ end
+ } def
+
+
+ /JobProclam {
+ jobproclam
+ } def
+
+ /JobEndclam {
+ jobendclam
+ } def
+
+% A fancy box around page
+
+ /BannerBorder {
+ .7 16 border
+ } def
+
+ /TrailerBorder {
+ 0 4 border
+ } def
+
+%
+% -------------------------------------------------------------------------
+%
+% The structure of separator pages is defined below. This is invoked by
+% using a line like:
+%
+% SeparatorPagesDict /Banner get exec
+%
+
+ /Banner {
+ SeparatorPagesDict
+ begin
+ Init
+ lpdglue
+ BannerBorder
+ JobProclam
+ /SkipPageLabels true def
+ ShowBanner
+ /SkipPageLabels false def
+ end
+ } def
+
+ /Trailer {
+ SeparatorPagesDict
+ begin
+ Init
+ lpdglue
+ TrailerBorder
+ JobEndclam
+ /SkipPageLabels true def
+ ShowBanner
+ /SkipPageLabels false def
+ end
+ } def
+
+ /SkipPageLabels false def
+end
+
+SeparatorPagesDict begin
+ clippath pathbbox /fbh exch def
+ /fbw exch def
+ pop pop
+ lpdglue
+end
+
+
+JobDict /Job_DoPageLabels get (YES) eq
+ JobDict /PageLabel get () ne and {
+ userdict begin
+ /showpage {
+ SeparatorPagesDict /SkipPageLabels get false eq {
+ gsave
+ initgraphics
+ /Courier-Bold findfont
+ 12 scalefont setfont
+
+ /ClippedLabel
+ JobDict /PageLabel get
+ SeparatorPagesDict /fbw get 60 sub
+ SeparatorPagesDict /clipSL get exec
+ def
+
+ /inf_len {
+ ClippedLabel stringwidth pop 6 add
+ } def
+
+ /page_mid SeparatorPagesDict /fbw get 2 div def
+
+ 10 setlinewidth
+
+ % print label for bottom of page
+ 0 setgray
+ page_mid inf_len 2 div sub 17 moveto
+ inf_len 0 rlineto stroke
+
+ 1 setgray
+ page_mid inf_len 2 div sub 14 moveto
+ ClippedLabel show
+
+ % print label for top of page
+ 0 setgray
+ page_mid inf_len 2 div sub
+ SeparatorPagesDict /fbh get 5 sub moveto
+ inf_len 0 rlineto stroke
+
+ 1 setgray
+ page_mid inf_len 2 div sub SeparatorPagesDict /fbh get 8
+ sub moveto ClippedLabel show
+ grestore
+ } if
+ systemdict /showpage get cvx exec
+ } bind def
+ end
+}if
+
+%% End of tsol_separator.ps
diff --git a/usr/src/cmd/lp/filter/postscript/postscript/tsol_trailer.ps b/usr/src/cmd/lp/filter/postscript/postscript/tsol_trailer.ps
new file mode 100644
index 0000000000..f716b3df06
--- /dev/null
+++ b/usr/src/cmd/lp/filter/postscript/postscript/tsol_trailer.ps
@@ -0,0 +1,29 @@
+%
+% 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 2007 Sun Microsystems, Inc. All rights reserved.
+% Use is subject to license terms.
+%
+%ident "%Z%%M% %I% %E% SMI"
+%
+% used in conjunction with tsol_separator.ps to create a trailer page
+%
+SeparatorPagesDict /Trailer get exec
diff --git a/usr/src/cmd/lp/model/Makefile b/usr/src/cmd/lp/model/Makefile
index d7908bc388..5da2ee6539 100644
--- a/usr/src/cmd/lp/model/Makefile
+++ b/usr/src/cmd/lp/model/Makefile
@@ -34,6 +34,7 @@ SUBDIRS = netpr
PROG = lp.set \
lp.cat \
lp.tell \
+ lp.tsol_separator \
drain.output
SRCS = $(PROG:%=%.c)
@@ -42,6 +43,10 @@ OBJS = $(PROG:%=%.o)
MODELS = standard \
netstandard \
+ tsol_standard \
+ tsol_netstandard \
+ tsol_standard_foomatic \
+ tsol_netstandard_foomatic \
uri
MISC = alert.proto
@@ -59,6 +64,7 @@ CPPFLAGS = -I$(LPINC) $(CPPFLAGS.master)
# conditional assignments
lp.tell := LDLIBS += $(LIBMSG) $(LIBLP)
lp.set drain.output lp.cat := LDLIBS += $(LIBLP) -lcurses
+lp.tsol_separator := LDLIBS += -ltsol
$(ROOTMISC) := FILEMODE = 0444
diff --git a/usr/src/cmd/lp/model/lp.tsol_separator.c b/usr/src/cmd/lp/model/lp.tsol_separator.c
new file mode 100644
index 0000000000..a7ea55a154
--- /dev/null
+++ b/usr/src/cmd/lp/model/lp.tsol_separator.c
@@ -0,0 +1,528 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Add TSOL banner, trailer, page header/footers to a print job
+ */
+
+/* system header files */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <limits.h>
+#include <errno.h>
+#include <signal.h>
+#include <locale.h>
+#include <tsol/label.h>
+
+/* typedefs */
+
+typedef int BOOL;
+
+/* constants */
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#define ME "lp.tsol_separator"
+#define POSTSCRIPTLIB "/usr/lib/lp/postscript"
+#define SEPARATORPS "tsol_separator.ps"
+#define BANNERPS "tsol_banner.ps"
+#define TRAILERPS "tsol_trailer.ps"
+#define MAXUSERLEN 32
+#define MAXHOSTLEN 32
+
+/* external variables */
+
+int optind; /* Used by getopt */
+char *optarg; /* Used by getopt */
+
+/* prototypes for static functions */
+
+static int ProcessArgs(int argc, char **argv);
+static void Usage(void);
+static void ParseUsername(char *input, char *user, char *host);
+static void EmitPSFile(const char *name);
+static BOOL EmitFile(FILE *file);
+static void EmitJobData(void);
+static void EmitPrologue(void);
+static void EmitCommandLineInfo(void);
+static void EmitClockBasedInfo(void);
+static void EmitLabelInfo(void);
+static void CopyStdin(void);
+
+/* static variables */
+
+static char *ArgSeparatorPS;
+static char *ArgBannerPS;
+static char *ArgTrailerPS;
+static char *ArgPSLib;
+static char *ArgPrinter;
+static char *ArgJobID;
+static char *ArgUser;
+static char *ArgTitle;
+static char *ArgFile;
+static BOOL ArgReverse;
+static BOOL ArgNoPageLabels;
+static int ArgDebugLevel;
+static FILE *ArgLogFile;
+static m_label_t *FileLabel;
+static char *remoteLabel;
+
+int
+main(int argc, char *argv[])
+{
+ int err;
+ /*
+ * Run immune from typical interruptions, so that
+ * we stand a chance to get the fault message.
+ * EOF (or startup error) is the only way out.
+ */
+ (void) signal(SIGHUP, SIG_IGN);
+ (void) signal(SIGINT, SIG_IGN);
+ (void) signal(SIGQUIT, SIG_IGN);
+ (void) signal(SIGTERM, SIG_IGN);
+
+ (void) setlocale(LC_ALL, "");
+#if !defined(TEXT_DOMAIN)
+#define TEXT_DOMAIN "SYS_TEST"
+#endif
+ (void) textdomain(TEXT_DOMAIN);
+
+ if (ProcessArgs(argc, argv) != 0)
+ exit(1);
+
+ if ((FileLabel = m_label_alloc(MAC_LABEL)) == NULL)
+ exit(1);
+ /*
+ * If the job was submitted via remotely, the label of the
+ * remote peer will be set in the SLABEL environment variable
+ * by copying it out of the SECURE structure.
+ *
+ * If there is no SLABEL value, the job was submitted locally
+ * via the named pipe, and the file label can be determined
+ * from its pathname.
+ */
+ if ((remoteLabel = getenv("SLABEL")) != NULL) {
+ m_label_free(FileLabel);
+ FileLabel = NULL;
+ if (str_to_label(remoteLabel, &FileLabel, MAC_LABEL,
+ L_NO_CORRECTION, &err) == -1) {
+ perror("str_to_label");
+ exit(1);
+ }
+ } else if (getlabel(ArgFile, FileLabel) != 0) {
+ (void) fprintf(ArgLogFile,
+ gettext("%1$s: cannot get label of %2$s: %3$s\n"),
+ ME, ArgFile, strerror(errno));
+ exit(1);
+ }
+
+ /* All of these functions exit if they encounter an error */
+ EmitJobData();
+ EmitPSFile(ArgSeparatorPS);
+ if (ArgReverse)
+ EmitPSFile(ArgTrailerPS);
+ else
+ EmitPSFile(ArgBannerPS);
+ CopyStdin();
+ if (ArgReverse)
+ EmitPSFile(ArgBannerPS);
+ else
+ EmitPSFile(ArgTrailerPS);
+ if (ArgDebugLevel >= 1)
+ (void) fprintf(ArgLogFile, gettext("Done.\n"));
+ m_label_free(FileLabel);
+ return (0);
+}
+
+static void
+EmitJobData(void)
+{
+ EmitPrologue();
+ EmitCommandLineInfo();
+ EmitClockBasedInfo();
+ EmitLabelInfo();
+
+ /* Emit ending PostScript code */
+ (void) printf("end\n\n");
+ (void) printf("%%%% End of code generated by lp.tsol_separator\n\n");
+
+}
+
+static void
+EmitPrologue(void)
+{
+ /* Emit preliminary PostScript code */
+ (void) printf("%%!\n\n");
+ (void) printf("%%%% Begin code generated by lp.tsol_separator\n\n");
+
+ (void) printf("%%%% Create JobDict if it doesn't exist\n");
+ (void) printf("userdict /JobDict known not {\n");
+ (void) printf(" userdict /JobDict 100 dict put\n");
+ (void) printf("} if\n\n");
+
+ (void) printf("%%%% Define job parameters, including TSOL security "
+ "info\n");
+ (void) printf("JobDict\n");
+ (void) printf("begin\n");
+}
+
+/* Emit parameters obtained from command line options */
+
+static void
+EmitCommandLineInfo(void)
+{
+ char user[MAXUSERLEN + 1];
+ char host[MAXHOSTLEN + 1];
+
+ (void) printf("\t/Job_Printer (%s) def\n", ArgPrinter);
+ ParseUsername(ArgUser, user, host);
+ (void) printf("\t/Job_Host (%s) def\n", host);
+ (void) printf("\t/Job_User (%s) def\n", user);
+ (void) printf("\t/Job_JobID (%s) def\n", ArgJobID);
+ (void) printf("\t/Job_Title (%s) def\n", ArgTitle);
+ (void) printf("\t/Job_DoPageLabels (%s) def\n",
+ ArgNoPageLabels ? "NO" : "YES");
+ (void) printf("\n");
+}
+
+/* Emit parameters generated from the system clock */
+
+static void
+EmitClockBasedInfo(void)
+{
+ char timebuf[80];
+ struct timeval clockval;
+
+ (void) gettimeofday(&clockval, NULL);
+ (void) strftime(timebuf, sizeof (timebuf), NULL,
+ localtime(&clockval.tv_sec));
+ (void) printf("\t/Job_Date (%s) def\n", timebuf);
+ (void) printf("\t/Job_Hash (%ld) def\n", clockval.tv_usec % 100000L);
+ (void) printf("\n");
+}
+
+/* Emit parameters derived from the SL and IL of the file being printed. */
+
+static void
+EmitLabelInfo(void)
+{
+ char *header = NULL; /* DIA banner page fields */
+ char *label = NULL;
+ char *caveats = NULL;
+ char *channels = NULL;
+ char *page_label = NULL; /* interior pages label */
+
+ if (label_to_str(FileLabel, &header, PRINTER_TOP_BOTTOM,
+ DEF_NAMES) != 0) {
+ (void) fprintf(ArgLogFile,
+ gettext("%s: label_to_str PRINTER_TOP_BOTTOM: %s.\n"),
+ ME, strerror(errno));
+ exit(1);
+ }
+ if (label_to_str(FileLabel, &label, PRINTER_LABEL,
+ DEF_NAMES) != 0) {
+ (void) fprintf(ArgLogFile,
+ gettext("%s: label_to_str PRINTER_LABEL: %s.\n"),
+ ME, strerror(errno));
+ exit(1);
+ }
+ if (label_to_str(FileLabel, &caveats, PRINTER_CAVEATS,
+ DEF_NAMES) != 0) {
+ (void) fprintf(ArgLogFile,
+ gettext("%s: label_to_str PRINTER_CAVEATS: %s.\n"),
+ ME, strerror(errno));
+ exit(1);
+ }
+ if (label_to_str(FileLabel, &channels, PRINTER_CHANNELS,
+ DEF_NAMES) != 0) {
+ (void) fprintf(ArgLogFile,
+ gettext("%s: label_to_str PRINTER_CHANNELS: %s.\n"),
+ ME, strerror(errno));
+ exit(1);
+ }
+ if (label_to_str(FileLabel, &page_label, M_LABEL,
+ LONG_NAMES) != 0) {
+ (void) fprintf(ArgLogFile,
+ gettext("%s: label_to_str M_LABEL: %s.\n"),
+ ME, strerror(errno));
+ exit(1);
+ }
+
+ (void) printf("\t/Job_Classification (%s) def\n", header);
+ (void) printf("\t/Job_Protect (%s) def\n", label);
+ (void) printf("\t/Job_Caveats (%s) def\n", caveats);
+ (void) printf("\t/Job_Channels (%s) def\n", channels);
+ (void) printf("\t/Job_SL_Internal (%s) def\n", page_label);
+
+ /* Free memory allocated label_to_str */
+ free(header);
+ free(label);
+ free(caveats);
+ free(channels);
+ free(page_label);
+}
+
+/*
+ * Parse input "host!user" to separate host and user names.
+ */
+
+static void
+ParseUsername(char *input, char *user, char *host)
+{
+ char *cp;
+
+ if ((cp = strchr(input, '@')) != NULL) {
+ /* user@host */
+ (void) strlcpy(host, cp + 1, MAXHOSTLEN + 1);
+ *cp = '\0';
+ (void) strlcpy(user, input, MAXUSERLEN + 1);
+ *cp = '@';
+ } else if ((cp = strchr(input, '!')) != NULL) {
+ /* host!user */
+ (void) strlcpy(user, cp + 1, MAXUSERLEN + 1);
+ *cp = '\0';
+ (void) strlcpy(host, input, MAXHOSTLEN + 1);
+ *cp = '!';
+ } else {
+ /* user */
+ (void) strlcpy(user, input, MAXUSERLEN + 1);
+ host[0] = '\0';
+ }
+}
+
+
+static void
+CopyStdin(void)
+{
+ if (!EmitFile(stdin)) {
+ (void) fprintf(ArgLogFile,
+ gettext("%s: Error copying stdin to stdout\n"), ME);
+ exit(1);
+ }
+}
+
+
+static BOOL
+EmitFile(FILE *file)
+{
+ int len;
+#define BUFLEN 1024
+ char buf[BUFLEN];
+
+ while ((len = fread(buf, 1, BUFLEN, file)) > 0) {
+ if (fwrite(buf, 1, len, stdout) != len)
+ return (FALSE);
+ }
+ if (!feof(file))
+ return (FALSE);
+ return (TRUE);
+}
+
+
+static void
+EmitPSFile(const char *name)
+{
+ char path[PATH_MAX];
+ FILE *file;
+ BOOL emitted;
+
+ if (name[0] != '/') {
+ (void) strlcpy(path, ArgPSLib, sizeof (path));
+ (void) strlcat(path, "/", sizeof (path));
+ (void) strlcat(path, name, sizeof (path));
+ } else {
+ (void) strlcpy(path, name, sizeof (path));
+ }
+
+ file = fopen(path, "r");
+ if (file == NULL) {
+ (void) fprintf(ArgLogFile,
+ gettext("%s: Error opening PostScript file %s. %s.\n"),
+ ME, path, strerror(errno));
+ exit(1);
+ }
+
+ emitted = EmitFile(file);
+ (void) fclose(file);
+ if (!emitted) {
+ (void) fprintf(ArgLogFile, gettext(
+ "%s: Error copying PostScript file %s to stdout.\n"),
+ ME, path);
+ exit(1);
+ }
+}
+
+
+static int
+ProcessArgs(int argc, char *argv[])
+{
+ int option_letter;
+ char *options_string = "lrd:e:s:b:t:L:";
+
+ /* set default values for arguments */
+ ArgSeparatorPS = SEPARATORPS;
+ ArgBannerPS = BANNERPS;
+ ArgTrailerPS = TRAILERPS;
+ ArgPSLib = POSTSCRIPTLIB;
+ ArgNoPageLabels = ArgReverse = FALSE;
+ ArgDebugLevel = 0;
+ ArgLogFile = stderr;
+
+ /* read switch arguments once to get error log file */
+ while ((option_letter = getopt(argc, argv, options_string)) != EOF) {
+ switch (option_letter) {
+ case 'd':
+ ArgDebugLevel = atoi(optarg);
+ break;
+ case 'e':
+ ArgLogFile = fopen(optarg, "a");
+ if (ArgLogFile == NULL) {
+ (void) fprintf(stderr,
+ gettext("Cannot open log file %s\n"),
+ optarg);
+ return (-1);
+ }
+ break;
+ case '?': /* ? or unrecognized option */
+ Usage();
+ return (-1);
+ }
+ }
+
+ if (ArgDebugLevel > 0)
+ (void) fprintf(ArgLogFile,
+ gettext("Processing switch arguments\n"));
+
+ /* re-read switch arguments */
+ optind = 1;
+ while ((option_letter = getopt(argc, argv, options_string)) != EOF) {
+ switch (option_letter) {
+ case 'd':
+ ArgDebugLevel = atoi(optarg);
+ break;
+ case 'e':
+ /* This was handled in earlier pass through args */
+ break;
+ case 'l':
+ ArgNoPageLabels = TRUE;
+ break;
+ case 'r':
+ ArgReverse = TRUE;
+ break;
+ case 's':
+ ArgSeparatorPS = optarg;
+ break;
+ case 'b':
+ ArgBannerPS = optarg;
+ break;
+ case 't':
+ ArgTrailerPS = optarg;
+ break;
+ case 'L':
+ ArgPSLib = optarg;
+ break;
+ case '?': /* ? or unrecognized option */
+ Usage();
+ return (-1);
+ }
+ }
+
+ /* Adjust arguments to skip over options */
+ argc -= optind; /* Number of remaining(non-switch) args */
+ argv += optind; /* argv[0] is first(non-switch) args */
+
+ if (argc != 5) {
+ (void) fprintf(ArgLogFile,
+ gettext("Wrong number of arguments.\n\n"));
+ Usage();
+ return (-1);
+ }
+
+ ArgPrinter = argv++[0];
+ ArgJobID = argv++[0];
+ ArgUser = argv++[0];
+ ArgTitle = argv++[0];
+ ArgFile = argv++[0];
+
+ if (ArgDebugLevel >= 1) {
+ (void) fprintf(ArgLogFile, gettext("Arguments processed\n"));
+ (void) fprintf(ArgLogFile, gettext("Printer: %s\n"),
+ ArgPrinter);
+ (void) fprintf(ArgLogFile, gettext("Job ID: %s\n"), ArgJobID);
+ (void) fprintf(ArgLogFile, gettext("User: %s\n"), ArgUser);
+ (void) fprintf(ArgLogFile, gettext("Title: %s\n"), ArgTitle);
+ (void) fprintf(ArgLogFile, gettext("File: %s\n"), ArgFile);
+ }
+
+ return (0);
+}
+
+
+static void
+Usage(void)
+{
+ static const char *OPTFMT = " %-8s %-9s %s\n";
+
+ (void) fprintf(ArgLogFile,
+ gettext("Usage: lp.tsol_separator [OPTIONS] %s\n"),
+ gettext("PRINTER JOBID HOST!USER TITLE FILE"));
+ (void) fprintf(ArgLogFile, gettext(" OPTIONS:\n"));
+ (void) fprintf(ArgLogFile, OPTFMT, "-r", gettext("Reverse"),
+ gettext("Reverse banner/trailer order"));
+ (void) fprintf(ArgLogFile, OPTFMT, "-l", gettext("Labels"),
+ gettext("Suppress page header/footer labels"));
+ (void) fprintf(ArgLogFile, OPTFMT, gettext("-b FILE"),
+ gettext("Banner"),
+ gettext("PostScript program for banner (default tsol_banner.ps)"));
+ (void) fprintf(ArgLogFile, OPTFMT, gettext("-s FILE"),
+ gettext("Separator"),
+ gettext("PostScript program for separator "
+ "(default tsol_separator.ps)"));
+ (void) fprintf(ArgLogFile, OPTFMT, gettext("-t FILE"),
+ gettext("Trailer"),
+ gettext("PostScript program for trailer "
+ "(default tsol_trailer.ps)"));
+ (void) fprintf(ArgLogFile, OPTFMT, gettext("-L DIR"),
+ gettext("Library"),
+ gettext("Directory to search for PostScript programs"));
+ (void) fprintf(ArgLogFile, OPTFMT, "", "",
+ gettext("(default /usr/lib/lp/postscript)"));
+ (void) fprintf(ArgLogFile, OPTFMT, gettext("-d N"), gettext("Debug"),
+ gettext("Set debug level to N"));
+ (void) fprintf(ArgLogFile, OPTFMT, gettext("-e FILE"),
+ gettext("Error File"),
+ gettext("Append error and debugging output to FILE"));
+}
diff --git a/usr/src/cmd/lp/model/tsol_netstandard b/usr/src/cmd/lp/model/tsol_netstandard
new file mode 100644
index 0000000000..6a04d5061d
--- /dev/null
+++ b/usr/src/cmd/lp/model/tsol_netstandard
@@ -0,0 +1,751 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+###########
+##
+## Network Standard printer interface program.
+##
+###########
+
+#####
+# We can't do much except exit if spooler/scheduler
+# cancels us.
+#####
+trap 'eval exit_clean 15' 15
+
+####
+#
+# Send standard error messages to /dev/null rather than to
+# the spooler. Avoids "Terminated" messages that shell puts out
+# when gets SIGTERM. Save standard error so it can be used
+# when we need it
+####
+exec 5>&2 2>/dev/null 3>&1
+
+####
+# set some global variables
+####
+
+: ${LPTMPDIR:=/tmp}
+: ${SPOOLDIR:=/usr/spool/lp}
+: ${LOCALPATH:=${SPOOLDIR}/bin}
+PATH="/bin:/usr/bin:${LOCALPATH}"
+exit_code=0
+
+
+# ${LPTELL} is the name of a program that will send its
+# standard input to the Spooler. It is used to forward
+# the description of a printer fault to the Spooler,
+# which uses it in an alert to the administrator.
+#####
+if [ ! -x "${LPTELL:=${LOCALPATH}/lp.tell}" ]
+then
+ fake_lptell () {
+ header="no"
+ while read line
+ do
+ if [ "no" = "${header}" ]
+ then
+ errmsg ERROR ${E_IP_UNKNOWN} \
+ "unknown printer/interface failure" \
+ "consult your system administrator;
+ reasons for failure (if any) follow:"
+ header=yes
+ fi
+ echo "${line}" >&2
+ done
+ return 1
+ }
+ LPTELL=fake_lptell
+fi
+
+#####
+# ${LPTSOLSEPARATOR} is the name of a program to put banner and trailer
+# pages around the job.
+#####
+if [ -x ${LOCALPATH}/lp.tsol_separator ]
+then
+ LPTSOLSEPARATOR=${LOCALPATH}/lp.tsol_separator
+else
+ echo "${LOCALPATH}/lp.tsol_separator not found." >&2
+ exit 1
+fi
+
+#####
+# Error message formatter:
+#
+# Invoke as
+#
+# errmsg severity message-number problem help
+#
+# where severity is "ERROR" or "WARNING", message-number is
+# a unique identifier, problem is a short description of the
+# problem, and help is a short suggestion for fixing the problem.
+#####
+
+LP_ERR_LABEL="UX:lp"
+E_IP_ARGS=1
+E_IP_OPTS=2
+#E_IP_FILTER=3
+E_IP_UNKNOWN=5
+E_IP_BADFILE=6
+E_IP_ERRORS=12 # (in slow.filter)
+
+errmsg () {
+
+ case $1 in
+ ERROR )
+ sev=" ERROR";
+ ;;
+ WARNING )
+ sev="WARNING";
+ ;;
+ esac
+
+ echo "${LP_ERR_LABEL}:$2 ${sev}: $3
+ TO FIX: $4" >&5
+}
+
+###########
+##
+## Check arguments
+###########
+
+parse () {
+ echo "`expr \"$1\" : \"^[^=]*=\(.*\)\"`"
+}
+
+#####
+##
+## Error Cleanup and Exit
+##
+#####
+
+exit_clean()
+{
+
+ if [ -f "${LPTMPDIR}/pr_eexit_code.$$" ]
+ then
+ /bin/rm ${LPTMPDIR}/pr_eexit_code.$$
+ fi
+
+ if [ -f "${LPTMPDIR}/small_banner.$$" ]
+ then
+ /bin/rm ${LPTMPDIR}/small_banner.$$
+ fi
+
+ if [ -f "${LPTMPDIR}/banner.exit_code.$$" ]
+ then
+ /bin/rm ${LPTMPDIR}/banner.exit_code.$$
+ fi
+
+ if [ -f "${LPTMPDIR}/banner.errmsg.$$" ]
+ then
+ /bin/rm ${LPTMPDIR}/banner.errmsg.$$
+ fi
+
+ if [ -f "${tmpfile}" ]
+ then
+ /bin/rm "${tmpfile}"
+ fi
+
+ exit $1
+}
+
+#####
+#
+# This program is invoked as
+#
+# ${SPOOLDIR}/.../printer request-id user title copies options files...
+#
+# The first three arguments are simply reprinted on the banner page,
+# the fourth (copies) is used to control the number of copies to print,
+# the fifth (options) is a blank separated list (in a single argument)
+# of user or Spooler supplied options (without the -o prefix),
+# and the last arguments are the files to print.
+#####
+
+if [ $# -lt 5 ]
+then
+
+ errmsg ERROR ${E_IP_ARGS} \
+ "wrong number of arguments to interface program" \
+ "consult your system administrator"
+ exit 1
+fi
+
+printer=`basename $0`
+request_id=$1
+user_name=$2
+title=$3
+copies=$4
+option_list=$5
+
+shift 5
+files="$*"
+
+
+#
+# debug sent to file if defined in /etc/syslog.conf
+# syslog.conf entry:
+# lpr.debug /path/filename
+#
+logger -p lpr.debug -t "tsol_netstandard: ${request_id}" " "
+logger -p lpr.debug -t "tsol_netstandard: ${request_id}" "INPUT"
+logger -p lpr.debug -t "tsol_netstandard: ${request_id}" " \
+ printer : ${printer}"
+logger -p lpr.debug -t "tsol_netstandard: ${request_id}" " \
+ request_id : ${request_id}"
+logger -p lpr.debug -t "tsol_netstandard: ${request_id}" " \
+ user_name : ${user_name}"
+logger -p lpr.debug -t "tsol_netstandard: ${request_id}" " title : ${title}"
+logger -p lpr.debug -t "tsol_netstandard: ${request_id}" " \
+ copies : ${copies}"
+logger -p lpr.debug -t "tsol_netstandard: ${request_id}" " \
+ option_list : ${option_list}"
+logger -p lpr.debug -t "tsol_netstandard: ${request_id}" " files : ${files}"
+logger -p lpr.debug -t "tsol_netstandard: ${request_id}" " \
+ spooler_key ${SPOOLER_KEY}"
+
+####
+# default: do print a banner
+####
+nobanner=no
+nolabels="no"
+nofilebreak="no"
+inlist=
+data_file_flag=
+
+for i in ${option_list}
+do
+ case "${inlist}${i}" in
+
+ nobanner )
+ nobanner="yes"
+ ;;
+
+ nofilebreak )
+ nofilebreak="yes"
+ ;;
+
+ nolabels )
+ nolabels="yes"
+ ;;
+
+ #####
+ #
+ # If you want to add simple options (e.g. -o simple)
+ # identify them here.
+ #####
+# simple )
+# simple="yes"
+# ;;
+
+ cpi=pica )
+ cpi=10
+ ;;
+ cpi=elite )
+ cpi=12
+ ;;
+ cpi=* )
+ cpi=`parse ${i}`
+ ;;
+
+ lpi=* )
+ lpi=`parse ${i}`
+ ;;
+
+ length=* )
+ length=`parse ${i}`
+ ;;
+
+ width=* )
+ width=`parse ${i}`
+ ;;
+ dest=* )
+ dest="-d `parse ${i}`"
+ ;;
+
+ protocol=* )
+ protocol="-P `parse ${i}`"
+ ;;
+ bsdctrl=* )
+ controlfile="-c `parse ${i}`"
+ ;;
+ timeout=* )
+ timeout="-t `parse ${i}`"
+ ;;
+
+ data-file-type=* )
+ data_file_flag="-f `parse ${i}`"
+ ;;
+
+ #####
+ #
+ # If you want to add simple-value options (e.g. -o value=a)
+ # identify them here.
+ #####
+# value=* )
+# value=`parse ${i}`
+# ;;
+
+ #####
+ #
+ # If you want to add options that,
+ # take a list (e.g. -o lopt='a b c'), identif
+ # them here and below (look for LOPT).
+ #####
+
+# flist=* | lpd=* | options=* )
+ flist=* | lpd=* )
+#LOPT stty=* | flist=* | lpd=* | lopt=* )
+
+ inlist=`expr "${inlist}${i}" : "^\([^=]*=\)"`
+ case "${i}" in
+ ${inlist}\'*\' )
+ item=`expr "${i}" : "^[^=]*='*\(.*\)'\$"`
+ ;;
+ ${inlist}\' )
+ continue
+ ;;
+ ${inlist}\'* )
+ item=`expr "${i}" : "^[^=]*='*\(.*\)\$"`
+ ;;
+ ${inlist}* )
+ item=`expr "${i}" : "^[^=]*=\(.*\)\$"`
+ ;;
+ *\' )
+ item=`expr "${i}" : "^\(.*\)'\$"`
+ ;;
+ * )
+ item="${i}"
+ ;;
+ esac
+
+ #####
+ #
+ # We don't dare use "eval" because a clever user could
+ # put something in an option value that we'd end up
+ # exec'ing.
+ #####
+ case "${inlist}" in
+ flist= )
+ flist="${flist} ${item}"
+ ;;
+ lpd= )
+ lpd="${lpd} ${item}"
+ ;;
+#LOPT lopt= )
+#LOPT lopt="${lopt} ${item}"
+#LOPT ;;
+# options= )
+# options="${options} ${item}"
+# ;;
+ esac
+
+ case "${i}" in
+ ${inlist}\'*\' )
+ inlist=
+ ;;
+ ${inlist}\'* )
+ ;;
+ *\' | ${inlist}* )
+ inlist=
+ ;;
+ esac
+ ;;
+
+ * )
+ errmsg WARNING ${E_IP_OPTS} \
+ "unrecognized \"-o ${i}\" option" \
+ "check the option, resubmit if necessary
+ printing continues"
+ ;;
+ esac
+done
+
+logger -p lpr.debug -t "tsol_netstandard: ${request_id}" "term : ${TERM}"
+
+if [ -z "${FILTER}" ]
+then
+ #####
+ #
+ # If no filter is being used, we use netpr to push the
+ # file to the printer.
+ # (QUOTES ARE IMPORTANT!)
+ #####
+
+ case "$TERM" in
+ PS )
+ # make the "postscript" printers use cat
+ # (TSOL banners are added during filtering, so we have
+ # to use some filter.)
+ FILTER=/bin/cat
+ ;;
+ PSR )
+ # make the "reverse postscript" printers reverse the
+ # output and the use postio to talk to the printer
+ #FILTER="/usr/lib/lp/postscript/postreverse "
+ #FILTER=
+ FILTER="/usr/lib/lp/postscript/postreverse "
+ ;;
+ * )
+ # We don't know the type, so just assume that the
+ # input and output are the same. Use netpr.
+ #FILTER=/bin/cat
+ FILTER=
+ ;;
+ esac
+fi
+
+####
+# sets default value for ordering of data and control files with
+# bsd protocol. Default: data files first. Administrator
+# may set to control file first with lpadmin -o bsdctrl=first
+####
+
+banner_flag=""
+case "${nobanner}" in
+ yes )
+ banner_flag="-b"
+ ;;
+esac
+
+NETPR="/usr/lib/lp/bin/netpr ${banner_flag} ${data_file_flag} \
+ -I ${request_id} -U ${user_name} \
+ -p ${printer} ${dest} -T \"${title}\" \
+ ${timeout} ${protocol} ${controlfile} "
+LPTELL_OPTS="-l" # netpr sends LaserWriter style messages back
+
+logger -p lpr.debug -t "tsol_netstandard: ${request_id}" "NETPR= ${NETPR}"
+logger -p lpr.debug -t "tsol_netstandard: ${request_id}" "filter : ${FILTER}"
+
+node=`uname -n`
+pid=$$
+tmpfile=${LPTMPDIR}/${node}.${pid}
+
+logger -p lpr.debug -t "tsol_netstandard: ${request_id}" "tmpfile : ${tmpfile}"
+
+#####
+#
+# Set up filter for banner page
+#
+#####
+banner_filter=
+case "${TERM}" in
+PS | PSR )
+ banner_filter=" | /usr/lib/lp/postscript/postprint "
+ LPTELL_OPTS="-l"
+ ;;
+esac
+
+#####
+#
+# Build temporary file that is the banner page
+#
+#####
+PAD="#####${NL}"
+CR="\r"
+NL="${CR}\n"
+FF=
+
+small_banner() {
+ echo "${CR}\c"
+ echo "${PAD}\c"
+ echo "##### User: ${user_name}${NL}\c"
+ if [ -n "${title}" ]
+ then
+ echo "##### Title: ${title}${NL}\c"
+ fi
+ echo "##### Date: `LANG=C date '+%a %H:%M %h %d, %Y'`${NL}\c"
+ echo "##### Job: ${request_id}${NL}\c"
+ echo "${PAD}\c"
+ if [ -n "${FF}" ]
+ then
+ echo "${CR}${FF}\c"
+ fi
+}
+
+#####
+#
+# Doing small banner as we don't know what printer is out there
+#
+#####
+banner=small_banner
+
+## Skip this for PS/PSR printers, since lp.tsol_separator handles the banners
+if [ "no" = "${nobanner}" -a "${TERM}" != "PSR" -a "${TERM}" != "PS" ]
+then
+ eval "${banner} ${banner_filter}" 2>&1 1>${LPTMPDIR}/small_banner.$$
+fi
+
+###########
+##
+## Surround the job by PostScript code to produce banner
+## and trailerpages and page headers and footers.
+##
+###########
+
+BANNER_EXIT_CODE=${LPTMPDIR}/banner.exit_code.$$
+echo 0 > ${BANNER_EXIT_CODE}
+TSOLSEPARATOR_LOG=${LPTMPDIR}/banner.errmsg.$$
+
+tsol_bannerize () {
+ TSOLSEPARATOR_OPTS="-e ${TSOLSEPARATOR_LOG}"
+
+ if [ "yes" = "${nolabels}" ]
+ then
+ TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -l"
+ fi
+
+ if [ "yes" = "${nobanner}" ]
+ then
+ TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -t /dev/null -b /dev/null"
+ fi
+
+ if [ "${TERM}" = "PSR" ]
+ then
+ TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -r"
+ fi
+
+ # Get rid of the #, TAB and NL characters in the title
+ tsol_title=`echo $title`
+ tsol_title=`echo $tsol_title | sed 's/#//g'`
+
+ logger -p lpr.debug -t "tsol_netstandard: ${request_id}" \
+ "banner command: ${LPTSOLSEPARATOR} ${TSOLSEPARATOR_OPTS} \
+ ${printer} ${request_id} ${user_name} \"${tsol_title}\" ${file}"
+ ${LPTSOLSEPARATOR} ${TSOLSEPARATOR_OPTS} ${printer} \
+ ${request_id} ${user_name} "${tsol_title}" ${file}
+
+ echo $? > ${BANNER_EXIT_CODE}
+ true
+}
+
+bannerize=tsol_bannerize
+
+if [ "yes" = "${nobanner}" -a "yes" = "${nolabels}" ]
+then
+ bannerize=cat
+fi
+
+if [ "${TERM}" != "PSR" -a "${TERM}" != "PS" ]
+then
+ bannerize=cat
+fi
+
+#####
+#
+# Print banner page before job unless PS or PSR.
+#
+#####
+
+if [ "no" = "${nobanner}" -a "${TERM}" != "PSR" -a "${TERM}" != "PS" ]
+then
+ (
+ eval ${NETPR} ${LPTMPDIR}/small_banner.$$ 2>&1
+ echo $? > ${LPTMPDIR}/pr_eexit_code.$$
+ ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
+
+ exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$`
+ logger -p lpr.debug -t "tsol_netstandard: ${request_id}" \
+ "banner page exit code : ${exit_code}"
+
+fi
+
+i=1
+while [ $i -le $copies ]
+do
+ for file in ${files}
+ do
+ if [ -r "${file}" ]
+ then
+
+ if [ ! -z "${FILTER}" ]
+ then
+ (
+ #####
+ # There is a filter, use it
+ #
+ # Put 0<${file} before the "eval" to keep
+ # clever users from giving a file name that
+ # evaluates as something to execute.
+ # Redirect stderr to stdout so LPTELL will
+ # get error messages from pipe.
+ #####
+ 0<${file} $bannerize | eval ${FILTER} 2>&1 1>${tmpfile}
+ echo $? > ${LPTMPDIR}/pr_eexit_code.$$
+ ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
+
+ # if lp.tsol_separator had an error, send its logged
+ # error message to LPTELL.
+ banner_exit_code=`cat ${BANNER_EXIT_CODE}`
+ if [ -n "${banner_exit_code}" -a \
+ 0 -ne "${banner_exit_code}" -a \
+ -n "${LPTELL}" -a \
+ -r "${TSOLSEPARATOR_LOG}" ]
+ then
+ cat ${TSOLSEPARATOR_LOG} | ${LPTELL} ${printer}
+ echo 77 > ${LPTMPDIR}/pr_eexit_code
+ fi
+
+ exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$`
+ logger -p lpr.debug \
+ -t "tsol_netstandard: ${request_id}" \
+ "filter exit_code : ${exit_code}"
+
+ if [ -n "${exit_code}" ]
+ then
+ if [ "${exit_code}" -eq 0 ]
+ then
+ printfile=${tmpfile}
+ else
+ ####
+ # The filter did not succeed, so don't try to print
+ ####
+ printfile=
+ fi
+ fi
+
+ else
+ printfile=${file}
+ fi
+
+ logger -p lpr.debug \
+ -t "tsol_netstandard: ${request_id}" \
+ "printfile : ${printfile}"
+
+ #####
+ # Print the file
+ #####
+
+ if [ -r "${printfile}" ]
+ then
+ (
+ eval ${NETPR} ${printfile} 2>&1
+ echo $? > ${LPTMPDIR}/pr_eexit_code.$$
+ ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
+
+ exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$`
+ logger -p lpr.debug \
+ -t "tsol_netstandard: ${request_id}" \
+ "netpr exit_code : ${exit_code}"
+
+# if [ -f "${tmpfile}" ]
+# then
+# /bin/rm "${tmpfile}"
+# fi
+
+ if [ -n "${exit_code}" ]
+ then
+ if [ "${exit_code}" -eq 0 ]
+ then
+ printone=yes
+ else
+ if [ "${exit_code}" -lt 128 ]
+ then
+ noprint=yes
+ else
+ retry=yes
+ fi
+ fi
+ fi
+
+
+ else
+
+ errmsg WARNING ${E_IP_BADFILE} \
+ "cannot read temporary file \"${printfile}\""\
+ "see if file still exists,
+ or consult your system administrator;
+ printing continues"
+
+ fi
+ else
+
+ #####
+ #
+ # Don't complain about not being able to read
+ # a file on second and subsequent copies, unless
+ # we've not complained yet. This removes repeated
+ # messages about the same file yet reduces the
+ # chance that the user can remove a file and not
+ # know that we had trouble finding it.
+ #####
+
+ if [ "${i}" -le 1 -o -z "${badfileyet}" ]
+ then
+ errmsg WARNING ${E_IP_BADFILE} \
+ "cannot read file \"${file}\"" \
+ "see if the file still exists and is readable,
+ or consult your system administrator;
+ printing continues"
+ badfileyet=yes
+ fi
+
+ fi
+
+# for file in ${files}
+ done
+ i=`expr $i + 1`
+done
+
+#####
+#
+# If printing in reverse order, print the banner page now
+# Skip this for TSOL, since lp.tsol_separator handles the banners
+#
+#####
+
+#
+# if [ "no" = "${nobanner}" -a "${TERM}" = "PSR" ]
+# then
+# (
+# eval ${NETPR} ${LPTMPDIR}/small_banner.$$ 2>&1
+# echo $? > ${LPTMPDIR}/pr_eexit_code.$$
+# ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
+# fi
+
+exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$`
+logger -p lpr.debug -t "tsol_netstandard: ${request_id}" \
+ "banner page exit code : ${exit_code}"
+
+if [ -n "${printone}" -a -z "${retry}" -a -z "${noprint}" ]
+then
+ exit_code=`expr 0`
+else
+ if [ -n "${retry}" -a -z "${printone}" -a -z "${noprint}" ]
+ then
+ exit_code=`expr 129`
+ else
+ exit_code=`expr 1`
+ fi
+fi
+
+logger -p lpr.debug -t "tsol_netstandard: ${request_id}" \
+ "FINAL exit_code : ${exit_code}"
+
+exit_clean ${exit_code}
diff --git a/usr/src/cmd/lp/model/tsol_netstandard_foomatic b/usr/src/cmd/lp/model/tsol_netstandard_foomatic
new file mode 100644
index 0000000000..b23d06a1ba
--- /dev/null
+++ b/usr/src/cmd/lp/model/tsol_netstandard_foomatic
@@ -0,0 +1,788 @@
+#
+# 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"
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#
+###########
+##
+## Network Standard printer interface program for foomatic.
+##
+###########
+
+#####
+# We can't do much except exit if spooler/scheduler
+# cancels us.
+#####
+trap 'eval exit_clean 15' 15
+
+####
+#
+# Send standard error messages to /dev/null rather than to
+# the spooler. Avoids "Terminated" messages that shell puts out
+# when gets SIGTERM. Save standard error so it can be used
+# when we need it
+####
+exec 5>&2 2>/dev/null 3>&1
+
+####
+# set some global variables
+####
+
+: ${LPTMPDIR:=/tmp}
+: ${SPOOLDIR:=/usr/spool/lp}
+: ${LOCALPATH:=${SPOOLDIR}/bin}
+PATH="/bin:/usr/bin:${LOCALPATH}"
+exit_code=0
+
+
+# ${LPTELL} is the name of a program that will send its
+# standard input to the Spooler. It is used to forward
+# the description of a printer fault to the Spooler,
+# which uses it in an alert to the administrator.
+#####
+if [ ! -x "${LPTELL:=${LOCALPATH}/lp.tell}" ]
+then
+ fake_lptell () {
+ header="no"
+ while read line
+ do
+ if [ "no" = "${header}" ]
+ then
+ errmsg ERROR ${E_IP_UNKNOWN} \
+ "unknown printer/interface failure" \
+ "consult your system administrator;
+ reasons for failure (if any) follow:"
+ header=yes
+ fi
+ echo "${line}" >&2
+ done
+ return 1
+ }
+ LPTELL=fake_lptell
+fi
+
+#####
+# ${LPTSOLSEPARATOR} is the name of a program to put banner and trailer
+# pages around the job.
+#####
+if [ -x ${LOCALPATH}/lp.tsol_separator ]
+then
+ LPTSOLSEPARATOR=${LOCALPATH}/lp.tsol_separator
+else
+ echo "${LOCALPATH}/lp.tsol_separator not found." >&2
+ exit 1
+fi
+
+#####
+# Error message formatter:
+#
+# Invoke as
+#
+# errmsg severity message-number problem help
+#
+# where severity is "ERROR" or "WARNING", message-number is
+# a unique identifier, problem is a short description of the
+# problem, and help is a short suggestion for fixing the problem.
+#####
+
+LP_ERR_LABEL="UX:lp"
+E_IP_ARGS=1
+E_IP_OPTS=2
+#E_IP_FILTER=3
+E_IP_UNKNOWN=5
+E_IP_BADFILE=6
+E_IP_ERRORS=12 # (in slow.filter)
+
+errmsg () {
+
+ case $1 in
+ ERROR )
+ sev=" ERROR";
+ ;;
+ WARNING )
+ sev="WARNING";
+ ;;
+ esac
+
+ echo "${LP_ERR_LABEL}:$2 ${sev}: $3
+ TO FIX: $4" >&5
+}
+
+###########
+##
+## Check arguments
+###########
+
+parse () {
+ echo "`expr \"$1\" : \"^[^=]*=\(.*\)\"`"
+}
+
+#####
+##
+## Error Cleanup and Exit
+##
+#####
+
+exit_clean()
+{
+
+ if [ -f "${LPTMPDIR}/pr_eexit_code.$$" ]
+ then
+ /bin/rm ${LPTMPDIR}/pr_eexit_code.$$
+ fi
+
+ if [ -f "${LPTMPDIR}/small_banner.$$" ]
+ then
+ /bin/rm ${LPTMPDIR}/small_banner.$$
+ fi
+
+ if [ -f "${LPTMPDIR}/banner.exit_code.$$" ]
+ then
+ /bin/rm ${LPTMPDIR}/banner.exit_code.$$
+ fi
+
+ if [ -f "${LPTMPDIR}/banner.errmsg.$$" ]
+ then
+ /bin/rm ${LPTMPDIR}/banner.errmsg.$$
+ fi
+
+ if [ -f "${tmpfile}" ]
+ then
+ /bin/rm "${tmpfile}"
+ fi
+
+ exit $1
+}
+
+#####
+#
+# This program is invoked as
+#
+# ${SPOOLDIR}/.../printer request-id user title copies options files...
+#
+# The first three arguments are simply reprinted on the banner page,
+# the fourth (copies) is used to control the number of copies to print,
+# the fifth (options) is a blank separated list (in a single argument)
+# of user or Spooler supplied options (without the -o prefix),
+# and the last arguments are the files to print.
+#####
+
+if [ $# -lt 5 ]
+then
+
+ errmsg ERROR ${E_IP_ARGS} \
+ "wrong number of arguments to interface program" \
+ "consult your system administrator"
+ exit 1
+fi
+
+printer=`basename $0`
+request_id=$1
+user_name=$2
+title=$3
+copies=$4
+option_list=$5
+
+shift 5
+files="$*"
+
+
+#
+# debug sent to file if defined in /etc/syslog.conf
+# syslog.conf entry:
+# lpr.debug /path/filename
+#
+logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" " "
+logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" "INPUT"
+logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
+ " printer : ${printer}"
+logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
+ " request_id : ${request_id}"
+logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
+ " user_name : ${user_name}"
+logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
+ " title : ${title}"
+logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
+ " copies : ${copies}"
+logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
+ " option_list : ${option_list}"
+logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
+ " files : ${files}"
+logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
+ " spooler_key ${SPOOLER_KEY}"
+
+####
+# default: do print a banner
+####
+nobanner=no
+nolabels="no"
+nofilebreak="no"
+inlist=
+data_file_flag=
+
+for i in ${option_list}
+do
+ case "${inlist}${i}" in
+
+ nobanner )
+ nobanner="yes"
+ ;;
+
+ nofilebreak )
+ nofilebreak="yes"
+ ;;
+
+ nolabels )
+ nolabels="yes"
+ ;;
+
+ #####
+ #
+ # If you want to add simple options (e.g. -o simple)
+ # identify them here.
+ #####
+# simple )
+# simple="yes"
+# ;;
+
+ cpi=pica )
+ cpi=10
+ ;;
+ cpi=elite )
+ cpi=12
+ ;;
+ cpi=* )
+ cpi=`parse ${i}`
+ ;;
+
+ lpi=* )
+ lpi=`parse ${i}`
+ ;;
+
+ length=* )
+ length=`parse ${i}`
+ ;;
+
+ width=* )
+ width=`parse ${i}`
+ ;;
+ dest=* )
+ dest="-d `parse ${i}`"
+ ;;
+
+ protocol=* )
+ protocol="-P `parse ${i}`"
+ ;;
+ bsdctrl=* )
+ controlfile="-c `parse ${i}`"
+ ;;
+ timeout=* )
+ timeout="-t `parse ${i}`"
+ ;;
+
+ data-file-type=* )
+ data_file_flag="-f `parse ${i}`"
+ ;;
+
+ #
+ # The IPP/PAPI attributes are handled by the foomatic-rip filter so
+ # all we need to do here is ignore them so that they don't invoke the
+ # "unrecognized option" message.
+ #
+
+ finishing=* | page-ranges=* | sides=* )
+ ;;
+ number-up=* | orientation-requested=* | media=* )
+ ;;
+ printer-resolution=* | print-quality=* )
+ ;;
+
+ #####
+ #
+ # If you want to add simple-value options (e.g. -o value=a)
+ # identify them here.
+ #####
+# value=* )
+# value=`parse ${i}`
+# ;;
+
+ #####
+ #
+ # If you want to add options that,
+ # take a list (e.g. -o lopt='a b c'), identif
+ # them here and below (look for LOPT).
+ #####
+
+# flist=* | lpd=* | options=* )
+ flist=* | lpd=* )
+#LOPT stty=* | flist=* | lpd=* | lopt=* )
+
+ inlist=`expr "${inlist}${i}" : "^\([^=]*=\)"`
+ case "${i}" in
+ ${inlist}\'*\' )
+ item=`expr "${i}" : "^[^=]*='*\(.*\)'\$"`
+ ;;
+ ${inlist}\' )
+ continue
+ ;;
+ ${inlist}\'* )
+ item=`expr "${i}" : "^[^=]*='*\(.*\)\$"`
+ ;;
+ ${inlist}* )
+ item=`expr "${i}" : "^[^=]*=\(.*\)\$"`
+ ;;
+ *\' )
+ item=`expr "${i}" : "^\(.*\)'\$"`
+ ;;
+ * )
+ item="${i}"
+ ;;
+ esac
+
+ #####
+ #
+ # We don't dare use "eval" because a clever user could
+ # put something in an option value that we'd end up
+ # exec'ing.
+ #####
+ case "${inlist}" in
+ flist= )
+ flist="${flist} ${item}"
+ ;;
+ lpd= )
+ lpd="${lpd} ${item}"
+ ;;
+#LOPT lopt= )
+#LOPT lopt="${lopt} ${item}"
+#LOPT ;;
+# options= )
+# options="${options} ${item}"
+# ;;
+ esac
+
+ case "${i}" in
+ ${inlist}\'*\' )
+ inlist=
+ ;;
+ ${inlist}\'* )
+ ;;
+ *\' | ${inlist}* )
+ inlist=
+ ;;
+ esac
+ ;;
+
+ * )
+ errmsg WARNING ${E_IP_OPTS} \
+ "unrecognized \"-o ${i}\" option" \
+ "check the option, resubmit if necessary
+ printing continues"
+ ;;
+ esac
+done
+
+logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
+ "term : ${TERM}"
+
+if [ -z "${FILTER}" ]
+then
+ #####
+ #
+ # If no filter is being used, we use netpr to push the
+ # file to the printer.
+ # (QUOTES ARE IMPORTANT!)
+ #####
+
+ case "$TERM" in
+ PS )
+ # make the "postscript" printers use cat
+ # (TSOL banners are added during filtering, so we have
+ # to use some filter.)
+ FILTER=/bin/cat
+ ;;
+ PSR )
+ # make the "reverse postscript" printers reverse the
+ # output and the use postio to talk to the printer
+ #FILTER="/usr/lib/lp/postscript/postreverse "
+ #FILTER=
+ FILTER="/usr/lib/lp/postscript/postreverse "
+ ;;
+ * )
+ # We don't know the type, so just assume that the
+ # input and output are the same. Use netpr.
+ #FILTER=/bin/cat
+ FILTER=
+ ;;
+ esac
+fi
+
+####
+# sets default value for ordering of data and control files with
+# bsd protocol. Default: data files first. Administrator
+# may set to control file first with lpadmin -o bsdctrl=first
+####
+
+banner_flag=""
+case "${nobanner}" in
+ yes )
+ banner_flag="-b"
+ ;;
+esac
+
+NETPR="/usr/lib/lp/bin/netpr ${banner_flag} ${data_file_flag} \
+ -I ${request_id} -U ${user_name} \
+ -p ${printer} ${dest} -T \"${title}\" \
+ ${timeout} ${protocol} ${controlfile} "
+LPTELL_OPTS="-l" # netpr sends LaserWriter style messages back
+PPDFILTER=/usr/lib/lp/bin/foomatic-rip
+PPDFILTERA="${PPDFILTER} ${request_id} ${user_name} \"${title}\" ${copies} \"${option_list}\""
+
+logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
+ "NETPR= ${NETPR}"
+logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
+ "filter : ${FILTER}"
+logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
+ "ppdfilter : ${PPDFILTERA}"
+
+node=`uname -n`
+pid=$$
+tmpfile=${LPTMPDIR}/${node}.${pid}
+tmpfilefoo=${LPTMPDIR}/${node}.${pid}.1
+
+logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
+ "tmpfile : ${tmpfile}"
+
+#####
+#
+# Set up filter for banner page
+#
+#####
+banner_filter=
+case "${TERM}" in
+PS | PSR )
+ banner_filter=" | /usr/lib/lp/postscript/postprint "
+ LPTELL_OPTS="-l"
+ ;;
+esac
+
+#####
+#
+# Build temporary file that is the banner page
+#
+#####
+PAD="#####${NL}"
+CR="\r"
+NL="${CR}\n"
+FF=
+
+small_banner() {
+ echo "${CR}\c"
+ echo "${PAD}\c"
+ echo "##### User: ${user_name}${NL}\c"
+ if [ -n "${title}" ]
+ then
+ echo "##### Title: ${title}${NL}\c"
+ fi
+ echo "##### Date: `LANG=C date '+%a %H:%M %h %d, %Y'`${NL}\c"
+ echo "##### Job: ${request_id}${NL}\c"
+ echo "${PAD}\c"
+ if [ -n "${FF}" ]
+ then
+ echo "${CR}${FF}\c"
+ fi
+}
+
+#####
+#
+# Doing small banner as we don't know what printer is out there
+#
+#####
+banner=small_banner
+
+## Skip this for PS/PSR printers, since lp.tsol_separator handles the banners
+if [ "no" = "${nobanner}" -a "${TERM}" != "PSR" -a "${TERM}" != "PS" ]
+then
+ eval "${banner} ${banner_filter}" 2>&1 1>${LPTMPDIR}/small_banner.$$
+fi
+
+###########
+##
+## Surround the job by PostScript code to produce banner
+## and trailerpages and page headers and footers.
+##
+###########
+
+BANNER_EXIT_CODE=${LPTMPDIR}/banner.exit_code.$$
+echo 0 > ${BANNER_EXIT_CODE}
+TSOLSEPARATOR_LOG=${LPTMPDIR}/banner.errmsg.$$
+
+tsol_bannerize () {
+ TSOLSEPARATOR_OPTS="-e ${TSOLSEPARATOR_LOG}"
+
+ if [ "yes" = "${nolabels}" ]
+ then
+ TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -l"
+ fi
+
+ if [ "yes" = "${nobanner}" ]
+ then
+ TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -t /dev/null -b /dev/null"
+ fi
+
+ if [ "${TERM}" = "PSR" ]
+ then
+ TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -r"
+ fi
+
+ # Get rid of the #, TAB and NL characters in the title
+ tsol_title=`echo $title`
+ tsol_title=`echo $tsol_title | sed 's/#//g'`
+
+ logger -p lpr.debug -t "tsol_netstandard: ${request_id}" \
+ "banner command: ${LPTSOLSEPARATOR} ${TSOLSEPARATOR_OPTS} \
+ ${printer} ${request_id} ${user_name} \"${tsol_title}\" ${file}"
+ ${LPTSOLSEPARATOR} ${TSOLSEPARATOR_OPTS} ${printer} \
+ ${request_id} ${user_name} "${tsol_title}" ${file}
+
+ echo $? > ${BANNER_EXIT_CODE}
+ true
+}
+
+bannerize=tsol_bannerize
+
+if [ "yes" = "${nobanner}" -a "yes" = "${nolabels}" ]
+then
+ bannerize=cat
+fi
+
+if [ "${TERM}" != "PSR" -a "${TERM}" != "PS" ]
+then
+ bannerize=cat
+fi
+
+#####
+#
+# Print banner page before job unless PSR or PS
+#
+#####
+
+
+## Skip this for PS/PSR printers, since lp.tsol_separator handles the banners
+if [ "no" = "${nobanner}" -a "${TERM}" != "PSR" -a "${TERM}" != "PS" ]
+then
+ (
+ eval ${NETPR} ${LPTMPDIR}/small_banner.$$ 2>&1
+ echo $? > ${LPTMPDIR}/pr_eexit_code.$$
+ ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
+
+ exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$`
+ logger -p lpr.debug -t \
+ "tsol_netstandard_foomatic: ${request_id}" \
+ "banner page exit code : ${exit_code}"
+
+fi
+
+i=1
+while [ $i -le $copies ]
+do
+ for file in ${files}
+ do
+ if [ -r "${file}" ]
+ then
+
+ if [ ! -z "${FILTER}" ]
+ then
+ (
+ #####
+ # There is a filter, use it
+ #
+ # Put 0<${file} before the "eval" to keep
+ # clever users from giving a file name that
+ # evaluates as something to execute.
+ # Redirect stderr to stdout so LPTELL will
+ # get error messages from pipe.
+ #####
+
+ 0<${file} $bannerize | eval ${FILTER} 2>&1 1>${tmpfile}
+ echo $? > ${LPTMPDIR}/pr_eexit_code.$$
+ ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
+
+ # if lp.tsol_separator had an error,
+ # send its logged error message to LPTELL.
+ banner_exit_code=`cat ${BANNER_EXIT_CODE}`
+ if [ -n "${banner_exit_code}" -a \
+ 0 -ne "${banner_exit_code}" -a \
+ -n "${LPTELL}" -a \
+ -r "${TSOLSEPARATOR_LOG}" ]
+ then
+ cat ${TSOLSEPARATOR_LOG} | ${LPTELL} ${printer}
+ echo 77 > ${LPTMPDIR}/pr_eexit_code
+ fi
+
+ exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$`
+ logger -p lpr.debug -t \
+ "tsol_netstandard_foomatic: ${request_id}" \
+ "filter exit_code : ${exit_code}"
+
+ if [ -n "${exit_code}" ]
+ then
+ if [ "${exit_code}" -eq 0 ]
+ then
+ printfile=${tmpfile}
+ else
+ ####
+ # The filter did not succeed, so don't try to print
+ ####
+ printfile=
+ fi
+ fi
+
+ else
+ printfile=${file}
+ fi
+
+ logger -p lpr.debug -t \
+ "tsol_netstandard_foomatic: ${request_id}" \
+ "printfile : ${printfile}"
+
+ #####
+ # Print the file
+ #####
+
+ if [ -r "${printfile}" ]
+ then
+ (
+logger -p lpr.debug -t \
+ "@1 tsol_netstandard_foomatic: printfile = ${printfile}" ""
+logger -p lpr.debug -t \
+ "tsol_netstandard_foomatic: ${NETPR} ${printfile}" ""
+ #eval ${NETPR} ${printfile} 2>&1
+ cat ${printfile} | ${PPDFILTER} \
+ ${request_id} ${user_name} "${title}" ${copies} "${option_list}" \
+ > ${tmpfilefoo} 2> /dev/null
+ eval ${NETPR} ${tmpfilefoo} 2>&1
+ echo $? > ${LPTMPDIR}/pr_eexit_code.$$
+ /bin/rm -f ${tmpfilefoo}
+ ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
+
+ exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$`
+ logger -p lpr.debug -t \
+ "@2 netstandard_foomatic: ${request_id}" \
+ "netpr exit_code : ${exit_code}"
+
+# if [ -f "${tmpfile}" ]
+# then
+# /bin/rm "${tmpfile}"
+# fi
+
+ if [ -n "${exit_code}" ]
+ then
+ if [ "${exit_code}" -eq 0 ]
+ then
+ printone=yes
+ else
+ if [ "${exit_code}" -lt 128 ]
+ then
+ noprint=yes
+ else
+ retry=yes
+ fi
+ fi
+ fi
+
+
+ else
+
+ errmsg WARNING ${E_IP_BADFILE} \
+ "cannot read temporary file \"${printfile}\""\
+ "see if file still exists,
+ or consult your system administrator;
+ printing continues"
+
+ fi
+ else
+
+ #####
+ #
+ # Don't complain about not being able to read
+ # a file on second and subsequent copies, unless
+ # we've not complained yet. This removes repeated
+ # messages about the same file yet reduces the
+ # chance that the user can remove a file and not
+ # know that we had trouble finding it.
+ #####
+
+ if [ "${i}" -le 1 -o -z "${badfileyet}" ]
+ then
+ errmsg WARNING ${E_IP_BADFILE} \
+ "cannot read file \"${file}\"" \
+ "see if the file still exists and is readable,
+ or consult your system administrator;
+ printing continues"
+ badfileyet=yes
+ fi
+
+ fi
+
+# for file in ${files}
+ done
+ i=`expr $i + 1`
+done
+
+#####
+#
+# If printing in reverse order, print the banner page now
+# Skip this for TSOL, since lp.tsol_separator handles the banners
+#
+#####
+
+#if [ "no" = "${nobanner}" -a "${TERM}" = "PSR" ]
+#then
+#(
+# eval ${NETPR} ${LPTMPDIR}/small_banner.$$ 2>&1
+# echo $? > ${LPTMPDIR}/pr_eexit_code.$$
+#) | ${LPTELL} ${LPTELL_OPTS} ${printer}
+#fi
+
+exit_code=`cat ${LPTMPDIR}/pr_eexit_code.$$`
+logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
+ "banner page exit code : ${exit_code}"
+
+if [ -n "${printone}" -a -z "${retry}" -a -z "${noprint}" ]
+then
+ exit_code=`expr 0`
+else
+ if [ -n "${retry}" -a -z "${printone}" -a -z "${noprint}" ]
+ then
+ exit_code=`expr 129`
+ else
+ exit_code=`expr 1`
+ fi
+fi
+
+logger -p lpr.debug -t "tsol_netstandard_foomatic: ${request_id}" \
+ "FINAL exit_code : ${exit_code}"
+
+exit_clean ${exit_code}
diff --git a/usr/src/cmd/lp/model/tsol_standard b/usr/src/cmd/lp/model/tsol_standard
new file mode 100644
index 0000000000..fe972a4148
--- /dev/null
+++ b/usr/src/cmd/lp/model/tsol_standard
@@ -0,0 +1,1162 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+###########
+##
+## Standard printer interface program.
+###########
+
+#####
+#
+# Until we get to the point below where the printer port
+# and physical printer are initialized, we can't do much
+# except exit if the Spooler/Scheduler cancels us.
+#####
+trap 'exit' 15
+
+#####
+#
+# We can be clever about getting a hangup or interrupt, though, at least
+# until the filter runs. Do this early, even though $LPTELL
+# isn't defined, so that we're covered.
+#####
+catch_hangup () {
+ if [ -n "${LPTELL}" ]
+ then
+ echo \
+"The connection to the printer dropped; perhaps the printer went off-line?" \
+ | ${LPTELL} ${printer}
+ fi
+ return 0
+}
+catch_interrupt () {
+ if [ -n "${LPTELL}" ]
+ then
+ echo \
+"Received an interrupt from the printer. The reason is unknown,
+although a common cause is that the baud rate is too high." \
+ | ${LPTELL} ${printer}
+ fi
+ return 0
+}
+trap 'catch_hangup; exit_code=129 exit 129' 1
+trap 'catch_interrupt; exit_code=129 exit 129' 2 3
+
+#####
+#
+# Most of the time we don't want the standard error to be captured
+# by the Spooler, mainly to avoid "Terminated" messages that the
+# shell puts out when we get a SIGTERM. We'll save the standard
+# error channel under another number, so we can use it when it
+# should be captured.
+#
+# Open another channel to the printer port, for use when the
+# regular standard output won't be directed there, such as in
+# command substitution (`cmd`).
+#####
+exec 5>&2 2>/dev/null 3>&1
+
+#####
+#
+# Set some globally used variables and functions.
+#####
+
+: ${TMPDIR:=/tmp}
+: ${SPOOLDIR:=/usr/spool/lp}
+: ${TERMINFO:=/usr/lib/terminfo}
+: ${CHARSETDIR:=/usr/lib/charsets}
+
+: ${LOCALPATH:=${SPOOLDIR}/bin}
+PATH="/bin:/usr/bin:${LOCALPATH}"
+
+MAX_COLS_SMALL_BANNER=40
+
+#####
+#
+# On the 3.2 release of the 386unix product, the parallel port does
+# not support any ioctl calls. As a result, we cannot set the opost
+# and onlcr attributes to have <NL>'s expanded to <CR><NL>. This
+# "filter" gets the job done for us.
+#####
+: ${FIX386BD:=${LOCALPATH}/386parallel}
+if [ -n "${FIX386BD}" -a -x "${FIX386BD}" ]
+then
+ FIX386BD="| ${FIX386BD}"
+else
+ FIX386BD=""
+fi
+
+#####
+# Use ${TMPPREFIX} as the prefix for all temporary files, so
+# that cleanup is easy. The prefix may be up to 13 characters
+# long, so you only have space for one more character to make
+# a file name. If necessary, make a directory using this prefix
+# for better management of unique temporary file names.
+#####
+TMPPREFIX=${TMPDIR}/`uname -n`$$
+
+#####
+# Before exiting, set ${exit_code} to the value with which to exit.
+# Otherwise, the exit from this script will be 0.
+#####
+trap 'rm -fr ${TMPPREFIX}*; exit ${exit_code}' 0
+
+#####
+# ${LPTELL} is the name of a program that will send its
+# standard input to the Spooler. It is used to forward
+# the description of a printer fault to the Spooler,
+# which uses it in an alert to the administrator.
+#####
+if [ ! -x "${LPTELL:=${LOCALPATH}/lp.tell}" ]
+then
+ fake_lptell () {
+ header="no"
+ while read line
+ do
+ if [ "no" = "${header}" ]
+ then
+ errmsg ERROR ${E_IP_UNKNOWN} \
+ "unknown printer/interface failure" \
+ "consult your system administrator;
+ reasons for failure (if any) follow:"
+ header=yes
+ fi
+ echo "${line}" >&2
+ done
+ return 1
+ }
+ LPTELL=fake_lptell
+fi
+
+#####
+# ${DRAIN} is the name of a program that will wait
+# long enough for data sent to the printer to print.
+#####
+if [ -x "${LOCALPATH}/drain.output" ]
+then
+ DRAIN="${LOCALPATH}/drain.output 5" # wait only five seconds
+else
+ DRAIN=
+fi
+
+#####
+# ${LPTSOLSEPARATOR} is the name of a program to put banner and trailer
+# pages around the job.
+#####
+if [ -x ${LOCALPATH}/lp.tsol_separator ]
+then
+ LPTSOLSEPARATOR=${LOCALPATH}/lp.tsol_separator
+else
+ echo "${LOCALPATH}/lp.tsol_separator not found." >&2
+ exit 1
+fi
+
+#####
+# ${LPCAT} is the name of a program to use as a default
+# filter. Minimally it should copy its standard input to
+# the standard output, but it should also trap printer
+# faults. The current LPCAT traps hangups (DCD dropping, SIGHUP),
+# interrupts (SIGINT, SIGQUIT), broken pipe (SIGPIPE), and
+# excess delays in sending data to the printer, interpreting all
+# as printer faults.
+#####
+if [ ! -x "${LPCAT:=${LOCALPATH}/lp.cat}" ]
+then
+ LPCAT="cat"
+fi
+
+#####
+# ${LPSET} is the name of a program that will set the
+# character pitch, line pitch, page width, page length,
+# and character set. It helps to have this in a single
+# binary program so that (1) it's faster than calls
+# to "tput"; and (2) it can access the new Terminfo
+# capabilities for printers (on pre SVR3.2 machines, tput can't).
+#####
+if [ ! -x "${LPSET:=${LOCALPATH}/lp.set}" ]
+then
+ fake_lpset () {
+ echo H V W L S >&2
+ false
+ }
+ LPSET=fake_lpset
+fi
+
+internal_lpset () {
+ #####
+ #
+ # The funny business with the "2>&1 1>&3" is to let us capture
+ # the standard ERROR, not the standard OUTPUT as is the usual case
+ # with foo=`cmd`. The standard output will go to the printer.
+ #####
+ [ -n "${stty1}" ] && stty ${stty1} 0<&1
+ chk=`${LPSET} "$1" "$2" "$3" "$4" "$5" 2>&1 1>&3`
+ [ -n "${stty2}" ] && stty ${stty2} 0<&1
+
+ #####
+ #
+ # The standard error of the delivered ${LPSET} program
+ # is a string of letters, H, V, W, L, S, which correspond
+ # to cpi, lpi, width, length, and character set. A letter
+ # is present only if the corresponding attribute could not
+ # be set.
+ #####
+ for err in ${chk}
+ do
+ case ${err} in
+ H )
+ errmsg WARNING ${E_IP_BADCPI} \
+ "can't select the character pitch \"${cpi}\"" \
+ "check the valid pitches for the printer,
+ or consult your system administrator;
+ printing continues"
+ ;;
+ V )
+ errmsg WARNING ${E_IP_BADLPI} \
+ "can't select the line pitch \"${lpi}\"" \
+ "check the valid pitches for the printer,
+ or consult your system administrator;
+ printing continues"
+ ;;
+ W )
+ width=${cols}
+ errmsg WARNING ${E_IP_BADWIDTH} \
+ "can't select the page width \"${width}\"" \
+ "check the valid widths for the printer,
+ or consult your system administrator;
+ printing continues"
+ ;;
+ L )
+ length=${lines}
+ errmsg WARNING ${E_IP_BADLENGTH} \
+ "can't select the page length \"${length}\"" \
+ "check the valid lengths for the printer,
+ or consult your system administrator;
+ printing continues"
+ ;;
+ S )
+ errmsg WARNING ${E_IP_BADCHARSET} \
+ "can't select the character set \"${CHARSET}\"" \
+ "check the name given in the -S option,
+ or consult your system administrator;
+ printing continues"
+ ;;
+ esac
+ done
+}
+
+
+#####
+# ${TPUT} is "tput" IF it works. We'll disable it if we get an
+# ugly error message the first time we use it. See the TERM variable
+# later in the script.
+#
+# NOTE: The check we use to see if "tput" works is to use an OLD
+# Terminfo capability, like "lines". If it works with that it may
+# still fail with some of the newer capabilities like "init" (SVR3.0)
+# or "swidm" (SVR3.2), because the version of "tput" we have on your
+# machine is older. Thus, on some of the code where ${TPUT} is used
+# you'll see "2>/dev/null" being used to avoid ugly error messages.
+#####
+TPUT=tput
+
+#####
+# Error message formatter:
+#
+# Invoke as
+#
+# errmsg severity message-number problem help
+#
+# where severity is "ERROR" or "WARNING", message-number is
+# a unique identifier, problem is a short description of the
+# problem, and help is a short suggestion for fixing the problem.
+#####
+
+LP_ERR_LABEL="UX:lp"
+
+E_IP_ARGS=1
+E_IP_OPTS=2
+#E_IP_FILTER=3
+E_IP_STTY=4
+E_IP_UNKNOWN=5
+E_IP_BADFILE=6
+E_IP_BADCHARSET=7
+E_IP_BADCPI=8
+E_IP_BADLPI=9
+E_IP_BADWIDTH=10
+E_IP_BADLENGTH=11
+E_IP_ERRORS=12 # (in slow.filter)
+
+errmsg () {
+ case $1 in
+ ERROR )
+ sev=" ERROR";
+ ;;
+ WARNING )
+ sev="WARNING";
+ ;;
+ esac
+# tag=`expr "${LP_ERR_LABEL}" : "\(.*\):"``expr "${LP_ERR_LABEL}" : ".*:\(.*\)"`
+ echo "${LP_ERR_LABEL}: ${sev}: $3
+ TO FIX: $4" >&5
+}
+
+
+###########
+##
+## Check arguments
+###########
+
+parse () {
+ echo "`expr \"$1\" : \"^[^=]*=\(.*\)\"`"
+}
+
+#####
+#
+# This program is invoked as
+#
+# ${SPOOLDIR}/.../printer request-id user title copies options files...
+#
+# The first three arguments are simply reprinted on the banner page,
+# the fourth (copies) is used to control the number of copies to print,
+# the fifth (options) is a blank separated list (in a single argument)
+# of user or Spooler supplied options (without the -o prefix),
+# and the last arguments are the files to print.
+#####
+
+if [ $# -lt 5 ]
+then
+ errmsg ERROR ${E_IP_ARGS} \
+ "wrong number of arguments to interface program" \
+ "consult your system administrator"
+ exit 1
+fi
+
+printer=`basename $0`
+request_id=$1
+user_name=$2
+title=$3
+copies=$4
+option_list=$5
+
+shift 5
+files="$*"
+
+nobanner="no"
+nofilebreak="no"
+nolabels="no"
+stty=
+
+inlist=
+for i in ${option_list}
+do
+ case "${inlist}${i}" in
+
+
+ nobanner )
+ nobanner="yes"
+ ;;
+
+ nofilebreak )
+ nofilebreak="yes"
+ ;;
+
+ nolabels )
+ nolabels="yes"
+ ;;
+
+ #####
+ #
+ # If you want to add simple options (e.g. -o simple)
+ # identify them here.
+ #####
+# simple )
+# simple="yes"
+# ;;
+
+
+ cpi=pica )
+ cpi=10
+ ;;
+ cpi=elite )
+ cpi=12
+ ;;
+ cpi=* )
+ cpi=`parse ${i}`
+ ;;
+
+ lpi=* )
+ lpi=`parse ${i}`
+ ;;
+
+ length=* )
+ length=`parse ${i}`
+ ;;
+
+ width=* )
+ width=`parse ${i}`
+ ;;
+
+ #####
+ #
+ # If you want to add simple-value options (e.g. -o value=a)
+ # identify them here.
+ #####
+# value=* )
+# value=`parse ${i}`
+# ;;
+
+
+ #####
+ #
+ # If you want to add options that, like "stty",
+ # take a list (e.g. -o lopt='a b c'), identify
+ # them here and below (look for LOPT).
+ #####
+ stty=* | flist=* | lpd=* )
+#LOPT stty=* | flist=* | lpd=* | lopt=* )
+
+ inlist=`expr "${inlist}${i}" : "^\([^=]*=\)"`
+ case "${i}" in
+ ${inlist}\'*\' )
+ item=`expr "${i}" : "^[^=]*='*\(.*\)'\$"`
+ ;;
+ ${inlist}\' )
+ continue
+ ;;
+ ${inlist}\'* )
+ item=`expr "${i}" : "^[^=]*='*\(.*\)\$"`
+ ;;
+ ${inlist}* )
+ item=`expr "${i}" : "^[^=]*=\(.*\)\$"`
+ ;;
+ *\' )
+ item=`expr "${i}" : "^\(.*\)'\$"`
+ ;;
+ * )
+ item="${i}"
+ ;;
+ esac
+
+ #####
+ #
+ # We don't dare use "eval" because a clever user could
+ # put something in an option value that we'd end up
+ # exec'ing.
+ #####
+ case "${inlist}" in
+ stty= )
+ stty="${stty} ${item}"
+ ;;
+ flist= )
+ flist="${flist} ${item}"
+ ;;
+ lpd= )
+ lpd="${lpd} ${item}"
+ ;;
+#LOPT lopt= )
+#LOPT lopt="${lopt} ${item}"
+#LOPT ;;
+ esac
+
+ case "${i}" in
+ ${inlist}\'*\' )
+ inlist=
+ ;;
+ ${inlist}\'* )
+ ;;
+ *\' | ${inlist}* )
+ inlist=
+ ;;
+ esac
+ ;;
+
+ * )
+ errmsg WARNING ${E_IP_OPTS} \
+ "unrecognized \"-o ${i}\" option" \
+ "check the option, resubmit if necessary
+ printing continues"
+ ;;
+ esac
+done
+
+#####
+#
+# Additional ``parameters'' are passed via Shell environment
+# variables:
+#
+# TERM The printer type (used for Terminfo access)
+# CHARSET The character set to choose
+# FILTER The filter to run
+#####
+
+#####
+# Set defaults for unset variables.
+#####
+
+: ${TERM:=unknown}
+tput lines 1>/dev/null 2>&1 || TPUT=:
+
+: ${CHARSET:=cs0}
+
+if [ -z "${FILTER}" ]
+then
+ #####
+ #
+ # If no filter is being used, we have a little routine that
+ # will push the data to the printer. It traps hangups (loss
+ # of carrier) and checks for excessive delays in sending the
+ # data to the printer. The lesser of the print rate of the printer
+ # (obtained from Terminfo) or the baud rate is used to compute
+ # the expected delay. If neither of these is correct, you
+ # may be experiencing false alarms. If so, give the correct
+ # rate, in characters per second, as a single argument.
+ # An argument of 0 means don't check for delays.
+ # Give an -r option to get a printout of actual delays.
+ # (QUOTES ARE IMPORTANT!)
+ #####
+ case "$TERM" in
+ PS )
+ # make the "postscript" printers use postio to
+ # talk to the printer and periodically get a
+ # status from them
+ FILTER="/usr/lib/lp/postscript/postio"
+ ;;
+ PSR )
+ # make the "reverse postscript" printers reverse the
+ # output and the use postio to talk to the printer
+ FILTER="/usr/lib/lp/postscript/postreverse | \
+ /usr/lib/lp/postscript/postio"
+ ;;
+ * )
+ # we don't know the type, so just assume that the
+ # input and output are the same
+ if [ `basename "${LPCAT}"` = "lp.cat" ] ; then
+ FILTER="${LPCAT} 0" # infinite delays
+ # FILTER="${LPCAT} 120" # e.g. 120 CPS
+ # FILTER="${LPCAT} -r 0 2>/tmp/delays"
+ # FILTER=${LPCAT}
+ fi
+ ;;
+ esac
+fi
+
+###########
+##
+## Initialize the printer port
+###########
+
+#####
+#
+# SERIAL PORTS:
+# Initialize everything.
+#
+# PARALLEL PORTS:
+# Don't initialize baud rate.
+#
+# It's not obvious how to tell if a port is parallel or serial.
+# However, by splitting the initialization into two steps and letting
+# the serial-only part fail nicely, it'll work.
+#
+# Another point: The output must be a ``tty'' device. If not, don't
+# bother with any of this.
+#####
+stty1= stty2=
+tty 0<&1 1>/dev/null 2>&1 && {
+
+ #####
+ #
+ # First set the default parameters,
+ # then the requested parameters.
+ #####
+
+ stty \
+ 9600 \
+ 0<&1 2>/dev/null 1>&2
+ stty \
+ cs8 -cstopb -parenb -parodd \
+ ixon -ixany \
+ opost -olcuc onlcr -ocrnl -onocr -onlret -ofill \
+ nl0 cr0 tab0 bs0 vt0 ff0 \
+ 0<&1 2>/dev/null 1>&2
+
+ if [ -n "${stty}" ]
+ then
+ if stty ${stty} 0<&1 1>/dev/null 2>&5
+ then
+ :
+ else
+ errmsg ERROR ${E_IP_STTY} \
+ "stty option list failed" \
+ "check the \"-o stty\" option you used,
+ or consult your system administrator"
+ exit 1
+ fi
+ fi
+
+ #####
+ #
+ # Here you may want to add other port initialization code.
+ # Some examples:
+ #
+ # estty # for printer needing hardware flow control (3B2/EPORTS)
+ # fctty # for printer needing hardware flow control (3B15,3B20)
+ #####
+ #estty 0<&1
+ #fctty 0<&1
+
+
+ ##########
+ #
+ # Find out if we have to turn off opost before initializing the
+ # printer and on after. Likewise, check clocal.
+ #
+ # Turning OFF opost (output postprocessing) keeps the UNIX system
+ # from changing what we try to send to the printer. Turning ON
+ # clocal keeps the UNIX system from dropping what we are trying to
+ # send if the printer drops DTR. An example of the former is the
+ # AT&T 479, which wants to send a linefeed (ASCII 10) when a page
+ # width of 10 is set; with opost on, this COULD BE turned into a
+ # carriage-return/linefeed pair. An example of the latter is the
+ # AT&T 455, which momentarily drops DTR when it gets the
+ # initialization string, is2; with clocal off, the UNIX system
+ # stops sending the rest of the initialization sequence at that
+ # point.
+ #
+ # THIS CODE MUST FOLLOW THE REST OF THE PORT INITIALIZATION CODE.
+ ##########
+ cur_stty=`stty -a 0<&3`
+ expr "${cur_stty}" : '.*-opost' 1>/dev/null 2>&1 \
+ || stty1="${stty1} -opost" stty2="${stty2} opost"
+ expr "${cur_stty}" : '.*-clocal' 1>/dev/null 2>&1 \
+ && stty1="${stty1} clocal" stty2="${stty2} -clocal"
+ expr "${cur_stty}" : '.* opost.*' 1>/dev/null 2>&1 \
+ || banner_filter=${FIX386BD}
+
+}
+
+
+###########
+##
+## Initialize the physical printer (Part I).
+## Here we bring the printer to a sane state and set the page size.
+###########
+
+##########
+#
+# WARNING! The "echo" command will catch backslashes (\) and
+# try to interpret the characters following it. Thus, using
+# "echo" to print string values obtained from "tput" is dangerous.
+##########
+
+#####
+# We're confident that most printers don't have backslashes
+# in the control sequences for carriage return and form-feed.
+# We're also confident that these don't contain newlines.
+# We're also confident that most printers have a linefeed
+# in the control sequence for doing a newline (move to beginning
+# of next line), but we can't capture it like we do the
+# carriage return or form-feed. Thus we set it unconditionally.
+# We don't set form-feed if it isn't defined, however, because
+# maybe the printer doesn't have a formfeed. If not set, we're
+# out of luck.
+#####
+
+CR=`${TPUT} cr`
+[ -z "${CR}" ] && CR="\r"
+
+FF=`${TPUT} ff`
+
+NL="${CR}\n"
+
+lines=`${TPUT} lines`
+[ -z "${lines}" -o 0 -ge "${lines}" ] && lines=66
+
+cols=`${TPUT} cols`
+[ -z "${cols}" -o 0 -ge "${cols}" ] && cols=132
+
+#####
+#
+# Basic initialization. The ``else'' clause is equivalent,
+# but covers cases where old Terminal Information Utilities are present.
+#####
+[ -n "${stty1}" ] && stty ${stty1} 0<&1
+
+#
+# "tput init" will return an "^M" in many cases to "stdout", i.e., printer!
+# This creates problems for some PS printers
+#
+if [ "${TERM}" = "PS" -o "${TERM}" = "PSR" ]
+then
+ :
+elif ${TPUT} init 2>/dev/null
+then
+ :
+else
+ pgm=`${TPUT} iprog`
+ if [ -x "${pgm}" ]
+ then
+ eval ${pgm}
+ fi
+
+ ${TPUT} is1
+ ${TPUT} is2
+
+ tabset=
+ if [ "8" != "`${TPUT} it`" ]
+ then
+ stty tab3 0<&1 1>/dev/null 2>&1
+
+ elif `${TPUT} ht >/dev/null`
+ then
+ tabset="/usr/lib/tabset/${TERM}"
+ if [ -r ${tabset} ]
+ then
+ cat -s ${tabset}
+ fi
+ stty tab3 0<&1 1>/dev/null 2>&1
+ fi
+
+ file=`${TPUT} if`
+ if [ "${tabset}" != "${file}" -a -r "${file}" ]
+ then
+ cat -s "${file}"
+ fi
+
+ ${TPUT} is3
+ echo "${CR}\c"
+fi
+[ -n "${stty2}" ] && stty ${stty2} 0<&1
+
+#####
+#
+# Set the page size and print spacing, but not the character set.
+# We will be doing the character set later (after the header).
+#####
+internal_lpset "${cpi}" "${lpi}" "${width}" "${length}" ""
+
+#####
+#
+# The banner page (and cancellation page) will
+# use double width characters if they're available.
+#####
+WIDE_CS=`${TPUT} swidm 2>/dev/null` && NORM_CS=`${TPUT} rwidm 2>/dev/null`
+PAD="#####${NL}"
+
+#####
+#
+# Some printers need to have the banner page filtered.
+#####
+case "${TERM}" in
+
+PS | PSR )
+ banner_filter="/usr/lib/lp/postscript/postprint | /usr/lib/lp/postscript/postio"
+ LPTELL_OPTS="-l"
+ ;;
+
+esac
+if [ -n "${banner_filter}" ]
+then
+ banner_filter="| ${banner_filter}"
+fi
+
+#####
+#
+# Now that the printer is ready for printing, we're able
+# to record on paper a cancellation.
+#####
+
+cancel_banner () {
+ echo "${PAD}${PAD}\c"
+ echo "#####${WIDE_CS} Job ${request_id}${NORM_CS}${NL}\c"
+ echo "#####${WIDE_CS} suspended or canceled${NORM_CS}${NL}\c"
+ echo "${PAD}${PAD}\c"
+}
+
+canceled () {
+ ${TPUT} scs 0 2>/dev/null
+ echo "${CR}\c"
+ if [ "${width:-${cols}}" -lt "${MAX_COLS_SMALL_BANNER}" ]
+ then
+ WIDE_CS= NORM_CS=
+ fi
+ cancel_banner
+ if [ -n "${FF}" ]
+ then
+ echo "${CR}${FF}\c"
+ fi
+}
+
+trap 'eval canceled ${banner_filter}; exit_code=0 exit' 15
+
+
+###########
+##
+## Print the banner page
+###########
+
+#####
+#
+# You may want to change the following code to get a custom banner.
+#####
+
+regular_banner () {
+ echo "${CR}\c"
+ echo "${PAD}${PAD}${PAD}${PAD}${PAD}\c"
+ echo "#####${WIDE_CS} User: ${user_name}${NORM_CS}${NL}\c"
+ if [ -n "$ALIAS_USERNAME" ]
+ then
+ echo "${PAD}\c"
+ echo "#####${WIDE_CS} Alias: ${ALIAS_USERNAME}${NORM_CS}${NL}\c"
+ fi
+ if [ -n "${title}" ]
+ then
+ echo "${PAD}\c"
+ echo "#####${WIDE_CS} Title: ${title}${NORM_CS}${NL}\c"
+ fi
+ echo "${PAD}\c"
+ echo "#####${WIDE_CS} Printed: `LANG=C date '+%a %H:%M %h %d, %Y'`${NORM_CS}${NL}\c"
+ echo "${PAD}\c"
+ echo "#####${WIDE_CS} Job number: ${request_id}${NORM_CS}${NL}\c"
+ echo "${PAD}${PAD}${PAD}${PAD}${PAD}\c"
+ if [ -n "${FF}" ]
+ then
+ echo "${CR}${FF}\c"
+ fi
+}
+
+small_banner () {
+ echo "${CR}\c"
+ echo "${PAD}\c"
+ echo "##### User: ${user_name}${NL}\c"
+ if [ -n "${title}" ]
+ then
+ echo "##### Title: ${title}${NL}\c"
+ fi
+ echo "##### Date: `LANG=C date '+%a %H:%M %h %d, %Y'`${NL}\c"
+ echo "##### Job: ${request_id}${NL}\c"
+ echo "${PAD}\c"
+ if [ -n "${FF}" ]
+ then
+ echo "${CR}${FF}\c"
+ fi
+}
+
+if [ "${width:-${cols}}" -lt "${MAX_COLS_SMALL_BANNER}" ]
+then
+ banner=small_banner
+else
+ banner=regular_banner
+fi
+
+## Skip this for PS/PSR in TSOL, since lp.tsol_separator handles the banners
+if [ "no" = "${nobanner}" -a "${TERM}" != "PSR" -a "${TERM}" != "PS" ]
+then
+ ( eval "${banner} ${banner_filter}" 2>&1 1>&3 ) \
+ | ${LPTELL} ${LPTELL_OPTS} ${printer}
+fi
+
+###########
+##
+## Surround the job by PostScript code to produce banner
+## and trailerpages and page headers and footers.
+##
+###########
+
+BANNER_EXIT_CODE=${TMPPREFIX}.banner.exit_code
+echo 0 > ${BANNER_EXIT_CODE}
+TSOLSEPARATOR_LOG=${TMPPREFIX}.banner.errmsg
+
+tsol_bannerize () {
+ TSOLSEPARATOR_OPTS="-e ${TSOLSEPARATOR_LOG}"
+
+ if [ "yes" = "${nolabels}" ]
+ then
+ TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -l"
+ fi
+
+ if [ "yes" = "${nobanner}" ]
+ then
+ TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -t /dev/null -b /dev/null"
+ fi
+
+ if [ "${TERM}" = "PSR" ]
+ then
+ TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -r"
+ fi
+
+ # Get rid of the #, TAB and NL characters in the title
+ tsol_title=`echo $title`
+ tsol_title=`echo $tsol_title | sed 's/#//g'`
+
+ LC_TIME=C ${LPTSOLSEPARATOR} ${TSOLSEPARATOR_OPTS} "${printer}" \
+ "${request_id}" "${user_name}" "${tsol_title}" "${file}"
+ echo $? > ${BANNER_EXIT_CODE}
+ true
+}
+
+bannerize=tsol_bannerize
+
+if [ "yes" = "${nobanner}" -a "yes" = "${nolabels}" ]
+then
+ bannerize=cat
+fi
+
+if [ "${TERM}" != "PSR" -a "${TERM}" != "PS" ]
+then
+ bannerize=cat
+fi
+
+
+###########
+##
+## Initialize the physical printer (Part II)
+## Here we select the character set.
+## One could argue that this should be done before the banner is printed,
+## but we don't, to keep the banner page looking consistent for the
+## operator. You can move this code before the banner code if you
+## disagree. If you do, combine it with the other call to "internal_lpset"
+## to do everything in one shot.
+###########
+internal_lpset "" "" "" "" "${CHARSET}"
+
+###########
+##
+## Print some copies of the file(s)
+###########
+
+#####
+#
+# The protocol between the interface program and the Spooler
+# is fairly simple:
+#
+# All standard error output is assumed to indicate a
+# fault WITH THE REQUEST. The output is mailed to the
+# user who submitted the print request and the print
+# request is finished.
+#
+# If the interface program sets a zero exit code,
+# it is assumed that the file printed correctly.
+# If the interface program sets a non-zero exit code
+# less than 128, it is assumed that the file did not
+# print correctly, and the user will be notified.
+# In either case the print request is finished.
+#
+# If the interface program sets an exit code greater
+# than 128, it is assumed that the file did not print
+# because of a printer fault. If an alert isn't already
+# active (see below) one will be activated. (Exit code
+# 128 should not be used at all. The shell, which executes
+# this program, turns SIGTERM, used to kill this program
+# for a cancellation or disabling, into exit 128. The
+# Spooler thus interpretes 128 as SIGTERM.)
+#
+# A message sent to the standard input of the ${LPTELL}
+# program is assumed to describe a fault WITH THE PRINTER.
+# The output is used in an alert (if alerts are defined).
+# If the fault recovery is "wait" or "begin", the printer
+# is disabled (killing the interface program if need be),
+# and the print request is left on the queue.
+# If the fault recovery is "continue", the interface program
+# is allowed to wait for the printer fault to be cleared so
+# it can resume printing.
+#
+# This interface program relies on filters to detect printer faults.
+# In absence of a filter provided by the customer, it uses a simple
+# filter (${LPCAT}) to detect the class of faults that cause DCD
+# (``carrier'') drop. The protocol between the interface program and
+# the filter:
+#
+# The filter should exit with zero if printing was
+# successful and non-zero if printing failed because
+# of a printer fault. This interface program turns a
+# non-zero exit of the filter into an "exit 129" from
+# itself, thus telling the Spooler that a printer fault
+# (still) exists.
+#
+# The filter should report printer faults via a message
+# to its standard error. This interface program takes all
+# standard error output from the filter and feeds it as
+# standard input to the ${LPTELL} program.
+#
+# The filter should wait for a printer fault to clear,
+# and should resume printing when the fault clears.
+# Preferably it should resume at the top of the page
+# that was being printed when the fault occurred.
+# If it waits and finishes printing, it should exit
+# with a 0 exit code. If it can't wait, it should exit
+# with a non-zero exit code.
+#
+# The interface program expects that ANY message on the
+# standard error from the filter indicates a printer fault.
+# Therefore, a filter should not put user (input) error
+# messages on the standard error, but on the standard output
+# (where the user can read them when he or she examines
+# the print-out).
+#
+#####
+
+badfileyet=
+i=1
+while [ $i -le $copies ]
+do
+ for file in ${files}
+ do
+ if [ -r "${file}" ]
+ then
+ #####
+ #
+ # Here's where we set up the $LPTELL program to
+ # capture fault messages, and...
+ #
+ # Here's where we print the file.
+ #
+ # We set up a pipeline to $LPTELL, but play a trick
+ # to get the filter's standard ERROR piped instead of
+ # its standard OUTPUT: Divert the standard error (#2) to
+ # the standard output (#1) IN THE PIPELINE. The shell
+ # will have changed #1 to be the pipe, not the
+ # printer, so diverting #2 connects it to the pipe.
+ # We then change the filter's #1 to a copy of the real
+ # standard output (the printer port) made earlier,
+ # so that is connected back to the printer again.
+ #
+ # We do all this inside a parenthesized expression
+ # so that we can get the exit code; this is necessary
+ # because the exit code of a pipeline is the exit
+ # code of the right-most command, which isn't the
+ # filter.
+ #
+ # These two tricks could be avoided by using a named
+ # pipe to connect the standard error to $LPTELL. In
+ # fact an early prototype of this script did just
+ # that; however, the named pipe introduced a timing
+ # problem. The processes that open a named pipe hang
+ # until both ends of the pipe are opened. Cancelling
+ # a request or disabling the printer often killed one
+ # of the processes, causing the other process to hang
+ # forever waiting for the other end of the pipe to
+ # be opened.
+ #####
+ EXIT_CODE=${TMPPREFIX}e
+ trap '' 1 # Let the filter handle a hangup
+ trap '' 2 3 # and interrupts
+ (
+ #####
+ # Put the 0<${file} before the "eval" to keep
+ # clever users from giving a file name that
+ # evaluates as something to execute.
+ #####
+ 0<${file} $bannerize | eval ${FILTER} 2>&1 1>&3
+ echo $? >${EXIT_CODE}
+ ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
+
+ # if lp.tsol_separator had an error, send its logged
+ # error message to LPTELL.
+ banner_exit_code=`cat ${BANNER_EXIT_CODE}`
+ if [ -n "${banner_exit_code}" -a \
+ 0 -ne "${banner_exit_code}" -a \
+ -n "${LPTELL}" -a \
+ -r "${TSOLSEPARATOR_LOG}" ]
+ then
+ cat ${TSOLSEPARATOR_LOG} | ${LPTELL} ${printer}
+ echo 77 > ${EXIT_CODE}
+ fi
+
+ trap 'catch_hangup; exit_code=129 exit 129' 1
+ trap 'catch_interrupt; exit_code=129 exit 129' 2 3
+ exit_code=`cat ${EXIT_CODE}`
+
+ if [ -n "${exit_code}" -a 0 -ne "${exit_code}" ]
+ then
+ trap '' 15 # Avoid dying from disable
+ sleep 4 # Give $LPTELL a chance to tell
+ exit ${exit_code}
+ fi
+
+ if [ -n "${FF}" -a "no" = "${nofilebreak}" ]
+ then
+ echo "${CR}${FF}\c"
+ fi
+
+ else
+
+ #####
+ #
+ # Don't complain about not being able to read
+ # a file on second and subsequent copies, unless
+ # we've not complained yet. This removes repeated
+ # messages about the same file yet reduces the
+ # chance that the user can remove a file and not
+ # know that we had trouble finding it.
+ #####
+ if [ "${i}" -le 1 -o -z "${badfileyet}" ]
+ then
+ errmsg WARNING ${E_IP_BADFILE} \
+ "cannot read file \"${file}\"" \
+ "see if the file still exists and is readable,
+ or consult your system administrator;
+ printing continues"
+ badfileyet=yes
+ fi
+
+ fi
+
+ done
+ i=`expr $i + 1`
+
+done
+
+# Skip this for TSOL, since lp.tsol_separator handles the banners
+#
+# if [ "no" = "${nobanner}" -a "${TERM}" = "PSR" ]
+# then
+# ( eval "${banner} ${banner_filter}" 2>&1 1>&3 ) \
+# | ${LPTELL} ${LPTELL_OPTS} ${printer}
+# fi
+
+if [ -n "${exit_code}" -a 0 -ne "${exit_code}" ]
+then
+ exit ${exit_code}
+fi
+
+#####
+#
+# Always ensure the complete job ends with a ``formfeed'', to
+# let the next job start on a new page. (If someone wants to
+# concatenate files, they can give them in one job.)
+# So, if we haven't been putting out a ``formfeed'' between files,
+# it means we haven't followed the last file with a formfeed,
+# so we do it here.
+#####
+if [ -n "${FF}" -a "yes" = "${nofilebreak}" ]
+then
+ echo "${CR}${FF}\c"
+fi
+
+${DRAIN}
+
+exit_code=0 exit 0
diff --git a/usr/src/cmd/lp/model/tsol_standard_foomatic b/usr/src/cmd/lp/model/tsol_standard_foomatic
new file mode 100644
index 0000000000..c446b0ad8c
--- /dev/null
+++ b/usr/src/cmd/lp/model/tsol_standard_foomatic
@@ -0,0 +1,1190 @@
+#
+# 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"
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+###########
+##
+## Standard printer interface program.
+##
+###########
+
+#####
+#
+# Until we get to the point below where the printer port
+# and physical printer are initialized, we can't do much
+# except exit if the Spooler/Scheduler cancels us.
+#####
+trap 'exit' 15
+
+#####
+#
+# We can be clever about getting a hangup or interrupt, though, at least
+# until the filter runs. Do this early, even though $LPTELL
+# isn't defined, so that we're covered.
+#####
+catch_hangup () {
+ if [ -n "${LPTELL}" ]
+ then
+ echo \
+"The connection to the printer dropped; perhaps the printer went off-line?" \
+ | ${LPTELL} ${printer}
+ fi
+ return 0
+}
+catch_interrupt () {
+ if [ -n "${LPTELL}" ]
+ then
+ echo \
+"Received an interrupt from the printer. The reason is unknown,
+although a common cause is that the baud rate is too high." \
+ | ${LPTELL} ${printer}
+ fi
+ return 0
+}
+trap 'catch_hangup; exit_code=129 exit 129' 1
+trap 'catch_interrupt; exit_code=129 exit 129' 2 3
+
+#####
+#
+# Most of the time we don't want the standard error to be captured
+# by the Spooler, mainly to avoid "Terminated" messages that the
+# shell puts out when we get a SIGTERM. We'll save the standard
+# error channel under another number, so we can use it when it
+# should be captured.
+#
+# Open another channel to the printer port, for use when the
+# regular standard output won't be directed there, such as in
+# command substitution (`cmd`).
+#####
+exec 5>&2 2>/dev/null 3>&1
+
+#####
+#
+# Set some globally used variables and functions.
+#####
+
+: ${TMPDIR:=/tmp}
+: ${SPOOLDIR:=/usr/spool/lp}
+: ${TERMINFO:=/usr/lib/terminfo}
+: ${CHARSETDIR:=/usr/lib/charsets}
+
+: ${LOCALPATH:=${SPOOLDIR}/bin}
+PATH="/bin:/usr/bin:${LOCALPATH}"
+
+MAX_COLS_SMALL_BANNER=40
+
+#####
+#
+# On the 3.2 release of the 386unix product, the parallel port does
+# not support any ioctl calls. As a result, we cannot set the opost
+# and onlcr attributes to have <NL>'s expanded to <CR><NL>. This
+# "filter" gets the job done for us.
+#####
+: ${FIX386BD:=${LOCALPATH}/386parallel}
+if [ -n "${FIX386BD}" -a -x "${FIX386BD}" ]
+then
+ FIX386BD="| ${FIX386BD}"
+else
+ FIX386BD=""
+fi
+
+#####
+# Use ${TMPPREFIX} as the prefix for all temporary files, so
+# that cleanup is easy. The prefix may be up to 13 characters
+# long, so you only have space for one more character to make
+# a file name. If necessary, make a directory using this prefix
+# for better management of unique temporary file names.
+#####
+TMPPREFIX=${TMPDIR}/`uname -n`$$
+
+#####
+# Before exiting, set ${exit_code} to the value with which to exit.
+# Otherwise, the exit from this script will be 0.
+#####
+trap 'rm -fr ${TMPPREFIX}*; exit ${exit_code}' 0
+
+#####
+# ${LPTELL} is the name of a program that will send its
+# standard input to the Spooler. It is used to forward
+# the description of a printer fault to the Spooler,
+# which uses it in an alert to the administrator.
+#####
+if [ ! -x "${LPTELL:=${LOCALPATH}/lp.tell}" ]
+then
+ fake_lptell () {
+ header="no"
+ while read line
+ do
+ if [ "no" = "${header}" ]
+ then
+ errmsg ERROR ${E_IP_UNKNOWN} \
+ "unknown printer/interface failure" \
+ "consult your system administrator;
+ reasons for failure (if any) follow:"
+ header=yes
+ fi
+ echo "${line}" >&2
+ done
+ return 1
+ }
+ LPTELL=fake_lptell
+fi
+
+#####
+# ${DRAIN} is the name of a program that will wait
+# long enough for data sent to the printer to print.
+#####
+if [ -x "${LOCALPATH}/drain.output" ]
+then
+ DRAIN="${LOCALPATH}/drain.output 5" # wait only five seconds
+else
+ DRAIN=
+fi
+
+#####
+# ${LPTSOLSEPARATOR} is the name of a program to put banner and trailer
+# pages around the job.
+#####
+if [ -x ${LOCALPATH}/lp.tsol_separator ]
+then
+ LPTSOLSEPARATOR=${LOCALPATH}/lp.tsol_separator
+else
+ echo "${LOCALPATH}/lp.tsol_separator not found." >&2
+ exit 1
+fi
+
+#####
+# ${LPCAT} is the name of a program to use as a default
+# filter. Minimally it should copy its standard input to
+# the standard output, but it should also trap printer
+# faults. The current LPCAT traps hangups (DCD dropping, SIGHUP),
+# interrupts (SIGINT, SIGQUIT), broken pipe (SIGPIPE), and
+# excess delays in sending data to the printer, interpreting all
+# as printer faults.
+#####
+if [ ! -x "${LPCAT:=${LOCALPATH}/lp.cat}" ]
+then
+ LPCAT="cat"
+fi
+
+#####
+# ${LPSET} is the name of a program that will set the
+# character pitch, line pitch, page width, page length,
+# and character set. It helps to have this in a single
+# binary program so that (1) it's faster than calls
+# to "tput"; and (2) it can access the new Terminfo
+# capabilities for printers (on pre SVR3.2 machines, tput can't).
+#####
+if [ ! -x "${LPSET:=${LOCALPATH}/lp.set}" ]
+then
+ fake_lpset () {
+ echo H V W L S >&2
+ false
+ }
+ LPSET=fake_lpset
+fi
+
+internal_lpset () {
+ #####
+ #
+ # The funny business with the "2>&1 1>&3" is to let us capture
+ # the standard ERROR, not the standard OUTPUT as is the usual case
+ # with foo=`cmd`. The standard output will go to the printer.
+ #####
+ [ -n "${stty1}" ] && stty ${stty1} 0<&1
+ chk=`${LPSET} "$1" "$2" "$3" "$4" "$5" 2>&1 1>&3`
+ [ -n "${stty2}" ] && stty ${stty2} 0<&1
+
+ #####
+ #
+ # The standard error of the delivered ${LPSET} program
+ # is a string of letters, H, V, W, L, S, which correspond
+ # to cpi, lpi, width, length, and character set. A letter
+ # is present only if the corresponding attribute could not
+ # be set.
+ #####
+ for err in ${chk}
+ do
+ case ${err} in
+ H )
+ errmsg WARNING ${E_IP_BADCPI} \
+ "can't select the character pitch \"${cpi}\"" \
+ "check the valid pitches for the printer,
+ or consult your system administrator;
+ printing continues"
+ ;;
+ V )
+ errmsg WARNING ${E_IP_BADLPI} \
+ "can't select the line pitch \"${lpi}\"" \
+ "check the valid pitches for the printer,
+ or consult your system administrator;
+ printing continues"
+ ;;
+ W )
+ width=${cols}
+ errmsg WARNING ${E_IP_BADWIDTH} \
+ "can't select the page width \"${width}\"" \
+ "check the valid widths for the printer,
+ or consult your system administrator;
+ printing continues"
+ ;;
+ L )
+ length=${lines}
+ errmsg WARNING ${E_IP_BADLENGTH} \
+ "can't select the page length \"${length}\"" \
+ "check the valid lengths for the printer,
+ or consult your system administrator;
+ printing continues"
+ ;;
+ S )
+ errmsg WARNING ${E_IP_BADCHARSET} \
+ "can't select the character set \"${CHARSET}\"" \
+ "check the name given in the -S option,
+ or consult your system administrator;
+ printing continues"
+ ;;
+ esac
+ done
+}
+
+
+#####
+# ${TPUT} is "tput" IF it works. We'll disable it if we get an
+# ugly error message the first time we use it. See the TERM variable
+# later in the script.
+#
+# NOTE: The check we use to see if "tput" works is to use an OLD
+# Terminfo capability, like "lines". If it works with that it may
+# still fail with some of the newer capabilities like "init" (SVR3.0)
+# or "swidm" (SVR3.2), because the version of "tput" we have on your
+# machine is older. Thus, on some of the code where ${TPUT} is used
+# you'll see "2>/dev/null" being used to avoid ugly error messages.
+#####
+TPUT=tput
+
+#####
+# Error message formatter:
+#
+# Invoke as
+#
+# errmsg severity message-number problem help
+#
+# where severity is "ERROR" or "WARNING", message-number is
+# a unique identifier, problem is a short description of the
+# problem, and help is a short suggestion for fixing the problem.
+#####
+
+LP_ERR_LABEL="UX:lp"
+
+E_IP_ARGS=1
+E_IP_OPTS=2
+#E_IP_FILTER=3
+E_IP_STTY=4
+E_IP_UNKNOWN=5
+E_IP_BADFILE=6
+E_IP_BADCHARSET=7
+E_IP_BADCPI=8
+E_IP_BADLPI=9
+E_IP_BADWIDTH=10
+E_IP_BADLENGTH=11
+E_IP_ERRORS=12 # (in slow.filter)
+
+errmsg () {
+ case $1 in
+ ERROR )
+ sev=" ERROR";
+ ;;
+ WARNING )
+ sev="WARNING";
+ ;;
+ esac
+# tag=`expr "${LP_ERR_LABEL}" : "\(.*\):"``expr "${LP_ERR_LABEL}" : ".*:\(.*\)"`
+ echo "${LP_ERR_LABEL}: ${sev}: $3
+ TO FIX: $4" >&5
+}
+
+
+###########
+##
+## Check arguments
+###########
+
+parse () {
+ echo "`expr \"$1\" : \"^[^=]*=\(.*\)\"`"
+}
+
+#####
+#
+# This program is invoked as
+#
+# ${SPOOLDIR}/.../printer request-id user title copies options files...
+#
+# The first three arguments are simply reprinted on the banner page,
+# the fourth (copies) is used to control the number of copies to print,
+# the fifth (options) is a blank separated list (in a single argument)
+# of user or Spooler supplied options (without the -o prefix),
+# and the last arguments are the files to print.
+#####
+
+if [ $# -lt 5 ]
+then
+ errmsg ERROR ${E_IP_ARGS} \
+ "wrong number of arguments to interface program" \
+ "consult your system administrator"
+ exit 1
+fi
+
+printer=`basename $0`
+request_id=$1
+user_name=$2
+title=$3
+copies=$4
+option_list=$5
+
+shift 5
+files="$*"
+
+nobanner="no"
+nofilebreak="no"
+nolabels="no"
+stty=
+
+inlist=
+for i in ${option_list}
+do
+ case "${inlist}${i}" in
+
+
+ nobanner )
+ nobanner="yes"
+ ;;
+
+ nofilebreak )
+ nofilebreak="yes"
+ ;;
+
+ nolabels )
+ nolabels="yes"
+ ;;
+
+ #
+ # The IPP/PAPI attributes are handled by the foomatic-rip filter so
+ # all we need to do here is ignore them so that they don't invoke the
+ # "unrecognized option" message.
+ #
+
+ finishing=* | page-ranges=* | sides=* )
+ ;;
+ number-up=* | orientation-requested=* | media=* )
+ ;;
+ printer-resolution=* | print-quality=* )
+ ;;
+
+ #####
+ #
+ # If you want to add simple options (e.g. -o simple)
+ # identify them here.
+ #####
+# simple )
+# simple="yes"
+# ;;
+
+
+ cpi=pica )
+ cpi=10
+ ;;
+ cpi=elite )
+ cpi=12
+ ;;
+ cpi=* )
+ cpi=`parse ${i}`
+ ;;
+
+ lpi=* )
+ lpi=`parse ${i}`
+ ;;
+
+ length=* )
+ length=`parse ${i}`
+ ;;
+
+ width=* )
+ width=`parse ${i}`
+ ;;
+
+ #####
+ #
+ # If you want to add simple-value options (e.g. -o value=a)
+ # identify them here.
+ #####
+# value=* )
+# value=`parse ${i}`
+# ;;
+
+
+ #####
+ #
+ # If you want to add options that, like "stty",
+ # take a list (e.g. -o lopt='a b c'), identify
+ # them here and below (look for LOPT).
+ #####
+ stty=* | flist=* | lpd=* )
+#LOPT stty=* | flist=* | lpd=* | lopt=* )
+
+ inlist=`expr "${inlist}${i}" : "^\([^=]*=\)"`
+ case "${i}" in
+ ${inlist}\'*\' )
+ item=`expr "${i}" : "^[^=]*='*\(.*\)'\$"`
+ ;;
+ ${inlist}\' )
+ continue
+ ;;
+ ${inlist}\'* )
+ item=`expr "${i}" : "^[^=]*='*\(.*\)\$"`
+ ;;
+ ${inlist}* )
+ item=`expr "${i}" : "^[^=]*=\(.*\)\$"`
+ ;;
+ *\' )
+ item=`expr "${i}" : "^\(.*\)'\$"`
+ ;;
+ * )
+ item="${i}"
+ ;;
+ esac
+
+ #####
+ #
+ # We don't dare use "eval" because a clever user could
+ # put something in an option value that we'd end up
+ # exec'ing.
+ #####
+ case "${inlist}" in
+ stty= )
+ stty="${stty} ${item}"
+ ;;
+ flist= )
+ flist="${flist} ${item}"
+ ;;
+ lpd= )
+ lpd="${lpd} ${item}"
+ ;;
+#LOPT lopt= )
+#LOPT lopt="${lopt} ${item}"
+#LOPT ;;
+ esac
+
+ case "${i}" in
+ ${inlist}\'*\' )
+ inlist=
+ ;;
+ ${inlist}\'* )
+ ;;
+ *\' | ${inlist}* )
+ inlist=
+ ;;
+ esac
+ ;;
+
+ * )
+ errmsg WARNING ${E_IP_OPTS} \
+ "unrecognized \"-o ${i}\" option" \
+ "check the option, resubmit if necessary
+ printing continues"
+ ;;
+ esac
+done
+
+#####
+#
+# Additional ``parameters'' are passed via Shell environment
+# variables:
+#
+# TERM The printer type (used for Terminfo access)
+# CHARSET The character set to choose
+# FILTER The filter to run
+#####
+
+#####
+# Set defaults for unset variables.
+#####
+
+: ${TERM:=unknown}
+tput lines 1>/dev/null 2>&1 || TPUT=:
+
+: ${CHARSET:=cs0}
+
+PPDFILTER=/usr/lib/lp/bin/foomatic-rip
+PPDFILTERA="${PPDFILTER} ${request_id} ${user_name} \"${title}\" ${copies} \"${option_list}\""
+
+if [ -z "${FILTER}" ]
+then
+ #####
+ #
+ # If no filter is being used, we have a little routine that
+ # will push the data to the printer. It traps hangups (loss
+ # of carrier) and checks for excessive delays in sending the
+ # data to the printer. The lesser of the print rate of the printer
+ # (obtained from Terminfo) or the baud rate is used to compute
+ # the expected delay. If neither of these is correct, you
+ # may be experiencing false alarms. If so, give the correct
+ # rate, in characters per second, as a single argument.
+ # An argument of 0 means don't check for delays.
+ # Give an -r option to get a printout of actual delays.
+ # (QUOTES ARE IMPORTANT!)
+ #####
+ case "$TERM" in
+ PS )
+ # make the "postscript" printers use postio to
+ # talk to the printer and periodically get a
+ # status from them
+ FILTER="/usr/lib/lp/postscript/postio"
+ ;;
+ PSR )
+ # make the "reverse postscript" printers reverse the
+ # output and the use postio to talk to the printer
+ FILTER="/usr/lib/lp/postscript/postreverse | \
+ /usr/lib/lp/postscript/postio"
+ ;;
+ * )
+ # we don't know the type, so just assume that the
+ # input and output are the same
+ if [ `basename "${LPCAT}"` = "lp.cat" ] ; then
+ FILTER="${LPCAT} 0" # infinite delays
+ # FILTER="${LPCAT} 120" # e.g. 120 CPS
+ # FILTER="${LPCAT} -r 0 2>/tmp/delays"
+ # FILTER=${LPCAT}
+ fi
+ ;;
+ esac
+fi
+
+logger -p lpr.debug -t "tsol_standard_foomatic: ${request_id}" "filter : ${FILTER}"
+logger -p lpr.debug -t "tsol_standard_foomatic: ${request_id}" "ppdfilter : ${PPDFILTERA}"
+
+#
+# Append the PPD foomatic-rip filter
+#
+FILTER="${FILTER} | ${PPDFILTERA}"
+
+###########
+##
+## Initialize the printer port
+###########
+
+#####
+#
+# SERIAL PORTS:
+# Initialize everything.
+#
+# PARALLEL PORTS:
+# Don't initialize baud rate.
+#
+# It's not obvious how to tell if a port is parallel or serial.
+# However, by splitting the initialization into two steps and letting
+# the serial-only part fail nicely, it'll work.
+#
+# Another point: The output must be a ``tty'' device. If not, don't
+# bother with any of this.
+#####
+stty1= stty2=
+tty 0<&1 1>/dev/null 2>&1 && {
+
+ #####
+ #
+ # First set the default parameters,
+ # then the requested parameters.
+ #####
+
+ stty \
+ 9600 \
+ 0<&1 2>/dev/null 1>&2
+ stty \
+ cs8 -cstopb -parenb -parodd \
+ ixon -ixany \
+ opost -olcuc onlcr -ocrnl -onocr -onlret -ofill \
+ nl0 cr0 tab0 bs0 vt0 ff0 \
+ 0<&1 2>/dev/null 1>&2
+
+ if [ -n "${stty}" ]
+ then
+ if stty ${stty} 0<&1 1>/dev/null 2>&5
+ then
+ :
+ else
+ errmsg ERROR ${E_IP_STTY} \
+ "stty option list failed" \
+ "check the \"-o stty\" option you used,
+ or consult your system administrator"
+ exit 1
+ fi
+ fi
+
+ #####
+ #
+ # Here you may want to add other port initialization code.
+ # Some examples:
+ #
+ # estty # for printer needing hardware flow control (3B2/EPORTS)
+ # fctty # for printer needing hardware flow control (3B15,3B20)
+ #####
+ #estty 0<&1
+ #fctty 0<&1
+
+
+ ##########
+ #
+ # Find out if we have to turn off opost before initializing the
+ # printer and on after. Likewise, check clocal.
+ #
+ # Turning OFF opost (output postprocessing) keeps the UNIX system
+ # from changing what we try to send to the printer. Turning ON
+ # clocal keeps the UNIX system from dropping what we are trying to
+ # send if the printer drops DTR. An example of the former is the
+ # AT&T 479, which wants to send a linefeed (ASCII 10) when a page
+ # width of 10 is set; with opost on, this COULD BE turned into a
+ # carriage-return/linefeed pair. An example of the latter is the
+ # AT&T 455, which momentarily drops DTR when it gets the
+ # initialization string, is2; with clocal off, the UNIX system
+ # stops sending the rest of the initialization sequence at that
+ # point.
+ #
+ # THIS CODE MUST FOLLOW THE REST OF THE PORT INITIALIZATION CODE.
+ ##########
+ cur_stty=`stty -a 0<&3`
+ expr "${cur_stty}" : '.*-opost' 1>/dev/null 2>&1 \
+ || stty1="${stty1} -opost" stty2="${stty2} opost"
+ expr "${cur_stty}" : '.*-clocal' 1>/dev/null 2>&1 \
+ && stty1="${stty1} clocal" stty2="${stty2} -clocal"
+ expr "${cur_stty}" : '.* opost.*' 1>/dev/null 2>&1 \
+ || banner_filter=${FIX386BD}
+
+}
+
+
+###########
+##
+## Initialize the physical printer (Part I).
+## Here we bring the printer to a sane state and set the page size.
+###########
+
+##########
+#
+# WARNING! The "echo" command will catch backslashes (\) and
+# try to interpret the characters following it. Thus, using
+# "echo" to print string values obtained from "tput" is dangerous.
+##########
+
+#####
+# We're confident that most printers don't have backslashes
+# in the control sequences for carriage return and form-feed.
+# We're also confident that these don't contain newlines.
+# We're also confident that most printers have a linefeed
+# in the control sequence for doing a newline (move to beginning
+# of next line), but we can't capture it like we do the
+# carriage return or form-feed. Thus we set it unconditionally.
+# We don't set form-feed if it isn't defined, however, because
+# maybe the printer doesn't have a formfeed. If not set, we're
+# out of luck.
+#####
+
+CR=`${TPUT} cr`
+[ -z "${CR}" ] && CR="\r"
+
+FF=`${TPUT} ff`
+BFF=$FF
+[ -z "${BFF}" ] && BFF="\f"
+
+NL="${CR}\n"
+
+lines=`${TPUT} lines`
+[ -z "${lines}" -o 0 -ge "${lines}" ] && lines=66
+
+cols=`${TPUT} cols`
+[ -z "${cols}" -o 0 -ge "${cols}" ] && cols=132
+
+#####
+#
+# Basic initialization. The ``else'' clause is equivalent,
+# but covers cases where old Terminal Information Utilities are present.
+#####
+[ -n "${stty1}" ] && stty ${stty1} 0<&1
+
+#
+# "tput init" will return an "^M" in many cases to "stdout", i.e., printer!
+# This creates problems for some PS printers
+#
+if [ "${TERM}" = "PS" -o "${TERM}" = "PSR" ]
+then
+ :
+elif ${TPUT} init 2>/dev/null
+then
+ :
+else
+ pgm=`${TPUT} iprog`
+ if [ -x "${pgm}" ]
+ then
+ eval ${pgm}
+ fi
+
+ ${TPUT} is1
+ ${TPUT} is2
+
+ tabset=
+ if [ "8" != "`${TPUT} it`" ]
+ then
+ stty tab3 0<&1 1>/dev/null 2>&1
+
+ elif `${TPUT} ht >/dev/null`
+ then
+ tabset="/usr/lib/tabset/${TERM}"
+ if [ -r ${tabset} ]
+ then
+ cat -s ${tabset}
+ fi
+ stty tab3 0<&1 1>/dev/null 2>&1
+ fi
+
+ file=`${TPUT} if`
+ if [ "${tabset}" != "${file}" -a -r "${file}" ]
+ then
+ cat -s "${file}"
+ fi
+
+ ${TPUT} is3
+ echo "${CR}\c"
+fi
+[ -n "${stty2}" ] && stty ${stty2} 0<&1
+
+#####
+#
+# Set the page size and print spacing, but not the character set.
+# We will be doing the character set later (after the header).
+#####
+internal_lpset "${cpi}" "${lpi}" "${width}" "${length}" ""
+
+#####
+#
+# The banner page (and cancellation page) will
+# use double width characters if they're available.
+#####
+WIDE_CS=`${TPUT} swidm 2>/dev/null` && NORM_CS=`${TPUT} rwidm 2>/dev/null`
+PAD="#####${NL}"
+
+#####
+#
+# Some printers need to have the banner page filtered.
+#####
+case "${TERM}" in
+
+PS | PSR )
+ banner_filter="/usr/lib/lp/postscript/postprint | /usr/lib/lp/postscript/postio"
+ LPTELL_OPTS="-l"
+ ;;
+
+esac
+if [ -n "${banner_filter}" ]
+then
+ banner_filter="| ${banner_filter}"
+fi
+
+#####
+#
+# Now that the printer is ready for printing, we're able
+# to record on paper a cancellation.
+#####
+
+cancel_banner () {
+ echo "${PAD}${PAD}\c"
+ echo "#####${WIDE_CS} Job ${request_id}${NORM_CS}${NL}\c"
+ echo "#####${WIDE_CS} suspended or canceled${NORM_CS}${NL}\c"
+ echo "${PAD}${PAD}\c"
+}
+
+canceled () {
+ ${TPUT} scs 0 2>/dev/null
+ echo "${CR}\c"
+ if [ "${width:-${cols}}" -lt "${MAX_COLS_SMALL_BANNER}" ]
+ then
+ WIDE_CS= NORM_CS=
+ fi
+ cancel_banner
+ if [ -n "${BFF}" ]
+ then
+ echo "${CR}${BFF}\c"
+ fi
+}
+
+trap 'eval canceled ${banner_filter}; exit_code=0 exit' 15
+
+
+###########
+##
+## Print the banner page
+###########
+
+#####
+#
+# You may want to change the following code to get a custom banner.
+#####
+
+regular_banner () {
+ echo "${CR}\c"
+ echo "${PAD}${PAD}${PAD}${PAD}${PAD}\c"
+ echo "#####${WIDE_CS} User: ${user_name}${NORM_CS}${NL}\c"
+ if [ -n "$ALIAS_USERNAME" ]
+ then
+ echo "${PAD}\c"
+ echo "#####${WIDE_CS} Alias: ${ALIAS_USERNAME}${NORM_CS}${NL}\c"
+ fi
+ if [ -n "${title}" ]
+ then
+ echo "${PAD}\c"
+ echo "#####${WIDE_CS} Title: ${title}${NORM_CS}${NL}\c"
+ fi
+ echo "${PAD}\c"
+ echo "#####${WIDE_CS} Printed: `LANG=C date '+%a %H:%M %h %d, %Y'`${NORM_CS}${NL}\c"
+ echo "${PAD}\c"
+ echo "#####${WIDE_CS} Job number: ${request_id}${NORM_CS}${NL}\c"
+ echo "${PAD}${PAD}${PAD}${PAD}${PAD}\c"
+ if [ -n "${BFF}" ]
+ then
+ echo "${CR}${BFF}\c"
+ fi
+}
+
+small_banner () {
+ echo "${CR}\c"
+ echo "${PAD}\c"
+ echo "##### User: ${user_name}${NL}\c"
+ if [ -n "${title}" ]
+ then
+ echo "##### Title: ${title}${NL}\c"
+ fi
+ echo "##### Date: `LANG=C date '+%a %H:%M %h %d, %Y'`${NL}\c"
+ echo "##### Job: ${request_id}${NL}\c"
+ echo "${PAD}\c"
+ if [ -n "${BFF}" ]
+ then
+ echo "${CR}${BFF}\c"
+ fi
+}
+
+if [ "${width:-${cols}}" -lt "${MAX_COLS_SMALL_BANNER}" ]
+then
+ banner=small_banner
+else
+ banner=regular_banner
+fi
+
+## Skip this for PS/PSR in TSOL, since lp.tsol_separator handles the banners
+if [ "no" = "${nobanner}" -a "${TERM}" != "PSR" -a "${TERM}" != "PS" ]
+then
+ ( eval "${banner} ${banner_filter}" 2>&1 1>&3 ) \
+ | ${LPTELL} ${LPTELL_OPTS} ${printer}
+fi
+
+###########
+##
+## Surround the job by PostScript code to produce banner
+## and trailerpages and page headers and footers.
+##
+###########
+
+BANNER_EXIT_CODE=${TMPPREFIX}.banner.exit_code
+echo 0 > ${BANNER_EXIT_CODE}
+TSOLSEPARATOR_LOG=${TMPPREFIX}.banner.errmsg
+
+tsol_bannerize () {
+ TSOLSEPARATOR_OPTS="-e ${TSOLSEPARATOR_LOG}"
+
+ if [ "yes" = "${nolabels}" ]
+ then
+ TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -l"
+ fi
+
+ if [ "yes" = "${nobanner}" ]
+ then
+ TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -t /dev/null -b /dev/null"
+ fi
+
+ if [ "${TERM}" = "PSR" ]
+ then
+ TSOLSEPARATOR_OPTS="${TSOLSEPARATOR_OPTS} -r"
+ fi
+
+ # Get rid of the #, TAB and NL characters in the title
+ tsol_title=`echo $title`
+ tsol_title=`echo $tsol_title | sed 's/#//g'`
+
+ LC_TIME=C ${LPTSOLSEPARATOR} ${TSOLSEPARATOR_OPTS} "${printer}" \
+ "${request_id}" "${user_name}" "${tsol_title}" "${file}"
+ echo $? > ${BANNER_EXIT_CODE}
+ true
+}
+
+bannerize=tsol_bannerize
+
+if [ "yes" = "${nobanner}" -a "yes" = "${nolabels}" ]
+then
+ bannerize=cat
+fi
+
+if [ "${TERM}" != "PSR" -a "${TERM}" != "PS" ]
+then
+ bannerize=cat
+fi
+
+
+###########
+##
+## Initialize the physical printer (Part II)
+## Here we select the character set.
+## One could argue that this should be done before the banner is printed,
+## but we don't, to keep the banner page looking consistent for the
+## operator. You can move this code before the banner code if you
+## disagree. If you do, combine it with the other call to "internal_lpset"
+## to do everything in one shot.
+###########
+internal_lpset "" "" "" "" "${CHARSET}"
+
+###########
+##
+## Print some copies of the file(s)
+###########
+
+#####
+#
+# The protocol between the interface program and the Spooler
+# is fairly simple:
+#
+# All standard error output is assumed to indicate a
+# fault WITH THE REQUEST. The output is mailed to the
+# user who submitted the print request and the print
+# request is finished.
+#
+# If the interface program sets a zero exit code,
+# it is assumed that the file printed correctly.
+# If the interface program sets a non-zero exit code
+# less than 128, it is assumed that the file did not
+# print correctly, and the user will be notified.
+# In either case the print request is finished.
+#
+# If the interface program sets an exit code greater
+# than 128, it is assumed that the file did not print
+# because of a printer fault. If an alert isn't already
+# active (see below) one will be activated. (Exit code
+# 128 should not be used at all. The shell, which executes
+# this program, turns SIGTERM, used to kill this program
+# for a cancellation or disabling, into exit 128. The
+# Spooler thus interpretes 128 as SIGTERM.)
+#
+# A message sent to the standard input of the ${LPTELL}
+# program is assumed to describe a fault WITH THE PRINTER.
+# The output is used in an alert (if alerts are defined).
+# If the fault recovery is "wait" or "begin", the printer
+# is disabled (killing the interface program if need be),
+# and the print request is left on the queue.
+# If the fault recovery is "continue", the interface program
+# is allowed to wait for the printer fault to be cleared so
+# it can resume printing.
+#
+# This interface program relies on filters to detect printer faults.
+# In absence of a filter provided by the customer, it uses a simple
+# filter (${LPCAT}) to detect the class of faults that cause DCD
+# (``carrier'') drop. The protocol between the interface program and
+# the filter:
+#
+# The filter should exit with zero if printing was
+# successful and non-zero if printing failed because
+# of a printer fault. This interface program turns a
+# non-zero exit of the filter into an "exit 129" from
+# itself, thus telling the Spooler that a printer fault
+# (still) exists.
+#
+# The filter should report printer faults via a message
+# to its standard error. This interface program takes all
+# standard error output from the filter and feeds it as
+# standard input to the ${LPTELL} program.
+#
+# The filter should wait for a printer fault to clear,
+# and should resume printing when the fault clears.
+# Preferably it should resume at the top of the page
+# that was being printed when the fault occurred.
+# If it waits and finishes printing, it should exit
+# with a 0 exit code. If it can't wait, it should exit
+# with a non-zero exit code.
+#
+# The interface program expects that ANY message on the
+# standard error from the filter indicates a printer fault.
+# Therefore, a filter should not put user (input) error
+# messages on the standard error, but on the standard output
+# (where the user can read them when he or she examines
+# the print-out).
+#
+#####
+
+badfileyet=
+i=1
+while [ $i -le $copies ]
+do
+ for file in ${files}
+ do
+ if [ -r "${file}" ]
+ then
+ #####
+ #
+ # Here's where we set up the $LPTELL program to
+ # capture fault messages, and...
+ #
+ # Here's where we print the file.
+ #
+ # We set up a pipeline to $LPTELL, but play a trick
+ # to get the filter's standard ERROR piped instead of
+ # its standard OUTPUT: Divert the standard error (#2) to
+ # the standard output (#1) IN THE PIPELINE. The shell
+ # will have changed #1 to be the pipe, not the
+ # printer, so diverting #2 connects it to the pipe.
+ # We then change the filter's #1 to a copy of the real
+ # standard output (the printer port) made earlier,
+ # so that is connected back to the printer again.
+ #
+ # We do all this inside a parenthesized expression
+ # so that we can get the exit code; this is necessary
+ # because the exit code of a pipeline is the exit
+ # code of the right-most command, which isn't the
+ # filter.
+ #
+ # These two tricks could be avoided by using a named
+ # pipe to connect the standard error to $LPTELL. In
+ # fact an early prototype of this script did just
+ # that; however, the named pipe introduced a timing
+ # problem. The processes that open a named pipe hang
+ # until both ends of the pipe are opened. Cancelling
+ # a request or disabling the printer often killed one
+ # of the processes, causing the other process to hang
+ # forever waiting for the other end of the pipe to
+ # be opened.
+ #####
+ EXIT_CODE=${TMPPREFIX}e
+ trap '' 1 # Let the filter handle a hangup
+ trap '' 2 3 # and interrupts
+ (
+ #####
+ # Put the 0<${file} before the "eval" to keep
+ # clever users from giving a file name that
+ # evaluates as something to execute.
+ #####
+ 0<${file} $bannerize | eval ${FILTER} 2>&1 1>&3
+ echo $? >${EXIT_CODE}
+ ) | ${LPTELL} ${LPTELL_OPTS} ${printer}
+
+ # if lp.tsol_separator had an error, send its logged
+ # error message to LPTELL.
+ banner_exit_code=`cat ${BANNER_EXIT_CODE}`
+ if [ -n "${banner_exit_code}" -a \
+ 0 -ne "${banner_exit_code}" -a \
+ -n "${LPTELL}" -a \
+ -r "${TSOLSEPARATOR_LOG}" ]
+ then
+ cat ${TSOLSEPARATOR_LOG} | ${LPTELL} ${printer}
+ echo 77 > ${EXIT_CODE}
+ fi
+
+ trap 'catch_hangup; exit_code=129 exit 129' 1
+ trap 'catch_interrupt; exit_code=129 exit 129' 2 3
+ exit_code=`cat ${EXIT_CODE}`
+
+ if [ -n "${exit_code}" -a 0 -ne "${exit_code}" ]
+ then
+ trap '' 15 # Avoid dying from disable
+ sleep 4 # Give $LPTELL a chance to tell
+ exit ${exit_code}
+ fi
+
+ if [ -n "${FF}" -a "no" = "${nofilebreak}" ]
+ then
+ echo "${CR}${FF}\c"
+ fi
+
+ else
+
+ #####
+ #
+ # Don't complain about not being able to read
+ # a file on second and subsequent copies, unless
+ # we've not complained yet. This removes repeated
+ # messages about the same file yet reduces the
+ # chance that the user can remove a file and not
+ # know that we had trouble finding it.
+ #####
+ if [ "${i}" -le 1 -o -z "${badfileyet}" ]
+ then
+ errmsg WARNING ${E_IP_BADFILE} \
+ "cannot read file \"${file}\"" \
+ "see if the file still exists and is readable,
+ or consult your system administrator;
+ printing continues"
+ badfileyet=yes
+ fi
+
+ fi
+
+ done
+ i=`expr $i + 1`
+
+done
+
+# Skip this for TSOL, since lp.tsol_separator handles the banners
+#
+# if [ "no" = "${nobanner}" -a "${TERM}" = "PSR" ]
+# then
+# ( eval "${banner} ${banner_filter}" 2>&1 1>&3 ) \
+# | ${LPTELL} ${LPTELL_OPTS} ${printer}
+# fi
+
+if [ -n "${exit_code}" -a 0 -ne "${exit_code}" ]
+then
+ exit ${exit_code}
+fi
+
+#####
+#
+# Always ensure the complete job ends with a ``formfeed'', to
+# let the next job start on a new page. (If someone wants to
+# concatenate files, they can give them in one job.)
+# So, if we haven't been putting out a ``formfeed'' between files,
+# it means we haven't followed the last file with a formfeed,
+# so we do it here.
+#####
+if [ -n "${FF}" -a "yes" = "${nofilebreak}" ]
+then
+ echo "${CR}${FF}\c"
+fi
+
+${DRAIN}
+
+exit_code=0 exit 0
diff --git a/usr/src/cmd/tsol/Makefile b/usr/src/cmd/tsol/Makefile
new file mode 100644
index 0000000000..9163f24351
--- /dev/null
+++ b/usr/src/cmd/tsol/Makefile
@@ -0,0 +1,95 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/tsol/Makefile
+#
+
+include ../Makefile.cmd
+
+SUBDIRS = \
+ atohexlabel \
+ getlabel \
+ demo \
+ misc \
+ zones \
+ labeld \
+ updatehome \
+ plabel \
+ setlabel \
+ tnchkdb \
+ tninfo \
+ tnctl \
+ tnd \
+ tsol-zones \
+ getzonepath \
+ hextoalabel \
+ lslabels
+
+
+MSGSUBDIRS = \
+ getlabel \
+ setlabel \
+ tnchkdb \
+ tninfo \
+ tnctl \
+ tnd \
+ getzonepath
+
+$(CLOSED_BUILD)SUBDIRS += $(CLOSED)/cmd/tsol/chk_encodings \
+ $(CLOSED)/cmd/tsol/labeld
+
+$(CLOSED_BUILD)CLOSED_MSGSUBDIRS = $(CLOSED)/cmd/tsol/chk_encodings \
+ $(CLOSED)/cmd/tsol/labeld
+
+#
+# for messaging catalog
+#
+POFILE= tsol-cmd.po
+POFILES= $(MSGSUBDIRS:%=%/%.po)
+
+all := TARGET = all
+install := TARGET = install
+clean := TARGET = clean
+clobber := TARGET = clobber
+lint := TARGET = lint
+_msg := TARGET = _msg
+
+.KEEP_STATE:
+
+.PARALLEL: $(SUBDIRS)
+
+all install clean clobber lint: $(SUBDIRS)
+
+$(POFILE): $(MSGSUBDIRS) $(CLOSED_MSGSUBDIRS)
+ $(RM) $(POFILE)
+ $(CAT) $(POFILES) > $(POFILE)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include Makefile.targ
diff --git a/usr/src/cmd/tsol/Makefile.targ b/usr/src/cmd/tsol/Makefile.targ
new file mode 100644
index 0000000000..e42655357f
--- /dev/null
+++ b/usr/src/cmd/tsol/Makefile.targ
@@ -0,0 +1,77 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# Conditional assignment of default group/owner/permissions for SMF
+# manifests and method scripts.
+#
+$(ROOTMANIFEST) := OWNER= root
+$(ROOTMANIFEST) := GROUP= sys
+$(ROOTMANIFEST) := FILEMODE= 444
+$(ROOTSVCBIN) := OWNER= root
+$(ROOTSVCBIN) := GROUP= bin
+$(ROOTSVCBIN) := FILEMODE= 544
+
+clobber: clean
+ -$(RM) $(PROG) $(CLOBBERFILES)
+
+lint_PROG: $$(PROG).c
+ $(LINT.c) $(PROG).c $(LDLIBS)
+
+lint_SRCS: $$(SRCS)
+ $(LINT.c) $(SRCS) $(LDLIBS)
+
+$(ROOTCMDDIR)/%: $(ROOTCMDDIR) %
+ $(INS.file)
+
+$(ROOTCMDDIR) $(ROOTCMDDIR64):
+ $(INS.dir)
+
+$(ROOTCMDDIR64)/%: $(ROOTCMDDIR64) %
+ $(INS.file)
+
+$(ROOTMANIFEST): $(ROOTMANIFESTDIR)
+
+$(ROOTMANIFESTDIR):
+ $(INS.dir)
+
+$(ROOTMANIFESTDIR)/%: %
+ $(INS.file)
+
+#
+# For message catalogue files
+#
+_msg: $(POFILE)
+
+# the build of the $(DCFILE) should be defined locally
+# its .dc extension gets renamed to .po upon installation
+#
+_dc: $(DCMSGDOMAIN) $(DCFILE)
+ $(RM) $(DCMSGDOMAIN)/$(DCFILE)
+ $(CP) $(DCFILE) $(DCMSGDOMAIN)/$(DCFILE:.dc=.po)
+
+$(MSGDOMAIN) $(DCMSGDOMAIN):
+ $(INS.dir)
diff --git a/usr/src/cmd/tsol/atohexlabel/Makefile b/usr/src/cmd/tsol/atohexlabel/Makefile
new file mode 100644
index 0000000000..1725e7b8b5
--- /dev/null
+++ b/usr/src/cmd/tsol/atohexlabel/Makefile
@@ -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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# cmd/tsol/atohexlabel
+#
+PROG= atohexlabel
+
+include ../../Makefile.cmd
+
+LDLIBS += -ltsol
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all $(ROOTUSRSBINPROG)
+
+clean:
+
+lint: lint_PROG
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/tsol/atohexlabel/atohexlabel.c b/usr/src/cmd/tsol/atohexlabel/atohexlabel.c
new file mode 100644
index 0000000000..a8d607a4db
--- /dev/null
+++ b/usr/src/cmd/tsol/atohexlabel/atohexlabel.c
@@ -0,0 +1,161 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * atohexlabel - Convert a human readable label to its internal
+ * equivalent.
+ */
+
+#include <errno.h>
+#include <libintl.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/param.h>
+
+#include <tsol/label.h>
+
+#if !defined(TEXT_DOMAIN)
+#define TEXT_DOMAIN "SYS_TEST"
+#endif /* !defined(TEXT_DOMAIN) */
+
+static void
+label_error(const char *ascii, const int err)
+{
+ if (errno == EINVAL) {
+ switch (err) {
+ case M_BAD_STRING:
+ (void) fprintf(stderr,
+ gettext("atohexlabel: bad string %s\n"), ascii);
+ break;
+ case M_BAD_LABEL:
+ (void) fprintf(stderr,
+ gettext("atohexlabel: bad previous label\n"));
+ break;
+ default:
+ (void) fprintf(stderr,
+ gettext("atohexlabel: parsing error found in "
+ "\"%s\" at position %d\n"), ascii, err);
+ break;
+ }
+ } else {
+ perror("atohexlabel");
+ }
+ exit(1);
+ /*NOTREACHED*/
+}
+
+int
+main(int argc, char **argv)
+{
+ int cflg = 0; /* true if Clearance only */
+ int errflg = 0; /* true if arg error */
+ m_label_t *label = NULL; /* binary labels */
+ char ascii[PIPE_BUF]; /* human readable label */
+ char *hex = NULL; /* internal label to print */
+ int err = 0; /* label error */
+ int c;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain(TEXT_DOMAIN);
+
+ opterr = 0;
+ while ((c = getopt(argc, argv, "c")) != EOF) {
+
+ switch (c) {
+ case 'c':
+ cflg++;
+ break;
+
+ default:
+ errflg++;
+ break;
+ }
+ }
+
+ argc -= optind - 1;
+ if (errflg || argc > 2) {
+
+ (void) fprintf(stderr,
+ gettext("usage: %s [-c] [human readable label]\n"),
+ argv[0]);
+ exit(1);
+ /*NOTREACHED*/
+ }
+
+ if (argc == 2) {
+ /* use label on command line */
+
+ (void) strlcpy(ascii, argv[optind], sizeof (ascii));
+ } else {
+ /* read label from standard input */
+ if ((c = read(STDIN_FILENO, ascii, sizeof (ascii))) < 0) {
+ perror(gettext("reading ASCII coded label"));
+ exit(1);
+ /*NOTREACHED*/
+ }
+ if (ascii[c-1] == '\n') {
+ /* replace '\n' with end of string */
+ ascii[c-1] = '\0';
+ } else {
+ /* ensure end of string */
+ ascii[c] = '\0';
+ }
+ }
+
+ if (cflg) {
+ if (str_to_label(ascii, &label, USER_CLEAR, L_NO_CORRECTION,
+ &err) == -1) {
+ label_error(ascii, err);
+ }
+ if (label_to_str(label, &hex, M_INTERNAL, DEF_NAMES) != 0) {
+ perror("label_to_str");
+ exit(1);
+ }
+ (void) printf("%s\n", hex);
+ m_label_free(label);
+ free(hex);
+ } else {
+ if (str_to_label(ascii, &label, MAC_LABEL, L_NO_CORRECTION,
+ &err) == -1) {
+ label_error(ascii, err);
+ }
+ if (label_to_str(label, &hex, M_INTERNAL, DEF_NAMES) != 0) {
+ perror("label_to_str");
+ exit(1);
+ }
+ (void) printf("%s\n", hex);
+ m_label_free(label);
+ free(hex);
+ }
+
+ return (0); /* really exit(0); */
+}
diff --git a/usr/src/cmd/tsol/demo/Makefile b/usr/src/cmd/tsol/demo/Makefile
new file mode 100644
index 0000000000..a8d28afe21
--- /dev/null
+++ b/usr/src/cmd/tsol/demo/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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# lib/libexacct/demo/Makefile
+#
+
+include ../../../cmd/Makefile.cmd
+
+.KEEP_STATE:
+
+DEMOFILES = \
+ clonebylabel.sh \
+ getmounts.sh \
+ runinzone.ksh \
+ runwlabel.ksh \
+ waitforzone.ksh
+
+ROOTDEMODIR = $(ROOT)/usr/demo/tsol
+ROOTDEMOFILES = $(DEMOFILES:%=$(ROOTDEMODIR)/%)
+
+all:
+
+install: all $(ROOTDEMOFILES)
+
+clean:
+
+lint: lint_PROG
+
+$(ROOTDEMODIR):
+ $(INS.dir)
+
+$(ROOTDEMODIR)/%: %
+ $(INS.file)
+
+$(ROOTDEMOFILES): $(ROOTDEMODIR)
+
+$(ROOTDEMODIR) := OWNER = root
+$(ROOTDEMODIR) := GROUP = bin
+$(ROOTDEMODIR) := DIRMODE = 755
+
+$(ROOTDEMOFILES) := OWNER = root
+$(ROOTDEMOFILES) := GROUP = bin
+$(ROOTDEMOFILES) := FILEMODE = 555
+
+include ../../../cmd/Makefile.targ
diff --git a/usr/src/cmd/tsol/demo/clonebylabel.sh b/usr/src/cmd/tsol/demo/clonebylabel.sh
new file mode 100644
index 0000000000..ffbb89018f
--- /dev/null
+++ b/usr/src/cmd/tsol/demo/clonebylabel.sh
@@ -0,0 +1,107 @@
+#!/bin/sh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# clonebylabel
+#
+# This script installs zones by cloning a zfs snapshot.
+# For each sensitivity label dominated by the clearance
+# a zone is installed if necessary. If the zone name is
+# not already defined in tnzonecfg, the user is prompted
+# to provide a unique zone name.
+#
+# $1 is the label upper bound (clearance)
+#
+# $2 is the zone snaphot to clone for a new zone
+
+ZONECFG=/etc/security/tsol/tnzonecfg
+clearance=$1
+image=$2
+
+#
+# Configure a zone
+#
+
+configure()
+{
+ config=/tmp/zfg.$$
+ echo "create -F -t SUNWtsoldef" > $config
+ echo "set zonepath=/zone/$zonename" >> $config
+ echo "commit" >> $config
+ /usr/sbin/zonecfg -z $zonename -f $config
+ rm $config
+}
+
+#
+# Clone a zone
+#
+
+clone()
+{
+ echo Cloning $zonename from $image ...
+ found=`zoneadm -z $zonename list -p 2>/dev/null`
+ if [ $found ]; then
+ true
+ else
+ echo "$zonename is being configured."
+ configure
+ fi
+ /usr/sbin/zfs clone $image zone/$zonename
+ /usr/sbin/zoneadm -z $zonename attach -F
+}
+
+#
+# Create missing zones for each label dominated by clearance
+#
+
+for label in `lslabels -h "$clearance"`; do
+ zonename=`/bin/grep $label: $ZONECFG | cut -d ":" -f1`
+ if [ $zonename ]; then
+ state=`zoneadm -z $zonename list -p 2>/dev/null | cut -d ":" -f3`
+ if [ $state ]; then
+ if [ $state != configured ]; then
+ echo $zonename is already installed.
+ continue
+ fi
+ fi
+ else
+ zonelabel=`hextoalabel $label`
+ echo Enter zone name for $zonelabel
+ echo or RETURN to skip this label:
+ read zonename
+ if [ $zonename ]; then
+ nz=`/bin/grep "^$zonename:" $ZONECFG | cut -d ":" -f1`
+ if [ $nz ]; then
+ echo $zonename is already used for another label.
+ else
+ echo "$zonename:$label:0::" >> $ZONECFG
+ fi
+ else
+ echo Skipping zone for $zonelabel
+ continue
+ fi
+ fi
+ clone
+done
diff --git a/usr/src/cmd/tsol/demo/getmounts.sh b/usr/src/cmd/tsol/demo/getmounts.sh
new file mode 100644
index 0000000000..3f5d18b13f
--- /dev/null
+++ b/usr/src/cmd/tsol/demo/getmounts.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+cut -f2 /etc/mnttab | while read mntpnt; do
+ /usr/bin/getlabel $mntpnt
+done
diff --git a/usr/src/cmd/tsol/demo/runinzone.ksh b/usr/src/cmd/tsol/demo/runinzone.ksh
new file mode 100644
index 0000000000..ed02400d0b
--- /dev/null
+++ b/usr/src/cmd/tsol/demo/runinzone.ksh
@@ -0,0 +1,41 @@
+#!/bin/ksh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+#
+# Usage:
+# runinzone zonename username my-program
+#
+
+zonename=$1
+user=$2
+program=$3
+
+# Boot the specified zone
+zoneadm -z ${zonename} boot
+
+# Run the command in the specified zone
+zlogin ${zonename} /usr/demo/tsol/waitforzone.ksh ${user} ${program} ${DISPLAY}
+
diff --git a/usr/src/cmd/tsol/demo/runwlabel.ksh b/usr/src/cmd/tsol/demo/runwlabel.ksh
new file mode 100644
index 0000000000..6eb0ce235f
--- /dev/null
+++ b/usr/src/cmd/tsol/demo/runwlabel.ksh
@@ -0,0 +1,50 @@
+#!/bin/sh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+#
+# Usage:
+# runwlabel "my-label" my-program
+#
+
+[ ! -x /usr/sbin/zoneadm ] && exit 0 # SUNWzoneu not installed
+
+PATH=/usr/sbin:/usr/bin; export PATH
+
+# Get the zone path associated with the "my-label" zone
+# Remove the trailing "/root"
+zonepath=`getzonepath "$1" | sed -e 's/\/root$//'`
+progname="$2"
+
+# Find the zone name that is associated with this zone path
+for zone in `zoneadm list -pi | nawk -F: -v zonepath=${zonepath} '{
+ if ("$4" == "${zonepath}") {
+ print $2
+ }
+}'`; do
+ # Run the specified command in the matching zone
+ zlogin ${zone} ${progname}
+ done
+exit
diff --git a/usr/src/cmd/tsol/demo/waitforzone.ksh b/usr/src/cmd/tsol/demo/waitforzone.ksh
new file mode 100644
index 0000000000..29e6bec6cd
--- /dev/null
+++ b/usr/src/cmd/tsol/demo/waitforzone.ksh
@@ -0,0 +1,42 @@
+#!/bin/ksh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+user=$1
+program=$2
+display=$3
+
+# Wait for the local zone automounter to come up
+# by checking for the auto_home trigger being loaded
+
+while [ ! -d /home/${user} ]; do
+sleep 1
+done
+
+# Now, run the command you specified as the specified user
+
+su - ${user} -c "${program} -display ${display}"
+
diff --git a/usr/src/cmd/tsol/getlabel/Makefile b/usr/src/cmd/tsol/getlabel/Makefile
new file mode 100644
index 0000000000..2d68597fb9
--- /dev/null
+++ b/usr/src/cmd/tsol/getlabel/Makefile
@@ -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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# cmd/tsol/getlabel
+#
+PROG= getlabel
+
+include ../../Makefile.cmd
+
+LDLIBS += -ltsol
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all $(ROOTPROG)
+
+clean:
+
+lint: lint_PROG
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/tsol/getlabel/getlabel.c b/usr/src/cmd/tsol/getlabel/getlabel.c
new file mode 100644
index 0000000000..1f6a3b1239
--- /dev/null
+++ b/usr/src/cmd/tsol/getlabel/getlabel.c
@@ -0,0 +1,152 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * getlabel - gets file label.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <locale.h>
+#include <tsol/label.h>
+
+#define s_flag 0x04
+#define S_flag 0x08
+
+
+static int
+get_label(char *filename, uint_t opt_flag)
+{
+ m_label_t *fl;
+ char *label;
+
+ if ((fl = m_label_alloc(MAC_LABEL)) == NULL) {
+ perror("m_label_alloc");
+ return (1);
+ } else if (getlabel(filename, fl) != 0) {
+ perror(filename);
+ m_label_free(fl);
+ return (1);
+ }
+
+ (void) printf("%s:\t", filename);
+ switch (opt_flag) {
+ case S_flag:
+ if (label_to_str(fl, &label, M_LABEL, LONG_NAMES) != 0) {
+ perror(gettext("%s:unable to translate "
+ "Sensitivity label"));
+ m_label_free(fl);
+ return (2);
+ }
+ break;
+ case s_flag:
+ if (label_to_str(fl, &label, M_LABEL, SHORT_NAMES) != 0) {
+ perror(gettext("unable to translate "
+ "Sensitivity label"));
+ m_label_free(fl);
+ return (2);
+ }
+ break;
+ default:
+ if (label_to_str(fl, &label, M_LABEL, DEF_NAMES) != 0) {
+ perror(gettext("unable to translate "
+ "Sensitivity label"));
+ m_label_free(fl);
+ return (2);
+ }
+ break;
+ }
+ (void) printf("%s\n", label);
+
+ free(label);
+ m_label_free(fl);
+ return (0);
+}
+
+void
+usage(char *prog)
+{
+ (void) fprintf(stderr, gettext("Usage: \n"));
+ (void) fprintf(stderr, gettext("\t%s [-S | -s] filename ...\n"),
+ prog);
+ exit(1);
+}
+
+
+int
+main(int argc, char **argv)
+{
+ uint_t opt_flag = 0;
+ int rc = 0;
+ int opt;
+ char *prog;
+
+ (void) setlocale(LC_ALL, "");
+#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
+#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
+#endif
+ (void) textdomain(TEXT_DOMAIN);
+
+ if ((prog = strrchr(argv[0], '/')) == NULL)
+ prog = argv[0];
+ else
+ prog++;
+
+ if (argc < 2) {
+ usage(prog);
+ }
+
+ while ((opt = getopt(argc, argv, ":sS")) != EOF) {
+ switch (opt) {
+ case 's':
+ if (opt_flag != 0)
+ usage(prog);
+ opt_flag = s_flag;
+ break;
+ case 'S':
+ if (opt_flag != 0)
+ usage(prog);
+ opt_flag = S_flag;
+ break;
+ default:
+ usage(prog);
+ }
+ }
+ if ((argc -= optind) < 1) {
+ usage(prog);
+ }
+ argv += optind;
+ while (argc-- > 0) {
+ if (get_label(*argv++, opt_flag) != 0)
+ rc = 2;
+ }
+ return (rc);
+}
diff --git a/usr/src/cmd/tsol/getzonepath/Makefile b/usr/src/cmd/tsol/getzonepath/Makefile
new file mode 100644
index 0000000000..861cf558f1
--- /dev/null
+++ b/usr/src/cmd/tsol/getzonepath/Makefile
@@ -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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# cmd/tsol/getzonepath
+#
+PROG= getzonepath
+
+include ../../Makefile.cmd
+
+LDLIBS += -ltsol
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all $(ROOTPROG)
+
+clean:
+
+lint: lint_PROG
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/tsol/getzonepath/getzonepath.c b/usr/src/cmd/tsol/getzonepath/getzonepath.c
new file mode 100644
index 0000000000..f8e05df481
--- /dev/null
+++ b/usr/src/cmd/tsol/getzonepath/getzonepath.c
@@ -0,0 +1,111 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Name: getzonepath.c
+ *
+ * Description: Get the zone pathname associated with a label.
+ *
+ * Usage: getzonepath sensitivity_label
+ */
+
+#include <errno.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <tsol/label.h>
+
+static char *prog;
+
+static void
+label_error(const char *label, const int err)
+{
+ if (errno == EINVAL) {
+ switch (err) {
+ case M_BAD_STRING:
+ (void) fprintf(stderr,
+ gettext("%s: bad string %s\n"), prog, label);
+ break;
+ case M_BAD_LABEL:
+ (void) fprintf(stderr,
+ gettext("%s: bad previous label\n"), prog);
+ break;
+ default:
+ (void) fprintf(stderr,
+ gettext("%s: parsing error found in "
+ "\"%s\" at position %d\n"), prog, label, err);
+ break;
+ }
+ } else {
+ perror(prog);
+ }
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ int err = 0;
+ m_label_t *label = NULL;
+ char *zone_root;
+
+ (void) setlocale(LC_ALL, "");
+#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
+#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it were'nt */
+#endif
+ (void) textdomain(TEXT_DOMAIN);
+
+ if ((prog = strrchr(argv[0], '/')) == NULL)
+ prog = argv[0];
+ else
+ prog++;
+
+ if (argc != 2) {
+ (void) fprintf(stderr, gettext(
+ "Usage: %s label\n"), prog);
+ return (1);
+ }
+
+ if (str_to_label(argv[1], &label, MAC_LABEL, L_NO_CORRECTION,
+ &err) == -1) {
+ label_error(argv[1], err);
+ }
+
+ if ((zone_root = getzonerootbylabel(label)) == NULL) {
+ (void) fprintf(stderr,
+ gettext("%s: cannot get path for label: %s.\n"), prog,
+ strerror(errno));
+ return (3);
+ }
+
+ (void) printf("%s\n", zone_root);
+
+ return (0);
+} /* end main() */
diff --git a/usr/src/cmd/tsol/hextoalabel/Makefile b/usr/src/cmd/tsol/hextoalabel/Makefile
new file mode 100644
index 0000000000..32d0e342ce
--- /dev/null
+++ b/usr/src/cmd/tsol/hextoalabel/Makefile
@@ -0,0 +1,51 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# cmd/tsol/hextoalabel/Makefile
+#
+PROG= hextoalabel
+
+include ../../Makefile.cmd
+
+LDLIBS += -ltsol
+
+CPPFLAGS += -I$(SRC)/lib/libtsol/common/label
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all $(ROOTUSRSBINPROG)
+
+clean:
+
+lint: lint_PROG
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/tsol/hextoalabel/hextoalabel.c b/usr/src/cmd/tsol/hextoalabel/hextoalabel.c
new file mode 100644
index 0000000000..f82df57006
--- /dev/null
+++ b/usr/src/cmd/tsol/hextoalabel/hextoalabel.c
@@ -0,0 +1,161 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * hextoalabel - Convert an internal label to its human readable
+ * equivalent.
+ */
+
+#include <errno.h>
+#include <libintl.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/param.h>
+
+#include <tsol/label.h>
+
+#if !defined(TEXT_DOMAIN)
+#define TEXT_DOMAIN "SYS_TEST"
+#endif /* !defined(TEXT_DOMAIN) */
+
+static void
+label_error(const char *hex, const int err)
+{
+ if (errno == EINVAL) {
+ switch (err) {
+ case M_BAD_STRING:
+ (void) fprintf(stderr,
+ gettext("hextoalabel: bad string %s\n"), hex);
+ break;
+ case M_BAD_LABEL:
+ (void) fprintf(stderr,
+ gettext("hextoalabel: bad previous label\n"));
+ break;
+ default:
+ (void) fprintf(stderr,
+ gettext("hextoalabel: parsing error found in "
+ "\"%s\" at position %d\n"), hex, err);
+ break;
+ }
+ } else {
+ perror("hextoalabel");
+ }
+ exit(1);
+ /*NOTREACHED*/
+}
+
+int
+main(int argc, char **argv)
+{
+ int cflg = 0; /* true if Clearance only */
+ int errflg = 0; /* true if arg error */
+ m_label_t *label = NULL;
+ char hex[PIPE_BUF]; /* internal label */
+ char *ascii = NULL; /* human readable label to print */
+ int err = 0; /* label error */
+ int c;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain(TEXT_DOMAIN);
+
+ opterr = 0;
+ while ((c = getopt(argc, argv, "c")) != EOF) {
+
+ switch (c) {
+ case 'c':
+ cflg++;
+ break;
+ default:
+ errflg++;
+ break;
+ }
+ }
+
+ argc -= optind - 1;
+ if (errflg || argc > 2) {
+
+ (void) fprintf(stderr,
+ gettext("usage: %s [-c] [hexadecimal label]\n"), argv[0]);
+ exit(1);
+ /*NOTREACHED*/
+ }
+
+ if (argc == 2) {
+ /* use label on command line */
+
+ (void) strlcpy(hex, argv[optind], sizeof (hex));
+ } else {
+ /* read label from standard input */
+
+ if ((c = read(STDIN_FILENO, hex, sizeof (hex))) < 0) {
+
+ perror(gettext("reading hexadecimal label"));
+ exit(1);
+ /*NOTREACHED*/
+ }
+ if (hex[c-1] == '\n') {
+ /* replace '\n' with end of string */
+ hex[c-1] = '\000';
+ } else {
+ /* ensure end of string */
+ hex[c] = '\000';
+ }
+ }
+
+ if (cflg) {
+ if (str_to_label(hex, &label, USER_CLEAR, L_NO_CORRECTION,
+ &err) == -1) {
+ label_error(hex, err);
+ }
+ if (label_to_str(label, &ascii, M_LABEL, DEF_NAMES) != 0) {
+ perror("label_to_str");
+ exit(1);
+ }
+ (void) printf("%s\n", ascii);
+ m_label_free(label);
+ free(ascii);
+ } else {
+ if (str_to_label(hex, &label, MAC_LABEL, L_NO_CORRECTION,
+ &err) == -1) {
+ label_error(hex, err);
+ }
+ if (label_to_str(label, &ascii, M_LABEL, DEF_NAMES) != 0) {
+ perror("label_to_str");
+ exit(1);
+ }
+ (void) printf("%s\n", ascii);
+ m_label_free(label);
+ free(ascii);
+ }
+
+ return (0); /* really exit(0); */
+}
diff --git a/usr/src/cmd/tsol/labeld/Makefile b/usr/src/cmd/tsol/labeld/Makefile
new file mode 100644
index 0000000000..a38af2a9fa
--- /dev/null
+++ b/usr/src/cmd/tsol/labeld/Makefile
@@ -0,0 +1,58 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/tsol/labeld/Makefile
+#
+
+ETCTSOLFILES=tnrhdb tnrhtp tnzonecfg
+
+include ../../Makefile.cmd
+
+all:= TARGET= all
+clean:= TARGET= clean
+clobber:= TARGET= clobber
+install:= TARGET= install
+lint:= TARGET= lint
+_msg:= TARGET= _msg
+
+MANIFEST= labeld.xml
+ROOTMANIFESTDIR = $(ROOTSVCSYSTEM)
+SVCMETHOD= svc-labeld
+$(ROOTMANIFEST) := FILEMODE= 444
+
+.KEEP_STATE:
+
+all:
+
+install: $(ROOTMANIFEST) $(ROOTSVCMETHOD)
+
+clean clobber:
+
+lint:
+
+_msg:
+
+FRC:
diff --git a/usr/src/cmd/tsol/labeld/labeld.xml b/usr/src/cmd/tsol/labeld/labeld.xml
new file mode 100644
index 0000000000..6ae4f975a1
--- /dev/null
+++ b/usr/src/cmd/tsol/labeld/labeld.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ ident "%Z%%M% %I% %E% SMI"
+-->
+
+<service_bundle type='manifest' name='SUNWtsg:labeld'>
+
+<service
+ name='system/labeld'
+ type='service'
+ version='1'>
+
+ <create_default_instance enabled='false' />
+
+ <single_instance/>
+
+ <dependency
+ name='usr'
+ type='service'
+ grouping='require_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/filesystem/minimal' />
+ </dependency>
+
+ <exec_method
+ type='method'
+ name='start'
+ exec='/lib/svc/method/svc-labeld %m'
+ timeout_seconds='180' />
+
+ <exec_method
+ type='method'
+ name='stop'
+ exec='/lib/svc/method/svc-labeld %m'
+ timeout_seconds='180' />
+
+ <property_group name='general' type='framework'>
+ <!-- start and stop labeld -->
+ <propval name='action_authorization' type='astring'
+ value='solaris.smf.manage.labels' />
+ <propval name='value_authorization' type='astring'
+ value='solaris.smf.manage.labels' />
+ </property_group>
+
+ <stability value='Unstable' />
+
+ <template>
+ <common_name>
+ <loctext xml:lang='C'> label daemon
+ </loctext>
+ </common_name>
+ <documentation>
+ <doc_link
+ name='Solaris Trusted Extensions Label Administration Guide'
+ uri='http://docs.sun.com' />
+ </documentation>
+ </template>
+</service>
+
+</service_bundle>
diff --git a/usr/src/cmd/tsol/labeld/svc-labeld b/usr/src/cmd/tsol/labeld/svc-labeld
new file mode 100644
index 0000000000..3e566a4cbb
--- /dev/null
+++ b/usr/src/cmd/tsol/labeld/svc-labeld
@@ -0,0 +1,282 @@
+#!/sbin/sh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+. /lib/svc/share/smf_include.sh
+
+ROOT_PATH=""
+if [ $# -gt 1 ]; then
+ if [ $# -ne 3 -o "$2" != "-R" ]; then
+ echo "$0: invalid syntax"
+ exit $SMF_EXIT_ERR_CONFIG
+ fi
+ if [ "$3" != "/" ]; then
+ ROOT_PATH=$3
+ fi
+fi
+if [ -n "$ROOT_PATH" -a "$1" != "start" ]; then
+ echo "$0: invalid syntax: -R allowed for start method only"
+ exit $SMF_EXIT_ERR_CONFIG
+fi
+if [ -n "$ROOT_PATH" -a ! -d "$ROOT_PATH" ]; then
+ echo "$0: invalid -R rootpath dir specified"
+ exit $SMF_EXIT_ERR_CONFIG
+fi
+
+if smf_is_nonglobalzone; then
+ echo "$0: not supported in a local zone"
+ exit $SMF_EXIT_ERR_CONFIG
+fi
+
+do_logindev()
+{
+ # Comment out audio and usb device entries in /etc/logindevperm.
+ LOGINDEVPERM=$ROOT_PATH/etc/logindevperm
+ if [ -f $LOGINDEVPERM ]; then
+ line="\/dev\/console 0600 \/dev\/sound\/\*"
+ sed -e "s/^$line/#$line/" $LOGINDEVPERM > /tmp/tmp.$$
+ cp /tmp/tmp.$$ $LOGINDEVPERM
+ line="\/dev\/console 0600 \/dev\/usb\/\[0-9a-f\]+\[.\]\[0-9a-f\]+\/\[0-9\]+\/\*"
+ sed -e "s/^$line/#$line/" $LOGINDEVPERM > /tmp/tmp.$$
+ cp /tmp/tmp.$$ $LOGINDEVPERM
+ rm -f /tmp/tmp.$$
+ fi
+}
+
+do_otherservices()
+{
+ # Setup dependent services
+ cat >> $ROOT_PATH/var/svc/profile/upgrade <<\__ENABLE_OTHERS
+ /usr/sbin/svcadm enable -s svc:/network/tnd:default
+ /usr/sbin/svcadm enable -s svc:/system/tsol-zones:default
+ /usr/sbin/svccfg -s svc:/application/x11/x11-server \
+ setprop options/tcp_listen = true
+ /usr/sbin/svcadm enable svc:/network/rpc/rstat:default
+__ENABLE_OTHERS
+
+}
+
+do_bsmconv()
+{
+ # Run bsmconv so audit and device allocation is enabled by
+ # default with Trusted Extensions.
+ if [ "$ROOT_PATH" = "/" -o "$ROOT_PATH" = "" ]; then
+ BSMDIR=""
+ else
+ BSMDIR=$ROOT_PATH
+ fi
+ echo "Running bsmconv ..."
+ echo `TEXTDOMAIN="SUNW_OST_OSCMD" gettext "y"` | \
+ $ROOT_PATH/etc/security/bsmconv $ROOT_PATH
+}
+
+do_nscd()
+{
+# For Trusted Extensions, make nscd service transient in local zones.
+cat >> $ROOT_PATH/var/svc/profile/upgrade <<\_DEL_LOCAL_NSCD
+ if [ `/sbin/zonename` != "global" ]; then
+ nscd="svc:/system/name-service-cache"
+ duration=""
+ if /bin/svcprop -q -c -p startd/duration $nscd ; then
+ duration=`/bin/svcprop -c -p startd/duration $nscd`
+ fi
+ if [ "$duration" != "transient" ]; then
+ /usr/sbin/svccfg -s $nscd addpg startd framework
+ /usr/sbin/svccfg -s $nscd setprop \
+ startd/duration = astring: transient
+ /usr/sbin/svccfg -s $nscd setprop stop/exec = :true
+ /usr/sbin/svcadm refresh $nscd
+ fi
+ fi
+_DEL_LOCAL_NSCD
+}
+
+do_bootupd()
+{
+ if [ -f $ROOT_PATH/platform/`/sbin/uname -m`/boot_archive ]; then
+ if [ -z "$ROOT_PATH" -o "$ROOT_PATH" = "/" ]; then
+ /sbin/bootadm update-archive
+ else
+ /sbin/bootadm update-archive -R $ROOT_PATH
+ fi
+ fi
+}
+
+do_commonstart()
+{
+ echo "$0: Updating $ROOT_PATH/etc/system..."
+ if [ ! -f ${ROOT_PATH}/etc/system ]; then
+ touch ${ROOT_PATH}/etc/system
+ fi
+
+ # Set sys_labeling in etc/system
+ grep -v "sys_labeling=" ${ROOT_PATH}/etc/system > /tmp/etc.system.$$
+ echo "set sys_labeling=1" >> /tmp/etc.system.$$
+ mv /tmp/etc.system.$$ ${ROOT_PATH}/etc/system
+ grep "set sys_labeling=1" ${ROOT_PATH}/etc/system > /dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ echo "$0: ERROR: cannot set sys_labeling in $ROOT_PATH/etc/system"
+ exit $SMF_EXIT_ERR_FATAL
+ fi
+
+ do_bootupd
+
+ # Setup dependent services
+ do_otherservices
+
+ do_logindev
+ do_bsmconv
+ do_nscd
+}
+
+
+daemon_start()
+{
+ # If a labeld door exists, check for a labeld process and exit
+ # if the daemon is already running.
+ if [ -r /var/tsol/doors/labeld ]; then
+ if /usr/bin/pgrep -x -u 0 -P 1 labeld >/dev/null 2>&1; then
+ echo "$0: labeld is already running"
+ exit $SMF_EXIT_ERR_FATAL
+ fi
+ fi
+ /usr/bin/rm -f /var/tsol/doors/labeld
+ /usr/lib/labeld
+}
+
+PATH=/usr/sbin:/usr/bin; export PATH
+
+case "$1" in
+'start')
+ if [ -z "$ROOT_PATH" -o "$ROOT_PATH" = "/" ]; then
+ # native
+
+ if [ -z "$SMF_FMRI" ]; then
+ echo "$0: this script can only be invoked by smf(5)"
+ exit $SMF_EXIT_ERR_NOSMF
+ fi
+
+ tx_enabled=`/usr/bin/svcprop -c -p general/enabled $SMF_FMRI`
+ if [ "$tx_enabled" = "false" ]; then
+ # A sign of trying temporary enablement...no-no
+ echo "$0: Temporarily enabling Trusted Extensions is not allowed."
+ exit $SMF_EXIT_ERR_CONFIG
+ fi
+
+ if (smf_is_system_labeled); then
+ daemon_start
+ exit $SMF_EXIT_OK
+ fi
+
+ # Make changes to enable Trusted Extensions
+ grep "^set sys_labeling=1" ${ROOT_PATH}/etc/system > /dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ echo "$0: already enabled. Exiting."
+ exit $SMF_EXIT_OK
+ fi
+
+ if [ "`/usr/sbin/zoneadm list -c`" != "global" ]; then
+ echo "$0: Must remove zones before enabling Trusted Extensions."
+ exit $SMF_EXIT_ERR_CONFIG
+ fi
+
+ do_commonstart
+
+ # start daemon proccess so our service doesn't go into
+ # maintenance state
+ daemon_start
+
+ echo "$0: Started. Must reboot and configure Trusted Extensions."
+ else
+ # Support jumpstart etc
+
+ # Make changes to enable Trusted Extensions
+ grep "^set sys_labeling=1" ${ROOT_PATH}/etc/system > /dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ echo "$0: already enabled. Exiting."
+ exit $SMF_EXIT_OK
+ fi
+
+ # Setup dependent services
+ cat >> $ROOT_PATH/var/svc/profile/upgrade <<\__TRUSTED_ENABLE
+ /usr/sbin/svcadm enable -s svc:/system/labeld:default
+__TRUSTED_ENABLE
+
+ do_commonstart
+ echo "$0: Started. Must configure Trusted Extensions before booting."
+ fi
+ ;;
+
+'stop')
+ tx_enabled=`/usr/bin/svcprop -c -p general/enabled $SMF_FMRI`
+ if [ "$tx_enabled" = "true" ]; then
+ /usr/bin/pkill -x -u 0 -P 1 -z `smf_zonename` labeld
+ exit $SMF_EXIT_OK
+ fi
+
+ if [ "`/usr/sbin/zoneadm list -c`" != "global" ]; then
+ echo "$0: Must remove zones before disabling Trusted Extensions."
+ exit $SMF_EXIT_ERR_CONFIG
+ fi
+
+ # Stop Trusted services.
+ /usr/sbin/svcadm disable svc:/system/tsol-zones:default 2>/dev/null
+ /usr/sbin/svcadm disable svc:/network/tnd:default 2>/dev/null
+
+ # Uncomment audio and usb device entries in /etc/logindevperm.
+ LOGINDEVPERM=$ROOT_PATH/etc/logindevperm
+ if [ -f $LOGINDEVPERM ]; then
+ line="\/dev\/console 0600 \/dev\/sound\/\*"
+ sed -e "s/^#$line/$line/" $LOGINDEVPERM > /tmp/tmp.$$
+ cp /tmp/tmp.$$ $LOGINDEVPERM
+ line="\/dev\/console 0600 \/dev\/usb\/\[0-9a-f\]+\[.\]\[0-9a-f\]+\/\[0-9\]+\/\*"
+ sed -e "s/^#$line/$line/" $LOGINDEVPERM > /tmp/tmp.$$
+ cp /tmp/tmp.$$ $LOGINDEVPERM
+ rm -f /tmp/tmp.$$
+ fi
+
+ # Remove sys_labeling from /etc/system
+ grep -v "sys_labeling" ${ROOT_PATH}/etc/system > /tmp/etc.system.$$
+ mv /tmp/etc.system.$$ ${ROOT_PATH}/etc/system
+ grep "sys_labeling" ${ROOT_PATH}/etc/system > /dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ echo "$0: ERROR: cannot remove sys_labeling in $ROOT_PATH/etc/system"
+ exit $SMF_EXIT_ERR_FATAL
+ fi
+
+ do_bootupd
+
+ /usr/bin/pkill -x -u 0 -P 1 -z `smf_zonename` labeld
+ echo "$0: Stopped. Will take effect at next boot."
+ ;;
+
+*)
+ echo "Usage: $0 { start | stop }"
+ exit 1
+ ;;
+esac
+
+exit $SMF_EXIT_OK
+
diff --git a/usr/src/cmd/tsol/lslabels/Makefile b/usr/src/cmd/tsol/lslabels/Makefile
new file mode 100644
index 0000000000..67547b175a
--- /dev/null
+++ b/usr/src/cmd/tsol/lslabels/Makefile
@@ -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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# cmd/tsol/lslabels
+#
+PROG= lslabels
+OBJS= lslabels.o
+SRCS= $(OBJS:%.o=%.c)
+
+include ../../Makefile.cmd
+
+LDLIBS += -ltsol
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all $(ROOTLIBPROG)
+
+clean:
+ $(RM) $(OBJS)
+
+lint: lint_PROG
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/tsol/lslabels/lslabels.c b/usr/src/cmd/tsol/lslabels/lslabels.c
new file mode 100644
index 0000000000..029fcbda71
--- /dev/null
+++ b/usr/src/cmd/tsol/lslabels/lslabels.c
@@ -0,0 +1,214 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * lslabels - Display all labels dominating the specified label.
+ */
+
+#include <errno.h>
+#include <libintl.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/param.h>
+
+#include <tsol/label.h>
+#include <sys/tsol/label_macro.h>
+#include <iso/limits_iso.h>
+
+#if !defined(TEXT_DOMAIN)
+#define TEXT_DOMAIN "SYS_TEST"
+#endif /* !defined(TEXT_DOMAIN) */
+
+int hflg = 0; /* true if hex output */
+
+/*
+ * Compartment mask macros.
+ */
+
+typedef uint32_t comp_chunk_t;
+
+#define __NBWRD (CHAR_BIT * sizeof (comp_chunk_t))
+#define COMP_BITS (CHAR_BIT * sizeof (Compartments_t))
+#define compmask(n) (1 << ((__NBWRD - 1) - ((n) % __NBWRD)))
+#define compword(n) ((n)/__NBWRD)
+
+#define COMP_ADDSET(a, p) ((comp_chunk_t *)(a))[compword(p)] |= \
+ compmask(p)
+#define COMP_DELSET(a, p) ((comp_chunk_t *)(a))[compword(p)] &= \
+ ~compmask(p)
+#define COMP_ISMEMBER(a, p) ((((comp_chunk_t *)(a))[compword(p)] & \
+ compmask(p)) != 0)
+
+/* Need functions to test if bit is on */
+
+
+void
+bitfinder(m_label_t label, int next_bit) {
+ char *labelstr = NULL;
+
+ Compartments_t *comps = &label.compartments;
+
+ while (next_bit < COMP_BITS) {
+ if (COMP_ISMEMBER(comps, next_bit)) {
+ bitfinder(label, next_bit + 1);
+ COMP_DELSET(comps, next_bit);
+
+ if (label_to_str(&label, &labelstr, M_LABEL,
+ LONG_NAMES) == 0) {
+ m_label_t *label2 = NULL;
+ int err;
+
+ if (str_to_label(labelstr, &label2, MAC_LABEL,
+ L_NO_CORRECTION, &err) == 0) {
+ if (!hflg) {
+ (void) printf("%s\n", labelstr);
+ } else {
+ free(labelstr);
+ (void) label_to_str(&label,
+ &labelstr, M_INTERNAL, 0);
+ (void) printf("%s\n", labelstr);
+ }
+ m_label_free(label2);
+ }
+ free(labelstr);
+ }
+ bitfinder(label, next_bit + 1);
+ break;
+ }
+ next_bit++;
+ }
+}
+
+static void
+label_error(const char *ascii, const int err)
+{
+ if (errno == EINVAL) {
+ switch (err) {
+ case M_BAD_STRING:
+ (void) fprintf(stderr,
+ gettext("lslabels: bad string %s\n"), ascii);
+ break;
+ case M_BAD_LABEL:
+ (void) fprintf(stderr,
+ gettext("lslabels: bad previous label\n"));
+ break;
+ default:
+ (void) fprintf(stderr,
+ gettext("lslabels: parsing error found in "
+ "\"%s\" at position %d\n"), ascii, err);
+ break;
+ }
+ } else {
+ perror("lslabels");
+ }
+ exit(1);
+ /*NOTREACHED*/
+}
+
+int
+main(int argc, char **argv)
+{
+ int errflg = 0; /* true if arg error */
+ m_label_t *label = NULL; /* binary labels */
+ char ascii[PIPE_BUF]; /* human readable label */
+ char *labelstr = NULL; /* external label to start from */
+ int err = 0; /* label error */
+ int c;
+ int mode = M_LABEL;
+ _Classification *level;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain(TEXT_DOMAIN);
+
+ opterr = 0;
+ while ((c = getopt(argc, argv, "h")) != EOF) {
+
+ switch (c) {
+ case 'h':
+ hflg++;
+ mode = M_INTERNAL;
+ break;
+
+ default:
+ errflg++;
+ break;
+ }
+ }
+
+ argc -= optind - 1;
+ if (errflg || argc > 2) {
+
+ (void) fprintf(stderr,
+ gettext("usage: %s [-h] [label]\n"),
+ argv[0]);
+ exit(1);
+ /*NOTREACHED*/
+ }
+
+ if (argc == 2) {
+ /* use label on command line */
+
+ (void) strlcpy(ascii, argv[optind], sizeof (ascii));
+ } else {
+ /* read label from standard input */
+ if ((c = read(STDIN_FILENO, ascii, sizeof (ascii))) < 0) {
+ perror(gettext("reading ASCII coded label"));
+ exit(1);
+ /*NOTREACHED*/
+ }
+ if (ascii[c-1] == '\n') {
+ /* replace '\n' with end of string */
+ ascii[c-1] = '\0';
+ } else {
+ /* ensure end of string */
+ ascii[c] = '\0';
+ }
+ }
+
+ if (str_to_label(ascii, &label, MAC_LABEL, L_NO_CORRECTION,
+ &err) == -1) {
+ label_error(ascii, err);
+ }
+ if (label_to_str(label, &labelstr, mode,
+ DEF_NAMES) == 0) {
+ (void) printf("%s\n", labelstr);
+ }
+
+ level = &label->classification.class_u.class_chunk;
+ while (*level > 0) {
+ bitfinder(*label, 0);
+ *level -= 1;
+ }
+ m_label_free(label);
+
+ return (0); /* really exit(0); */
+}
diff --git a/usr/src/cmd/tsol/misc/Makefile b/usr/src/cmd/tsol/misc/Makefile
new file mode 100755
index 0000000000..0537a30a3d
--- /dev/null
+++ b/usr/src/cmd/tsol/misc/Makefile
@@ -0,0 +1,53 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# cmd/tsol/misc
+#
+SCRIPT=txzonemgr
+ETCTSOLFILES=relabel
+
+include ../../Makefile.cmd
+
+$(ROOTETCTSOL)/relabel := FILEMODE= 0755
+
+.KEEP_STATE:
+
+all: $(SCRIPT) $(ETCTSOLFILES)
+
+install: all $(ROOTUSRSBINSCRIPT) $(ROOTETCTSOLFILES)
+
+clean:
+ $(RM) $(SCRIPT) $(ETCTSOLFILES)
+
+lint:
+
+_msg:
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/tsol/misc/relabel.sh b/usr/src/cmd/tsol/misc/relabel.sh
new file mode 100644
index 0000000000..b7388b1c1a
--- /dev/null
+++ b/usr/src/cmd/tsol/misc/relabel.sh
@@ -0,0 +1,77 @@
+#!/bin/sh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+# This program is invoked to do the actual file transfer
+# associated with an invocation of the setflabel(3TSOL) function.
+#
+# It executes in the global zone with the user's identity and
+# basic privileges plus the file_dac_search privilege. This
+# script should not not assume that stdio is available or that
+# any particular environment variables are set. In particular,
+# the DISPLAY variable will not normally be pre-set.
+#
+# Authorization checks and zone limit privilege checks
+# are done before calling this script. Auditing is done
+# upon return.
+#
+##############################################################
+#
+# Calling sequence:
+#
+# $1 is the global zone real pathname of the source file
+#
+# $2 is the global zone real destination pathname
+#
+# Exit status:
+#
+# 0 on success
+# 1 on error
+#
+##############################################################
+#
+# This script can be customized or replaced to perform
+# additional processing such as tranquility checks, dirty
+# word filtering, copying instead of moving, etc.
+#
+# By default it does a check to determine if the source file
+# is in use by calling fuser(1). However, this check
+# does not work for filesystems that were automounted in
+# non-global zones.
+#
+# Perform a simple tranquility check
+#
+inuse=`/usr/sbin/fuser $1 2>&1 | /usr/bin/cut -d ":" -f2`
+if [ $inuse ]; then
+#
+# file is in use
+#
+ exit 1
+else
+#
+# Perform an inter-zone move of the data
+ /usr/bin/mv $1 $2
+ exit $?
+fi
diff --git a/usr/src/cmd/tsol/misc/txzonemgr.sh b/usr/src/cmd/tsol/misc/txzonemgr.sh
new file mode 100644
index 0000000000..806e26311b
--- /dev/null
+++ b/usr/src/cmd/tsol/misc/txzonemgr.sh
@@ -0,0 +1,778 @@
+#!/bin/pfksh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+# This script provides a simple GUI for managing labeled zones.
+# It takes no arguments, but provides contextual menus which
+# provide appropriate choices. It must be run in the global
+# zone as root.
+
+PATH=/usr/bin:/usr/sbin:/usr/lib export PATH
+title="Labeled Zone Manager"
+maxlabel=`chk_encodings -X 2>/dev/null`
+if [[ ! -n $maxlabel ]]; then
+ maxlabel=0x000a-08-f8
+fi
+config=/tmp/zfg.$$ ;
+
+consoleCheck() {
+ zconsole=`pgrep -f "zlogin -C $zonename"`
+ if [ $? != 0 ]; then
+ console="Zone Console...\n"
+ fi
+}
+
+labelCheck() {
+ hexlabel=`/bin/grep "^$zonename:" \
+ /etc/security/tsol/tnzonecfg|cut -d ":" -f2`;
+ if [ $hexlabel ] ; then
+ label=
+ curlabel=`hextoalabel $hexlabel`
+ else
+ label="Select Label...\n"
+ curlabel=...
+ fi
+}
+
+snapshotCheck() {
+ filesystem=`zfs list |grep zone/$zonename |cut -d " " -f1`
+ if [[ -n $filesystem ]]; then
+ snapshot="Create Snapshot\n"
+ fi
+}
+
+copyCheck() {
+ zonelist=""
+ for p in `zoneadm list -ip`; do
+ q=`echo $p|cut -d ":" -f2`
+ if [ $q != $zonename ]; then
+ zonelist="$zonelist $q"
+ fi
+ done
+ if [[ -n $zonelist ]]; then
+ copy="Copy...\n"; \
+ clone="Clone\n"; \
+ fi
+}
+
+relabelCheck() {
+ macstate=`zonecfg -z $zonename info|grep win_mac_write`
+ if [[ -n $macstate ]]; then
+ permitrelabel="Deny Relabeling\n"
+ else
+ permitrelabel="Permit Relabeling\n"
+ fi
+}
+
+selectLabel() {
+ labelList=""
+ for p in `lslabels -h $maxlabel`; do
+ hexlabel=`/bin/grep :$p: /etc/security/tsol/tnzonecfg`
+ if [ $? != 0 ]; then
+ newlabel=`hextoalabel $p`
+ labelList="$labelList $newlabel\n"
+ fi
+ done
+ alabel=$(echo $labelList|zenity --list \
+ --title="$title" \
+ --height=300 \
+ --width=400 \
+ --column="Available Sensitivity Labels")
+
+ if [[ -n $alabel ]]; then
+ newlabel=`atohexlabel "$alabel" 2>null`
+ if [[ -n $newlabel ]]; then
+ echo $zonename:$newlabel:0:: >> /etc/security/tsol/tnzonecfg
+ else
+ x=$(zenity --error \
+ --title="$title" \
+ --text="$alabel is not valid")
+ fi
+ fi
+}
+
+clone() {
+ image=`zfs list |grep snapshot|cut -d " " -f1| \
+ zenity --list \
+ --title="$title" \
+ --height=300 \
+ --column="ZFS Zone Snapshots"`
+ if [[ -n $image ]]; then
+ dataset=`zfs list |grep zone/$zonename |cut -d " " -f1`
+ if [[ -n $dataset ]]; then
+ /usr/sbin/zfs destroy zone/$zonename
+ fi
+ /usr/sbin/zfs clone $image zone/$zonename
+ /usr/sbin/zoneadm -z $zonename attach -F
+ if [ ! -f /var/ldap/ldap_client_file ]; then
+ sharePasswd
+ fi
+ fi
+}
+
+copy() {
+
+ image=`zenity --list \
+ --title="$title: Copy From" \
+ --height=300 \
+ --column="Installed Zones" $zonelist`
+
+ /usr/bin/gnome-terminal \
+ --title="$title: Copying $image to $zonename zone" \
+ --command "zoneadm -z $zonename clone -m copy $image"
+ --hide-menubar
+
+ if [ ! -f /var/ldap/ldap_client_file ]; then
+ sharePasswd
+ fi
+}
+
+initialize() {
+ hostname=`hostname`
+ hostname=$(zenity --entry \
+ --title="$title" \
+ --text="Enter Host Name: " \
+ --entry-text $hostname)
+ if [ $? != 0 ]; then
+ exit 1
+ fi
+
+ ZONE_PATH=`zoneadm list -cp|grep ":${zonename}:"|cut -d ":" -f4`
+ ZONE_ETC_DIR=$ZONE_PATH/root/etc
+ ipaddress=`getent hosts $hostname|cut -f1`
+ SYSIDCFG=${ZONE_ETC_DIR}/sysidcfg
+
+ if [ -f /var/ldap/ldap_client_file ]; then
+ ldapaddress=`ldapclient list | \
+ /bin/grep "^NS_LDAP_SERVERS" | cut -d " " -f2`
+ echo "name_service=LDAP {" > ${SYSIDCFG}
+ domain=`domainname`
+ echo "domain_name=$domain" >> ${SYSIDCFG}
+ profName=`ldapclient list | \
+ /bin/grep "^NS_LDAP_PROFILE" | cut -d " " -f2`
+ proxyPwd=`ldapclient list | \
+ /bin/grep "^NS_LDAP_BINDPASSWD" | cut -d " " -f2`
+ proxyDN=`ldapclient list | \
+ /bin/grep "^NS_LDAP_BINDDN" | cut -d " " -f 2`
+ if [ "$proxyDN" ]; then
+ echo "proxy_dn=\"$proxyDN\"" >> ${SYSIDCFG}
+ echo "proxy_password=\"$proxyPwd\"" >> ${SYSIDCFG}
+ fi
+ echo "profile=$profName" >> ${SYSIDCFG}
+ echo "profile_server=$ldapaddress }" >> ${SYSIDCFG}
+ cp /etc/nsswitch.conf $ZONE_ETC_DIR/nsswitch.ldap
+ else
+ echo "name_service=NONE" > ${SYSIDCFG}
+ sharePasswd
+ fi
+
+ echo "security_policy=NONE" >> ${SYSIDCFG}
+ locale=`locale|grep LANG | cut -d "=" -f2`
+ if [[ -z $locale ]]; then
+ locale="C"
+ fi
+ echo "system_locale=$locale" >> ${SYSIDCFG}
+ timezone=`/bin/grep "^TZ" /etc/TIMEZONE|cut -d "=" -f2`
+ echo "timezone=$timezone" >> ${SYSIDCFG}
+ echo "terminal=vt100" >> ${SYSIDCFG}
+ rootpwd=`/bin/grep "^root:" /etc/shadow|cut -d ":" -f2`
+ echo "root_password=$rootpwd" >> ${SYSIDCFG}
+ echo "network_interface=PRIMARY {" >> ${SYSIDCFG}
+ echo "protocol_ipv6=no" >> ${SYSIDCFG}
+ echo "hostname=$hostname" >> ${SYSIDCFG}
+ echo "ip_address=$ipaddress }" >> ${SYSIDCFG}
+ cp /etc/default/nfs ${ZONE_ETC_DIR}/default/nfs
+ touch ${ZONE_ETC_DIR}/.NFS4inst_state.domain
+}
+
+install() {
+ # if there is a zfs pool for zone
+ # create a new dataset for the zone
+ # This step is done automatically by zonecfg
+ # in Solaris Express 8/06 or newer
+
+ zp=`zpool list -H zone 2>/dev/null`
+ if [ $? = 0 ]; then
+ zfs create zone/$zonename
+ chmod 700 /zone/$zonename
+ fi
+
+ /usr/bin/gnome-terminal \
+ --title="$title: Installing $zonename zone" \
+ --command "zoneadm -z $zonename install" \
+ --hide-menubar
+
+ initialize
+}
+
+delete() {
+ # if there is an entry for this zone in tnzonecfg, remove it
+ # before deleting the zone.
+
+ tnzone=`egrep "^$zonename:" /etc/security/tsol/tnzonecfg 2>/dev/null`
+ if [ -n "${tnzone}" ]; then
+ sed -e "/^$tnzone:*/d" /etc/security/tsol/tnzonecfg > \
+ /tmp/tnzonefg.$$ 2>/dev/null
+ mv /tmp/tnzonefg.$$ /etc/security/tsol/tnzonecfg
+ fi
+ zonecfg -z $zonename delete -F
+ zonename=
+}
+
+getNIC(){
+
+ nics=
+ for i in `ifconfig -a4|grep "^[a-z].*:" |grep -v LOOPBACK`
+ do
+ echo $i |grep "^[a-z].*:" >/dev/null 2>&1
+ if [ $? -eq 1 ]; then
+ continue
+ fi
+ i=${i%:} # Remove colon after interface name
+ echo $i |grep ":" >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ continue
+ fi
+ nics="$nics $i"
+ done
+
+ nic=$(zenity --list \
+ --title="$title" \
+ --column="Interface" \
+ $nics)
+}
+
+getNetmask() {
+
+ cidr=
+ nm=$(zenity --entry \
+ --title="$title" \
+ --text="$ipaddr: Enter netmask: " \
+ --entry-text 255.255.255.0)
+ if [ $? != 0 ]; then
+ return;
+ fi
+
+ cidr=`perl -e 'use Socket; print unpack("%32b*",inet_aton($ARGV[0])), "\n";' $nm`
+}
+
+addNet() {
+ getNIC
+ if [[ -z $nic ]]; then
+ return;
+ fi
+ getIPaddr
+ if [[ -z $ipaddr ]]; then
+ return;
+ fi
+ getNetmask
+ if [[ -z $cidr ]]; then
+ return;
+ fi
+ zcfg="
+add net
+set address=${ipaddr}/${cidr}
+set physical=$nic
+end
+commit
+"
+ echo "$zcfg" > $config ;
+ zonecfg -z $zonename -f $config ;
+ rm $config
+}
+
+getAttrs() {
+ zone=global
+ type=ignore
+ for j in `ifconfig $nic`
+ do
+ case $j in
+ inet) type=$j;;
+ zone) type=$j;;
+ all-zones) zone=all-zones;;
+ flags*) flags=$j;;
+ *) case $type in
+ inet) ipaddr=$j ;;
+ zone) zone=$j ;;
+ *) continue ;;
+ esac;\
+ type=ignore;;
+ esac
+ done
+ if [ $ipaddr != 0.0.0.0 ]; then
+ template=`tninfo -h $ipaddr|grep Template| cut -d" " -f3`
+ else
+ template="..."
+ ipaddr="..."
+ fi
+}
+
+updateTnrhdb() {
+ tnctl -h ${ipaddr}:$template
+ x=`grep "^${ipaddr}[^0-9]" /etc/security/tsol/tnrhdb`
+ if [ $? = 0 ]; then
+ sed s/$x/${ipaddr}:$template/g /etc/security/tsol/tnrhdb \
+ > /tmp/txnetmgr.$$
+ mv /tmp/txnetmgr.$$ /etc/security/tsol/tnrhdb
+ else
+ echo ${ipaddr}:$template >> /etc/security/tsol/tnrhdb
+ fi
+}
+
+getIPaddr() {
+ hostname=$(zenity --entry \
+ --title="$title" \
+ --text="$nic: Enter hostname: ")
+
+ if [ $? != 0 ]; then
+ return;
+ fi
+
+ ipaddr=`getent hosts $hostname|cut -f1`
+ if [[ -z $ipaddr ]]; then
+
+ ipaddr=$(zenity --entry \
+ --title="$title" \
+ --text="$nic: Enter IP address: " \
+ --entry-text a.b.c.d)
+ if [ $? != 0 ]; then
+ return;
+ fi
+ fi
+
+}
+
+addHost() {
+ # Update hosts and ipnodes
+ if [[ -z $ipaddr ]]; then
+ return;
+ fi
+ grep "^${ipaddr}[^0-9]" /etc/inet/hosts >/dev/null
+ if [ $? -eq 1 ]; then
+ echo "$ipaddr\t$hostname" >> /etc/inet/hosts
+ fi
+
+ grep "^${ipaddr}[^0-9]" /etc/inet/ipnodes >/dev/null
+ if [ $? -eq 1 ]; then
+ echo "$ipaddr\t$hostname" >> /etc/inet/ipnodes
+ fi
+
+ template=cipso
+ updateTnrhdb
+
+ ifconfig $nic $ipaddr netmask + broadcast +
+ echo $hostname > /etc/hostname.$nic
+}
+
+getTemplate() {
+ templates=$(cat /etc/security/tsol/tnrhtp|\
+ grep "^[A-z]"|grep "type=cipso"|cut -f1 -d":")
+
+ while [ 1 -gt 0 ]; do
+ t_cmd=$(zenity --list \
+ --title="$title" \
+ --height=300 \
+ --column="Network Templates" \
+ $templates)
+
+ if [ $? != 0 ]; then
+ break;
+ fi
+
+ t_label=$(tninfo -t $t_cmd | grep sl|zenity --list \
+ --title="$title" \
+ --height=300 \
+ --width=450 \
+ --column="Click OK to associate $t_cmd template with $ipaddr" )
+
+ if [ $? != 0 ]; then
+ continue
+ fi
+ template=$t_cmd
+ updateTnrhdb
+ break
+ done
+}
+
+createInterface() {
+ msg=`ifconfig $nic addif 0.0.0.0`
+ $(zenity --info \
+ --title="$title" \
+ --text="$msg" )
+}
+
+shareInterface() {
+ ifconfig $nic all-zones;\
+ if_file=/etc/hostname.$nic
+ sed q | sed -e "s/$/ all-zones/" < $if_file >/tmp/txnetmgr.$$
+ mv /tmp/txnetmgr.$$ $if_file
+}
+
+setMacPrivs() {
+ zcfg="
+set limitpriv=default,win_mac_read,win_mac_write,win_selection,win_dac_read,win_dac_write,file_downgrade_sl,file_upgrade_sl,sys_trans_label
+commit
+"
+ echo "$zcfg" > $config ;
+ zonecfg -z $zonename -f $config ;
+ rm $config
+}
+
+resetMacPrivs() {
+ zcfg="
+set limitpriv=default
+commit
+"
+ echo "$zcfg" > $config ;
+ zonecfg -z $zonename -f $config ;
+ rm $config
+}
+
+sharePasswd() {
+ passwd=`zonecfg -z $zonename info|grep /etc/passwd`
+ if [[ $? -eq 1 ]]; then
+ zcfg="
+add fs
+set special=/etc/passwd
+set dir=/etc/passwd
+set type=lofs
+end
+add fs
+set special=/etc/shadow
+set dir=/etc/shadow
+set type=lofs
+end
+commit
+"
+ echo "$zcfg" > $config ;
+ zonecfg -z $zonename -f $config ;
+ rm $config
+ fi
+}
+
+manageNets() {
+ while [ 1 -gt 0 ]; do
+ attrs=
+ for i in `ifconfig -au4|grep "^[a-z].*:" |grep -v LOOPBACK`
+ do
+ echo $i |grep "^[a-z].*:" >/dev/null 2>&1
+ if [ $? -eq 1 ]; then
+ continue
+ fi
+ nic=${i%:} # Remove colon after interface name
+ getAttrs
+ attrs="$nic $zone $ipaddr $template Up $attrs"
+ done
+
+ for i in `ifconfig -ad4 |grep "^[a-z].*:" |grep -v LOOPBACK`
+ do
+ echo $i |grep "^[a-z].*:" >/dev/null 2>&1
+ if [ $? -eq 1 ]; then
+ continue
+ fi
+ nic=${i%:} # Remove colon after interface name
+ getAttrs
+ attrs="$nic $zone $ipaddr $template Down $attrs"
+ done
+
+ nic=$(zenity --list \
+ --title="$title" \
+ --height=300 \
+ --width=450 \
+ --column="Interface" \
+ --column="Zone Name" \
+ --column="IP Address" \
+ --column="Template" \
+ --column="State" \
+ $attrs)
+
+ if [[ -z $nic ]]; then
+ return
+ fi
+
+ getAttrs
+
+ # Clear list of commands
+
+ share=
+ setipaddr=
+ settemplate=
+ newlogical=
+ unplumb=
+ bringup=
+ bringdown=
+
+ # Check for physical interface
+
+ hascolon=`echo $nic |grep :`
+ if [ $? != 0 ]; then
+ newlogical="Create Logical Interface\n";
+ else
+ up=`echo $flags|grep "UP,"`
+ if [ $? != 0 ]; then
+ unplumb="Remove Logical Interface\n"
+ if [ $ipaddr != "..." ]; then
+ bringup="Bring Up\n"
+ fi
+ else
+ bringdown="Bring Down\n"
+ fi
+ fi
+
+ if [ $ipaddr = "..." ]; then
+ setipaddr="Set IP address...\n";
+ else
+ settemplate="View Templates...\n"
+ if [ $zone = global ]; then
+ share="Share\n"
+ fi
+ fi
+
+ command=$(echo ""\
+ $share \
+ $setipaddr \
+ $settemplate \
+ $newlogical \
+ $unplumb \
+ $bringup \
+ $bringdown \
+ | zenity --list \
+ --title="$title" \
+ --height=300 \
+ --column "Interface: $nic" )
+
+ case $command in
+ " Create Logical Interface")\
+ createInterface;;
+ " Set IP address...")\
+ getIPaddr
+ addHost;;
+ " Share")\
+ shareInterface;;
+ " View Templates...")\
+ getTemplate;;
+ " Remove Logical Interface")\
+ ifconfig $nic unplumb;\
+ rm -f /etc/hostname.$nic;;
+ " Bring Up")\
+ ifconfig $nic up;;
+ " Bring Down")\
+ ifconfig $nic down;;
+ *) continue;;
+ esac
+ done
+}
+
+# Main loop for top-level window
+#
+# Always display vni0 since it is useful for cross-zone networking
+#
+ifconfig vni0 > /dev/null 2>&1
+if [ $? != 0 ]; then
+ ifconfig vni0 plumb >/dev/null 2>&1
+fi
+while [ "${command}" != Exit ]; do
+ if [[ ! -n $zonename ]]; then
+ zonelist=""
+ for p in `zoneadm list -cp|grep -v global:`; do
+ zonename=`echo $p|cut -d : -f2`
+ state=`echo $p|cut -d : -f3`
+ labelCheck
+ zonelist="$zonelist$zonename\n$state\n$curlabel\n"
+ done
+
+ zonelist="${zonelist}Create a new zone...\n\n\nManage Network Interfaces...\n\n"
+ zonename=$(echo $zonelist|zenity --list \
+ --title="$title" \
+ --height=300 \
+ --width=500 \
+ --column="Zone Name" \
+ --column="Status" \
+ --column="Sensitivity Label" \
+ )
+
+ if [[ ! -n $zonename ]]; then
+ exit
+ fi
+
+ if [ "$zonename" = "Manage Network Interfaces..." ]; then
+ zonename=
+ manageNets
+ continue
+ elif [ "$zonename" = "Create a new zone..." ]; then
+ zonename=$(zenity --entry \
+ --title="$title" \
+ --entry-text="" \
+ --text="Enter Zone Name: ")
+
+ if [[ ! -n $zonename ]]; then
+ continue
+ fi
+
+ zcfg="
+create -t SUNWtsoldef
+set zonepath=/zone/$zonename
+commit
+"
+ echo "$zcfg" > $config ;
+ zonecfg -z $zonename -f $config ;
+ rm $config
+ fi
+ fi
+
+ # Clear list of commands
+
+ console=
+ label=
+ start=
+ reboot=
+ stop=
+ clone=
+ copy=
+ install=
+ ready=
+ uninstall=
+ delete=
+ snapshot=
+ addnet=
+ deletenet=
+ permitrelabel=
+
+ zonestate=`zoneadm -z $zonename list -p | cut -d ":" -f 3`
+
+ consoleCheck;
+ labelCheck;
+ delay=0
+
+ case $zonestate in
+ running) ready="Ready\n"; \
+ reboot="Reboot\n"; \
+ stop="Halt\n"; \
+ ;;
+ ready) start="Boot\n"; \
+ stop="Halt\n" \
+ ;;
+ installed)
+ if [[ -z $label ]]; then \
+ ready="Ready\n"; \
+ start="Boot\n"; \
+ fi; \
+ uninstall="Uninstall\n"; \
+ snapshotCheck; \
+ relabelCheck;
+ addnet="Add Network...\n"
+ ;;
+ configured) install="Install...\n"; \
+ copyCheck; \
+ delete="Delete\n"; \
+ console=; \
+ ;;
+ incomplete) delete="Delete\n"; \
+ ;;
+ *)
+ ;;
+ esac
+
+ command=$(echo ""\
+ $console \
+ $label \
+ $start \
+ $reboot \
+ $stop \
+ $clone \
+ $copy \
+ $install \
+ $ready \
+ $uninstall \
+ $delete \
+ $snapshot \
+ $addnet \
+ $deletenet \
+ $permitrelabel \
+ "Select another zone...\n" \
+ "Exit" \
+ | zenity --list \
+ --title="$title" \
+ --height=300 \
+ --column "$zonename: $zonestate" )
+
+ case $command in
+ " Zone Console...")
+ delay=2; \
+ /usr/bin/gnome-terminal \
+ --title="Zone Terminal Console: $zonename" \
+ --command "/usr/sbin/zlogin -C $zonename" &;;
+
+ " Select Label...")
+ selectLabel;;
+
+ " Ready")
+ zoneadm -z $zonename ready ;;
+
+ " Boot")
+ zoneadm -z $zonename boot ;;
+
+ " Halt")
+ zoneadm -z $zonename halt ;;
+
+ " Reboot")
+ zoneadm -z $zonename reboot ;;
+
+ " Install...")
+ install;;
+
+ " Clone")
+ clone ;;
+
+ " Copy...")
+ copy ;;
+
+ " Uninstall")
+ zoneadm -z $zonename uninstall -F;;
+
+ " Delete")
+ delete ;;
+
+ " Create Snapshot")
+ zfs snapshot zone/${zonename}@snapshot;;
+
+ " Add Network...")
+ addNet ;;
+
+ " Permit Relabeling")
+ setMacPrivs ;;
+
+ " Deny Relabeling")
+ resetMacPrivs ;;
+
+ " Select another zone...")
+ zonename= ;;
+
+ *)
+ exit ;;
+ esac
+ sleep $delay;
+done
diff --git a/usr/src/cmd/tsol/plabel/Makefile b/usr/src/cmd/tsol/plabel/Makefile
new file mode 100644
index 0000000000..e088a1c369
--- /dev/null
+++ b/usr/src/cmd/tsol/plabel/Makefile
@@ -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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# cmd/tsol/plabel
+#
+PROG= plabel
+OBJS= plabel.o
+SRCS= $(OBJS:%.o=%.c)
+
+include ../../Makefile.cmd
+
+LDLIBS += -ltsol
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all $(ROOTPROG)
+
+clean:
+ $(RM) $(OBJS)
+
+lint: lint_PROG
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/tsol/plabel/plabel.c b/usr/src/cmd/tsol/plabel/plabel.c
new file mode 100644
index 0000000000..60df5a073f
--- /dev/null
+++ b/usr/src/cmd/tsol/plabel/plabel.c
@@ -0,0 +1,236 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * plabel - gets process label.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <locale.h>
+#include <procfs.h>
+#include <sys/proc.h>
+#include <zone.h>
+
+#include <sys/tsol/label_macro.h>
+
+#include <tsol/label.h>
+
+#define s_flag 0x04
+#define S_flag 0x08
+
+#define INIT_ALLOC_LEN 1024
+#define MAX_ALLOC_NUM 11
+
+static int look(char *);
+static int perr(char *);
+static void usage(void);
+
+static char procname[64];
+
+static unsigned int opt_flag = 0;
+static char *cmd = NULL;
+
+int
+main(int argc, char **argv)
+{
+ int err, rc = 0;
+ int opt;
+
+ (void) setlocale(LC_ALL, "");
+#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
+#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
+#endif
+ (void) textdomain(TEXT_DOMAIN);
+
+ if ((cmd = strrchr(argv[0], '/')) == NULL)
+ cmd = argv[0];
+ else
+ cmd++;
+
+ /* Error if labeling is not active. */
+ if (!is_system_labeled()) {
+ (void) fprintf(stderr,
+ gettext("%s: Trusted Extensions must be enabled\n"), cmd);
+ return (1);
+ }
+
+ while ((opt = getopt(argc, argv, "sS")) != EOF) {
+ switch (opt) {
+ case 's':
+ if (opt_flag & (s_flag | S_flag)) {
+ usage();
+ return (1);
+ }
+ opt_flag |= s_flag;
+ break;
+
+ case 'S':
+ if (opt_flag & (s_flag | S_flag)) {
+ usage();
+ return (1);
+ }
+ opt_flag |= S_flag;
+ break;
+ default:
+ usage();
+ return (1);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+ if (argc == 0) {
+ char pid[11]; /* 32 bit pids go to 4294967295 plus a NUL */
+
+ (void) sprintf(pid, "%d", (int)getpid());
+ rc = look(pid);
+ } else {
+ while (argc-- > 0) {
+ err = look(*argv++);
+ if (rc == 0)
+ rc = err;
+ }
+ }
+ return (rc);
+}
+
+static int
+look(char *arg)
+{
+ int fd;
+ m_label_t *plabel;
+ psinfo_t info; /* process information from /proc */
+ char *str;
+ int wordlen = DEF_NAMES;
+
+ if (opt_flag == S_flag)
+ wordlen = LONG_NAMES;
+ else if (opt_flag == s_flag)
+ wordlen = SHORT_NAMES;
+
+ if (strchr(arg, '/') != NULL)
+ (void) strncpy(procname, arg, sizeof (procname));
+ else {
+ (void) strcpy(procname, "/proc/");
+ (void) strncat(procname, arg,
+ sizeof (procname) - strlen(procname));
+ }
+ (void) strlcat(procname, "/psinfo", sizeof (procname)
+ - strlen(procname));
+
+ /*
+ * Open the process to be examined.
+ */
+retry:
+ if ((fd = open(procname, O_RDONLY)) < 0) {
+ /*
+ * Make clean message for non-existent process.
+ */
+ if (errno == ENOENT) {
+ errno = ESRCH;
+ perror(arg);
+ return (1);
+ }
+ return (perr(NULL));
+ }
+
+
+ /*
+ * Get the info structure for the process and close quickly.
+ */
+ if (read(fd, &info, sizeof (info)) < 0) {
+ int saverr = errno;
+
+ (void) close(fd);
+ if (saverr == EAGAIN)
+ goto retry;
+ if (saverr != ENOENT)
+ perror(arg);
+ return (1);
+ }
+ (void) close(fd);
+
+ if (info.pr_lwp.pr_state == 0) /* can't happen? */
+ return (1);
+
+ if ((plabel = getzonelabelbyid(info.pr_zoneid)) == NULL) {
+ return (1);
+ }
+
+ /*
+ * The process label for global zone is admin_high
+ */
+ if (info.pr_zoneid == GLOBAL_ZONEID) {
+ _BSLHIGH(plabel);
+ }
+
+ if (label_to_str(plabel, &str, M_LABEL, wordlen) != 0) {
+ perror(arg);
+ return (2);
+ }
+ (void) printf("%s\n", str);
+ m_label_free(plabel);
+ free(str);
+ return (0);
+}
+
+
+/*
+ * usage()
+ *
+ * This routine is called whenever there is a usage type of error has
+ * occured. For example, when a invalid option has has been specified.
+ *
+ */
+static void
+usage(void)
+{
+
+ (void) fprintf(stderr, "Usage: \n");
+ (void) fprintf(stderr,
+ gettext(" %s [pid ...] \n"), cmd);
+ (void) fprintf(stderr,
+ gettext(" %s -s [pid ...] \n"), cmd);
+ (void) fprintf(stderr,
+ gettext(" %s -S [pid ...] \n"), cmd);
+}
+
+static int
+perr(char *s) {
+
+ if (s)
+ (void) fprintf(stderr, "%s: ", procname);
+ else
+ s = procname;
+ perror(s);
+ return (1);
+}
diff --git a/usr/src/cmd/tsol/setlabel/Makefile b/usr/src/cmd/tsol/setlabel/Makefile
new file mode 100644
index 0000000000..64431414ba
--- /dev/null
+++ b/usr/src/cmd/tsol/setlabel/Makefile
@@ -0,0 +1,50 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# cmd/tsol/setlabel
+#
+#
+PROG= setlabel
+
+include ../../Makefile.cmd
+
+LDLIBS += -ltsol
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all $(ROOTPROG)
+
+clean:
+
+lint: lint_PROG
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/tsol/setlabel/setlabel.c b/usr/src/cmd/tsol/setlabel/setlabel.c
new file mode 100644
index 0000000000..71b2c5dcae
--- /dev/null
+++ b/usr/src/cmd/tsol/setlabel/setlabel.c
@@ -0,0 +1,175 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * setlabel - sets a file label.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <utmp.h>
+
+#include <tsol/label.h>
+
+static int set_label(char *, char *);
+static int setlabel(char *, bslabel_t *);
+static void usage(void);
+static void m_label_err(const char *, const int);
+
+static char *prog = NULL;
+
+int
+main(int argc, char **argv)
+{
+ int rc = 0;
+ char *label;
+
+ (void) setlocale(LC_ALL, "");
+#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
+#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
+#endif
+ (void) textdomain(TEXT_DOMAIN);
+
+ if ((prog = strrchr(argv[0], '/')) == NULL)
+ prog = argv[0];
+ else
+ prog++;
+
+ if (argc < 3) {
+ usage();
+ return (2);
+ }
+
+ argv++;
+ argc--;
+
+ label = *argv;
+ argv++;
+ argc--;
+ while (argc-- > 0) {
+ if (set_label(*argv++, label) != 0)
+ rc = 1;
+ }
+
+ return (rc);
+}
+
+static int
+set_label(char *filename, char *label)
+{
+ int rval = 0;
+ int err;
+ m_label_t *blabel;
+
+ if ((blabel = m_label_alloc(MAC_LABEL)) == NULL) {
+ (void) fprintf(stderr, "setlabel: ");
+ perror(filename);
+ return (2);
+ }
+ rval = getlabel(filename, blabel);
+ if (rval) {
+ (void) fprintf(stderr, "setlabel: ");
+ perror(filename);
+ return (rval);
+ }
+ if (!bslvalid(blabel)) {
+ (void) fprintf(stderr,
+ gettext("%s: Current label is invalid\n"),
+ filename);
+ blabel = NULL;
+ }
+ if (str_to_label(label, &blabel, MAC_LABEL, L_DEFAULT, &err) == -1) {
+ m_label_err(label, err);
+ }
+
+ rval = setlabel(filename, blabel);
+ if (rval == 0)
+ m_label_free(blabel);
+ return (rval);
+}
+
+static int
+setlabel(char *filename, bslabel_t *label)
+{
+ int rval;
+
+ rval = setflabel(filename, label);
+
+ if (rval) {
+ (void) fprintf(stderr, "setlabel: ");
+ perror(filename);
+ }
+ return (rval);
+}
+
+static void
+m_label_err(const char *ascii, const int err)
+{
+ if (errno == EINVAL) {
+ switch (err) {
+ case M_BAD_STRING:
+ (void) fprintf(stderr,
+ gettext("setlabel: bad string %s\n"), ascii);
+ break;
+ case M_BAD_LABEL:
+ (void) fprintf(stderr,
+ gettext("setlabel: bad previous label\n"));
+ break;
+ default:
+ (void) fprintf(stderr,
+ gettext("setlabel: parsing error found in "
+ "\"%s\" at position %d\n"), ascii, err);
+ break;
+ }
+ } else {
+ perror("setlabel");
+ }
+ exit(1);
+}
+/*
+ * usage()
+ *
+ * This routine is called whenever there is a usage type of error has
+ * occured. For example, when a invalid option has has been specified.
+ *
+ */
+static void
+usage(void)
+{
+
+ (void) fprintf(stderr, gettext("Usage: \n"));
+ (void) fprintf(stderr, gettext(
+ " %s newlabel filename [...] \n"), prog);
+
+}
diff --git a/usr/src/cmd/tsol/tnchkdb/Makefile b/usr/src/cmd/tsol/tnchkdb/Makefile
new file mode 100644
index 0000000000..4fb1222567
--- /dev/null
+++ b/usr/src/cmd/tsol/tnchkdb/Makefile
@@ -0,0 +1,47 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/tsol/tnchkdb/Makefile
+#
+PROG= tnchkdb
+
+POFILES= $(PROG).po
+
+include ../../Makefile.cmd
+
+LDLIBS += -ltsnet -ltsol
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all $(ROOTUSRSBINPROG)
+
+clean:
+
+lint: lint_PROG
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/tsol/tnchkdb/tnchkdb.c b/usr/src/cmd/tsol/tnchkdb/tnchkdb.c
new file mode 100644
index 0000000000..29de0789a7
--- /dev/null
+++ b/usr/src/cmd/tsol/tnchkdb/tnchkdb.c
@@ -0,0 +1,642 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * tnchkdb.c - Trusted network database checking utility
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <locale.h>
+#include <malloc.h>
+#include <string.h>
+#include <libtsnet.h>
+#include <netinet/in.h>
+#include <nss_dbdefs.h>
+
+static void usage(void);
+static void check_tnrhtp(const char *);
+static void check_tnrhdb(const char *);
+static void check_tnzonecfg(const char *);
+
+static boolean_t tnrhtp_bad;
+static int exitval;
+
+struct tsol_name_list {
+ struct tsol_name_list *next;
+ int linenum;
+ char name[TNTNAMSIZ];
+};
+
+struct tsol_addr_list {
+ struct tsol_addr_list *next;
+ int linenum;
+ int prefix_len;
+ in6_addr_t addr;
+};
+
+static struct tsol_name_list *tp_list_head;
+static struct tsol_addr_list *rh_list_head;
+static struct tsol_name_list *zc_list_head;
+
+typedef struct mlp_info_list_s {
+ struct mlp_info_list_s *next;
+ int linenum;
+ tsol_mlp_t mlp;
+ char name[TNTNAMSIZ];
+} mlp_info_list_t;
+
+static mlp_info_list_t *global_mlps;
+
+static void
+add_name(struct tsol_name_list **head, const char *name, int linenum)
+{
+ int err;
+ struct tsol_name_list *entry;
+
+ entry = malloc(sizeof (struct tsol_name_list));
+ if (entry == NULL) {
+ err = errno;
+
+ (void) fprintf(stderr,
+ gettext("tnchkdb: allocating name list: %s\n"),
+ strerror(err));
+ exit(1);
+ }
+ (void) strlcpy(entry->name, name, sizeof (entry->name));
+ entry->next = *head;
+ entry->linenum = linenum;
+ *head = entry;
+}
+
+static struct tsol_name_list *
+find_name(struct tsol_name_list *head, const char *name)
+{
+ struct tsol_name_list *entry;
+
+ for (entry = head; entry != NULL; entry = entry->next)
+ if (strcmp(entry->name, name) == 0)
+ break;
+ return (entry);
+}
+
+static void
+add_addr(struct tsol_addr_list **head, int prefix_len, in6_addr_t addr,
+ int linenum)
+{
+ int err;
+ struct tsol_addr_list *entry;
+
+ entry = malloc(sizeof (struct tsol_addr_list));
+ if (entry == NULL) {
+ err = errno;
+
+ (void) fprintf(stderr,
+ gettext("tnchkdb: allocating addr list: %s\n"),
+ strerror(err));
+ exit(2);
+ }
+ entry->prefix_len = prefix_len;
+ entry->addr = addr;
+ entry->next = *head;
+ entry->linenum = linenum;
+ *head = entry;
+}
+
+static struct tsol_addr_list *
+find_addr(struct tsol_addr_list *head, int prefix_len, in6_addr_t addr)
+{
+ struct tsol_addr_list *entry;
+
+ for (entry = head; entry != NULL; entry = entry->next)
+ if (entry->prefix_len == prefix_len &&
+ IN6_ARE_ADDR_EQUAL(&entry->addr, &addr))
+ break;
+ return (entry);
+}
+
+static void
+add_template(const char *name, int linenum)
+{
+ add_name(&tp_list_head, name, linenum);
+}
+
+static struct tsol_name_list *
+find_template(const char *name)
+{
+ return (find_name(tp_list_head, name));
+}
+
+static void
+add_host(int prefix_len, in6_addr_t addr, int linenum)
+{
+ add_addr(&rh_list_head, prefix_len, addr, linenum);
+}
+
+static struct tsol_addr_list *
+find_host(int prefix_len, in6_addr_t addr)
+{
+ return (find_addr(rh_list_head, prefix_len, addr));
+}
+
+static void
+add_zone(const char *name, int linenum)
+{
+ add_name(&zc_list_head, name, linenum);
+}
+
+static struct tsol_name_list *
+find_zone(const char *name)
+{
+ return (find_name(zc_list_head, name));
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *tnrhdb_file = TNRHDB_PATH;
+ const char *tnrhtp_file = TNRHTP_PATH;
+ const char *tnzonecfg_file = TNZONECFG_PATH;
+ int chr;
+
+ /* set the locale for only the messages system (all else is clean) */
+ (void) setlocale(LC_ALL, "");
+#ifndef TEXT_DOMAIN /* Should be defined by cc -D */
+#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
+#endif
+ (void) textdomain(TEXT_DOMAIN);
+
+ while ((chr = getopt(argc, argv, "h:t:z:")) != EOF) {
+ switch (chr) {
+ case 'h':
+ tnrhdb_file = optarg;
+ break;
+ case 't':
+ tnrhtp_file = optarg;
+ break;
+ case 'z':
+ tnzonecfg_file = optarg;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ check_tnrhtp(tnrhtp_file);
+ check_tnrhdb(tnrhdb_file);
+ check_tnzonecfg(tnzonecfg_file);
+
+ return (exitval);
+}
+
+static void
+usage(void)
+{
+ (void) fprintf(stderr, gettext(
+ "usage: tnchkdb [-h path] [-t path] [-z path]\n"));
+ exit(2);
+}
+
+static void
+print_error(int linenum, int err, const char *errstr)
+{
+ (void) fprintf(stderr, gettext("line %1$d: %2$s: %.32s\n"), linenum,
+ tsol_strerror(err, errno), errstr);
+}
+
+static void
+cipso_representable(const bslabel_t *lab, int linenum, const char *template,
+ const char *name)
+{
+ const _blevel_impl_t *blab = (const _blevel_impl_t *)lab;
+ int lclass;
+ uint32_t c8;
+
+ if (!bltype(lab, SUN_SL_ID)) {
+ (void) fprintf(stderr, gettext("tnchkdb: "
+ "%1$s type %2$d is invalid for cipso labels: "
+ "line %3$d entry %4$s\n"), name, GETBLTYPE(lab), linenum,
+ template);
+ exitval = 1;
+ }
+ lclass = LCLASS(blab);
+ if (lclass & 0xff00) {
+ (void) fprintf(stderr, gettext("tnchkdb: "
+ "%1$s classification %2$x is invalid for cipso labels: "
+ "line %3$d entry %4$s\n"), name, lclass, linenum,
+ template);
+ exitval = 1;
+ }
+ c8 = blab->compartments.c8;
+#ifdef _BIG_ENDIAN
+ if (c8 & 0x0000ffff) {
+#else
+ if (c8 & 0xffff0000) {
+#endif
+ (void) fprintf(stderr, gettext("tnchkdb: %1$s "
+ "compartments 241-256 must be zero for cipso labels: "
+ "line %2$d entry %3$s\n"), name, linenum, template);
+ exitval = 1;
+ }
+}
+
+static void
+check_tnrhtp(const char *file)
+{
+ tsol_tpent_t *tpentp;
+ tsol_tpstr_t tpstr;
+ int err;
+ char *errstr;
+ FILE *fp;
+ blevel_t *l1, *l2;
+ char line[2048], *cp;
+ int linenum = 0;
+ struct tsol_name_list *tnl;
+ char buf[NSS_BUFLEN_TSOL_TP];
+ uint32_t initial_doi = 0;
+ boolean_t multiple_doi_found = B_FALSE;
+ boolean_t doi_zero_found = B_FALSE;
+
+ (void) printf(gettext("checking %s ...\n"), file);
+
+ if ((fp = fopen(file, "r")) == NULL) {
+ err = errno;
+ (void) fprintf(stderr,
+ gettext("tnchkdb: cannot open %1$s: %2$s\n"), file,
+ strerror(err));
+ exitval = 2;
+ tnrhtp_bad = B_TRUE;
+ return;
+ }
+
+ while (fgets(line, sizeof (line), fp) != NULL) {
+ linenum++;
+ if (line[0] == '#')
+ continue;
+ if ((cp = strchr(line, '\n')) != NULL)
+ *cp = '\0';
+ (void) str_to_tpstr(line, strlen(line), &tpstr, buf,
+ sizeof (buf));
+ tpentp = tpstr_to_ent(&tpstr, &err, &errstr);
+ if (tpentp == NULL) {
+ if (err == LTSNET_EMPTY)
+ continue;
+ print_error(linenum, err, errstr);
+ exitval = 1;
+ /*
+ * Flag is set *only* for parsing errors, which result
+ * in omitting the entry from tsol_name_list.
+ */
+ tnrhtp_bad = B_TRUE;
+ continue;
+ }
+
+ switch (tpentp->host_type) {
+ case UNLABELED:
+ /*
+ * check doi
+ */
+ if (initial_doi == 0)
+ initial_doi = tpentp->tp_cipso_doi_unl;
+ if (tpentp->tp_cipso_doi_unl != initial_doi)
+ multiple_doi_found = B_TRUE;
+ if (tpentp->tp_cipso_doi_unl == 0)
+ doi_zero_found = B_TRUE;
+
+ cipso_representable(&tpentp->tp_def_label, linenum,
+ tpentp->name, TP_DEFLABEL);
+
+ /*
+ * check max_sl dominates min_sl
+ */
+ l1 = &tpentp->tp_gw_sl_range.lower_bound;
+ l2 = &tpentp->tp_gw_sl_range.upper_bound;
+ if (!bldominates(l2, l1)) {
+ (void) fprintf(stderr,
+ gettext("tnchkdb: max_sl does not "
+ "dominate min_sl: line %$1d entry %2$s\n"),
+ linenum, tpentp->name);
+ exitval = 1;
+ }
+
+ cipso_representable(l1, linenum, tpentp->name,
+ TP_MINLABEL);
+ l1 = (blevel_t *)&tpentp->tp_gw_sl_set[0];
+ l2 = (blevel_t *)&tpentp->tp_gw_sl_set[NSLS_MAX];
+ for (; l1 < l2; l1++) {
+ if (bisinvalid(l1))
+ break;
+ cipso_representable(l1, linenum, tpentp->name,
+ TP_SET);
+ }
+ break;
+
+ case SUN_CIPSO:
+ /*
+ * check max_sl dominates min_sl
+ */
+ l1 = &tpentp->tp_sl_range_cipso.lower_bound;
+ l2 = &tpentp->tp_sl_range_cipso.upper_bound;
+ if (!bldominates(l2, l1)) {
+ (void) fprintf(stderr,
+ gettext("tnchkdb: max_sl does not "
+ "dominate min_sl: line %$1d entry %2$s\n"),
+ linenum, tpentp->name);
+ exitval = 1;
+ }
+
+ cipso_representable(l1, linenum, tpentp->name,
+ TP_MINLABEL);
+
+ l1 = (blevel_t *)&tpentp->tp_sl_set_cipso[0];
+ l2 = (blevel_t *)&tpentp->tp_sl_set_cipso[NSLS_MAX];
+ for (; l1 < l2; l1++) {
+ if (bisinvalid(l1))
+ break;
+ cipso_representable(l1, linenum, tpentp->name,
+ TP_SET);
+ }
+
+ /*
+ * check doi
+ */
+ if (initial_doi == 0)
+ initial_doi = tpentp->tp_cipso_doi_cipso;
+ if (tpentp->tp_cipso_doi_cipso != initial_doi)
+ multiple_doi_found = B_TRUE;
+ if (tpentp->tp_cipso_doi_cipso == 0)
+ doi_zero_found = B_TRUE;
+ break;
+
+ default:
+ (void) fprintf(stderr, gettext("tnchkdb: unknown host "
+ "type %$1d: line %2$d entry %3$s\n"),
+ tpentp->host_type, linenum, tpentp->name);
+ exitval = 1;
+ } /* switch */
+
+ /*
+ * check if a duplicated entry
+ */
+ if ((tnl = find_template(tpentp->name)) != NULL) {
+ (void) fprintf(stderr, gettext("tnchkdb: duplicated "
+ "entry: %1$s at lines %2$d and %3$d\n"),
+ tpentp->name, tnl->linenum, linenum);
+ exitval = 1;
+ } else {
+ add_template(tpentp->name, linenum);
+ }
+ tsol_freetpent(tpentp);
+ }
+ if (multiple_doi_found == B_TRUE) {
+ (void) fprintf(stderr,
+ gettext("tnchkdb: Warning: tnrhtp entries do not all "
+ "contain the same DOI value\n"));
+ }
+ if (doi_zero_found == B_TRUE) {
+ (void) fprintf(stderr,
+ gettext("tnchkdb: Warning: DOI=0 found in some "
+ "tnrhtp entries\n"));
+ }
+ (void) fclose(fp);
+}
+
+static void
+check_tnrhdb(const char *file)
+{
+ tsol_rhent_t *rhentp;
+ tsol_rhstr_t rhstr;
+ int err;
+ char *errstr;
+ FILE *fp;
+ char line[2048], *cp;
+ int linenum;
+ in6_addr_t addr;
+ struct tsol_addr_list *tal;
+ char buf[NSS_BUFLEN_TSOL_RH];
+
+ (void) printf(gettext("checking %s ...\n"), file);
+
+ if ((fp = fopen(file, "r")) == NULL) {
+ err = errno;
+ (void) fprintf(stderr,
+ gettext("tnchkdb: failed to open %s: %s\n"), file,
+ strerror(err));
+ exitval = 2;
+ return;
+ }
+
+ /*
+ * check that all templates used in tnrhdb file are defined by tnrhtp
+ */
+ linenum = 0;
+ while (fgets(line, sizeof (line), fp) != NULL) {
+ linenum++;
+ if (line[0] == '#')
+ continue;
+ if ((cp = strchr(line, '\n')) != NULL)
+ *cp = '\0';
+ (void) str_to_rhstr(line, strlen(line), &rhstr, buf,
+ sizeof (buf));
+ rhentp = rhstr_to_ent(&rhstr, &err, &errstr);
+ if (rhentp == NULL) {
+ if (err == LTSNET_EMPTY)
+ continue;
+ print_error(linenum, err, errstr);
+ exitval = 1;
+ continue;
+ }
+
+ if (rhentp->rh_address.ta_family == AF_INET) {
+ IN6_INADDR_TO_V4MAPPED(&rhentp->rh_address.ta_addr_v4,
+ &addr);
+ } else {
+ addr = rhentp->rh_address.ta_addr_v6;
+ }
+ if ((tal = find_host(rhentp->rh_prefix, addr)) != NULL) {
+ (void) fprintf(stderr,
+ gettext("tnchkdb: duplicate entry: lines %1$d and "
+ "%2$d\n"), tal->linenum, linenum);
+ exitval = 1;
+ } else {
+ add_host(rhentp->rh_prefix, addr, linenum);
+ }
+
+ if (!tnrhtp_bad && find_template(rhentp->rh_template) == NULL) {
+ (void) fprintf(stderr,
+ gettext("tnchkdb: unknown template name: %1$s at "
+ "line %2$d\n"), rhentp->rh_template, linenum);
+ exitval = 1;
+ }
+
+ tsol_freerhent(rhentp);
+ }
+ (void) fclose(fp);
+}
+
+static void
+check_mlp_conflicts(tsol_mlp_t *mlps, boolean_t isglobal, const char *name,
+ int linenum)
+{
+ tsol_mlp_t *mlpptr, *mlp2;
+ mlp_info_list_t *mil;
+
+ for (mlpptr = mlps; !TSOL_MLP_END(mlpptr); mlpptr++) {
+ if (mlpptr->mlp_port_upper == 0)
+ mlpptr->mlp_port_upper = mlpptr->mlp_port;
+
+ /* First, validate against self for duplicates */
+ for (mlp2 = mlps; mlp2 < mlpptr; mlp2++) {
+ if (mlp2->mlp_ipp == mlpptr->mlp_ipp &&
+ !(mlp2->mlp_port_upper < mlpptr->mlp_port ||
+ mlp2->mlp_port > mlpptr->mlp_port_upper))
+ break;
+ }
+
+ if (mlp2 < mlpptr) {
+ (void) fprintf(stderr, gettext("tnchkdb: self-overlap "
+ "of %1$s MLP protocol %2$d port %3$d-%4$d with "
+ "%5$d-%6$d: zone %7$s line %8$d\n"),
+ gettext(isglobal ? "global" : "zone-specific"),
+ mlpptr->mlp_ipp, mlpptr->mlp_port,
+ mlpptr->mlp_port_upper, mlp2->mlp_port,
+ mlp2->mlp_port_upper, name, linenum);
+ exitval = 1;
+ }
+
+ if (isglobal) {
+ /* Next, validate against list for duplicates */
+ for (mil = global_mlps; mil != NULL; mil = mil->next) {
+ if (strcmp(mil->name, name) == 0)
+ continue;
+ if (mil->mlp.mlp_ipp == mlpptr->mlp_ipp &&
+ !(mil->mlp.mlp_port_upper <
+ mlpptr->mlp_port ||
+ mil->mlp.mlp_port >
+ mlpptr->mlp_port_upper))
+ break;
+ }
+
+ if (mil != NULL) {
+ (void) fprintf(stderr, gettext("tnchkdb: "
+ "overlap of global MLP protocol %2$d port "
+ "%3$d-%4$d with zone %$5s %6$d-%7$d: zone "
+ "%8$s lines %9$d and %10$d\n"),
+ mlpptr->mlp_ipp, mlpptr->mlp_port,
+ mlpptr->mlp_port_upper, mil->name,
+ mil->mlp.mlp_port, mil->mlp.mlp_port_upper,
+ name, mil->linenum, linenum);
+ exitval = 1;
+ }
+
+ /* Now throw into list */
+ if ((mil = malloc(sizeof (*mil))) == NULL) {
+ (void) fprintf(stderr, gettext("tnchkdb: "
+ "malloc error: %s\n"), strerror(errno));
+ exit(2);
+ }
+ (void) strlcpy(mil->name, name, sizeof (mil->name));
+ mil->linenum = linenum;
+ mil->mlp = *mlpptr;
+ mil->next = global_mlps;
+ global_mlps = mil;
+ }
+ }
+}
+
+static void
+check_tnzonecfg(const char *file)
+{
+ tsol_zcent_t *zc;
+ int err;
+ char *errstr;
+ FILE *fp;
+ char line[2048], *cp;
+ int linenum;
+ boolean_t saw_global;
+ struct tsol_name_list *tnl;
+
+ (void) printf(gettext("checking %s ...\n"), file);
+
+ if ((fp = fopen(file, "r")) == NULL) {
+ err = errno;
+ (void) fprintf(stderr,
+ gettext("tnchkdb: failed to open %s: %s\n"), file,
+ strerror(err));
+ exitval = 2;
+ return;
+ }
+
+ saw_global = B_FALSE;
+ linenum = 0;
+ while (fgets(line, sizeof (line), fp) != NULL) {
+ if ((cp = strchr(line, '\n')) != NULL)
+ *cp = '\0';
+
+ linenum++;
+ if ((zc = tsol_sgetzcent(line, &err, &errstr)) == NULL) {
+ if (err == LTSNET_EMPTY)
+ continue;
+ print_error(linenum, err, errstr);
+ exitval = 1;
+ continue;
+ }
+
+ cipso_representable(&zc->zc_label, linenum, zc->zc_name,
+ "label");
+
+ if (strcmp(zc->zc_name, "global") == 0)
+ saw_global = B_TRUE;
+
+ if ((tnl = find_zone(zc->zc_name)) != NULL) {
+ (void) fprintf(stderr,
+ gettext("tnchkdb: duplicate zones: %1$s at lines "
+ "%2$d and %3$d\n"), zc->zc_name, tnl->linenum,
+ linenum);
+ exitval = 1;
+ } else {
+ add_zone(zc->zc_name, linenum);
+ }
+
+ if (zc->zc_private_mlp != NULL)
+ check_mlp_conflicts(zc->zc_private_mlp, B_FALSE,
+ zc->zc_name, linenum);
+ if (zc->zc_shared_mlp != NULL)
+ check_mlp_conflicts(zc->zc_shared_mlp, B_TRUE,
+ zc->zc_name, linenum);
+
+ tsol_freezcent(zc);
+ }
+ (void) fclose(fp);
+
+ if (!saw_global) {
+ (void) fprintf(stderr, gettext("tnchkdb: missing required "
+ "entry for global zone in %s\n"), file);
+ exitval = 1;
+ }
+}
diff --git a/usr/src/cmd/tsol/tnctl/Makefile b/usr/src/cmd/tsol/tnctl/Makefile
new file mode 100644
index 0000000000..3351c996f4
--- /dev/null
+++ b/usr/src/cmd/tsol/tnctl/Makefile
@@ -0,0 +1,58 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/tsol/tnctl/Makefile
+#
+PROG= tnctl
+ETCTSOLFILES=tnrhdb tnrhtp tnzonecfg
+
+POFILES = $(PROG).po
+
+include ../../Makefile.cmd
+
+MANIFEST= tnctl.xml
+ROOTMANIFESTDIR = $(ROOTSVCNETWORK)
+SVCMETHOD= svc-tnctl
+$(ROOTMANIFEST) := FILEMODE= 444
+
+LDLIBS += -lnsl -ltsnet
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all $(ROOTSBINPROG) $(ROOTMANIFEST) $(ROOTSVCMETHOD) \
+ $(ROOTUSRSBIN)/$(PROG) $(ROOTETCTSOLFILES)
+
+$(ROOTUSRSBIN)/$(PROG):
+ rm -f $(ROOTUSRSBIN)/$(PROG)
+ $(SYMLINK) ../../sbin/$(PROG) $(ROOTUSRSBIN)/$(PROG)
+
+clean:
+
+lint: lint_PROG
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/tsol/tnctl/svc-tnctl b/usr/src/cmd/tsol/tnctl/svc-tnctl
new file mode 100644
index 0000000000..462e049bc2
--- /dev/null
+++ b/usr/src/cmd/tsol/tnctl/svc-tnctl
@@ -0,0 +1,34 @@
+#!/sbin/sh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+. /lib/svc/share/smf_include.sh
+
+[ ! -x /sbin/tnctl ] && exit $SMF_EXIT_ERR_CONFIG
+
+/sbin/tnctl -fz /etc/security/tsol/tnzonecfg
+status=$?
+/sbin/tnctl -fT /etc/security/tsol/tnrhtp -H /etc/security/tsol/tnrhdb &&
+exit $status
diff --git a/usr/src/cmd/tsol/tnctl/tnctl.c b/usr/src/cmd/tsol/tnctl/tnctl.c
new file mode 100644
index 0000000000..04a44e33cf
--- /dev/null
+++ b/usr/src/cmd/tsol/tnctl/tnctl.c
@@ -0,0 +1,597 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * tnctl.c -
+ * Trusted Network control utility
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <locale.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <libtsnet.h>
+#include <zone.h>
+#include <nss_dbdefs.h>
+
+static void process_rh(const char *);
+static void process_rhl(const char *);
+static void process_mlp(const char *);
+static void process_tp(const char *);
+static void process_tpl(const char *);
+static void process_tnzone(const char *);
+static void usage(void);
+
+static boolean_t verbose_mode;
+static boolean_t delete_mode;
+static boolean_t flush_mode;
+
+int
+main(int argc, char **argv)
+{
+ extern char *optarg;
+ int chr;
+
+ /* Don't do anything if labeling is not active. */
+ if (!is_system_labeled())
+ return (0);
+
+ /* set the locale for only the messages system (all else is clean) */
+ (void) setlocale(LC_ALL, "");
+#ifndef TEXT_DOMAIN /* Should be defined by cc -D */
+#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
+#endif
+
+ (void) textdomain(TEXT_DOMAIN);
+
+ while ((chr = getopt(argc, argv, "dfh:H:m:t:T:vz:")) != EOF) {
+ switch (chr) {
+ case 'd':
+ delete_mode = B_TRUE;
+ break;
+ case 'f':
+ flush_mode = B_TRUE;
+ break;
+ case 'h':
+ process_rh(optarg);
+ break;
+ case 'H':
+ process_rhl(optarg);
+ break;
+ case 'm':
+ process_mlp(optarg);
+ break;
+ case 't':
+ process_tp(optarg);
+ break;
+ case 'T':
+ process_tpl(optarg);
+ break;
+ case 'v':
+ verbose_mode = B_TRUE;
+ break;
+ case 'z':
+ process_tnzone(optarg);
+ break;
+ case '?':
+ usage();
+ }
+ }
+ return (0);
+}
+
+static void
+print_error(int linenum, int err, const char *errstr)
+{
+ if (linenum > 0)
+ (void) fprintf(stderr, gettext("line %1$d: %2$s:\n"), linenum,
+ tsol_strerror(err, errno));
+ else
+ (void) fprintf(stderr, gettext("tnctl: parsing error: %s\n"),
+ tsol_strerror(err, errno));
+ (void) fprintf(stderr, "%.32s\n", errstr);
+}
+
+/*
+ * Load remote host entries from the designated file.
+ */
+static void
+process_rhl(const char *file)
+{
+ boolean_t success = B_FALSE;
+ tsol_rhent_t *rhentp = NULL;
+ FILE *fp;
+
+ if ((fp = fopen(file, "r")) == NULL) {
+ (void) fprintf(stderr,
+ gettext("tnctl: failed to open %1$s: %2$s\n"),
+ file, strerror(errno));
+ exit(1);
+ }
+
+ tsol_setrhent(1);
+ while (rhentp = tsol_fgetrhent(fp)) {
+ /* First time through the loop, flush it all */
+ if (!success && flush_mode)
+ (void) tnrh(TNDB_FLUSH, NULL);
+ success = B_TRUE;
+
+ if (verbose_mode)
+ (void) printf("loading rh entry...\n");
+
+ if (tnrh(TNDB_LOAD, rhentp) != 0) {
+ (void) fclose(fp);
+ if (errno == EFAULT)
+ perror("tnrh");
+ else
+ (void) fprintf(stderr,
+ gettext("tnctl: load of remote-host entry "
+ "%1$s into kernel cache failed: %2$s\n"),
+ rhentp->rh_template, strerror(errno));
+ tsol_endrhent();
+ exit(1);
+ }
+ tsol_freerhent(rhentp);
+ }
+ if (!success) {
+ (void) fprintf(stderr,
+ gettext("tnctl: No valid tnrhdb entries found in %s\n"),
+ file);
+ }
+ (void) fclose(fp);
+ tsol_endrhent();
+}
+
+/*
+ * The argument can be either a host name, an address
+ * in tnrhdb address format, or a complete tnrhdb entry.
+ */
+static void
+process_rh(const char *hostname)
+{
+ tsol_rhstr_t rhstr;
+ tsol_rhent_t rhent;
+ tsol_rhent_t *rhentp;
+ int err;
+ int alen;
+ char *errstr;
+ /* abuf holds: <numeric-ip-addr>'/'<prefix-length>'\0' */
+ char abuf[INET6_ADDRSTRLEN+5];
+ const char *cp;
+ char *cp1;
+ char *cp2;
+ void *aptr;
+ char buf[NSS_BUFLEN_TSOL_RH];
+ struct in6_addr ipv6addr;
+
+ /* was a template name provided on the command line? */
+ if ((cp = strrchr(hostname, ':')) != NULL && cp != hostname &&
+ cp[-1] != '\\') {
+ /* use common tnrhdb line conversion function */
+ (void) str_to_rhstr(hostname, strlen(hostname), &rhstr, buf,
+ sizeof (buf));
+ rhentp = rhstr_to_ent(&rhstr, &err, &errstr);
+ if (rhentp == NULL) {
+ print_error(0, err, errstr);
+ exit(1);
+ }
+ } else {
+ char *hostname_p;
+ char *prefix_p;
+ struct hostent *hp;
+
+ /* Check for a subnet prefix length */
+ if ((prefix_p = strchr(hostname, '/')) != NULL) {
+ cp1 = prefix_p + 1;
+ errno = 0;
+ rhent.rh_prefix = strtol(cp1, &cp2, 0);
+ if (*cp2 != '\0' || errno != 0 || rhent.rh_prefix < 0) {
+ (void) fprintf(stderr, gettext("tnct: invalid "
+ "prefix length: %s\n"), cp);
+ exit(2);
+ }
+ } else {
+ rhent.rh_prefix = -1;
+ }
+
+ /* Strip any backslashes from numeric address */
+ hostname_p = malloc(strlen(hostname)+1);
+ if (hostname_p == NULL) {
+ perror("tnctl");
+ exit(2);
+ }
+ cp1 = hostname_p;
+ while (*hostname != '\0' && *hostname != '/') {
+ *cp1 = *hostname++;
+ if (*cp1 != '\\')
+ cp1++;
+ }
+ *cp1 = '\0';
+
+ /* Convert address or hostname to binary af_inet6 format */
+ hp = getipnodebyname(hostname_p, AF_INET6,
+ AI_ALL | AI_ADDRCONFIG | AI_V4MAPPED, &err);
+ if (hp == NULL) {
+ (void) fprintf(stderr, gettext("tnctl: unknown host "
+ "or invalid literal address: %s\n"), hostname_p);
+ if (err == TRY_AGAIN)
+ (void) fprintf(stderr,
+ gettext("\t(try again later)\n"));
+ exit(2);
+ }
+ free(hostname_p);
+ (void) memcpy(&ipv6addr, hp->h_addr, hp->h_length);
+
+ /* if ipv4 address, convert to af_inet format */
+ if (IN6_IS_ADDR_V4MAPPED(&ipv6addr)) {
+ rhent.rh_address.ta_family = AF_INET;
+ IN6_V4MAPPED_TO_INADDR(&ipv6addr,
+ &rhent.rh_address.ta_addr_v4);
+ if (rhent.rh_prefix == -1)
+ rhent.rh_prefix = 32;
+ } else {
+ rhent.rh_address.ta_family = AF_INET6;
+ rhent.rh_address.ta_addr_v6 = ipv6addr;
+ if (rhent.rh_prefix == -1)
+ rhent.rh_prefix = 128;
+ }
+ rhent.rh_template[0] = '\0';
+ rhentp = &rhent;
+ }
+
+ /* produce ascii format of address and prefix length */
+ if (rhentp->rh_address.ta_family == AF_INET6) {
+ aptr = &(rhentp->rh_address.ta_addr_v6);
+ alen = sizeof (ipv6addr);
+ (void) inet_ntop(rhentp->rh_address.ta_family, aptr, abuf,
+ sizeof (abuf));
+ if (rhentp->rh_prefix != 128) {
+ cp1 = abuf + strlen(abuf);
+ (void) sprintf(cp1, "/%d", rhentp->rh_prefix);
+ }
+ } else {
+ aptr = &(rhentp->rh_address.ta_addr_v4);
+ alen = sizeof (rhent.rh_address.ta_addr_v4);
+ (void) inet_ntop(rhentp->rh_address.ta_family, aptr, abuf,
+ sizeof (abuf));
+ if (rhentp->rh_prefix != 32) {
+ cp1 = abuf + strlen(abuf);
+ (void) sprintf(cp1, "/%d", rhentp->rh_prefix);
+ }
+ }
+
+ /*
+ * look up the entry from ldap or tnrhdb if this is a load
+ * request and a template name was not provided.
+ */
+ if (!delete_mode &&
+ rhentp->rh_template[0] == '\0' &&
+ (rhentp = tsol_getrhbyaddr(abuf, alen,
+ rhent.rh_address.ta_family)) == NULL) {
+ (void) fprintf(stderr,
+ gettext("tnctl: database lookup failed for %s\n"),
+ abuf);
+ exit(1);
+ }
+
+ if (verbose_mode)
+ (void) printf("%s rh entry %s\n", delete_mode ? "deleting" :
+ "loading", abuf);
+
+ /* update the tnrhdb entry in the kernel */
+ if (tnrh(delete_mode ? TNDB_DELETE : TNDB_LOAD, rhentp) != 0) {
+ if (errno == EFAULT)
+ perror("tnrh");
+ else if (errno == ENOENT)
+ (void) fprintf(stderr,
+ gettext("tnctl: %1$s of remote-host kernel cache "
+ "entry %2$s failed: no such entry\n"),
+ delete_mode ? gettext("delete") : gettext("load"),
+ abuf);
+ else
+ (void) fprintf(stderr,
+ gettext("tnctl: %1$s of remote-host kernel cache "
+ "entry %2$s failed: %3$s\n"),
+ delete_mode ? gettext("delete") : gettext("load"),
+ abuf, strerror(errno));
+ exit(1);
+ }
+ if (rhentp != &rhent)
+ tsol_freerhent(rhentp);
+}
+
+static void
+handle_mlps(zoneid_t zoneid, tsol_mlp_t *mlp, int flags, int cmd)
+{
+ tsol_mlpent_t tsme;
+
+ tsme.tsme_zoneid = zoneid;
+ tsme.tsme_flags = flags;
+ while (!TSOL_MLP_END(mlp)) {
+ tsme.tsme_mlp = *mlp;
+ if (tnmlp(cmd, &tsme) != 0) {
+ /*
+ * Usage of ?: here is ugly, but helps with
+ * localization.
+ */
+ (void) fprintf(stderr,
+ flags & TSOL_MEF_SHARED ?
+ gettext("tnctl: cannot set "
+ "shared MLP on %1$d-%2$d/%3$d: %4$s\n") :
+ gettext("tnctl: cannot set "
+ "zone-specific MLP on %1$d-%2$d/%3$d: %4$s\n"),
+ mlp->mlp_port, mlp->mlp_port_upper, mlp->mlp_ipp,
+ strerror(errno));
+ exit(1);
+ }
+ mlp++;
+ }
+}
+
+/*
+ * This reads the configuration for the global zone out of tnzonecfg
+ * and sets it in the kernel. The non-global zones are configured
+ * by zoneadmd.
+ */
+static void
+process_tnzone(const char *file)
+{
+ tsol_zcent_t *zc;
+ tsol_mlpent_t tsme;
+ int err;
+ char *errstr;
+ FILE *fp;
+ char line[2048], *cp;
+ int linenum, errors;
+
+ if ((fp = fopen(file, "r")) == NULL) {
+ (void) fprintf(stderr,
+ gettext("tnctl: failed to open %s: %s\n"), file,
+ strerror(errno));
+ exit(1);
+ }
+
+ linenum = errors = 0;
+ zc = NULL;
+ while (fgets(line, sizeof (line), fp) != NULL) {
+ if ((cp = strchr(line, '\n')) != NULL)
+ *cp = '\0';
+
+ linenum++;
+ if ((zc = tsol_sgetzcent(line, &err, &errstr)) == NULL) {
+ if (err == LTSNET_EMPTY)
+ continue;
+ if (errors == 0) {
+ int errtmp = errno;
+
+ (void) fprintf(stderr, gettext("tnctl: errors "
+ "parsing %s:\n"), file);
+ errno = errtmp;
+ }
+ print_error(linenum, err, errstr);
+ errors++;
+ continue;
+ }
+
+ if (strcasecmp(zc->zc_name, "global") == 0)
+ break;
+ tsol_freezcent(zc);
+ }
+ (void) fclose(fp);
+
+ if (zc == NULL) {
+ (void) fprintf(stderr,
+ gettext("tnctl: cannot find global zone in %s\n"), file);
+ exit(1);
+ }
+
+ tsme.tsme_zoneid = GLOBAL_ZONEID;
+ tsme.tsme_flags = 0;
+ if (flush_mode)
+ (void) tnmlp(TNDB_FLUSH, &tsme);
+
+ handle_mlps(GLOBAL_ZONEID, zc->zc_private_mlp, 0, TNDB_LOAD);
+ handle_mlps(GLOBAL_ZONEID, zc->zc_shared_mlp, TSOL_MEF_SHARED,
+ TNDB_LOAD);
+
+ tsol_freezcent(zc);
+}
+
+static void
+process_tpl(const char *file)
+{
+ FILE *fp;
+ boolean_t success = B_FALSE;
+ tsol_tpent_t *tpentp;
+
+ if ((fp = fopen(file, "r")) == NULL) {
+ (void) fprintf(stderr,
+ gettext("tnctl: failed to open %s: %s\n"), file,
+ strerror(errno));
+ exit(1);
+ }
+
+ tsol_settpent(1);
+ while (tpentp = tsol_fgettpent(fp)) {
+ /* First time through the loop, flush it all */
+ if (!success && flush_mode)
+ (void) tnrhtp(TNDB_FLUSH, NULL);
+
+ success = B_TRUE;
+
+ if (verbose_mode)
+ (void) printf("tnctl: loading rhtp entry ...\n");
+
+ if (tnrhtp(TNDB_LOAD, tpentp) != 0) {
+ (void) fclose(fp);
+ if (errno == EFAULT)
+ perror("tnrhtp");
+ else
+ (void) fprintf(stderr, gettext("tnctl: load "
+ "of remote-host template %1$s into kernel "
+ "cache failed: %2$s\n"), tpentp->name,
+ strerror(errno));
+ tsol_endtpent();
+ exit(1);
+ }
+ tsol_freetpent(tpentp);
+ }
+ if (!success) {
+ (void) fprintf(stderr,
+ gettext("tnctl: No valid tnrhtp entries found in %s\n"),
+ file);
+ }
+ (void) fclose(fp);
+ tsol_endtpent();
+}
+
+static void
+process_tp(const char *template)
+{
+ tsol_tpstr_t tpstr;
+ tsol_tpent_t tpent;
+ tsol_tpent_t *tpentp;
+ int err;
+ char *errstr;
+ char buf[NSS_BUFLEN_TSOL_TP];
+
+ if (strchr(template, ':') != NULL) {
+ (void) str_to_tpstr(template, strlen(template), &tpstr, buf,
+ sizeof (buf));
+ tpentp = tpstr_to_ent(&tpstr, &err, &errstr);
+ if (tpentp == NULL) {
+ print_error(0, err, errstr);
+ exit(1);
+ }
+ } else if (delete_mode) {
+ (void) memset(&tpent, 0, sizeof (tpent));
+ tpentp = &tpent;
+ (void) strlcpy(tpentp->name, template, sizeof (tpentp->name));
+ } else if ((tpentp = tsol_gettpbyname(template)) == NULL) {
+ (void) fprintf(stderr,
+ gettext("tnctl: template %s not found\n"), template);
+ exit(1);
+ }
+
+ if (verbose_mode)
+ (void) printf("%s rhtp entry ...\n", delete_mode ? "deleting" :
+ "loading");
+
+ if (tnrhtp(delete_mode ? TNDB_DELETE : TNDB_LOAD, tpentp) != 0) {
+ if (errno == EFAULT)
+ perror("tnrhtp");
+ else if (errno == ENOENT)
+ (void) fprintf(stderr,
+ gettext("tnctl: %1$s of remote-host template "
+ "kernel cache entry %2$s failed: no such "
+ "entry\n"),
+ delete_mode ? gettext("delete") : gettext("load"),
+ tpentp->name);
+ else
+ (void) fprintf(stderr,
+ gettext("tnctl: %1$s of remote-host template "
+ "kernel cache entry %2$s failed: %3$s\n"),
+ delete_mode ? gettext("delete") : gettext("load"),
+ tpentp->name, strerror(errno));
+ exit(1);
+ }
+ if (tpentp != &tpent)
+ tsol_freetpent(tpentp);
+}
+
+static void
+process_mlp(const char *str)
+{
+ const char *cp;
+ char zonename[ZONENAME_MAX];
+ zoneid_t zoneid;
+ tsol_zcent_t *zc;
+ int err;
+ char *errstr;
+ char *sbuf;
+
+ if ((cp = strchr(str, ':')) == NULL) {
+ if (!delete_mode) {
+ (void) fprintf(stderr,
+ gettext("tnctl: need MLP list to insert\n"));
+ exit(2);
+ }
+ (void) strlcpy(zonename, str, sizeof (zonename));
+ } else if (cp - str >= ZONENAME_MAX) {
+ (void) fprintf(stderr, gettext("tnctl: illegal zone name\n"));
+ exit(2);
+ } else {
+ (void) memcpy(zonename, str, cp - str);
+ zonename[cp - str] = '\0';
+ str = cp + 1;
+ }
+
+ if ((zoneid = getzoneidbyname(zonename)) == -1) {
+ (void) fprintf(stderr, gettext("tninfo: zone '%s' unknown\n"),
+ zonename);
+ exit(1);
+ }
+
+ sbuf = malloc(strlen(zonename) + sizeof (":ADMIN_LOW:0:") +
+ strlen(str));
+ if (sbuf == NULL) {
+ perror("malloc");
+ exit(1);
+ }
+ /* LINTED: sprintf is known not to be unbounded here */
+ (void) sprintf(sbuf, "%s:ADMIN_LOW:0:%s", zonename, str);
+ if ((zc = tsol_sgetzcent(sbuf, &err, &errstr)) == NULL) {
+ (void) fprintf(stderr,
+ gettext("tnctl: unable to parse MLPs\n"));
+ exit(1);
+ }
+ handle_mlps(zoneid, zc->zc_private_mlp, 0,
+ delete_mode ? TNDB_DELETE : TNDB_LOAD);
+ handle_mlps(zoneid, zc->zc_shared_mlp, TSOL_MEF_SHARED,
+ delete_mode ? TNDB_DELETE : TNDB_LOAD);
+ tsol_freezcent(zc);
+}
+
+static void
+usage(void)
+{
+ (void) fprintf(stderr, gettext("usage: tnctl [-dfv] "
+ "[-h host[/prefix][:tmpl]] [-m zone:priv:share]\n\t"
+ "[-t tmpl[:key=val[;key=val]]] [-[HTz] file]\n"));
+
+ exit(1);
+}
diff --git a/usr/src/cmd/tsol/tnctl/tnctl.xml b/usr/src/cmd/tsol/tnctl/tnctl.xml
new file mode 100644
index 0000000000..0960d6b118
--- /dev/null
+++ b/usr/src/cmd/tsol/tnctl/tnctl.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ ident "%Z%%M% %I% %E% SMI"
+-->
+
+<service_bundle type='manifest' name='SUNWtsg:tnctl'>
+
+<service
+ name='network/tnctl'
+ type='service'
+ version='1'>
+
+ <create_default_instance enabled='true' />
+
+ <single_instance/>
+
+ <dependent
+ name='tnctl_name-service-cache'
+ grouping='optional_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/name-service-cache' />
+ </dependent>
+
+ <dependent
+ name='tnctl_network-physical'
+ grouping='optional_all'
+ restart_on='none'>
+ <service_fmri value='svc:/network/physical' />
+ </dependent>
+
+ <exec_method
+ type='method'
+ name='start'
+ exec='/lib/svc/method/svc-tnctl'
+ timeout_seconds='60' />
+
+ <exec_method
+ type='method'
+ name='stop'
+ exec=':true'
+ timeout_seconds='60' />
+
+ <property_group name='general' type='framework'>
+ <propval name='action_authorization' type='astring'
+ value='solaris.smf.manage.tnctl'/>
+ </property_group>
+
+ <property_group name='startd' type='framework'>
+ <propval name='duration' type='astring'
+ value='transient' />
+ </property_group>
+
+ <stability value='Unstable' />
+
+ <template>
+ <common_name>
+ <loctext xml:lang='C'> trusted networking templates
+ </loctext>
+ </common_name>
+ <documentation>
+ <manpage title='tnctl' section='1M'
+ manpath='/usr/share/man' />
+ </documentation>
+ </template>
+</service>
+
+</service_bundle>
diff --git a/usr/src/cmd/tsol/tnctl/tnrhdb b/usr/src/cmd/tsol/tnctl/tnrhdb
new file mode 100644
index 0000000000..c514d1e13c
--- /dev/null
+++ b/usr/src/cmd/tsol/tnctl/tnrhdb
@@ -0,0 +1,41 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# The following are the boot-time defaults. These establish all IPv4 and
+# IPv6 addresses as unlabeled. Both are removed if this file contains any
+# non-blank entries.
+#
+#0.0.0.0/0:_unlab
+#\:\:0/0:_unlab
+#
+# Default value shipped with system. This allows global zone of the
+# system to obtain various services during initial boot. Administrators
+# should remove this entry after the system is fully configured.
+#
+0.0.0.0:admin_low
+#\:\:0:admin_low
+127.0.0.1:cipso
+#\:\:1:cipso
diff --git a/usr/src/cmd/tsol/tnctl/tnrhtp b/usr/src/cmd/tsol/tnctl/tnrhtp
new file mode 100644
index 0000000000..442dc1cb82
--- /dev/null
+++ b/usr/src/cmd/tsol/tnctl/tnrhtp
@@ -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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# The following is the default template used on the system.
+#
+#_unlab:host_type=unlabeled;doi=1;def_label=ADMIN_LOW;min_sl=ADMIN_LOW;max_sl=ADMIN_HIGH
+#
+# Default for locally plumbed interfaces
+cipso:host_type=cipso;doi=1;min_sl=ADMIN_LOW;max_sl=ADMIN_HIGH;
+#
+admin_low:host_type=unlabeled;doi=1;min_sl=ADMIN_LOW;max_sl=ADMIN_HIGH;def_label=ADMIN_LOW;
diff --git a/usr/src/cmd/tsol/tnctl/tnzonecfg b/usr/src/cmd/tsol/tnctl/tnzonecfg
new file mode 100644
index 0000000000..4ebd99bb47
--- /dev/null
+++ b/usr/src/cmd/tsol/tnctl/tnzonecfg
@@ -0,0 +1,60 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+#
+#There are five fields separated by colon in this configuration file:
+#First Field: Name for the corresponding zone.
+# It is used when zone is configured.
+#
+#Second Field: Label for the corresponding zone.
+# It is used to label the zone when zone is booted.
+# The label can be either hex label or symbolic ones defined by
+# label_encodings files.
+#
+#Third Field: Policy match level for non-transport traffic.
+# Currently unused.
+#
+#Fourth Field: Multi-Level port configuration entry for private addresses.
+# mlp info is list of semicolon separated mlp configuration entry.
+# Each mlp configuration entry is specified by port/protocol.
+#
+#Fifth Field: Multi-Level port configuration entry for shared address.
+# It only applies to global zones.
+#
+# This is the default global zone configuration. Note that although this
+# entry must have a label and match flag, neither is configurable by the user.
+#
+# Multilevel Port (MLP) specification:
+#
+# MLP PURPOSE
+# --- -------
+# 111 Port Mapper
+# 515 BSD Multilevel Printing
+# 631 IPP Multilevel Printing
+# 2049 NFSv4 server
+# 6000-6003 Multilevel Desktop
+#
+global:ADMIN_LOW:1:111/tcp;111/udp;515/tcp;631/tcp;2049/tcp;6000-6003/tcp:6000-6003/tcp
diff --git a/usr/src/cmd/tsol/tnd/Makefile b/usr/src/cmd/tsol/tnd/Makefile
new file mode 100644
index 0000000000..80030ef7eb
--- /dev/null
+++ b/usr/src/cmd/tsol/tnd/Makefile
@@ -0,0 +1,62 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/tsol/tnd/Makefile
+#
+PROG= tnd
+OBJS= tnd.o
+
+SRCS= $(OBJS:.o=.c)
+
+HDRS= tnd.h
+
+POFILES = tnd.po
+
+include ../../Makefile.cmd
+
+MANIFEST= tnd.xml
+ROOTMANIFESTDIR = $(ROOTSVCNETWORK)
+SVCMETHOD= svc-tnd
+$(ROOTMANIFEST) := FILEMODE= 444
+
+IFLAGS += -I.
+LDLIBS += -lnsl -ltsnet
+CPPFLAGS += $(IFLAGS)
+CPPFLAGS += -DDEBUG
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all $(ROOTTSOLPROG) $(ROOTMANIFEST) $(ROOTSVCMETHOD) \
+ $(ROOTUSRSBIN)/$(PROG)
+
+clean:
+ $(RM) $(OBJS) tags
+
+lint: lint_SRCS
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/tsol/tnd/svc-tnd b/usr/src/cmd/tsol/tnd/svc-tnd
new file mode 100644
index 0000000000..6e3eb3ae0b
--- /dev/null
+++ b/usr/src/cmd/tsol/tnd/svc-tnd
@@ -0,0 +1,46 @@
+#!/sbin/sh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+. /lib/svc/share/smf_include.sh
+
+[ ! -x /usr/sbin/tnd ] && exit $SMF_EXIT_ERR_CONFIG
+
+FMRI=svc:/network/tnd
+
+args=""
+
+val=`svcprop -p tnd/debug_level $FMRI`
+[ -n "$val" ] && args="$args -d $val"
+
+val=`svcprop -p tnd/debug_file $FMRI`
+val=`eval echo $val`
+[ -n "$val" ] && args="$args -f $val"
+
+val=`svcprop -p tnd/poll_interval $FMRI`
+[ -n "$val" ] && args="$args -p $val"
+
+/usr/sbin/tnd $args &
+
diff --git a/usr/src/cmd/tsol/tnd/tnd.c b/usr/src/cmd/tsol/tnd/tnd.c
new file mode 100644
index 0000000000..dfa8fc53e4
--- /dev/null
+++ b/usr/src/cmd/tsol/tnd/tnd.c
@@ -0,0 +1,1920 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <langinfo.h>
+#include <search.h>
+#include <tsol/label.h>
+#include <errno.h>
+#include <sys/tsol/tndb.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <signal.h>
+#include <sys/signal.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <syslog.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <grp.h>
+#include <door.h>
+#include <synch.h>
+#include <sys/tsol/tsyscall.h>
+#include <nss_dbdefs.h>
+#include <libtsnet.h>
+#include <zone.h>
+
+#include "tnd.h"
+
+static FILE *tnlog_open(char *);
+static void usage();
+static void parse_opts(int, char **);
+static int check_debugl(int);
+static void load_tp();
+static void load_tp_entry();
+static void tnd_serve();
+static void detachfromtty();
+static void terminate();
+static void noop();
+static char *gettime();
+static int isnumber(char *);
+static void poll_now();
+static int nss_get_tp();
+static int nss_get_rh();
+static void timer();
+static void load_rh_marked();
+static int rhtable_search_and_update(struct tsol_rhent *ent, int duplflag);
+static int is_better_match(in_addr_t newaddr, int indx, tnrh_tlb_t *tlbt);
+static int walk_cache_table(in_addr_t newaddr, char *name,
+ int indx, tnd_tnrhdb_t *src);
+static tnrh_tlb_t *lookup_cache_table(in_addr_t addr);
+static int update_cache_table(tsol_rhent_t *ent, tnd_tnrhdb_t *src);
+static void update_rh_entry(int op, struct tsol_rhent *rhentp);
+static int handle_unvisited_nodes();
+static in_addr_t rh_index_to_mask(uint_t masklen);
+static tnrh_tlb_ipv6_t *lookup_cache_table_v6(in6_addr_t addr);
+static in6_addr_t *rh_index_to_mask_v6(uint_t masklen, in6_addr_t *bitmask);
+static void load_rh_marked_v6();
+static int
+ rhtable_search_and_update_v6(struct tsol_rhent *ent, int duplflag);
+static int walk_cache_table_v6(in6_addr_t newaddr, char *name,
+ int indx, tnd_tnrhdb_t *src);
+static int update_cache_table_v6(tsol_rhent_t *ent, tnd_tnrhdb_t *src);
+static int handle_unvisited_nodes_v6();
+
+#ifdef DEBUG
+static void print_entry(tsol_rhent_t *ent, int af);
+static void print_tlbt(tnrh_tlb_t *tlbt);
+static void rhtable_print();
+static void cachetable_print();
+static void rhtable_walk(void (*action)());
+static void cachetable_print_v6();
+static void rhtable_print_v6();
+static void rhtable_walk_v6(void (*action)());
+#endif /* DEBUG */
+
+/*
+ * The following constants and structures and the functions
+ * that operate on them are similar to the ip_ire.c and ip6_ire.c
+ * code in the kernel.
+ */
+#define TNRH_TABLE_HASH_SIZE 256
+#define IP_ABITS 32
+#define IP_MASK_TABLE_SIZE (IP_ABITS + 1)
+#define RH_HOST_MASK (in_addr_t)0xffffffffU
+
+#define IPV6_ABITS 128
+#define IPV6_MASK_TABLE_SIZE (IPV6_ABITS + 1)
+#define s6_addr8 _S6_un._S6_u8
+#define s6_addr32 _S6_un._S6_u32
+
+/*
+ * Exclusive-or the 6 bytes that are likely to contain the MAC
+ * address. Assumes table_size does not exceed 256.
+ * Assumes EUI-64 format for good hashing.
+ */
+#define TNRH_ADDR_HASH_V6(addr) \
+ (((addr).s6_addr8[8] ^ (addr).s6_addr8[9] ^ \
+ (addr).s6_addr8[10] ^ (addr).s6_addr8[13] ^ \
+ (addr).s6_addr8[14] ^ (addr).s6_addr8[15]) % TNRH_TABLE_HASH_SIZE)
+
+#define TNRH_ADDR_MASK_HASH_V6(addr, mask) \
+ ((((addr).s6_addr8[8] & (mask).s6_addr8[8]) ^ \
+ ((addr).s6_addr8[9] & (mask).s6_addr8[9]) ^ \
+ ((addr).s6_addr8[10] & (mask).s6_addr8[10]) ^ \
+ ((addr).s6_addr8[13] & (mask).s6_addr8[13]) ^ \
+ ((addr).s6_addr8[14] & (mask).s6_addr8[14]) ^ \
+ ((addr).s6_addr8[15] & (mask).s6_addr8[15])) % TNRH_TABLE_HASH_SIZE)
+
+/* Mask comparison: is IPv6 addr a, and'ed with mask m, equal to addr b? */
+#define V6_MASK_EQ(a, m, b) \
+ ((((a).s6_addr32[0] & (m).s6_addr32[0]) == (b).s6_addr32[0]) && \
+ (((a).s6_addr32[1] & (m).s6_addr32[1]) == (b).s6_addr32[1]) && \
+ (((a).s6_addr32[2] & (m).s6_addr32[2]) == (b).s6_addr32[2]) && \
+ (((a).s6_addr32[3] & (m).s6_addr32[3]) == (b).s6_addr32[3]))
+
+
+const in6_addr_t ipv6_all_zeros = { 0, 0, 0, 0 };
+
+/*
+ * This is a table of hash tables to keep
+ * all the name service entries. We don't have
+ * a separate hash bucket structure, instead mantain
+ * a pointer to the hash chain.
+ */
+tnd_tnrhdb_t **tnrh_entire_table[IP_MASK_TABLE_SIZE];
+tnd_tnrhdb_t **tnrh_entire_table_v6[IPV6_MASK_TABLE_SIZE];
+
+/* reader/writer lock for tnrh_entire_table */
+rwlock_t entire_rwlp;
+rwlock_t entire_rwlp_v6;
+
+
+/*
+ * This is a hash table which keeps fully resolved
+ * tnrhdb entries <IP address, Host type>. We don't have
+ * a separate hash bucket structure, instead
+ * mantain a pointer to the hash chain.
+ */
+tnrh_tlb_t *tnrh_cache_table[TNRH_TABLE_HASH_SIZE];
+tnrh_tlb_ipv6_t *tnrh_cache_table_v6[TNRH_TABLE_HASH_SIZE];
+
+/* reader/writer lock for tnrh_cache_table */
+rwlock_t cache_rwlp;
+rwlock_t cache_rwlp_v6;
+
+FILE *logf;
+int debugl = 0;
+int poll_interval = TND_DEF_POLL_TIME;
+int delay_poll_flag = 0;
+
+void *tp_tree;
+
+#define _SZ_TIME_BUF 100
+char time_buf[_SZ_TIME_BUF];
+
+#define cprint(s, param) { \
+ register FILE *consl; \
+\
+ if ((consl = fopen("/dev/msglog", "w")) != NULL) { \
+ setbuf(consl, NULL); \
+ (void) fprintf(consl, "tnd: "); \
+ (void) fprintf(consl, s, param); \
+ (void) fclose(consl); \
+ } \
+ }
+
+#define RHENT_BUF_SIZE 300
+#define TPENT_BUF_SIZE 2000
+
+/* 128 privs * (24 bytes + 1 deliminator)= 3200 bytes + 1200 cushion */
+#define STRING_PRIVS_SIZE 4800
+#define ID_ENT_SIZE 500
+
+main(int argc, char **argv)
+{
+
+
+ const ucred_t *uc = NULL;
+ const priv_set_t *pset;
+ struct sigaction act;
+
+ /* set the locale for only the messages system (all else is clean) */
+ (void) setlocale(LC_ALL, "");
+#ifndef TEXT_DOMAIN /* Should be defined by cc -D */
+#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
+#endif
+ (void) textdomain(TEXT_DOMAIN);
+
+ if (getzoneid() != GLOBAL_ZONEID) {
+ syslog(LOG_ERR, "can not run tnd from a local zone");
+ exit(-1);
+ }
+
+
+ if (((uc = ucred_get(getpid())) == NULL) ||
+ ((pset = ucred_getprivset(uc, PRIV_EFFECTIVE)) == NULL)) {
+ syslog(LOG_ERR, "don't have privilege set");
+ exit(-1);
+ }
+
+ if (!priv_ismember(pset, PRIV_SYS_NET_CONFIG)) {
+ syslog(LOG_ERR, "don't have privilege to run tnd");
+ exit(-1);
+ }
+
+
+ /* parse command line options */
+ (void) parse_opts(argc, argv);
+
+ /*
+ * Initialize reader/writer locks. To be
+ * used within this process only.
+ */
+ if ((rwlock_init(&entire_rwlp, USYNC_THREAD, 0) != 0) ||
+ (rwlock_init(&entire_rwlp_v6, USYNC_THREAD, 0) != 0) ||
+ (rwlock_init(&cache_rwlp, USYNC_THREAD, 0) != 0) ||
+ (rwlock_init(&cache_rwlp_v6, USYNC_THREAD, 0) != 0)) {
+ syslog(LOG_ERR, "cannot initialize lock");
+ exit(-1);
+ }
+
+ /* catch the usual termination signals for graceful exit */
+ (void) sigset(SIGINT, terminate);
+ (void) sigset(SIGTERM, terminate);
+ (void) sigset(SIGQUIT, terminate);
+ (void) sigset(SIGUSR1, noop);
+
+ act.sa_handler = timer;
+ act.sa_flags = SA_RESTART;
+ (void *) sigemptyset(&act.sa_mask);
+ (void *) sigaddset(&act.sa_mask, SIGALRM);
+ (void *) sigaddset(&act.sa_mask, SIGHUP);
+ (void *) sigaction(SIGALRM, &act, NULL);
+ (void *) sigaction(SIGHUP, &act, NULL);
+
+ if (debugl == MAX_TND_DEBUG) {
+ (void) fprintf(logf, "%s : ", gettime());
+ (void) fprintf(logf, gettext("tnd started. pid= %d\n"),
+ getpid());
+ (void) fprintf(logf, "%s : ", gettime());
+ (void) fprintf(logf,
+ gettext("max level debugging! not forking\n"));
+ (void) fflush(logf);
+ } else {
+ detachfromtty();
+ }
+
+ if (!delay_poll_flag) {
+ (void) sigprocmask(SIG_BLOCK, &act.sa_mask, NULL);
+ timer();
+ (void) sigprocmask(SIG_UNBLOCK, &act.sa_mask, NULL);
+ }
+
+ if (debugl != MAX_TND_DEBUG) {
+ (void) sigsend(P_PID, getppid(), SIGUSR1);
+ }
+
+ (void) tnd_serve();
+
+ /* NOT REACHED */
+ return (0);
+}
+
+
+/*
+ * Compare addresses after masking off unneeded bits.
+ * We do this to handle addresses where prefix_len is
+ * less than the bit length.
+ */
+static int
+rhaddr_compar_mask(struct sockaddr_in *tp1, struct tnd_tnrhdb_c *tp2, int i)
+{
+ struct sockaddr_in *saddrp;
+ in_addr_t tmpmask = rh_index_to_mask(i);
+
+ saddrp = (struct sockaddr_in *)(&tp2->rh_ent.rh_address.ip_addr_v4);
+
+#ifdef DEBUG
+ (void) fprintf(logf, gettext("rhaddr_compar_mask mask = 0x%4x, \
+ tp1 = 0x%4x, tp2 = 0x%4x\n"), tmpmask, (tp1->sin_addr),
+ (saddrp->sin_addr.s_addr & tmpmask));
+ (void) fprintf(logf, gettext("rhaddr_compar_mask return = %d\n"),
+ (tp1->sin_addr.s_addr == (saddrp->sin_addr.s_addr & tmpmask)));
+#endif
+ return (tp1->sin_addr.s_addr == (saddrp->sin_addr.s_addr & tmpmask));
+}
+
+
+/*
+ * we use this where exact match is needed.
+ */
+static int
+rhaddr_compar(struct sockaddr_in *tp1, struct tnd_tnrhdb_c *tp2)
+{
+ struct sockaddr_in *saddrp;
+
+ saddrp = (struct sockaddr_in *)(&tp2->rh_ent.rh_address.ip_addr_v4);
+
+#ifdef DEBUG
+ (void) fprintf(logf, gettext("\t tp1 saddrp IP : %s %s\n"),
+ inet_ntoa(tp1->sin_addr), inet_ntoa(saddrp->sin_addr));
+#endif
+
+ return (tp1->sin_addr.s_addr == saddrp->sin_addr.s_addr);
+}
+
+/*
+ * Compare v6 addresses after masking off unneeded bits.
+ * We do this to handle addresses where prefix_len is
+ * less than the bit length.
+ */
+static int
+rhaddr_compar_mask_v6(struct sockaddr_in6 *tp1, struct tnd_tnrhdb_c *tp2, int i)
+{
+ struct sockaddr_in6 *saddrp;
+ in6_addr_t tmpmask;
+
+ (void) rh_index_to_mask_v6(i, &tmpmask);
+ saddrp = (struct sockaddr_in6 *)(&tp2->rh_ent.rh_address.ip_addr_v6);
+ return (V6_MASK_EQ(tp1->sin6_addr, tmpmask, saddrp->sin6_addr));
+}
+
+/*
+ * we use this where v6 exact match is needed.
+ */
+static int
+rhaddr_compar_v6(struct sockaddr_in6 *tp1, struct tnd_tnrhdb_c *tp2)
+{
+ struct sockaddr_in6 *saddrp;
+
+ saddrp = (struct sockaddr_in6 *)(&tp2->rh_ent.rh_address.ip_addr_v6);
+ return (IN6_ARE_ADDR_EQUAL(&tp1->sin6_addr, &saddrp->sin6_addr));
+}
+
+static int
+get_hashvalue(in_addr_t addr)
+{
+ unsigned char *bp;
+
+ bp = (unsigned char *) &addr;
+ return ((bp[0] ^ bp[1] ^ bp[2] ^ bp[3]) % TNRH_TABLE_HASH_SIZE);
+}
+
+/*
+ * Convert length for a mask to the mask.
+ */
+static in_addr_t
+rh_index_to_mask(uint_t masklen)
+{
+ if (masklen == 0)
+ return (0);
+ return (htonl(RH_HOST_MASK << (IP_ABITS - masklen)));
+}
+
+/*
+ * Convert length for a mask to the mask.
+ * Returns the argument bitmask.
+ */
+static in6_addr_t *
+rh_index_to_mask_v6(uint_t masklen, in6_addr_t *bitmask)
+{
+ uint32_t *ptr;
+
+ *bitmask = ipv6_all_zeros;
+
+ ptr = (uint32_t *)bitmask;
+ while (masklen > 32) {
+ *ptr++ = 0xffffffffU;
+ masklen -= 32;
+ }
+ *ptr = htonl(0xffffffffU << (32 - masklen));
+ return (bitmask);
+}
+
+
+static void
+parse_opts(argc, argv)
+ int argc;
+ char **argv;
+{
+ char *logfile = TNDLOG;
+ extern char *optarg;
+ int c;
+
+ while ((c = getopt(argc, argv, "d:f:p:n")) != EOF)
+ switch (c) {
+ case 'd':
+ if (isnumber(optarg)) {
+ debugl = atoi(optarg);
+ if (check_debugl(debugl) == -1)
+ debugl = 1; /* default to 1 */
+ } else {
+ usage();
+ exit(1);
+ }
+ break;
+ case 'f':
+ logfile = optarg;
+ break;
+ case 'p':
+ if (isnumber(optarg)) {
+ poll_interval = atoi(optarg);
+ if (poll_interval == 0)
+ usage();
+ } else {
+ usage();
+ }
+ break;
+ case 'n':
+ delay_poll_flag = 1;
+ break;
+ case '?':
+ usage();
+ }
+
+ logf = tnlog_open(logfile);
+}
+
+static int
+check_debugl(debug_level)
+ int debug_level;
+{
+ if (debug_level > MAX_TND_DEBUG) {
+ if ((debugl > 0) && (logf != NULL)) {
+ (void) fprintf(logf, "%s : ", gettime());
+ (void) fprintf(logf,
+ gettext("invalid debug level: %d, not changed!\n"),
+ debug_level);
+ (void) fflush(logf);
+ }
+ cprint("invalid debug level: %d, not changed!\n",
+ debug_level);
+ return (-1);
+ }
+ return (0);
+}
+
+static FILE *
+tnlog_open(logfile)
+ char *logfile;
+{
+ FILE *fp;
+
+ if ((fp = fopen(logfile, "a")) == NULL) {
+ syslog(LOG_ERR, "unable to open logfile %s",
+ logfile);
+ exit(-1);
+ }
+ (void) fprintf(fp, "%s : ", gettime());
+ (void) fprintf(fp, gettext("tnd starting\n"));
+
+ return (fp);
+}
+
+static void
+detachfromtty()
+{
+ pid_t tnd_pid;
+
+ (void) close(0);
+ (void) close(1);
+ (void) close(2);
+ switch (tnd_pid = fork()) {
+ case (pid_t)-1:
+ if (debugl && (logf != NULL)) {
+ (void) fprintf(logf, "%s : ", gettime());
+ (void) fprintf(logf,
+ gettext("fork() failed: %s\n"), strerror(errno));
+ (void) fflush(logf);
+ }
+ cprint("fork() failed: %s\n", strerror(errno));
+ break;
+ case 0:
+ break;
+ default:
+ if (debugl && (logf != NULL)) {
+ (void) fprintf(logf, "%s : ", gettime());
+ (void) fprintf(logf,
+ gettext("tnd started. pid= %d\n"), tnd_pid);
+ (void) fflush(logf);
+ }
+ /*
+ * Suspend parent till child signals it. We catch the signal
+ * in order to return correct exit value.
+ */
+
+ (void) pause();
+ exit(0);
+ }
+ (void) setsid();
+ (void) open("/dev/null", O_RDWR, 0);
+ (void) dup(0);
+ (void) dup(0);
+}
+
+static void
+usage()
+{
+ (void) fprintf(stderr, gettext(
+ "Usage:\n\ttnd [-d debug-level][-f debug-file]"
+ "[-p poll-interval]\n"));
+
+ exit(1);
+}
+
+static int
+isnumber(s)
+char *s;
+{
+ register c;
+
+ /* LINTED */
+ while (c = *s++)
+ if (!isdigit(c))
+ return (0);
+ return (1);
+}
+
+
+/*
+ * match any entry in any tree
+ * used in tree removal
+ */
+/* ARGSUSED */
+static int
+any_compar(const void *v1, const void *v2)
+{
+ return (0);
+}
+
+static int
+tp_compar(const void *v1, const void *v2)
+{
+ struct tnd_tnrhtp_c *tp1 = (struct tnd_tnrhtp_c *)v1;
+ struct tnd_tnrhtp_c *tp2 = (struct tnd_tnrhtp_c *)v2;
+ return (strcmp(tp1->tp_ent.name, tp2->tp_ent.name));
+}
+
+/*
+ * Build tree of tp entries, tossing duplicates
+ */
+static int
+nss_get_tp()
+{
+ tsol_tpent_t tp; /* to store result */
+ tsol_tpent_t *tpp;
+ struct tnd_tnrhtp_c *new, **old;
+ int count = 0;
+
+ tpp = &tp;
+
+ tsol_settpent(1);
+
+ while ((tpp = (tsol_tpent_t *)tsol_gettpent()) != NULL) {
+ if ((new = (struct tnd_tnrhtp_c *)
+ calloc(1, sizeof (struct tnd_tnrhtp_c))) == NULL)
+ continue;
+ (void) memcpy(&new->tp_ent, tpp, sizeof (tp));
+ old = (struct tnd_tnrhtp_c **)tsearch(new, &tp_tree, tp_compar);
+ if (*old != new)
+ free(new);
+ else
+ count++;
+ }
+ tsol_endtpent();
+
+ return (count);
+}
+
+/* load tp ents into kernel */
+static void
+load_tp()
+{
+ twalk(tp_tree, load_tp_entry);
+}
+
+
+static void
+/* LINTED */
+load_tp_entry(struct tnd_tnrhtp_c **tppp, VISIT visit, int level)
+{
+ struct tnd_tnrhtp_c *tpp;
+
+ if (!(visit == postorder || visit == leaf))
+ return;
+
+ tpp = *tppp;
+ if (tnrhtp(TNDB_LOAD, &tpp->tp_ent)) {
+ if (debugl && (logf != NULL)) {
+ (void) fprintf(logf, "%s : ", gettime());
+ (void) fprintf(logf, gettext("tnrhtp() failed 0: %s\n"),
+ strerror(errno));
+ (void) fprintf(logf,
+ gettext("load of remote-host template "
+ "%s into kernel cache failed\n"),
+ tpp->tp_ent.name);
+ (void) fflush(logf);
+ }
+ cprint("tnrhtp() failed here 1: %s\n", strerror(errno));
+ }
+}
+
+static void
+tp_flush_cache()
+{
+ struct tnd_tnrhtp_c dummy;
+ struct tnd_tnrhtp_c *tp;
+
+ while (tp = tfind(&dummy, tp_tree, any_compar)) {
+ (void) tdelete(tp, &tp_tree, tp_compar);
+ free(tp);
+ }
+}
+
+/*
+ * Build/update the table of rh entries from the
+ * name service sources, files, ldap etc.
+ */
+static int
+nss_get_rh()
+{
+ int found_entry = 0;
+ int count = 0;
+ int newflag = 0;
+ struct tsol_rhent rh; /* to store result */
+ struct tsol_rhent *rhp;
+ tsol_tpent_t tp;
+ sa_family_t af;
+ int v6cnt = 0;
+
+ rhp = &rh;
+
+ tsol_setrhent(1);
+ while ((rhp = (struct tsol_rhent *)
+ tsol_getrhent()) != NULL) {
+ /*
+ * Check if this is a known template name
+ * Entries with missing template in kernel will be logged
+ * and not added to cache.
+ */
+
+ (void) fprintf(logf, gettext("getrhent template name: %s\n"),
+ rhp->rh_template);
+
+ (void) strncpy(tp.name, rhp->rh_template, TNTNAMSIZ - 1);
+ if (tnrhtp(TNDB_GET, &tp) != 0) {
+ if (debugl && (logf != NULL))
+ (void) fprintf(logf,
+ gettext("Unknown template name: %s\n"),
+ rhp->rh_template);
+ cprint(gettext("Unknown template name: %s\n"),
+ rhp->rh_template);
+ continue;
+ }
+ found_entry++; /* found a valid tnrhdb entry */
+ af = rhp->rh_address.ta_family;
+
+ if (af == AF_INET) {
+#ifdef DEBUG
+ (void) fprintf(logf, gettext("nss_get_rh() v4\n"));
+#endif
+ (void) rw_wrlock(&entire_rwlp);
+ (void) rw_wrlock(&cache_rwlp);
+
+ /*
+ * Both cache table and entire table can be modified
+ * by this function. So, get both locks.
+ */
+ newflag = rhtable_search_and_update(rhp, 1);
+
+ (void) rw_unlock(&cache_rwlp);
+ (void) rw_unlock(&entire_rwlp);
+ } else if (af == AF_INET6) {
+#ifdef DEBUG
+ (void) fprintf(logf, gettext("nss_get_rh() v6\n"));
+#endif
+ v6cnt++;
+ (void) rw_wrlock(&entire_rwlp_v6);
+ (void) rw_wrlock(&cache_rwlp_v6);
+
+ /*
+ * Both cache table and entire table can be modified
+ * by this function. So, get both locks.
+ */
+ newflag = rhtable_search_and_update_v6(rhp, 1);
+
+ (void) rw_unlock(&cache_rwlp_v6);
+ (void) rw_unlock(&entire_rwlp_v6);
+ }
+ if (newflag)
+ count++;
+ }
+ tsol_endrhent();
+
+ /*
+ * If the first tsol_getrhent() failed, we bail out and
+ * try again at the next poll interval, just in case the
+ * name service was not reachable the first time.
+ */
+ if (!found_entry) {
+#ifdef DEBUG
+ if (logf != NULL)
+ (void) fprintf(logf,
+ gettext("Unable to contact ldap server?\n"));
+#endif
+ return (count);
+ }
+
+ (void) rw_wrlock(&entire_rwlp);
+ (void) rw_wrlock(&cache_rwlp);
+ /*
+ * Handle deletions in the name service entries
+ * Both cache table and entire table can be modified
+ * by this function. So, get both locks.
+ */
+ count += handle_unvisited_nodes();
+
+ (void) rw_unlock(&cache_rwlp);
+ (void) rw_unlock(&entire_rwlp);
+
+ if (v6cnt > 0) {
+ (void) rw_wrlock(&entire_rwlp_v6);
+ (void) rw_wrlock(&cache_rwlp_v6);
+ /*
+ * Handle deletions in the name service entries
+ * Both cache table and entire table can be modified
+ * by this function. So, get both locks.
+ */
+ count += handle_unvisited_nodes_v6();
+
+ (void) rw_unlock(&cache_rwlp_v6);
+ (void) rw_unlock(&entire_rwlp_v6);
+ }
+
+ return (count);
+}
+
+/*
+ * Check if any deletions in the name service tables
+ * affect the cache entries. We need to do this
+ * in order to not flush the entrie kernel tnrhdb
+ * cache every time we poll the name services.
+ */
+static int
+handle_unvisited_nodes()
+{
+ int i, j, cnt = 0;
+ tnrh_tlb_t *tlbt;
+ tnd_tnrhdb_t *rhent, *prev;
+
+ for (i = 0; i < TNRH_TABLE_HASH_SIZE; i++)
+ if ((tlbt = tnrh_cache_table[i]) != NULL)
+ do {
+ if (tlbt->src->visited == 0) {
+ /*
+ * Mark for deletion of both our cache
+ * entry and the kernel cache entry.
+ */
+ tlbt->reload = TNDB_DELETE;
+ cnt++;
+ }
+
+ tlbt = tlbt->next;
+ } while (tlbt != NULL);
+
+ /*
+ * Remove any unvisited nodes. This can
+ * happen if they are not in use by any cache entry. Then,
+ * mark all nodes in entire_table, un-visited, for next iteration.
+ */
+
+ for (i = 0; i <= IP_ABITS; i++) {
+ if (tnrh_entire_table[i] == NULL)
+ continue;
+
+ for (j = 0; j < TNRH_TABLE_HASH_SIZE; j++) {
+ prev = rhent = tnrh_entire_table[i][j];
+
+ while (rhent != NULL) {
+ if (rhent->visited == 0) {
+ /*
+ * Check if start node
+ */
+ if (rhent == tnrh_entire_table[i][j]) {
+ prev = tnrh_entire_table[i][j] =
+ rhent->rh_next;
+ } else {
+ /* bypass the deleted node */
+ prev->rh_next = rhent->rh_next;
+ prev = prev->rh_next;
+ }
+
+ free(rhent);
+
+ if (prev == NULL)
+ break;
+ else {
+ rhent = prev;
+ continue;
+ }
+ } else
+ rhent->visited = 0;
+
+ prev = rhent;
+ rhent = rhent->rh_next;
+ }
+ }
+ }
+
+ return (cnt);
+}
+
+/*
+ * Check if any deletions in the name service tables
+ * affect the cache entries. We need to do this
+ * in order to not flush the entrie kernel tnrhdb
+ * cache every time we poll the name services.
+ */
+static int
+handle_unvisited_nodes_v6()
+{
+ int i, j, cnt = 0;
+ tnrh_tlb_ipv6_t *tlbt;
+ tnd_tnrhdb_t *rhent, *prev;
+
+ for (i = 0; i < TNRH_TABLE_HASH_SIZE; i++)
+ if ((tlbt = tnrh_cache_table_v6[i]) != NULL)
+ do {
+ if (tlbt->src->visited == 0) {
+ /*
+ * Mark for deletion of both our cache entry
+ * and the kernel cache entry.
+ */
+ tlbt->reload = TNDB_DELETE;
+ cnt++;
+ }
+
+ tlbt = tlbt->next;
+ } while (tlbt != NULL);
+
+ /*
+ * Remove any unvisited nodes. This can
+ * happen if they are not in use by any cache entry. Then,
+ * mark all nodes in entire_table, un-visited, for next iteration.
+ */
+
+ for (i = 0; i <= IPV6_ABITS; i++) {
+ if (tnrh_entire_table_v6[i] == NULL)
+ continue;
+
+ for (j = 0; j < TNRH_TABLE_HASH_SIZE; j++) {
+ prev = rhent = tnrh_entire_table_v6[i][j];
+
+ while (rhent != NULL) {
+ if (rhent->visited == 0) { /* delete the node */
+ /* Check if start node */
+ if (rhent == tnrh_entire_table_v6[i][j]) {
+ prev = tnrh_entire_table_v6[i][j] =
+ rhent->rh_next;
+ } else {
+ /* bypass the deleted node */
+ prev->rh_next = rhent->rh_next;
+ prev = prev->rh_next;
+ }
+
+ free(rhent);
+ if (prev == NULL)
+ break;
+ else {
+ rhent = prev;
+ continue;
+ }
+ } else
+ rhent->visited = 0;
+
+ prev = rhent;
+ rhent = rhent->rh_next;
+ }
+ }
+ }
+
+ return (cnt);
+}
+
+
+/*
+ * Search the hash chain for the address. If not found,
+ * add the entry to the hash table. If necessary,
+ * construct the hash table.
+ * If the rh entry is in table, we may update its template name
+ */
+static int
+rhtable_search_and_update(struct tsol_rhent *ent, int duplflag)
+{
+ struct sockaddr_in *saddrp;
+ unsigned char hash;
+ tnd_tnrhdb_t *rhent;
+ int i;
+ int rflag = 1;
+
+ struct tnd_tnrhdb_c *new;
+
+ saddrp = (struct sockaddr_in *)&ent->rh_address.ip_addr_v4;
+ hash = (unsigned char) get_hashvalue(saddrp->sin_addr.s_addr);
+ i = ent->rh_prefix;
+
+#ifdef DEBUG
+ (void) fprintf(logf, gettext("\trhtable_search_and_update IP address:\
+ %s\n"), inet_ntoa(saddrp->sin_addr));
+#endif
+
+ if (tnrh_entire_table[i] == NULL) {
+ if ((tnrh_entire_table[i] = (tnd_tnrhdb_t **)calloc(
+ TNRH_TABLE_HASH_SIZE, sizeof (tnd_tnrhdb_t *))) == NULL) {
+ return (0);
+ }
+ }
+
+ rhent = tnrh_entire_table[i][hash];
+#ifdef DEBUG
+ (void) fprintf(logf, gettext("\tsearch_and_update i = %d hash = %d\n"),
+ i, hash);
+ if (rhent != NULL) {
+ (void) fprintf(logf, gettext("\trhent visited = %d\n"),
+ rhent->visited);
+ print_entry(&rhent->rh_ent, AF_INET);
+ } else {
+ (void) fprintf(logf, gettext("\tsearch_and_update null\n"));
+ }
+#endif
+ while (rhent != NULL) {
+ if (rhaddr_compar(saddrp, rhent) == 1) {
+ /* Check if this is a duplicate entry */
+ if ((rhent->visited == 1) && duplflag)
+ return (0);
+
+ if (duplflag)
+ rhent->visited = 1;
+
+ if (strcmp(ent->rh_template,
+ rhent->rh_ent.rh_template) != 0) {
+ /*
+ * Template is changed in the name service.
+ * Use the new template.
+ */
+ (void) strcpy(rhent->rh_ent.rh_template,
+ ent->rh_template);
+ /*
+ * Check if this modified entry
+ * affects the cache table.
+ */
+ rflag = update_cache_table(ent, rhent);
+ return (rflag);
+ } else
+ return (0);
+ }
+ rhent = rhent->rh_next;
+ }
+
+ /* Not found. Add the entry */
+ new = (struct tnd_tnrhdb_c *)calloc(1,
+ sizeof (struct tnd_tnrhdb_c));
+ if (new == NULL)
+ return (0);
+ (void) memcpy(&new->rh_ent, ent, sizeof (struct tsol_rhent));
+ if (duplflag)
+ new->visited = 1; /* Mark all new nodes visited */
+
+ /* linked list. Insert in the beginning */
+ new->rh_next = tnrh_entire_table[i][hash];
+ tnrh_entire_table[i][hash] = new;
+#ifdef DEBUG
+ (void) fprintf(logf, gettext("rhtable added i = %d, hash = %d\n"),
+ i, hash);
+#endif
+
+ /* Check if the new entry affects the cache table */
+ rflag = update_cache_table(ent, new);
+
+#ifdef DEBUG
+ (void) fprintf(logf, gettext("search_and_update rflag=%d\n"), rflag);
+#endif
+ return (rflag);
+}
+
+/*
+ * Search the hash chain for the address. If not found,
+ * add the entry to the hash table. If necessary,
+ * construct the hash table.
+ */
+static int
+rhtable_search_and_update_v6(struct tsol_rhent *ent, int duplflag)
+{
+ struct sockaddr_in6 *saddrp;
+ unsigned char hash;
+ tnd_tnrhdb_t *rhent;
+ int i;
+ int rflag = 1;
+
+ struct tnd_tnrhdb_c *new;
+ in6_addr_t tmpmask6;
+
+ saddrp = (struct sockaddr_in6 *)&ent->rh_address.ip_addr_v6;
+ i = ent->rh_prefix;
+ (void) rh_index_to_mask_v6(i, &tmpmask6);
+ hash = (unsigned char) TNRH_ADDR_MASK_HASH_V6(saddrp->sin6_addr,
+ tmpmask6);
+
+ if (tnrh_entire_table_v6[i] == NULL) {
+ if ((tnrh_entire_table_v6[i] = (tnd_tnrhdb_t **)calloc(
+ TNRH_TABLE_HASH_SIZE, sizeof (tnd_tnrhdb_t *))) == NULL) {
+ return (0);
+ }
+ }
+
+ rhent = tnrh_entire_table_v6[i][hash];
+ while (rhent != NULL) {
+ if (rhaddr_compar_v6(saddrp, rhent) == 1) {
+ /* Check if this is a duplicate entry */
+ if ((rhent->visited == 1) && duplflag)
+ return (0);
+
+ if (duplflag)
+ rhent->visited = 1;
+
+ if (strcmp(ent->rh_template,
+ rhent->rh_ent.rh_template) != 0) {
+ /*
+ * Template is changed in the name service.
+ * Use the new template.
+ */
+ (void) strcpy(rhent->rh_ent.rh_template,
+ ent->rh_template);
+ /*
+ * Check if this modified entry
+ * affects the cache table.
+ */
+ rflag = update_cache_table_v6(ent, rhent);
+ return (rflag);
+ } else
+ return (0);
+ }
+ rhent = rhent->rh_next;
+ }
+
+ /* Not found. Add the entry */
+ new = (struct tnd_tnrhdb_c *)calloc(1, sizeof (struct tnd_tnrhdb_c));
+ if (new == NULL)
+ return (0);
+ (void) memcpy(&new->rh_ent, ent, sizeof (struct tsol_rhent));
+ if (duplflag)
+ new->visited = 1; /* Mark all new nodes visited */
+
+ /* linked list. Insert in the beginning */
+ new->rh_next = tnrh_entire_table_v6[i][hash];
+ tnrh_entire_table_v6[i][hash] = new;
+
+ /* Check if the new entry affects the cache table */
+ rflag = update_cache_table_v6(ent, new);
+
+ return (rflag);
+}
+
+/*
+ * The array element i points to the hash table.
+ * Search the hash chain for the address.
+ */
+static struct tnd_tnrhdb_c *
+rhtable_lookup(struct sockaddr_in *saddrp, int i)
+{
+ unsigned char hash;
+ tnd_tnrhdb_t *rhent;
+
+ if (tnrh_entire_table[i] == NULL)
+ return (NULL);
+
+ hash = (unsigned char) get_hashvalue(saddrp->sin_addr.s_addr);
+ rhent = tnrh_entire_table[i][hash];
+
+#ifdef DEBUG
+ (void) fprintf(logf, gettext("rhtable_lookup i = %d, hash = %d\n"),
+ i, hash);
+#endif
+
+ while (rhent != NULL) {
+#ifdef DEBUG
+ struct sockaddr_in *saddrp2;
+ saddrp2 = (struct sockaddr_in *)(&rhent->rh_ent.rh_address.ip_addr_v4);
+ (void) fprintf(logf, gettext("rhtable_lookup addr = %s, tmpl = %s\n"),
+ inet_ntoa(saddrp2->sin_addr), rhent->rh_ent.rh_template);
+#endif
+ if (rhaddr_compar_mask(saddrp, rhent, i) == 1)
+ return (rhent);
+ rhent = rhent->rh_next;
+ }
+
+#ifdef DEBUG
+ (void) fprintf(logf, gettext("\trhtable_lookup failed\n"));
+#endif
+
+ /* Not found */
+ return (NULL);
+}
+
+/*
+ * The array element i points to the hash table.
+ * Search the hash chain for the address.
+ */
+static struct tnd_tnrhdb_c *
+rhtable_lookup_v6(struct sockaddr_in6 *saddrp, in6_addr_t mask, int i)
+{
+ unsigned char hash;
+ tnd_tnrhdb_t *rhent;
+
+ if (tnrh_entire_table_v6[i] == NULL)
+ return (NULL);
+
+ hash = (unsigned char) TNRH_ADDR_MASK_HASH_V6(saddrp->sin6_addr, mask);
+ rhent = tnrh_entire_table_v6[i][hash];
+
+ while (rhent != NULL) {
+ if (rhaddr_compar_mask_v6(saddrp, rhent, i) == 1)
+ return (rhent);
+ rhent = rhent->rh_next;
+ }
+
+ /* Not found */
+ return (NULL);
+}
+
+void
+add_cache_entry(in_addr_t addr, char *name, int indx,
+ tnd_tnrhdb_t *src)
+{
+ unsigned char hash;
+ tnrh_tlb_t *tlbt;
+
+ hash = (unsigned char) get_hashvalue(addr);
+
+ /* Look if some other thread already added this entry */
+ if (lookup_cache_table(addr) != NULL)
+ return;
+#ifdef DEBUG
+ (void) fprintf(logf, gettext("\tenter add_cache_entry\n"));
+#endif
+ if ((tlbt = (tnrh_tlb_t *)calloc(1, sizeof (tnrh_tlb_t))) == NULL)
+ return;
+ tlbt->addr = addr;
+ (void) strncpy(tlbt->template_name, name, TNTNAMSIZ-1);
+ tlbt->masklen_used = indx;
+ tlbt->reload = TNDB_LOAD;
+ tlbt->src = src;
+
+#ifdef DEBUG
+ (void) fprintf(logf, gettext("adding cache entry\n"));
+ print_tlbt(tlbt);
+#endif
+ /* Add to the chain */
+ if (tnrh_cache_table[hash] == NULL) {
+ tnrh_cache_table[hash] = tlbt;
+ } else {
+ /* Add in the beginning */
+ tlbt->next = tnrh_cache_table[hash];
+ tnrh_cache_table[hash] = tlbt;
+ }
+}
+
+static tnrh_tlb_t *
+lookup_cache_table(in_addr_t addr)
+{
+ tnrh_tlb_t *tlbt = NULL;
+ unsigned char hash;
+
+ hash = (unsigned char) get_hashvalue(addr);
+ tlbt = tnrh_cache_table[hash];
+ while (tlbt != NULL) {
+ if (addr == tlbt->addr)
+ break;
+ tlbt = tlbt->next;
+ }
+ return (tlbt);
+}
+
+static void
+add_cache_entry_v6(in6_addr_t addr, char *name, int indx,
+ tnd_tnrhdb_t *src)
+{
+ unsigned char hash;
+ tnrh_tlb_ipv6_t *tlbt;
+
+ hash = (unsigned char) TNRH_ADDR_HASH_V6(addr);
+
+ /* Look if some other thread already added this entry */
+ if (lookup_cache_table_v6(addr) != NULL)
+ return;
+
+ if ((tlbt = (tnrh_tlb_ipv6_t *)calloc(1,
+ sizeof (tnrh_tlb_ipv6_t))) == NULL)
+ return;
+ (void) memcpy(&tlbt->addr, &addr, sizeof (in6_addr_t));
+ (void) strncpy(tlbt->template_name, name, TNTNAMSIZ-1);
+ tlbt->masklen_used = indx;
+ tlbt->reload = TNDB_LOAD;
+ tlbt->src = src;
+
+ /* Add to the chain */
+ if (tnrh_cache_table_v6[hash] == NULL) {
+ tnrh_cache_table_v6[hash] = tlbt;
+ } else {
+ /* Add in the beginning */
+ tlbt->next = tnrh_cache_table_v6[hash];
+ tnrh_cache_table_v6[hash] = tlbt;
+ }
+}
+
+static tnrh_tlb_ipv6_t *
+lookup_cache_table_v6(in6_addr_t addr)
+{
+ tnrh_tlb_ipv6_t *tlbt = NULL;
+ unsigned char hash;
+
+ hash = (unsigned char) TNRH_ADDR_HASH_V6(addr);
+ tlbt = tnrh_cache_table_v6[hash];
+ while (tlbt != NULL) {
+ if (IN6_ARE_ADDR_EQUAL(&addr, &tlbt->addr))
+ break;
+ tlbt = tlbt->next;
+ }
+ return (tlbt);
+}
+
+
+/*
+ * Walk the cache table and check if this IP address/address prefix
+ * will be a better match for an existing entry in the cache.
+ * will add cache if not already exists
+ */
+static int
+update_cache_table(tsol_rhent_t *ent, tnd_tnrhdb_t *src)
+{
+ int i;
+ char result[TNTNAMSIZ];
+ in_addr_t tmpmask;
+ in_addr_t addr;
+ struct sockaddr_in *saddrp;
+ tnrh_tlb_t *tlbt;
+ struct tnd_tnrhdb_c *rhp;
+ int rflag = 0;
+
+ saddrp = (struct sockaddr_in *)&ent->rh_address.ip_addr_v4;
+ addr = saddrp->sin_addr.s_addr;
+
+ (void) rw_rdlock(&cache_rwlp);
+ tlbt = lookup_cache_table(addr);
+ (void) rw_unlock(&cache_rwlp);
+
+ if (tlbt == NULL) {
+ (void) rw_rdlock(&entire_rwlp);
+ for (i = (IP_MASK_TABLE_SIZE - 1); i >= 0; i--) {
+#ifdef DEBUG
+ (void) fprintf(logf, "update_cache_table i = %d\n", i);
+#endif
+ if (tnrh_entire_table[i] == NULL)
+ continue;
+
+ tmpmask = rh_index_to_mask(i);
+ saddrp->sin_addr.s_addr &= tmpmask;
+#ifdef DEBUG
+ (void) fprintf(logf,
+ "update_cache_table found i = %d\n", i);
+ (void) fprintf(logf, "\ti = %d, tmpmask = 0x%4x\n",
+ i, tmpmask);
+#endif
+ rhp = (struct tnd_tnrhdb_c *)rhtable_lookup(saddrp, i);
+ if (rhp != NULL) {
+ (void) strcpy(result, rhp->rh_ent.rh_template);
+ /* Add this result to the cache also */
+ (void) rw_wrlock(&cache_rwlp);
+ add_cache_entry(addr, result, i, rhp);
+ rflag++;
+ (void) rw_unlock(&cache_rwlp);
+ break;
+ } else {
+#ifdef DEBUG
+ (void) fprintf(logf,
+ "rhtable_lookup return null !!");
+#endif
+ }
+ }
+ (void) rw_unlock(&entire_rwlp);
+ }
+
+ rflag += walk_cache_table(addr, ent->rh_template, ent->rh_prefix, src);
+ return (rflag);
+}
+
+/*
+ * Walk the cache table and check if this IP address/address prefix
+ * will be a better match for an existing entry in the cache.
+ */
+static int
+update_cache_table_v6(tsol_rhent_t *ent, tnd_tnrhdb_t *src)
+{
+ int i;
+ char result[TNTNAMSIZ];
+ in6_addr_t addr;
+ struct sockaddr_in6 *saddrp;
+ tnrh_tlb_ipv6_t *tlbt;
+ struct tnd_tnrhdb_c *rhp;
+ in6_addr_t tmpmask6;
+ int rflag = 0;
+
+ saddrp = (struct sockaddr_in6 *)&ent->rh_address.ip_addr_v6;
+ (void) memcpy(&addr, &saddrp->sin6_addr, sizeof (in6_addr_t));
+
+ /* Look in the cache first */
+ (void) rw_rdlock(&cache_rwlp);
+ tlbt = lookup_cache_table_v6(addr);
+ (void) rw_unlock(&cache_rwlp);
+
+
+ if (tlbt == NULL) {
+ (void) rw_rdlock(&entire_rwlp_v6);
+ for (i = (IPV6_MASK_TABLE_SIZE - 1); i >= 0; i--) {
+ if (tnrh_entire_table_v6[i] == NULL)
+ continue;
+ (void) rh_index_to_mask_v6(i, &tmpmask6);
+ rhp = (struct tnd_tnrhdb_c *)
+ rhtable_lookup_v6(saddrp, tmpmask6, i);
+ if (rhp != NULL) {
+ (void) strcpy(result, rhp->rh_ent.rh_template);
+ /* Add this result to the cache also */
+ (void) rw_wrlock(&cache_rwlp_v6);
+ add_cache_entry_v6(addr, result, i, rhp);
+ rflag++;
+ (void) rw_unlock(&cache_rwlp_v6);
+ break;
+ }
+ }
+ (void) rw_unlock(&entire_rwlp_v6);
+ }
+
+ rflag += walk_cache_table_v6(addr, ent->rh_template,
+ ent->rh_prefix, src);
+ return (rflag);
+}
+
+
+/*
+ * Check if this prefix addr will be a better match
+ * for an existing entry.
+ */
+static int
+is_better_match(in_addr_t newaddr, int indx, tnrh_tlb_t *tlbt)
+{
+ if (tlbt->masklen_used <= indx) {
+ in_addr_t tmpmask = rh_index_to_mask(indx);
+
+ if ((newaddr) == (tlbt->addr & tmpmask))
+ return (1);
+ }
+
+ return (0);
+}
+
+/*
+ * Walk the cache table and update entries if needed.
+ * Mark entries for reload to kernel, if somehow their
+ * template changed.
+ * why is_better_match() is called???
+ */
+static int
+walk_cache_table(in_addr_t newaddr, char *name, int indx, tnd_tnrhdb_t *src)
+{
+ int i;
+ tnrh_tlb_t *tlbt;
+ int rflag = 0;
+
+ for (i = 0; i < TNRH_TABLE_HASH_SIZE; i++) {
+ tlbt = tnrh_cache_table[i];
+
+ while (tlbt != NULL) {
+ if (is_better_match(newaddr, indx, tlbt)) {
+ tlbt->masklen_used = indx;
+ tlbt->src = src;
+ /*
+ * Reload to the kernel only if the
+ * host type changed. There is no need
+ * to load, if only the mask used has changed,
+ * since the kernel does not need that
+ * information.
+ */
+ if (strcmp(name, tlbt->template_name) != 0) {
+ (void) strncpy(tlbt->template_name,
+ name, TNTNAMSIZ-1);
+ tlbt->reload = TNDB_LOAD;
+ rflag ++;
+ }
+ }
+
+ tlbt = tlbt->next;
+ }
+ }
+#ifdef DEBUG
+ (void) fprintf(logf, gettext("walk_cache_table rflag=%d\n"), rflag);
+#endif
+ return (rflag);
+}
+
+/*
+ * Check if this prefix addr will be a better match
+ * for an existing entry.
+ */
+static int
+is_better_match_v6(in6_addr_t newaddr, int indx, tnrh_tlb_ipv6_t *tlbt)
+{
+ in6_addr_t tmpmask;
+
+ if (tlbt->masklen_used <= indx) {
+ (void) rh_index_to_mask_v6(indx, &tmpmask);
+
+ if (V6_MASK_EQ(newaddr, tmpmask, tlbt->addr))
+ return (1);
+ }
+
+ return (0);
+}
+
+
+/*
+ * Walk the cache table and update entries if needed.
+ * Mark entries for reload to kernel, if somehow their
+ * template changed.
+ */
+static int
+walk_cache_table_v6(in6_addr_t newaddr, char *name, int indx, tnd_tnrhdb_t *src)
+{
+ int i;
+ tnrh_tlb_ipv6_t *tlbt;
+ int rflag = 0;
+
+ for (i = 0; i < TNRH_TABLE_HASH_SIZE; i++) {
+ tlbt = tnrh_cache_table_v6[i];
+
+ while (tlbt != NULL) {
+ if (is_better_match_v6(newaddr, indx, tlbt)) {
+ tlbt->masklen_used = indx;
+ tlbt->src = src;
+ /*
+ * Reload to the kernel only if the
+ * host type changed. There is no need
+ * to load, if only the mask used has changed,
+ * since the kernel does not need that
+ * information.
+ */
+ if (strcmp(name, tlbt->template_name) != 0) {
+ (void) strncpy(tlbt->template_name,
+ name, TNTNAMSIZ-1);
+ tlbt->reload = TNDB_LOAD;
+ rflag ++;
+ }
+ }
+
+ tlbt = tlbt->next;
+ }
+ }
+
+ return (rflag);
+}
+
+/*
+ * load/delete marked rh ents into kernel
+ * depending on the reload flag by invoking tnrh().
+ * It will mark other entries as TNDB_NOOP
+ */
+static void
+load_rh_marked()
+{
+ int i;
+ tnrh_tlb_t *tlbt, *prev;
+ struct tsol_rhent rhentp;
+
+ (void) memset((char *)&rhentp, '\0', sizeof (rhentp));
+
+ for (i = 0; i < TNRH_TABLE_HASH_SIZE; i++) {
+
+ prev = tlbt = tnrh_cache_table[i];
+
+ while (tlbt != NULL) {
+ if ((tlbt->reload == TNDB_LOAD) ||
+ (tlbt->reload == TNDB_DELETE)) {
+ /*
+ * We have to call tnrh() with tsol_rhent argument.
+ * Construct such a struct from the tlbt struct we have.
+ */
+ rhentp.rh_address.ip_addr_v4.sin_addr.s_addr =
+ tlbt->addr;
+ rhentp.rh_address.ip_addr_v4.sin_family =
+ AF_INET;
+ rhentp.rh_prefix = tlbt->masklen_used;
+ (void) strcpy(rhentp.rh_template,
+ tlbt->template_name);
+
+#ifdef DEBUG
+ (void) fprintf(logf, "load op =%d\n",
+ tlbt->reload);
+ print_tlbt(tlbt);
+#endif
+ update_rh_entry(tlbt->reload, &rhentp);
+
+ if (tlbt->reload == TNDB_DELETE) {
+ if (tlbt == tnrh_cache_table[i]) {
+ tnrh_cache_table[i] =
+ tlbt->next;
+ prev = tnrh_cache_table[i];
+ } else {
+ prev->next = tlbt->next;
+ prev = prev->next;
+ }
+
+ free(tlbt);
+ if (prev == NULL)
+ break;
+ else {
+ tlbt = prev;
+ continue;
+ }
+ }
+ tlbt->reload = TNDB_NOOP;
+ }
+
+ prev = tlbt;
+ tlbt = tlbt->next;
+ }
+ }
+
+}
+
+/* load marked rh ents into kernel */
+static void
+load_rh_marked_v6()
+{
+ int i;
+ tnrh_tlb_ipv6_t *tlbt, *prev;
+ struct tsol_rhent rhentp;
+
+ (void) memset((char *)&rhentp, '\0', sizeof (rhentp));
+
+ for (i = 0; i < TNRH_TABLE_HASH_SIZE; i++) {
+ prev = tlbt = tnrh_cache_table_v6[i];
+
+ while (tlbt != NULL) {
+ if ((tlbt->reload == TNDB_LOAD) ||
+ (tlbt->reload == TNDB_DELETE)) {
+ /*
+ * We have to call tnrh() with tsol_rhent argument.
+ * Construct such a struct from the tlbt struct we have.
+ */
+ (void) memcpy(&rhentp.rh_address.ip_addr_v6.sin6_addr,
+ &tlbt->addr, sizeof (in6_addr_t));
+ rhentp.rh_address.ip_addr_v6.sin6_family = AF_INET6;
+ rhentp.rh_prefix = tlbt->masklen_used;
+ (void) strcpy(rhentp.rh_template, tlbt->template_name);
+
+ update_rh_entry(tlbt->reload, &rhentp);
+
+ if (tlbt->reload == TNDB_DELETE) {
+ if (tlbt == tnrh_cache_table_v6[i]) {
+ tnrh_cache_table_v6[i] =
+ tlbt->next;
+ prev = tnrh_cache_table_v6[i];
+ } else {
+ prev->next = tlbt->next;
+ prev = prev->next;
+ }
+
+ free(tlbt);
+ if (prev == NULL)
+ break;
+ else {
+ tlbt = prev;
+ continue;
+ }
+ }
+ tlbt->reload = TNDB_NOOP;
+ }
+
+ prev = tlbt;
+ tlbt = tlbt->next;
+ }
+ }
+
+}
+
+/*
+ * Does the real load/delete for the entry depending on op code.
+ */
+
+static void
+update_rh_entry(int op, struct tsol_rhent *rhentp)
+{
+#ifdef DEBUG
+ (void) fprintf(logf, gettext("\t###update_rh_entry op = %d\n"), op);
+ print_entry(rhentp, AF_INET);
+#endif
+ if (tnrh(op, rhentp) != 0) {
+ if (debugl && (logf != NULL)) {
+ (void) fprintf(logf, "%s : ", gettime());
+ (void) fprintf(logf, gettext("tnrh() failed: %s\n"),
+ strerror(errno));
+ if (op == TNDB_LOAD)
+ (void) fprintf(logf,
+ gettext("load of remote host database "
+ "%s into kernel cache failed\n"),
+ rhentp->rh_template);
+ if (op == TNDB_DELETE)
+ (void) fprintf(logf,
+ gettext("delete of remote host database "
+ "%s from kernel cache failed\n"),
+ rhentp->rh_template);
+ (void) fflush(logf);
+ }
+ cprint("tnrh() failed..: %s\n", strerror(errno));
+ }
+}
+
+static void
+timer()
+{
+ poll_now();
+ (void) alarm(poll_interval);
+}
+
+#define max(a, b) ((a) > (b) ? (a) : (b))
+
+static void
+poll_now()
+{
+
+ (void) fprintf(logf, "enter poll_now at %s \n", gettime());
+ (void) fflush(logf);
+
+ if (nss_get_tp() > 0) {
+ load_tp();
+ tp_flush_cache();
+ }
+
+#ifdef DEBUG
+ (void) fprintf(logf, "now search for tnrhdb update %s \n", gettime());
+#endif
+
+ if (nss_get_rh() > 0) {
+ if (logf != NULL) {
+ (void) fprintf(logf, "tnrhdb needs update %s \n",
+ gettime());
+ }
+
+ (void) rw_wrlock(&cache_rwlp);
+ /* This function will cleanup cache table */
+ load_rh_marked();
+ (void) rw_unlock(&cache_rwlp);
+
+ (void) rw_wrlock(&cache_rwlp_v6);
+ /* This function will cleanup cache table */
+ load_rh_marked_v6();
+ (void) rw_unlock(&cache_rwlp_v6);
+ }
+
+#ifdef DEBUG
+ if (logf != NULL) {
+ cachetable_print();
+ cachetable_print_v6();
+
+ (void) fprintf(logf, "rh table begin\n");
+ rhtable_print();
+ rhtable_print_v6();
+ (void) fprintf(logf, "rh table end \n");
+ (void) fprintf(logf, "-------------------------\n\n");
+ (void) fflush(logf);
+ }
+#endif
+}
+
+static void
+tnd_serve()
+{
+ for (;;) {
+ (void) pause();
+ }
+}
+
+static void
+terminate()
+{
+ if (debugl && (logf != NULL)) {
+ (void) fprintf(logf, "%s : ", gettime());
+ (void) fprintf(logf, gettext("tnd terminating on signal.\n"));
+ (void) fflush(logf);
+ }
+ exit(1);
+}
+
+static void
+noop()
+{
+}
+
+static char *
+gettime()
+{
+ time_t now;
+ struct tm *tp, tm;
+ char *fmt;
+
+ (void) time(&now);
+ tp = localtime(&now);
+ (void) memcpy(&tm, tp, sizeof (struct tm));
+ fmt = nl_langinfo(_DATE_FMT);
+
+ (void) strftime(time_buf, _SZ_TIME_BUF, fmt, &tm);
+
+ return (time_buf);
+}
+/*
+ * debugging routines
+ */
+
+
+#ifdef DEBUG
+static void
+print_cache_entry(tnrh_tlb_t *tlbt)
+{
+ struct in_addr addr;
+
+ addr.s_addr = tlbt->addr;
+ (void) fprintf(logf, "\tIP address: %s", inet_ntoa(addr));
+ (void) fprintf(logf, "\tTemplate name: %s", tlbt->template_name);
+ (void) fprintf(logf, "\tMask length used: %d\n", tlbt->masklen_used);
+}
+
+static void
+print_cache_entry_v6(tnrh_tlb_ipv6_t *tlbt)
+{
+ char abuf[INET6_ADDRSTRLEN];
+
+ (void) fprintf(logf, "\tIP address: %s",
+ inet_ntop(AF_INET6, &tlbt->addr, abuf, sizeof (abuf)));
+ (void) fprintf(logf, "\tTemplate name: %s", tlbt->template_name);
+ (void) fprintf(logf, "\tMask length used: %d\n", tlbt->masklen_used);
+}
+
+static void
+cachetable_print()
+{
+ int i;
+ tnrh_tlb_t *tlbt;
+
+ (void) fprintf(logf, "-------------------------\n");
+ (void) fprintf(logf, "Cache table begin\n");
+
+ for (i = 0; i < TNRH_TABLE_HASH_SIZE; i++) {
+ if ((tlbt = tnrh_cache_table[i]) != NULL)
+ print_cache_entry(tlbt);
+ }
+
+ (void) fprintf(logf, "Cache table end \n");
+ (void) fprintf(logf, "-------------------------\n\n");
+}
+
+static void
+cachetable_print_v6()
+{
+ int i;
+ tnrh_tlb_ipv6_t *tlbt;
+
+ (void) fprintf(logf, "-------------------------\n");
+ (void) fprintf(logf, "Cache table begin\n");
+
+ for (i = 0; i < TNRH_TABLE_HASH_SIZE; i++) {
+ if ((tlbt = tnrh_cache_table_v6[i]) != NULL)
+ print_cache_entry_v6(tlbt);
+ }
+
+ (void) fprintf(logf, "Cache table end \n");
+ (void) fprintf(logf, "-------------------------\n\n");
+}
+
+
+static void
+print_entry(tsol_rhent_t *ent, int af)
+{
+ struct sockaddr_in *saddrp;
+ struct sockaddr_in6 *saddrp6;
+ char abuf[INET6_ADDRSTRLEN];
+
+ if (af == AF_INET) {
+ saddrp = (struct sockaddr_in *)&ent->rh_address.ip_addr_v4;
+ (void) fprintf(logf, gettext("\tIP address: %s"),
+ inet_ntoa(saddrp->sin_addr));
+ } else if (af == AF_INET6) {
+ saddrp6 = (struct sockaddr_in6 *)&ent->rh_address.ip_addr_v6;
+ (void) fprintf(logf, gettext("\tIP address: %s"),
+ inet_ntop(AF_INET6, &saddrp6->sin6_addr, abuf,
+ sizeof (abuf)));
+ }
+
+ (void) fprintf(logf,
+ gettext("\tTemplate name: %s"), ent->rh_template);
+ (void) fprintf(logf, gettext("\tprefix_len: %d\n"), ent->rh_prefix);
+ (void) fflush(logf);
+}
+
+static void
+print_tlbt(tnrh_tlb_t *tlbt)
+{
+ (void) fprintf(logf, "tlbt addr = 0x%4x name = %s \
+ mask = %u, reload = %d\n", tlbt->addr, tlbt->template_name,
+ tlbt->masklen_used, tlbt->reload);
+}
+
+static void
+rhtable_print()
+{
+ rhtable_walk(print_entry);
+ (void) fprintf(logf, "-----------------------------\n\n");
+}
+
+static void
+rhtable_print_v6()
+{
+ rhtable_walk_v6(print_entry);
+ (void) fprintf(logf, "-----------------------------\n\n");
+}
+
+/*
+ * Walk through all the entries in tnrh_entire_table[][]
+ * and execute the function passing the entry as argument.
+ */
+static void
+rhtable_walk(void (*action)())
+{
+ int i, j;
+ tnd_tnrhdb_t *rhent;
+
+ for (i = 0; i <= IP_ABITS; i++) {
+ if (tnrh_entire_table[i] == NULL)
+ continue;
+
+ for (j = 0; j < TNRH_TABLE_HASH_SIZE; j++) {
+ rhent = tnrh_entire_table[i][j];
+
+ while (rhent != NULL) {
+ action(&rhent->rh_ent, AF_INET);
+ rhent = rhent->rh_next;
+ }
+ }
+ }
+}
+
+/*
+ * Walk through all the entries in tnrh_entire_table_v6[][]
+ * and execute the function passing the entry as argument.
+ */
+static void
+rhtable_walk_v6(void (*action)())
+{
+ int i, j;
+ tnd_tnrhdb_t *rhent;
+
+ for (i = 0; i <= IPV6_ABITS; i++) {
+ if (tnrh_entire_table_v6[i] == NULL)
+ continue;
+
+ for (j = 0; j < TNRH_TABLE_HASH_SIZE; j++) {
+ rhent = tnrh_entire_table_v6[i][j];
+
+ while (rhent != NULL) {
+ action(&rhent->rh_ent, AF_INET6);
+ rhent = rhent->rh_next;
+ }
+ }
+ }
+}
+#endif /* DEBUG */
diff --git a/usr/src/cmd/tsol/tnd/tnd.h b/usr/src/cmd/tsol/tnd/tnd.h
new file mode 100644
index 0000000000..13ddb62d52
--- /dev/null
+++ b/usr/src/cmd/tsol/tnd/tnd.h
@@ -0,0 +1,138 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _TND_H_
+#define _TND_H_
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * TSOL Messages have the following header
+ */
+
+typedef struct {
+ uchar_t tnd_version; /* protocol version number */
+ uchar_t tnd_message; /* message type. */
+ uchar_t tnd_error_code; /* Error return for a reply. */
+} tsol_tnd_hdr_t;
+
+/*
+ * TND TSOL messages
+ */
+
+#define TND_DEBUG_REQ 127
+#define TND_POLL_REQ 128
+#define TND_REPLY 129
+
+/*
+ * TND errors
+ */
+
+#define TND_SUCCESS 1
+#define TND_FAIL_LOG 2
+#define TND_FAIL_DEBUG_LEVEL 4
+#define TND_NOT_SUPPORTED 8
+#define TND_DENIED 16
+
+/* TND door files */
+#define TND_DOORFILE "/etc/.tnd_door"
+#define TND_DOORFILE2 "/etc/.tnd_door2"
+
+/*
+ * tnd request messages have the following format
+ */
+
+struct tsol_tnd_msg {
+ tsol_tnd_hdr_t ttm_hdr; /* message header */
+ uint_t ttm_int; /* debug level or poll interval(in seconds) */
+};
+
+#define TNDLOG "/var/tsol/tndlog"
+#define MAX_TND_DEBUG 2
+#define DEF_TND_DEBUG 1
+
+#define HNAMELEN 64
+
+/*
+ * polling default (seconds)
+ */
+#define TND_DEF_POLL_TIME 1800 /* 30 minutes */
+
+/* tnrhtp_c cache structure */
+struct tnd_tnrhtp_c {
+ tsol_tpent_t tp_ent;
+ struct tnd_tnrhtp_c *tp_next;
+};
+
+/* tnrhdb_c cache structure */
+typedef struct tnd_tnrhdb_c {
+ tsol_rhent_t rh_ent;
+ int visited; /* Flag to handle deletions */
+ struct tnd_tnrhdb_c *rh_next;
+} tnd_tnrhdb_t;
+
+/* tnrhdb lookup table */
+typedef struct tnrh_tlb {
+ in_addr_t addr;
+ char template_name[TNTNAMSIZ];
+ int reload; /* flag to reload/delete */
+ int masklen_used; /* Which mask did we use */
+ tnd_tnrhdb_t *src; /* Which table entry is our source */
+ struct tnrh_tlb *next; /* Next in the hash chain */
+} tnrh_tlb_t;
+
+/* tnrhdb IPv6 address lookup table */
+typedef struct tnrh_tlb_ipv6 {
+ in6_addr_t addr;
+ char template_name[TNTNAMSIZ];
+ int reload; /* flag to reload/delete */
+ int masklen_used; /* Which mask did we use */
+ tnd_tnrhdb_t *src; /* Which table entry is our source */
+ struct tnrh_tlb_ipv6 *next; /* Next in the hash chain */
+} tnrh_tlb_ipv6_t;
+
+/* Clients of tnd can use this structure */
+typedef struct {
+ struct tsol_rhent rh;
+ union {
+ in_addr_t _v4addr;
+ in6_addr_t _v6addr;
+ } _addr_un;
+ sa_family_t af;
+ int flag; /* flag to reload/delete */
+} tndclnt_arg_t;
+#define v4addr _addr_un._v4addr
+#define v6addr _addr_un._v6addr
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TND_H_ */
diff --git a/usr/src/cmd/tsol/tnd/tnd.xml b/usr/src/cmd/tsol/tnd/tnd.xml
new file mode 100644
index 0000000000..7bcec09138
--- /dev/null
+++ b/usr/src/cmd/tsol/tnd/tnd.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ ident "%Z%%M% %I% %E% SMI"
+-->
+
+<service_bundle type='manifest' name='SUNWtsg:tnd'>
+
+<service
+ name='network/tnd'
+ type='service'
+ version='1'>
+
+ <create_default_instance enabled='false' />
+
+ <single_instance/>
+
+ <dependency
+ name='usr'
+ type='service'
+ grouping='require_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/filesystem/minimal' />
+ </dependency>
+
+ <dependency
+ name='tnctl'
+ type='service'
+ grouping='require_all'
+ restart_on='restart'>
+ <service_fmri value='svc:/network/tnctl' />
+ </dependency>
+
+ <dependency
+ name='name-service-cache'
+ type='service'
+ grouping='require_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/name-service-cache' />
+ </dependency>
+
+ <dependency
+ name='network-ldap-client'
+ type='service'
+ grouping='require_all'
+ restart_on='none'>
+ <service_fmri value='svc:/network/ldap/client' />
+ </dependency>
+
+ <exec_method
+ type='method'
+ name='start'
+ exec='/lib/svc/method/svc-tnd'
+ timeout_seconds='60' />
+
+ <exec_method
+ type='method'
+ name='stop'
+ exec=':kill -TERM'
+ timeout_seconds='60' />
+
+ <exec_method
+ type='method'
+ name='refresh'
+ exec=':kill -HUP'
+ timeout_seconds='60' />
+
+ <property_group name='general' type='framework'>
+ <propval name='action_authorization' type='astring'
+ value='solaris.smf.manage.tnd' />
+ </property_group>
+ <property_group name='tnd' type='application'>
+ <propval
+ name='debug_level'
+ type='integer'
+ value='0' />
+ <propval
+ name='debug_file'
+ type='astring'
+ value='/var/tsol/tndlog' />
+ <propval
+ name='poll_interval'
+ type='integer'
+ value='1800' />
+ <propval
+ name='value_authorization'
+ type='astring'
+ value='solaris.smf.value.tnd' />
+ </property_group>
+
+ <stability value='Unstable' />
+
+ <template>
+ <common_name>
+ <loctext xml:lang='C'> trusted networking templates
+ </loctext>
+ </common_name>
+ <documentation>
+ <manpage title='tnd' section='1M'
+ manpath='/usr/share/man' />
+ </documentation>
+ </template>
+</service>
+
+</service_bundle>
diff --git a/usr/src/cmd/tsol/tninfo/Makefile b/usr/src/cmd/tsol/tninfo/Makefile
new file mode 100644
index 0000000000..cf5fb03084
--- /dev/null
+++ b/usr/src/cmd/tsol/tninfo/Makefile
@@ -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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# cmd/tsol/tnctl/Makefile
+#
+PROG= tninfo
+
+POFILES= $(PROG).po
+
+include ../../Makefile.cmd
+
+CFLAGS += -I../tnctl
+LDLIBS += -lnsl -ltsnet -ltsol -lsocket
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all $(ROOTUSRSBINPROG)
+
+clean:
+ $(RM) $(OBJS) tags
+
+lint: lint_PROG
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/tsol/tninfo/tninfo.c b/usr/src/cmd/tsol/tninfo/tninfo.c
new file mode 100644
index 0000000000..5b153ba883
--- /dev/null
+++ b/usr/src/cmd/tsol/tninfo/tninfo.c
@@ -0,0 +1,339 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * tninfo.c - Trusted network reporting utility
+ */
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#include <locale.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libtsnet.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <tsol/label.h>
+#include <zone.h>
+
+/* maximum string size desired as returned by sb*tos calls */
+#define MAX_STRING_SIZE 60
+
+static void usage(void);
+static int print_rhtp(const char *);
+static int print_rh(const char *);
+static int print_mlp(const char *);
+
+int
+main(int argc, char *argv[])
+{
+ int chr;
+ int ret = 0; /* return code */
+
+ /* set the locale for only the messages system (all else is clean) */
+ (void) setlocale(LC_ALL, "");
+#ifndef TEXT_DOMAIN /* Should be defined by cc -D */
+#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
+#endif
+
+ (void) textdomain(TEXT_DOMAIN);
+
+ if (argc <= 1)
+ usage();
+
+ while ((chr = getopt(argc, argv, "h:m:t:")) != EOF) {
+ switch (chr) {
+ case 'h':
+ ret |= print_rh(optarg);
+ break;
+ case 'm':
+ ret |= print_mlp(optarg);
+ break;
+ case 't':
+ ret |= print_rhtp(optarg);
+ break;
+ default:
+ usage();
+ }
+ }
+
+ return (ret);
+}
+
+static void
+usage(void)
+{
+ (void) fprintf(stderr, gettext("usage: tninfo [-h host_name] "
+ "[-m zone_name] [-t template_name]\n"));
+ exit(1);
+}
+
+static int
+print_rhtp(const char *rhtp_name)
+{
+ tsol_tpent_t tp;
+ const char *str, *str2;
+ const bslabel_t *l1, *l2;
+ int i;
+
+ (void) strlcpy(tp.name, rhtp_name, sizeof (tp.name));
+
+ if (tnrhtp(TNDB_GET, &tp) != 0) {
+ if (errno == ENOENT)
+ (void) fprintf(stderr, gettext("tninfo: tnrhtp entry "
+ "%1$s does not exist\n"), tp.name);
+ else
+ (void) fprintf(stderr,
+ gettext("tninfo: tnrhtp TNDB_GET(%1$s) failed: "
+ "%2$s\n"), tp.name, strerror(errno));
+ return (1);
+ }
+
+ (void) printf("=====================================\n");
+ (void) printf(gettext("Remote Host Template Table Entries:\n"));
+
+ (void) printf("__________________________\n");
+ (void) printf(gettext("template: %s\n"), tp.name);
+
+ switch (tp.host_type) {
+ case UNLABELED:
+ (void) printf(gettext("host_type: UNLABELED\n"));
+ (void) printf(gettext("doi: %d\n"), tp.tp_doi);
+
+ if (tp.tp_mask_unl & TSOL_MSK_DEF_LABEL) {
+ str = sbsltos(&tp.tp_def_label, MAX_STRING_SIZE);
+ if (str == NULL)
+ str = gettext("translation failed");
+ str2 = bsltoh(&tp.tp_def_label);
+ if (str2 == NULL)
+ str2 = gettext("translation failed");
+ (void) printf(gettext("def_label: %s\nhex: %s\n"),
+ str, str2);
+ }
+
+ if (tp.tp_mask_unl & TSOL_MSK_SL_RANGE_TSOL) {
+ (void) printf(gettext("For routing only:\n"));
+ str = sbsltos(&tp.tp_gw_sl_range.lower_bound,
+ MAX_STRING_SIZE);
+ if (str == NULL)
+ str = gettext("translation failed");
+ str2 = bsltoh(&tp.tp_gw_sl_range.lower_bound);
+ if (str2 == NULL)
+ str2 = gettext("translation failed");
+ (void) printf(gettext("min_sl: %s\nhex: %s\n"),
+ str, str2);
+
+ str = sbsltos(&tp.tp_gw_sl_range.upper_bound,
+ MAX_STRING_SIZE);
+ if (str == NULL)
+ str = gettext("translation failed");
+ str2 = bsltoh(&tp.tp_gw_sl_range.upper_bound);
+ if (str2 == NULL)
+ str2 = gettext("translation failed");
+ (void) printf(gettext("max_sl: %s\nhex: %s\n"),
+ str, str2);
+
+ l1 = (const blevel_t *)&tp.tp_gw_sl_set[0];
+ l2 = (const blevel_t *)&tp.tp_gw_sl_set[NSLS_MAX];
+ for (i = 0; l1 < l2; l1++, i++) {
+ if (bisinvalid(l1))
+ break;
+ str = sbsltos(l1, MAX_STRING_SIZE);
+ if (str == NULL)
+ str = gettext("translation failed");
+ if ((str2 = bsltoh(l1)) == NULL)
+ str2 = gettext("translation failed");
+ (void) printf(gettext("sl_set[%1$d]: %2$s\n"
+ "hex: %3$s\n"), i, str, str2);
+ }
+ }
+ break;
+
+ case SUN_CIPSO:
+ (void) printf(gettext("host_type: CIPSO\n"));
+ (void) printf(gettext("doi: %d\n"), tp.tp_doi);
+ if (tp.tp_mask_cipso & TSOL_MSK_SL_RANGE_TSOL) {
+ str = sbsltos(&tp.tp_sl_range_cipso.lower_bound,
+ MAX_STRING_SIZE);
+ if (str == NULL)
+ str = gettext("translation failed");
+ str2 = bsltoh(&tp.tp_sl_range_cipso.lower_bound);
+ if (str2 == NULL)
+ str2 = gettext("translation failed");
+ (void) printf(gettext("min_sl: %s\nhex: %s\n"),
+ str, str2);
+ str = sbsltos(&tp.tp_sl_range_cipso.upper_bound,
+ MAX_STRING_SIZE);
+ if (str == NULL)
+ str = gettext("translation failed");
+ str2 = bsltoh(&tp.tp_sl_range_cipso.upper_bound);
+ if (str2 == NULL)
+ str2 = gettext("translation failed");
+ (void) printf(gettext("max_sl: %s\nhex: %s\n"),
+ str, str2);
+
+ l1 = (const blevel_t *)&tp.tp_sl_set_cipso[0];
+ l2 = (const blevel_t *)&tp.tp_sl_set_cipso[NSLS_MAX];
+ for (i = 0; l1 < l2; l1++, i++) {
+ if (bisinvalid(l1))
+ break;
+ str = sbsltos(l1, MAX_STRING_SIZE);
+ if (str == NULL)
+ str = gettext("translation failed");
+ if ((str2 = bsltoh(l1)) == NULL)
+ str2 = gettext("translation failed");
+ (void) printf(gettext("sl_set[%1$d]: %2$s\n"
+ "hex: %3$s\n"), i, str, str2);
+ }
+ }
+ break;
+
+ default:
+ (void) printf(gettext("unsupported host type: %ld\n"),
+ tp.host_type);
+ }
+ return (0);
+}
+
+static int
+print_rh(const char *rh_name)
+{
+ int herr;
+ struct hostent *hp;
+ in6_addr_t in6;
+ char abuf[INET6_ADDRSTRLEN];
+ tsol_rhent_t rhent;
+
+ if ((hp = getipnodebyname(rh_name, AF_INET6,
+ AI_ALL | AI_ADDRCONFIG | AI_V4MAPPED, &herr)) == NULL) {
+ (void) fprintf(stderr, gettext("tninfo: unknown host or "
+ "invalid literal address: %s\n"), rh_name);
+ if (herr == TRY_AGAIN)
+ (void) fprintf(stderr,
+ gettext("\t(try again later)\n"));
+ return (1);
+ }
+
+ (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));
+ }
+
+ (void) printf(gettext("IP address= %s\n"), abuf);
+
+ if (tnrh(TNDB_GET, &rhent) != 0) {
+ if (errno == ENOENT)
+ (void) fprintf(stderr, gettext("tninfo: tnrhdb entry "
+ "%1$s does not exist\n"), abuf);
+ else
+ (void) fprintf(stderr, gettext("tninfo: TNDB_GET(%1$s) "
+ "failed: %2$s\n"), abuf, strerror(errno));
+ return (1);
+ }
+
+ if (rhent.rh_template[0] != '\0')
+ (void) printf(gettext("Template = %.*s\n"), TNTNAMSIZ,
+ rhent.rh_template);
+ else
+ (void) printf(gettext("No template exists.\n"));
+
+ return (0);
+}
+
+static int
+iterate_mlps(tsol_mlpent_t *tsme, const char *type)
+{
+ struct protoent *pe;
+
+ /* get the first entry */
+ tsme->tsme_mlp.mlp_ipp = 0;
+ tsme->tsme_mlp.mlp_port = 0;
+ tsme->tsme_mlp.mlp_port_upper = 0;
+ if (tnmlp(TNDB_GET, tsme) == -1) {
+ if (errno == ENOENT) {
+ (void) printf(gettext("%s: no entries\n"), type);
+ return (0);
+ } else {
+ perror("tnmlp TNDB_GET");
+ return (-1);
+ }
+ }
+ (void) printf("%s: ", type);
+ for (;;) {
+ (void) printf("%u", tsme->tsme_mlp.mlp_port);
+ if (tsme->tsme_mlp.mlp_port != tsme->tsme_mlp.mlp_port_upper)
+ (void) printf("-%u", tsme->tsme_mlp.mlp_port_upper);
+ if ((pe = getprotobynumber(tsme->tsme_mlp.mlp_ipp)) == NULL)
+ (void) printf("/%u", tsme->tsme_mlp.mlp_ipp);
+ else
+ (void) printf("/%s", pe->p_name);
+ if (tsme->tsme_mlp.mlp_ipp == 255) {
+ tsme->tsme_mlp.mlp_port++;
+ tsme->tsme_mlp.mlp_ipp = 0;
+ } else {
+ tsme->tsme_mlp.mlp_ipp++;
+ }
+ if (tnmlp(TNDB_GET, tsme) == -1)
+ break;
+ (void) putchar(';');
+ }
+ (void) putchar('\n');
+ return (0);
+}
+
+/*
+ * Print all of the MLPs for the given zone.
+ */
+static int
+print_mlp(const char *zonename)
+{
+ tsol_mlpent_t tsme;
+
+ if ((tsme.tsme_zoneid = getzoneidbyname(zonename)) == -1) {
+ (void) fprintf(stderr, gettext("tninfo: zone '%s' unknown\n"),
+ zonename);
+ return (1);
+ }
+ tsme.tsme_flags = 0;
+ if (iterate_mlps(&tsme, gettext("private")) == -1)
+ return (1);
+ tsme.tsme_flags = TSOL_MEF_SHARED;
+ if (iterate_mlps(&tsme, gettext("shared")) == -1)
+ return (1);
+ return (0);
+}
diff --git a/usr/src/cmd/tsol/tsol-zones/Makefile b/usr/src/cmd/tsol/tsol-zones/Makefile
new file mode 100644
index 0000000000..9c88e42dec
--- /dev/null
+++ b/usr/src/cmd/tsol/tsol-zones/Makefile
@@ -0,0 +1,65 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# Makefile for tsol-zones service
+#
+
+##PROG= nscd
+MANIFEST= tsol-zones.xml
+SVCMETHOD= svc-tsol-zones
+
+include ../../Makefile.cmd
+
+ROOTMANIFESTDIR= $(ROOTSVCSYSTEM)
+$(ROOTMANIFEST) := FILEMODE= 444
+
+$(ROOTMANIFESTDIR)/%: %
+ $(INS.file)
+
+
+# install macros and rule
+#
+GROUP= bin
+
+.KEEP_STATE:
+
+all:
+
+lint:
+
+cstyle:
+
+install: all $(ROOTMANIFEST) $(ROOTSVCMETHOD)
+
+check: $(CHKMANIFEST)
+
+clean:
+
+
+include ../Makefile.targ
+
+
+
diff --git a/usr/src/cmd/tsol/tsol-zones/svc-tsol-zones b/usr/src/cmd/tsol/tsol-zones/svc-tsol-zones
new file mode 100644
index 0000000000..6c7a10787c
--- /dev/null
+++ b/usr/src/cmd/tsol/tsol-zones/svc-tsol-zones
@@ -0,0 +1,45 @@
+#!/sbin/sh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+#
+# This is a transient dummy service for Trusted Solaris. It's function is
+# to disable selected services so they will not be started in labeled zones.
+#
+
+. /lib/svc/share/smf_include.sh
+
+if [ `/sbin/zonename` = "global" ]; then
+
+ # In the global zone, there's nothing to do so this service exits.
+ /usr/sbin/svcadm disable $SMF_FMRI || exit 1
+
+fi
+
+# Disable any services here (remember to add dependencies to the
+# tsol-zones XML manifest) ...
+
+
+exit $SMF_EXIT_OK
diff --git a/usr/src/cmd/tsol/tsol-zones/tsol-zones.xml b/usr/src/cmd/tsol/tsol-zones/tsol-zones.xml
new file mode 100644
index 0000000000..7e0340f6fc
--- /dev/null
+++ b/usr/src/cmd/tsol/tsol-zones/tsol-zones.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ ident "%Z%%M% %I% %E% SMI"
+-->
+
+<service_bundle type='manifest' name='SUNWtsr:tsol-zones'>
+
+<service
+ name='system/tsol-zones'
+ type='service'
+ version='1'>
+
+ <create_default_instance enabled='false' />
+
+ <single_instance />
+
+ <dependency
+ name='filesystem'
+ grouping='require_all'
+ restart_on='none'
+ type='service'>
+ <service_fmri value='svc:/system/filesystem/minimal' />
+ </dependency>
+
+ <exec_method
+ type='method'
+ name='start'
+ exec='/lib/svc/method/svc-tsol-zones'
+ timeout_seconds='60' />
+
+ <exec_method
+ type='method'
+ name='stop'
+ exec=':true'
+ timeout_seconds='60' />
+
+ <property_group name='startd' type='framework'>
+ <propval name='duration' type='astring' value='transient' />
+ </property_group>
+
+ <stability value='Unstable' />
+
+ <template>
+ <common_name>
+ <loctext xml:lang='C'>
+ Trusted Solaris labeled zone services setup
+ </loctext>
+ </common_name>
+ <documentation>
+ <manpage
+ title='tsol'
+ section='5'
+ manpath='/usr/man' />
+ </documentation>
+ </template>
+
+</service>
+
+</service_bundle>
diff --git a/usr/src/cmd/tsol/updatehome/Makefile b/usr/src/cmd/tsol/updatehome/Makefile
new file mode 100644
index 0000000000..ed3ca8c04b
--- /dev/null
+++ b/usr/src/cmd/tsol/updatehome/Makefile
@@ -0,0 +1,57 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# cmd/tsol/updatehome
+#
+PROG= updatehome
+
+include ../../Makefile.cmd
+
+OBJS= setupfiles.o updatehome.o
+SRCS= $(OBJS:%.o=%.c)
+
+LDLIBS += -ltsol -lsecdb
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $@ $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+install: all $(ROOTPROG)
+
+clean:
+ $(RM) $(OBJS)
+
+lint: lint_SRCS
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/tsol/updatehome/setupfiles.c b/usr/src/cmd/tsol/updatehome/setupfiles.c
new file mode 100644
index 0000000000..280c6cf6f9
--- /dev/null
+++ b/usr/src/cmd/tsol/updatehome/setupfiles.c
@@ -0,0 +1,517 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+
+#include <errno.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <tsol/label.h>
+#include <zone.h>
+#include <sys/stat.h>
+
+#include "setupfiles.h"
+
+#define dperror(s) if (flags & DIAG) perror(s)
+#define dprintf(s, v) if (flags & DBUG) (void) printf(s, v)
+#define dprintf2(s, v1, v2) if (flags & DBUG) (void) printf(s, v1, v2)
+
+static int mkdirs(const char *dir, const char *target, int flags);
+static int copyfile(const char *min_home, const char *home, const char *target,
+ int flags);
+static int linkfile(const char *min_home, const char *home, const char *target,
+ int flags);
+
+
+/*
+ * __setupfiles - Process copy and link files directions in min $HOME.
+ *
+ * Entry pwd = user's password file entry.
+ * min_sl = user's minimum SL.
+ * flags = DBUG, if print debug messages.
+ * DIAG, if print diagnostics (perrors).
+ * IGNE, continue rather than abort on failures.
+ * REPC, if replace existing file.
+ * REPL, if replace existing symbolic link.
+ * process is running as user at correct label.
+ *
+ * Exit None.
+ *
+ * Returns 0, if success.
+ * errno, if failure.
+ *
+ * Uses COPY, CP, LINK, MAXPATHLEN.
+ *
+ * Calls blequal, copyfile, feof, fgets, fopen, getcmwplabel, stobsl,
+ * mkdirs, getzoneid, getzonelabelbyid, linkfile, strcat, strcpy,
+ * strlen.
+ *
+ * This program assumes the /zone is the autofs mountpoint for
+ * cross-zone mounts.
+ *
+ * It also assumes that the user's home directory path is the
+ * the same in each zone, relative to the zone's root.
+ *
+ * At this point, the cross-zone automounter only supports home
+ * directories starting with /home
+ */
+
+int
+__setupfiles(const struct passwd *pwd, const bslabel_t *min_sl, int flags)
+{
+ bslabel_t *plabel; /* process label */
+ char home[MAXPATHLEN]; /* real path to current $HOME */
+ char min_home[MAXPATHLEN]; /* real path to min $HOME */
+ char cl_file[MAXPATHLEN]; /* real path to .copy/.link_files */
+ char file[MAXPATHLEN]; /* file to copy/link */
+ FILE *clf; /* .copy/.link_file stream */
+ char zoneroot[MAXPATHLEN];
+ zoneid_t zoneid;
+ zoneid_t min_zoneid;
+
+ zoneid = getzoneid();
+ if ((plabel = getzonelabelbyid(zoneid)) == NULL) {
+
+ dperror("setupfiles can't get process label");
+ return (errno);
+ }
+
+ if (blequal(plabel, min_sl)) {
+ /* at min SL no files to setup */
+
+ return (0);
+ }
+
+ /* get current home real path */
+
+ (void) strlcpy(home, pwd->pw_dir, MAXPATHLEN);
+
+ /* Get zone id from min_sl */
+
+ if ((min_zoneid = getzoneidbylabel(min_sl)) == -1) {
+
+ dperror("setupfiles can't get zoneid for min sl");
+ return (errno);
+ }
+
+ /*
+ * Since the global zone home directories aren't public
+ * information, we don't support copy and link files there.
+ */
+ if (min_zoneid == GLOBAL_ZONEID)
+ return (0);
+
+ /*
+ * Get zone root path from zone id
+ *
+ * Could have used getzonenamebyid() but this assumes that /etc/zones
+ * directory is available, which is not true in labeled zones
+ */
+
+ if (zone_getattr(min_zoneid, ZONE_ATTR_ROOT, zoneroot,
+ sizeof (zoneroot)) == -1) {
+ dperror("setupfiles can't get zone root path for min sl");
+ return (errno);
+ }
+
+ (void) snprintf(min_home, MAXPATHLEN, "%s%s",
+ zoneroot, pwd->pw_dir);
+
+ /* process copy files */
+
+ if ((strlen(min_home) + strlen(COPY)) > (MAXPATHLEN - 1)) {
+
+ dprintf("setupfiles copy path %s", min_home);
+ dprintf("%s ", COPY);
+ dprintf("greater than %d\n", MAXPATHLEN);
+ errno = ENAMETOOLONG;
+ dperror("setupfiles copy path");
+ return (errno);
+ }
+
+ (void) strcpy(cl_file, min_home);
+ (void) strcat(cl_file, COPY);
+
+ if ((clf = fopen(cl_file, "r")) != NULL) {
+
+ while (fgets(file, MAXPATHLEN, clf) != NULL) {
+
+ if (!feof(clf)) /* remove trailing \n */
+ file[strlen(file) - 1] = '\0';
+
+ dprintf("copy file %s requested\n", file);
+
+ /* make any needed subdirectories */
+
+ if (mkdirs(home, file, flags) != 0) {
+
+ if ((flags & IGNE) == 0)
+ return (errno);
+ else
+ continue;
+ }
+
+ /* copy the file */
+
+ if (copyfile(min_home, home, file, flags) != 0) {
+
+ if ((flags & IGNE) == 0)
+ return (errno);
+ else
+ continue;
+
+ }
+
+ } /* while (fgets( ... ) != NULL) */
+ } else {
+ if (errno != ENOENT)
+ dperror("setupfiles copy file open");
+ dprintf("setupfiles no copyfile %s\n", cl_file);
+ } /* process copy files */
+
+
+ /* process link files */
+
+ if ((strlen(min_home) + strlen(LINK)) > (MAXPATHLEN - 1)) {
+
+ dprintf("setupfiles link path %s", min_home);
+ dprintf("%s ", LINK);
+ dprintf("greater than %d\n", MAXPATHLEN);
+ errno = ENAMETOOLONG;
+ dperror("setupfiles link path");
+ return (errno);
+ }
+
+ (void) strcpy(cl_file, min_home);
+ (void) strcat(cl_file, LINK);
+
+ if ((clf = fopen(cl_file, "r")) != NULL) {
+
+ while (fgets(file, MAXPATHLEN, clf) != NULL) {
+
+ if (!feof(clf)) /* remove trailing \n */
+ file[strlen(file) - 1] = '\0';
+
+ dprintf("link file %s requested\n", file);
+
+ /* make any needed subdirectories */
+
+ if (mkdirs(home, file, flags) != 0) {
+
+ if ((flags & IGNE) == 0)
+ return (errno);
+ else
+ continue;
+ }
+
+ /* link the file */
+
+ if (linkfile(min_home, home, file, flags) != 0) {
+
+ if ((flags & IGNE) == 0)
+ return (errno);
+ else
+ continue;
+ }
+
+ } /* while (fgets ... ) != NULL) */
+ } else {
+ if (errno != ENOENT)
+ dperror("setupfiles link file open");
+ dprintf("setupfiles no linkfile %s\n", cl_file);
+ } /* process link files */
+
+ return (0);
+} /* setupfiles() */
+
+
+/*
+ * mkdirs - Make any needed subdirectories in target's path.
+ *
+ * Entry home = base directory.
+ * file = file to create with intermediate subdirectories.
+ * flags = from __setupfiles -- for dprintf and dperror.
+ *
+ * Exit Needed subdirectories made.
+ *
+ * Returns 0, if success.
+ * errno, if failure.
+ *
+ * Uses MAXPATHLEN.
+ *
+ * Calls mkdir, strcat, strcpy, strlen, strtok.
+ */
+
+static int
+mkdirs(const char *home, const char *file, int flags)
+{
+ char path[MAXPATHLEN];
+ char dir[MAXPATHLEN];
+ char *tok;
+
+ if ((strlen(home) + strlen(file)) > (MAXPATHLEN - 2)) {
+
+ dprintf("setupfiles mkdirs path %s", home);
+ dprintf("/%s ", file);
+ dprintf("greater than %d\n", MAXPATHLEN);
+ errno = ENAMETOOLONG;
+ dperror("setupfiles mkdirs");
+ return (errno);
+ }
+
+ (void) strcpy(dir, file);
+
+ if ((tok = strrchr(dir, '/')) == NULL) {
+
+ dprintf("setupfiles no dirs to make in %s\n", dir);
+ return (0);
+ }
+
+ *tok = '\000'; /* drop last component, it's the target */
+
+ (void) strcpy(path, home);
+
+ for (tok = dir; tok = strtok(tok, "/"); tok = NULL) {
+
+ (void) strcat(path, "/");
+ (void) strcat(path, tok);
+
+ if ((mkdir(path, 0777) != 0) && (errno != EEXIST)) {
+
+ dperror("setupfiles mkdir");
+ dprintf("setupfiles mkdir path %s\n", path);
+ return (errno);
+ }
+
+ dprintf("setupfiles dir %s made or already exists\n", path);
+ }
+
+ return (0);
+} /* mkdirs() */
+
+
+/*
+ * copyfile - Copy a file from the base home directory to the current.
+ *
+ * Entry min_home = from home directory.
+ * home = current (to) home directory.
+ * target = file to copy.
+ * flags = from __setupfiles.
+ * REPC, if replace existing file.
+ *
+ * Exit File copied.
+ *
+ * Returns 0, if success.
+ * errno, if failure.
+ *
+ * Uses CP, MAXPATHLEN.
+ *
+ * Calls access, execlp, exit, lstat, strcat, strcpy, strlen, unlink,
+ * vfork, waitpid.
+ */
+
+static int
+copyfile(const char *min_home, const char *home, const char *target, int flags)
+{
+ char src[MAXPATHLEN];
+ char dest[MAXPATHLEN];
+ struct stat buf;
+ pid_t child;
+
+ /* prepare target */
+
+ if (snprintf(dest, sizeof (dest), "%s/%s", home, target) >
+ sizeof (dest) - 1) {
+ dprintf("setupfiles copy dest %s", dest);
+ dprintf("greater than %d\n", sizeof (dest));
+ errno = ENAMETOOLONG;
+ dperror("setupfiles copy to home");
+ return (errno);
+ }
+
+ if (lstat(dest, &buf) == 0) {
+ /* target exists */
+
+ if (flags & REPC) {
+ /* unlink and replace */
+
+ if (unlink(dest) != 0) {
+
+ dperror("setupfiles copy unlink");
+ dprintf("setupfiles copy unable to unlink %s\n",
+ dest);
+ return (errno);
+ }
+ } else {
+ /* target exists and is not to be replaced */
+
+ return (0);
+ }
+ } else if (errno != ENOENT) {
+ /* error on target */
+
+ dperror("setupfiles copy");
+ dprintf("setupfiles copy lstat %s\n", dest);
+ return (errno);
+ }
+
+ /* prepare source */
+
+ if (snprintf(src, sizeof (src), "%s/%s", min_home, target) >
+ sizeof (src) - 1) {
+ dprintf("setupfiles copy path %s", src);
+ dprintf("greater than %d\n", sizeof (src));
+ errno = ENAMETOOLONG;
+ dperror("setupfiles copy from home");
+ return (errno);
+ }
+
+ if (access(src, R_OK) != 0) {
+ /* can't access source */
+
+ dperror("setupfiles copy source access");
+ dprintf("setupfiles copy unable to access %s\n", src);
+ return (errno);
+ }
+
+ /* attempt the copy */
+
+ dprintf("setupfiles attempting to copy %s\n", src);
+ dprintf("\tto %s\n", dest);
+
+ if ((child = vfork()) != 0) { /* parent, wait for child status */
+ int status; /* child status */
+
+ (void) waitpid(child, &status, 0); /* wait for child */
+ dprintf("setupfiles copy child returned %x\n", status);
+ } else {
+ /* execute "cp -p min_home home" */
+
+ if (execlp(CP, CP, "-p", src, dest, 0) != 0) {
+ /* can't execute cp */
+
+ dperror("setupfiles copy exec");
+ dprintf("setupfiles copy couldn't exec \"%s -p\"\n",
+ CP);
+ exit(2);
+ }
+ }
+
+ return (0);
+} /* copyfile() */
+
+
+/*
+ * linkfile - Make a symlink from the the current directory to the base
+ * home directory.
+ *
+ * Entry min_home = from home directory.
+ * home = current (to) home directory.
+ * target = file to copy.
+ * flags = from __setupfiles.
+ * REPL, if replace existing symlink.
+ *
+ * Exit File symlinked.
+ *
+ * Returns 0, if success.
+ * errno, if failure.
+ *
+ * Uses MAXPATHLEN.
+ *
+ * Calls lstat, symlink, strcat, strcpy, strlen, unlink.
+ */
+
+static int
+linkfile(const char *min_home, const char *home, const char *target, int flags)
+{
+ char src[MAXPATHLEN];
+ char dest[MAXPATHLEN];
+ struct stat buf;
+
+ /* prepare target */
+
+ if (snprintf(dest, sizeof (dest), "%s/%s", home, target) >
+ sizeof (dest) - 1) {
+ dprintf("setupfiles link dest %s", dest);
+ dprintf("greater than %d\n", sizeof (dest));
+ errno = ENAMETOOLONG;
+ dperror("setupfiles link to home");
+ return (errno);
+ }
+
+ if (lstat(dest, &buf) == 0) {
+ /* target exists */
+
+ if (flags & REPL) {
+ /* unlink and replace */
+ if (unlink(dest) != 0) {
+ dperror("setupfiles link unlink");
+ dprintf("setupfiles link unable to unlink %s\n",
+ dest);
+ return (errno);
+ }
+ } else {
+ /* target exists and is not to be replaced */
+ return (0);
+ }
+ } else if (errno != ENOENT) {
+ /* error on target */
+ dperror("setupfiles link");
+ dprintf("setupfiles link lstat %s\n", dest);
+ return (errno);
+ }
+
+ if (snprintf(src, sizeof (src), "%s/%s", min_home, target) >
+ sizeof (src) - 1) {
+ dprintf("setupfiles link path %s", src);
+ dprintf("greater than %d\n", sizeof (src));
+ errno = ENAMETOOLONG;
+ dperror("setupfiles link from home");
+ return (errno);
+ }
+
+ /* attempt the copy */
+
+ dprintf("setupfiles attempting to link %s\n", dest);
+ dprintf("\tto %s\n", src);
+
+ if (symlink(src, dest) != 0) {
+ dperror("setupfiles link symlink");
+ dprintf("setupfiles link unable to symlink%s\n", "");
+ return (errno);
+ }
+
+ return (0);
+} /* linkfile */
diff --git a/usr/src/cmd/tsol/updatehome/setupfiles.h b/usr/src/cmd/tsol/updatehome/setupfiles.h
new file mode 100644
index 0000000000..4ee6aacfb9
--- /dev/null
+++ b/usr/src/cmd/tsol/updatehome/setupfiles.h
@@ -0,0 +1,55 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _SETUPFILES_H
+#define _SETUPFILES_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <pwd.h>
+#include <tsol/label.h>
+
+#define COPY "/.copy_files"
+#define LINK "/.link_files"
+#define CP "/usr/bin/cp"
+
+#define DBUG 0x001 /* print debug */
+#define DIAG 0x002 /* print diagnostics */
+#define IGNE 0x004 /* ignore copy/link errors */
+#define REPC 0x008 /* replace existing copies */
+#define REPL 0x010 /* replace existing links */
+
+extern int __setupfiles(const struct passwd *pwd, const bslabel_t *, int flags);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_SETUPFILES_H */
diff --git a/usr/src/cmd/tsol/updatehome/updatehome.c b/usr/src/cmd/tsol/updatehome/updatehome.c
new file mode 100644
index 0000000000..085c832aeb
--- /dev/null
+++ b/usr/src/cmd/tsol/updatehome/updatehome.c
@@ -0,0 +1,193 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * updatehome - Update the current label's $HOME copy and link files.
+ *
+ * Update home reads the user's minimum label copy and link
+ * control files (.copy_files and .link_files) which contain a list
+ * of files to be copied and symbolically linked from the user's minimum
+ * label $HOME to the user's current label's $HOME.
+ *
+ * This is done by the Trusted Solaris dtsession whenever a
+ * newly labeled workspace is created so that the user's favorite
+ * files are available for use. For example the user probably
+ * wants a symlink to .profile, .login, .cshrc, .exrc, .mailrc, ~/bin,
+ * ... . updatehome provides a convient mechanism for accomplishing
+ * this. The user may add any set of files either to be copied
+ * (.copy_files), or symbolically linked (.link_files).
+ *
+ * Files should not include embedded MLDs.
+ *
+ * Entry options = c, if replace existing current label $HOME copies
+ * (default is to ignore existing).
+ * d, if to print debug trace msgs (internal use only).
+ * i, if to ignore errors encountered (default is to
+ * abort).
+ * m, if to suppress error diagnostics -- perror
+ * (internal use only).
+ * r, if replace existing current label $HOME copies or
+ * symbolic links -- implies c and s (default is to
+ * ignore existing).
+ * s, if replace existing current label $HOME symbolic
+ * links (default is to ignore existing).
+ *
+ * Exit stderr = diagnostic messages.
+ * exis status = 0, no errors noted.
+ * 1, if errors noted.
+ *
+ * Calls __setupfiles (which does all the real work).
+ */
+
+
+/*
+ * There is a private contract between __setupfiles in this
+ * directory and login. Changes made to __setupfiles may need to be
+ * reflected in the source for login.
+ *
+ * G.Winiger 96/11/03
+ */
+
+
+#include <locale.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+
+#include <tsol/label.h>
+#include <sys/tsol/label_macro.h>
+#include <user_attr.h>
+
+#include "setupfiles.h"
+
+#if !defined(TEXT_DOMAIN)
+#define TEXT_DOMAIN "SYS_TEST"
+#endif /* !defined(TEXT_DOMAIN) */
+
+int
+main(int argc, char **argv)
+{
+ int opt; /* option switch value */
+ int flags; /* setupfiles flags */
+ uid_t uid;
+ extern int opterr; /* getopt error flag */
+ char *kv_str = NULL;
+ struct passwd *pwd; /* current user's password file entry */
+ userattr_t *userp = NULL; /* current user's user_attr entry */
+ m_label_t *min_sl;
+ m_label_t *clearance;
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain(TEXT_DOMAIN);
+
+ flags = DIAG;
+ opterr = 0; /* handle errors here */
+
+ while ((opt = getopt(argc, argv, "cdimrs")) != EOF) {
+ switch (opt) {
+ case 'c': /* replace existing copy */
+ flags |= REPC;
+ break;
+
+ case 'd': /* debug */
+ flags |= DBUG;
+ break;
+
+ case 'i': /* ignore copy/link errors */
+ flags |= IGNE;
+ break;
+
+ case 'm': /* suppress error diagnostic (perror) */
+ /* prints */
+ flags &= ~DIAG;
+ break;
+
+ case 'r': /* replace existing */
+ flags |= (REPC | REPL);
+ break;
+
+ case 's': /* replace existing symbolic links */
+ flags |= REPL;
+ break;
+
+ case '?': /* switch error */
+ (void) fprintf(stderr, gettext("Bad option -%c.\n"),
+ (char)optopt);
+
+ default:
+ (void) fprintf(stderr, gettext("usage: %s [-cirs].\n"),
+ argv[0]);
+ exit(1);
+ /*NOTREACHED*/
+ } /* switch (opt) */
+ } /* while ((opt = getopt()) */
+
+ uid = getuid();
+
+ if ((pwd = getpwuid(uid)) == (struct passwd *)0) {
+
+ (void) fprintf(stderr,
+ gettext("Unable to get password entry for uid %d.\n"), uid);
+ exit(1);
+ }
+
+ min_sl = m_label_alloc(MAC_LABEL);
+ clearance = m_label_alloc(USER_CLEAR);
+
+ if (((userp = getusernam(pwd->pw_name)) == NULL) ||
+ ((kv_str = kva_match(userp->attr, USERATTR_MINLABEL)) == NULL)) {
+
+ if (userdefs(min_sl, clearance) == -1) {
+ (void) fprintf(stderr,
+ gettext("Unable to get default user labels.\n"));
+ exit(1);
+ }
+ }
+
+ if (kv_str != NULL) {
+
+ if (str_to_label(kv_str, &min_sl, MAC_LABEL, L_NO_CORRECTION,
+ NULL) == -1) {
+ (void) fprintf(stderr,
+ gettext("stobsl failure on min_label for user"
+ " %s.\n"), pwd->pw_name);
+ exit(1);
+ }
+ }
+
+ if (__setupfiles(pwd, min_sl, flags) != 0) {
+
+ (void) fprintf(stderr, gettext("%s failed.\n"), argv[0]);
+ exit(1);
+ }
+
+ return (0);
+} /* update home */
diff --git a/usr/src/cmd/tsol/zones/Makefile b/usr/src/cmd/tsol/zones/Makefile
new file mode 100644
index 0000000000..f500e0579b
--- /dev/null
+++ b/usr/src/cmd/tsol/zones/Makefile
@@ -0,0 +1,62 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../../Makefile.cmd
+
+PROG = zoneshare zoneunshare
+
+ETCZONESFILES= SUNWtsoldef.xml
+ROOTLIBZONES= $(ROOTLIB)/zones
+ROOTLIBZONESFILES = $(PROG:%=$(ROOTLIBZONES)/%)
+
+$(ROOTETCZONESFILES) := FILEMODE = 0444
+
+$(ROOTLIBZONES) := DIRMODE = 0755
+$(ROOTLIBZONESFILES) := FILEMODE = 0555
+$(ROOTLIBZONESFILES) := OWNER = root
+$(ROOTLIBZONESFILES) := GROUP = sys
+
+all: $(PROG)
+install: all $(ROOTETCZONESFILES) $(ROOTLIBZONES) $(ROOTLIBZONESFILES)
+
+$(ROOTLIBZONES):
+ $(INS.dir)
+
+$(ROOTETCZONESFILES)/% $(ROOTLIBZONES)/%: %
+ $(INS.file)
+
+lint:
+
+clean:
+
+_msg:
+
+_dc:
+
+include ../Makefile.targ
+
+.KEEP_STATE:
diff --git a/usr/src/cmd/tsol/zones/SUNWtsoldef.xml b/usr/src/cmd/tsol/zones/SUNWtsoldef.xml
new file mode 100644
index 0000000000..30b777b4c9
--- /dev/null
+++ b/usr/src/cmd/tsol/zones/SUNWtsoldef.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ ident "%Z%%M% %I% %E% SMI"
+
+ DO NOT EDIT THIS FILE. Use zonecfg(1M) instead.
+-->
+
+<!DOCTYPE zone PUBLIC "-//Sun Microsystems Inc//DTD Zones//EN" "file:///usr/share/lib/xml/dtd/zonecfg.dtd.1">
+<zone name="tsoldef" zonepath="" autoboot="true">
+ <inherited-pkg-dir directory="/lib"/>
+ <inherited-pkg-dir directory="/platform"/>
+ <inherited-pkg-dir directory="/sbin"/>
+ <inherited-pkg-dir directory="/usr"/>
+ <inherited-pkg-dir directory="/opt"/>
+ <inherited-pkg-dir directory="/kernel"/>
+ <filesystem special="/var/tsol/doors" directory="/var/tsol/doors" type="lofs">
+ <fsoption name="ro"/>
+ </filesystem>
+</zone>
diff --git a/usr/src/cmd/tsol/zones/zoneshare.sh b/usr/src/cmd/tsol/zones/zoneshare.sh
new file mode 100644
index 0000000000..b106eeaa01
--- /dev/null
+++ b/usr/src/cmd/tsol/zones/zoneshare.sh
@@ -0,0 +1,81 @@
+#!/sbin/sh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# zoneshare -- share zone resources
+
+# Processes a non-global zone's dfstab file after translating
+# its zone-relative pathnames to global zone pathnames
+
+USAGE="zoneshare -z zonename [- | file]"
+set -- `getopt z: $*`
+if [ $? != 0 ] # invalid options
+ then
+ echo $USAGE >&2
+ exit 1
+fi
+for i in $* # pick up the options
+do
+ case $i in
+ -z) zonename=$2; shift 2;;
+ --) shift; break;;
+ esac
+done
+
+zoneattr=`/usr/sbin/zoneadm -z $zonename list -p 2> /dev/null`
+if [ $? -ne 0 ] # invalid zone
+ then
+ echo $USAGE >&2
+ exit 1
+fi
+
+prefix=`echo $zoneattr | cut -d ":" -f4`
+rootpath=$prefix/root
+
+if [ $# -gt 1 ] # accept only one argument
+then
+ echo $USAGE >&2
+ exit 1
+elif [ $# = 1 ]
+then
+ case $1 in
+ -) infile=;; # use stdin
+ *) infile=$1;; # use a given source file
+ esac
+else
+ infile=$prefix/etc/dfs/dfstab # default
+fi
+
+# Prepend each exported pathname with the zone's rootpath
+# Skip over comments and lines without a share command
+# Run each share command in its own shell
+
+while read line # get complete lines
+do
+ echo $line
+done < $infile |
+ `egrep -v "(^[#])" | nawk -v rootpath=$rootpath \
+ '/share/ { ORS = " "; for (i = 1; i < NF; i++) print $i ; \
+ print rootpath $NF ";" } ' | /sbin/sh`
diff --git a/usr/src/cmd/tsol/zones/zoneunshare.sh b/usr/src/cmd/tsol/zones/zoneunshare.sh
new file mode 100644
index 0000000000..584d252c17
--- /dev/null
+++ b/usr/src/cmd/tsol/zones/zoneunshare.sh
@@ -0,0 +1,77 @@
+#!/sbin/sh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# zoneunshare -- unshare zone resources
+
+# Processes the specified sharetab file and unshare
+# all entries shared by the specfied zone
+
+USAGE="zoneunshare -z zonename [- | file]"
+set -- `getopt z: $*`
+if [ $? != 0 ] # invalid options
+ then
+ echo $USAGE >&2
+ exit 1
+fi
+for i in $* # pick up the options
+do
+ case $i in
+ -z) zonename=$2; shift 2;;
+ --) shift; break;;
+ esac
+done
+
+zoneattr=`/usr/sbin/zoneadm -z $zonename list -p 2> /dev/null`
+if [ $? -ne 0 ] # invalid zone
+ then
+ echo $USAGE >&2
+ exit 1
+fi
+
+prefix=`echo $zoneattr | cut -d ":" -f4`
+rootpath=$prefix/root
+
+if [ $# -gt 1 ] # accept only one argument
+then
+ echo $USAGE >&2
+ exit 1
+elif [ $# = 1 ]
+then
+ case $1 in
+ -) infile=;; # use stdin
+ *) infile=$1;; # use a given source file
+ esac
+else
+ infile=/etc/dfs/sharetab # default
+fi
+
+# Run unshare for each resource in its own shell
+
+while read line # get complete lines
+do
+ echo $line
+done < $infile |
+ `egrep "^$rootpath"|nawk '{ print "/usr/sbin/unshare " $1 ";" }'|/sbin/sh`
diff --git a/usr/src/lib/libbsm/common/devalloc.h b/usr/src/lib/libbsm/common/devalloc.h
index 12ec8732d2..6755f94001 100644
--- a/usr/src/lib/libbsm/common/devalloc.h
+++ b/usr/src/lib/libbsm/common/devalloc.h
@@ -67,7 +67,6 @@ extern "C" {
#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 */
diff --git a/usr/src/lib/libpam/pam.conf b/usr/src/lib/libpam/pam.conf
index 5809778956..7bbc90da0b 100644
--- a/usr/src/lib/libpam/pam.conf
+++ b/usr/src/lib/libpam/pam.conf
@@ -96,18 +96,51 @@ passwd auth required pam_passwd_auth.so.1
#
cron account required pam_unix_account.so.1
#
+#
+# dtlogin service (explicit because of non-usage of pam_tsol_account.so.1)
+#
+dtlogin account requisite pam_roles.so.1
+dtlogin account required pam_unix_account.so.1
+#
+# dtsession service (explicit because of non-usage of pam_tsol_account.so.1)
+#
+dtsession account requisite pam_roles.so.1
+dtsession account required pam_unix_account.so.1
+#
+# gdm service (explicit because of non-usage of pam_tsol_account.so.1)
+#
+gdm account requisite pam_roles.so.1
+gdm account required pam_unix_account.so.1
+#
+# xscreensaver service (explicit because of non-usage of pam_tsol_account.so.1)
+#
+xscreensaver account requisite pam_roles.so.1
+xscreensaver account required pam_unix_account.so.1
+#
+# passwd service (explicit because of non-usage of pam_tsol_account.so.1)
+#
+passwd account requisite pam_roles.so.1
+passwd account required pam_unix_account.so.1
+#
+# dtpasswd service (explicit because of non-usage of pam_tsol_account.so.1)
+#
+dtpasswd account requisite pam_roles.so.1
+dtpasswd account required pam_unix_account.so.1
+#
+#
# Default definition for Account management
# Used when service name is not explicitly mentioned for account management
#
other account requisite pam_roles.so.1
other account required pam_unix_account.so.1
+other account required pam_tsol_account.so.1
#
# Default definition for Session management
# Used when service name is not explicitly mentioned for session management
#
other session required pam_unix_session.so.1
#
-# Default definition for Password management
+# Default definition for Password management
# Used when service name is not explicitly mentioned for password management
#
other password required pam_dhkeys.so.1
diff --git a/usr/src/lib/libsecdb/auth_attr.txt b/usr/src/lib/libsecdb/auth_attr.txt
index 536da81d16..0a472b4eda 100644
--- a/usr/src/lib/libsecdb/auth_attr.txt
+++ b/usr/src/lib/libsecdb/auth_attr.txt
@@ -51,11 +51,24 @@ solaris.device.mount.removable:::Device Mount Removable::help=DevMount.html
solaris.dhcpmgr.:::DHCP Service Management::help=DhcpmgrHeader.html
solaris.dhcpmgr.write:::Modify DHCP Service Configuration::help=DhcpmgrWrite.html
#
+solaris.file.:::File Operations::help=FileHeader.html
+solaris.file.chown:::Change File Owner::help=FileChown.html
+solaris.file.owner:::Act as File Owner::help=FileOwner.html
+#
solaris.jobs.:::Job Scheduler::help=JobHeader.html
solaris.jobs.admin:::Manage All Jobs::help=AuthJobsAdmin.html
solaris.jobs.grant:::Delegate Cron & At Administration::help=JobsGrant.html
solaris.jobs.user:::Manage Owned Jobs::help=AuthJobsUser.html
#
+solaris.label.:::Label Management::help=LabelHeader.html
+solaris.label.file.downgrade:::Downgrade File Label::help=LabelFileDowngrade.html
+solaris.label.file.upgrade:::Upgrade File Label::help=LabelFileUpgrade.html
+solaris.label.print:::View Printer Queue at All Labels::help=LabelPrint.html
+solaris.label.range:::Set Label Outside User Accred Range::help=LabelRange.html
+solaris.label.win.downgrade:::Downgrade DragNDrop or CutPaste Info::help=LabelWinDowngrade.html
+solaris.label.win.noview:::DragNDrop or CutPaste without viewing contents::help=LabelWinNoView.html
+solaris.label.win.upgrade:::Upgrade DragNDrop or CutPaste Info::help=LabelWinUpgrade.html
+#
solaris.login.:::Login Control::help=LoginHeader.html
solaris.login.enable:::Enable Logins::help=LoginEnable.html
solaris.login.remote:::Remote Login::help=LoginRemote.html
@@ -68,6 +81,14 @@ solaris.network.link.security:::Link Security::help=LinkSecurity.html
solaris.network.wifi.config:::Wifi Config::help=WifiConfig.html
solaris.network.wifi.wep:::Wifi Wep::help=WifiWep.html
#
+solaris.print.:::Printer Management::help=PrintHeader.html
+solaris.print.admin:::Administer Printer::help=PrintAdmin.html
+solaris.print.cancel:::Cancel Print Job::help=PrintCancel.html
+solaris.print.list:::List Jobs in Printer Queue::help=PrintList.html
+solaris.print.nobanner:::Print without Banner::help=PrintNoBanner.html
+solaris.print.ps:::Print Postscript::help=PrintPs.html
+solaris.print.unlabeled:::Print without Label::help=PrintUnlabeled.html
+#
solaris.profmgr.:::Rights::help=ProfmgrHeader.html
solaris.profmgr.assign:::Assign All Rights::help=AuthProfmgrAssign.html
solaris.profmgr.delegate:::Assign Owned Rights::help=AuthProfmgrDelegate.html
@@ -93,6 +114,7 @@ solaris.smf.manage.cron:::Manage Cron Service States::help=SmfCronStates.html
solaris.smf.manage.hal:::Manage HAL Service States::help=SmfHALStates.html
solaris.smf.manage.ipsec:::Manage IPsec Service States::help=SmfIPsecStates.html
solaris.smf.manage.idmap:::Manage Identity Mapping Service States::help=SmfIdmapStates.html
+solaris.smf.manage.labels:::Manage label server::help=LabelServer.html
solaris.smf.manage.name-service-cache:::Manage Name Service Cache Daemon Service States::help=SmfNscdStates.html
solaris.smf.manage.nwam:::Manage Network Auto-Magic Service States::help=SmfNWAMStates.html
solaris.smf.manage.power:::Manage Power Management Service States::help=SmfPowerStates.html
@@ -102,11 +124,14 @@ solaris.smf.manage.rpc.bind:::Manage RPC Program number mapper::help=SmfRPCBind.
solaris.smf.manage.sendmail:::Manage Sendmail Service States::help=SmfSendmailStates.html
solaris.smf.manage.ssh:::Manage Secure Shell Service States::help=SmfSshStates.html
solaris.smf.manage.system-log:::Manage Syslog Service States::help=SmfSyslogStates.html
+solaris.smf.manage.tnctl:::Manage Refresh of Trusted Network Parameters::help=TNctl.html
+solaris.smf.manage.tnd:::Manage Trusted Network Daemon::help=TNDaemon.html
solaris.smf.manage.wpa:::Manage WPA Service States::help=SmfWpaStates.html
solaris.smf.value.:::Change Values of SMF Service Properties::help=SmfValueHeader.html
solaris.smf.value.ipsec:::Change Values of SMF IPsec Properties::help=SmfValueIPsec.html
solaris.smf.value.nwam:::Change Values of SMF Network Auto-Magic Properties::help=SmfValueNWAM.html
solaris.smf.value.routing:::Change Values of SMF Routing Properties::help=SmfValueRouting.html
+solaris.smf.value.tnd:::Change Trusted Network Daemon Service Property Values::help=ValueTND.html
solaris.smf.value.idmap:::Change Values of SMF Identity Mapping Service Properties::help=SmfValueIdmap.html
#
solaris.system.:::Machine Administration::help=SysHeader.html
diff --git a/usr/src/lib/libsecdb/exec_attr.txt b/usr/src/lib/libsecdb/exec_attr.txt
index 21206ae2bc..35498e43e1 100644
--- a/usr/src/lib/libsecdb/exec_attr.txt
+++ b/usr/src/lib/libsecdb/exec_attr.txt
@@ -61,6 +61,8 @@ Device Security:suser:cmd:::/usr/sbin/list_devices:euid=0
Device Security:suser:cmd:::/usr/sbin/rem_drv:uid=0
Device Security:suser:cmd:::/usr/sbin/strace:euid=0
Device Security:suser:cmd:::/usr/sbin/update_drv:uid=0
+Device Security:suser:cmd:::/usr/sbin/add_allocatable:euid=0
+Device Security:suser:cmd:::/usr/sbin/remove_allocatable:euid=0
FTP Management:suser:cmd:::/usr/sbin/ftpaddhost:uid=0
FTP Management:suser:cmd:::/usr/sbin/ftpconfig:uid=0
FTP Management:suser:cmd:::/usr/sbin/ftprestart:euid=0
@@ -293,6 +295,7 @@ DAT Administration:solaris:cmd:::/usr/sbin/datadm:euid=0
ZFS File System Management:solaris:cmd:::/sbin/zfs:euid=0
ZFS Storage Management:solaris:cmd:::/sbin/zpool:uid=0
ZFS Storage Management:solaris:cmd:::/usr/lib/zfs/availdevs:uid=0
+Zone Management:solaris:cmd:::/usr/sbin/txzonemgr:uid=0
Zone Management:solaris:cmd:::/usr/sbin/zonecfg:uid=0
Zone Management:solaris:cmd:::/usr/sbin/zoneadm:uid=0
Zone Management:solaris:cmd:::/usr/sbin/zlogin:uid=0
diff --git a/usr/src/lib/libsecdb/help/auths/FileChown.html b/usr/src/lib/libsecdb/help/auths/FileChown.html
new file mode 100644
index 0000000000..2882025523
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/FileChown.html
@@ -0,0 +1,35 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user to change the ownership and group of a file.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/FileHeader.html b/usr/src/lib/libsecdb/help/auths/FileHeader.html
new file mode 100644
index 0000000000..f952e31447
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/FileHeader.html
@@ -0,0 +1,35 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+The authorizations allow users access to files with various permissions.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/FileOwner.html b/usr/src/lib/libsecdb/help/auths/FileOwner.html
new file mode 100644
index 0000000000..0ead73516d
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/FileOwner.html
@@ -0,0 +1,39 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user to act as a file's owner.
+This includes the ability to change the permission bits, access control list,
+Sensitivity Label, and privilege sets of files owned by other users.
+Also included is the ability to read and search directories, copy,
+move, and delete files not owned.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/LabelFileDowngrade.html b/usr/src/lib/libsecdb/help/auths/LabelFileDowngrade.html
new file mode 100644
index 0000000000..e73904b00c
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/LabelFileDowngrade.html
@@ -0,0 +1,36 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user to change the Sensitivity Label of a file when the
+new label does not dominate the file's existing Sensitivity Label.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/LabelFileUpgrade.html b/usr/src/lib/libsecdb/help/auths/LabelFileUpgrade.html
new file mode 100644
index 0000000000..8900a97593
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/LabelFileUpgrade.html
@@ -0,0 +1,36 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user to change the Sensitivity Label of a file when the
+new label dominates the file's existing Sensitivity Label.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/LabelHeader.html b/usr/src/lib/libsecdb/help/auths/LabelHeader.html
new file mode 100644
index 0000000000..03a7938301
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/LabelHeader.html
@@ -0,0 +1,36 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+The authorizations allow users to do various operations related
+to sensitivity labels.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/LabelPrint.html b/usr/src/lib/libsecdb/help/auths/LabelPrint.html
new file mode 100644
index 0000000000..d54345a37b
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/LabelPrint.html
@@ -0,0 +1,35 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user to cancel or list print jobs at any sensitivity label.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/LabelRange.html b/usr/src/lib/libsecdb/help/auths/LabelRange.html
new file mode 100644
index 0000000000..c0627c6a3e
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/LabelRange.html
@@ -0,0 +1,40 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user to use labels that are within the system accreditation
+range as defined in the label_encodings file, but are outside the
+user accreditation range.
+Using a label implies the ability to specify that label for any of the
+label building interfaces which include those used to re-label files and
+create workspaces.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/LabelServer.html b/usr/src/lib/libsecdb/help/auths/LabelServer.html
new file mode 100644
index 0000000000..e0d705b4e8
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/LabelServer.html
@@ -0,0 +1,35 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user to start, stop the label server.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/LabelWinDowngrade.html b/usr/src/lib/libsecdb/help/auths/LabelWinDowngrade.html
new file mode 100644
index 0000000000..4f1167919a
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/LabelWinDowngrade.html
@@ -0,0 +1,37 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user to downgrade information by dragging or pasting it
+to a window whose Sensitivity Label does
+not dominate the selected information's Sensitivity Label.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/LabelWinNoView.html b/usr/src/lib/libsecdb/help/auths/LabelWinNoView.html
new file mode 100644
index 0000000000..bf05df5f6c
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/LabelWinNoView.html
@@ -0,0 +1,36 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user to drag and drop a file or cut and paste selected
+information without viewing the contents.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/LabelWinUpgrade.html b/usr/src/lib/libsecdb/help/auths/LabelWinUpgrade.html
new file mode 100644
index 0000000000..47f08961e6
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/LabelWinUpgrade.html
@@ -0,0 +1,37 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user to upgrade information by dragging or pasting it
+to a window whose Sensitivity Label dominates
+the the selected information's Sensitivity Label.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/Makefile b/usr/src/lib/libsecdb/help/auths/Makefile
index 71882e6851..26350896f8 100644
--- a/usr/src/lib/libsecdb/help/auths/Makefile
+++ b/usr/src/lib/libsecdb/help/auths/Makefile
@@ -93,7 +93,29 @@ HTMLENTS = \
LinkSecurity.html \
IdmapRules.html \
SmfIdmapStates.html \
- SmfValueIdmap.html
+ SmfValueIdmap.html \
+ FileChown.html \
+ FileHeader.html \
+ FileOwner.html \
+ LabelFileDowngrade.html \
+ LabelFileUpgrade.html \
+ LabelHeader.html \
+ LabelPrint.html \
+ LabelRange.html \
+ LabelServer.html \
+ LabelWinDowngrade.html \
+ LabelWinNoView.html \
+ LabelWinUpgrade.html \
+ PrintAdmin.html \
+ PrintCancel.html \
+ PrintHeader.html \
+ PrintList.html \
+ PrintNoBanner.html \
+ PrintPs.html \
+ PrintUnlabeled.html \
+ TNDaemon.html \
+ TNctl.html \
+ ValueTND.html
HELPDIR=$(ROOT)/usr/lib/help
AUTHDIR=$(HELPDIR)/auths
diff --git a/usr/src/lib/libsecdb/help/auths/PrintAdmin.html b/usr/src/lib/libsecdb/help/auths/PrintAdmin.html
new file mode 100644
index 0000000000..7351d00319
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/PrintAdmin.html
@@ -0,0 +1,36 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user to perform Trusted Printing System administration.
+Allows a user to start and stop printing daemons.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/PrintCancel.html b/usr/src/lib/libsecdb/help/auths/PrintCancel.html
new file mode 100644
index 0000000000..d6ecf92cc0
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/PrintCancel.html
@@ -0,0 +1,35 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user to cancel a print request queued by any user.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/PrintHeader.html b/usr/src/lib/libsecdb/help/auths/PrintHeader.html
new file mode 100644
index 0000000000..fdeddf5867
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/PrintHeader.html
@@ -0,0 +1,36 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+The authorizations allow users to do various operations
+related to printing.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/PrintList.html b/usr/src/lib/libsecdb/help/auths/PrintList.html
new file mode 100644
index 0000000000..458da664fc
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/PrintList.html
@@ -0,0 +1,35 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user get a list of queued print jobs for all users.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/PrintNoBanner.html b/usr/src/lib/libsecdb/help/auths/PrintNoBanner.html
new file mode 100644
index 0000000000..87c983407e
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/PrintNoBanner.html
@@ -0,0 +1,37 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user to submit to the Trusted Printing System a print
+request that specifies (by means of the 'lp -o nobanner' option)
+that the print job's banner and trailer pages should be suppressed.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/PrintPs.html b/usr/src/lib/libsecdb/help/auths/PrintPs.html
new file mode 100644
index 0000000000..01011da2fa
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/PrintPs.html
@@ -0,0 +1,35 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user to print a PostScript file with the Trusted Printing System.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/PrintUnlabeled.html b/usr/src/lib/libsecdb/help/auths/PrintUnlabeled.html
new file mode 100644
index 0000000000..84d9094e6b
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/PrintUnlabeled.html
@@ -0,0 +1,37 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user to submit to the Trusted Printing System a print request
+(by means of the 'lp -o nolabels' option) that the body pages of the
+print job should have the top and bottom labels suppressed.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/TNDaemon.html b/usr/src/lib/libsecdb/help/auths/TNDaemon.html
new file mode 100644
index 0000000000..8786e3a781
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/TNDaemon.html
@@ -0,0 +1,35 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user to start, stop the trusted network daemon.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/TNctl.html b/usr/src/lib/libsecdb/help/auths/TNctl.html
new file mode 100644
index 0000000000..e0524ca472
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/TNctl.html
@@ -0,0 +1,35 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user to refresh the trusted network parameters.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/auths/ValueTND.html b/usr/src/lib/libsecdb/help/auths/ValueTND.html
new file mode 100644
index 0000000000..58198a61a5
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/auths/ValueTND.html
@@ -0,0 +1,35 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+Allows a user to change the property values of the trusted network daemon
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/profiles/Makefile b/usr/src/lib/libsecdb/help/profiles/Makefile
index 9609731158..ea403d7860 100644
--- a/usr/src/lib/libsecdb/help/profiles/Makefile
+++ b/usr/src/lib/libsecdb/help/profiles/Makefile
@@ -69,6 +69,9 @@ HTMLENTS = \
RtZFSFileSysMngmnt.html \
RtZFSStorageMngmnt.html \
RtZoneMngmnt.html \
+ RtInfoSec.html \
+ RtObjectLabelMngmnt.html \
+ RtOutsideAccred.html \
RtDefault.html \
RtIdmapMngmnt.html \
RtIdmapNameRulesMngmnt.html
diff --git a/usr/src/lib/libsecdb/help/profiles/RtInfoSec.html b/usr/src/lib/libsecdb/help/profiles/RtInfoSec.html
new file mode 100644
index 0000000000..86a9ddfec7
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/profiles/RtInfoSec.html
@@ -0,0 +1,39 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+<p>
+This right contains a set of other rights which are required for maintaining an
+information security policy. Mandatory Access Control (MAC) and
+Discretionary Access Control (DAC) policies can be established and
+maintained using this right.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/profiles/RtObjectLabelMngmnt.html b/usr/src/lib/libsecdb/help/profiles/RtObjectLabelMngmnt.html
new file mode 100644
index 0000000000..1820bda377
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/profiles/RtObjectLabelMngmnt.html
@@ -0,0 +1,37 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+<p>
+This right contains commands for maintaining the sensitivity labels
+of filesystem objects.
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/help/profiles/RtOutsideAccred.html b/usr/src/lib/libsecdb/help/profiles/RtOutsideAccred.html
new file mode 100644
index 0000000000..2c5eb96b5b
--- /dev/null
+++ b/usr/src/lib/libsecdb/help/profiles/RtOutsideAccred.html
@@ -0,0 +1,37 @@
+<HTML>
+<!--
+ 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 2007 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+-->
+<HEAD>
+ <TITLE> </TITLE>
+
+
+</HEAD>
+<BODY>
+
+<!-- ident "%Z%%M% %I% %E% SMI" -->
+<p>
+This right allows a user to operate outside the user accreditation range.
+
+</BODY>
+</HTML>
diff --git a/usr/src/lib/libsecdb/prof_attr.txt b/usr/src/lib/libsecdb/prof_attr.txt
index e4832e130c..48d6c60b5b 100644
--- a/usr/src/lib/libsecdb/prof_attr.txt
+++ b/usr/src/lib/libsecdb/prof_attr.txt
@@ -36,7 +36,7 @@ Audit Control:::Configure BSM auditing:auths=solaris.audit.config,solaris.jobs.a
Audit Review:::Review BSM auditing logs:auths=solaris.audit.read;help=RtAuditReview.html
Contract Observer:::Reliably observe any/all contract events:help=RtContractObserver.html
Device Management:::Control Access to Removable Media:auths=solaris.device.*;help=RtDeviceMngmnt.html
-Printer Management:::Manage printers, daemons, spooling:auths=solaris.print.admin:help=RtPrntAdmin.html
+Printer Management:::Manage printers, daemons, spooling:auths=solaris.print.*,solaris.label.print;help=RtPrntAdmin.html
Cron Management:::Manage at and cron jobs:auths=solaris.jobs.*,solaris.smf.manage.cron;help=RtCronMngmnt.html
Log Management:::Manage log files:help=RtLogMngmnt.html
Basic Solaris User:::Automatically assigned rights:auths=solaris.profmgr.read,solaris.jobs.user,solaris.mail.mailq,solaris.device.mount.removable;profiles=All;help=RtDefault.html
@@ -46,11 +46,11 @@ File System Management:::Manage, mount, share file systems:auths=solaris.smf.man
File System Security:::Manage file system security attributes:help=RtFileSysSecurity.html
HAL Management:::Manage HAL SMF service:auths=solaris.smf.manage.hal;help=RtHALMngmnt.html
Mail Management:::Manage sendmail & queues:auths=solaris.smf.manage.sendmail;help=RtMailMngmnt.html
-Maintenance and Repair:::Maintain and repair a system:auths=solaris.smf.manage.system-log;help=RtMaintAndRepair.html
+Maintenance and Repair:::Maintain and repair a system:auths=solaris.smf.manage.system-log,solaris.label.range;help=RtMaintAndRepair.html
Media Backup:::Backup files and file systems:help=RtMediaBkup.html
Media Restore:::Restore files and file systems from backups:help=RtMediaRestore.html
-Network Management:::Manage the host and network configuration:auths=solaris.smf.manage.name-service-cache,solaris.smf.manage.bind,solaris.smf.value.routing,solaris.smf.manage.routing,solaris.smf.value.nwam,solaris.smf.manage.nwam,solaris.smf.manage.wpa;profiles=Network Wifi Management;help=RtNetMngmnt.html
-Network Security:::Manage network and host security:auths=solaris.smf.manage.ssh;profiles=Network Wifi Security,Network Link Security,Network IPsec Management;help=RtNetSecure.html
+Network Management:::Manage the host and network configuration:auths=solaris.smf.manage.name-service-cache,solaris.smf.manage.bind,solaris.smf.value.routing,solaris.smf.manage.routing,solaris.smf.value.nwam,solaris.smf.manage.nwam,solaris.smf.manage.tnd,solaris.smf.manage.tnctl,solaris.smf.manage.wpa;profiles=Network Wifi Management;help=RtNetMngmnt.html
+Network Security:::Manage network and host security:auths=solaris.smf.manage.ssh,solaris.smf.value.tnd;profiles=Network Wifi Security,Network Link Security,Network IPsec Management;help=RtNetSecure.html
Network Wifi Management:::Manage wifi network configuration:auths=solaris.network.wifi.config;help=RtNetWifiMngmnt.html
Network Wifi Security:::Manage wifi network security:auths=solaris.network.wifi.wep;help=RtNetWifiSecure.html
Network Link Security:::Manage network link security:auths=solaris.network.link.security;help=RtNetLinkSecure.html
@@ -68,7 +68,7 @@ Service Operator:::Administer services:auths=solaris.smf.manage,solaris.smf.modi
Software Installation:::Add application software to the system:help=RtSoftwareInstall.html
System Event Management:::Manage system events and system event channels:help=RtSysEvMngmnt.html
User Management:::Manage users, groups, home directory:auths=solaris.profmgr.read;help=RtUserMngmnt.html
-User Security:::Manage passwords, clearances:auths=solaris.role.*,solaris.profmgr.*;help=RtUserSecurity.html
+User Security:::Manage passwords, clearances:auths=solaris.role.*,solaris.profmgr.*,solaris.label.range;help=RtUserSecurity.html
FTP Management:::Manage the FTP server:help=RtFTPMngmnt.html
Crypto Management:::Cryptographic Framework Administration:help=RtCryptoMngmnt.html
Kerberos Client Management:::Maintain and Administer Kerberos excluding the servers:help=RtKerberosClntMngmnt.html
@@ -79,3 +79,9 @@ ZFS Storage Management:::Create and Manage ZFS Storage Pools:help=RtZFSStorageMn
Zone Management:::Zones Virtual Application Environment Administration:help=RtZoneMngmnt.html
IP Filter Management:::IP Filter Administration:help=RtIPFilterMngmnt.html
Project Management:::Add/Modify/Remove projects:help=RtProjManagement.html
+#
+# Trusted Extensions profiles:
+#
+Information Security:::Maintains MAC and DAC security policies:profiles=Device Security,File System Security,Name Service Security,Network Security,Object Access Management,Object Label Management;help=RtInfoSec.html
+Object Label Management:::Change labels on files.:auths=solaris.device.allocate,solaris.label.file.downgrade,solaris.label.win.downgrade,solaris.label.win.upgrade,solaris.label.file.upgrade,solaris.label.range,solaris.smf.manage.labels;help=RtObjectLabelMngmnt.html
+Outside Accred:::Allow a user to operate outside the user accreditation range.:auths=solaris.label.range;help=RtOutsideAccred.html
diff --git a/usr/src/lib/libsecdb/user_attr.txt b/usr/src/lib/libsecdb/user_attr.txt
index 70a20356f3..81115c3d75 100644
--- a/usr/src/lib/libsecdb/user_attr.txt
+++ b/usr/src/lib/libsecdb/user_attr.txt
@@ -27,7 +27,7 @@
#
#pragma ident "%Z%%M% %I% %E% SMI"
#
-root::::auths=solaris.*,solaris.grant;profiles=All;lock_after_retries=no
+root::::auths=solaris.*,solaris.grant;profiles=All;lock_after_retries=no;min_label=admin_low;clearance=admin_high
lp::::profiles=Printer Management
adm::::profiles=Log Management
dladm::::auths=solaris.smf.manage.wpa,solaris.smf.modify
diff --git a/usr/src/lib/pam_modules/Makefile b/usr/src/lib/pam_modules/Makefile
index 53b7fa44c4..ad0dbeff66 100644
--- a/usr/src/lib/pam_modules/Makefile
+++ b/usr/src/lib/pam_modules/Makefile
@@ -44,6 +44,7 @@ SUBDIRS = \
rhosts_auth \
roles \
sample \
+ tsol_acct \
unix_auth \
unix_account \
unix_cred \
diff --git a/usr/src/lib/pam_modules/tsol_acct/Makefile b/usr/src/lib/pam_modules/tsol_acct/Makefile
new file mode 100644
index 0000000000..7f7344b7b7
--- /dev/null
+++ b/usr/src/lib/pam_modules/tsol_acct/Makefile
@@ -0,0 +1,50 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../../Makefile.lib
+
+SUBDIRS= $(MACH)
+$(BUILD64)SUBDIRS += $(MACH64)
+
+all := TARGET= all
+clean := TARGET= clean
+clobber := TARGET= clobber
+install := TARGET= install
+lint := TARGET= lint
+
+.KEEP_STATE:
+
+all clean clobber install lint: $(SUBDIRS)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+_msg:
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/pam_modules/tsol_acct/Makefile.com b/usr/src/lib/pam_modules/tsol_acct/Makefile.com
new file mode 100644
index 0000000000..fb0e0d9568
--- /dev/null
+++ b/usr/src/lib/pam_modules/tsol_acct/Makefile.com
@@ -0,0 +1,43 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# usr/src/lib/pam_modules/tsol/Makefile.com
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+#
+
+LIBRARY= pam_tsol_account.a
+VERS= .1
+OBJECTS= tsol_acct.o
+
+include ../../Makefile.pam_modules
+
+LDLIBS += -lc -lpam -ltsol -ltsnet
+
+all: $(LIBS)
+
+lint: lintcheck
+
+include $(SRC)/lib/Makefile.targ
diff --git a/usr/src/lib/pam_modules/tsol_acct/amd64/Makefile b/usr/src/lib/pam_modules/tsol_acct/amd64/Makefile
new file mode 100644
index 0000000000..4f72a58940
--- /dev/null
+++ b/usr/src/lib/pam_modules/tsol_acct/amd64/Makefile
@@ -0,0 +1,36 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# lib/pam_modules/tsol/amd64/Makefile
+
+include ../Makefile.com
+include ../../../Makefile.lib.64
+
+install: all $(ROOTLIBS64) $(ROOTLINKS64)
diff --git a/usr/src/lib/pam_modules/tsol_acct/i386/Makefile b/usr/src/lib/pam_modules/tsol_acct/i386/Makefile
new file mode 100644
index 0000000000..a69c2eeee2
--- /dev/null
+++ b/usr/src/lib/pam_modules/tsol_acct/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 2007 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)
diff --git a/usr/src/lib/pam_modules/tsol_acct/mapfile-vers b/usr/src/lib/pam_modules/tsol_acct/mapfile-vers
new file mode 100644
index 0000000000..a7618d747b
--- /dev/null
+++ b/usr/src/lib/pam_modules/tsol_acct/mapfile-vers
@@ -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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+SUNW_1.1 {
+ global:
+ pam_sm_acct_mgmt;
+ local:
+ *;
+};
diff --git a/usr/src/lib/pam_modules/tsol_acct/sparc/Makefile b/usr/src/lib/pam_modules/tsol_acct/sparc/Makefile
new file mode 100644
index 0000000000..a69c2eeee2
--- /dev/null
+++ b/usr/src/lib/pam_modules/tsol_acct/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 2007 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)
diff --git a/usr/src/lib/pam_modules/tsol_acct/sparcv9/Makefile b/usr/src/lib/pam_modules/tsol_acct/sparcv9/Makefile
new file mode 100644
index 0000000000..c29c771432
--- /dev/null
+++ b/usr/src/lib/pam_modules/tsol_acct/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 2007 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)
diff --git a/usr/src/lib/pam_modules/tsol_acct/tsol_acct.c b/usr/src/lib/pam_modules/tsol_acct/tsol_acct.c
new file mode 100644
index 0000000000..d9fabd9fc7
--- /dev/null
+++ b/usr/src/lib/pam_modules/tsol_acct/tsol_acct.c
@@ -0,0 +1,145 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <libtsnet.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <zone.h>
+
+#include <security/pam_appl.h>
+#include <security/pam_modules.h>
+#include <security/pam_impl.h>
+
+#include <tsol/label.h>
+
+/*
+ * pam_tsol_account - Trusted Extensions account management.
+ * Validates that the user's label range contains
+ * the process label (label of the zone).
+ */
+
+static void
+free_labels(m_range_t *r, m_label_t *l)
+{
+ m_label_free(r->lower_bound);
+ m_label_free(r->upper_bound);
+ free(r);
+ m_label_free(l);
+}
+
+/* ARGSUSED */
+int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ int i;
+ int debug = 0;
+ int allow_unlabeled = 0;
+ char *user;
+ char *rhost;
+ m_range_t *range;
+ m_label_t *plabel;
+
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0) {
+ debug = 1;
+ } else if (strcmp(argv[i], "allow_unlabeled") == 0) {
+ allow_unlabeled = 1;
+ } else {
+ __pam_log(LOG_AUTH | LOG_ERR,
+ "pam_tsol_account: illegal option %s", argv[i]);
+ }
+ }
+
+ /* Trusted Extensions not enabled */
+
+ if (!is_system_labeled())
+ return (PAM_IGNORE);
+
+ (void) pam_get_item(pamh, PAM_USER, (void **)&user);
+
+ (void) pam_get_item(pamh, PAM_RHOST, (void **)&rhost);
+
+ if (debug) {
+ __pam_log(LOG_AUTH | LOG_DEBUG,
+ "pam_tsol_account: allowed_unlabeled = %d, user %s, "
+ "rhost %s",
+ allow_unlabeled,
+ (user == NULL) ? "NULL" : (user == '\0') ? "ZERO" :
+ user,
+ (rhost == NULL) ? "NULL" : (rhost == '\0') ? "ZERO" :
+ rhost);
+ }
+ if (user == NULL || *user == '\0') {
+ __pam_log(LOG_AUTH | LOG_ERR,
+ "pam_tsol_account: no user");
+ return (PAM_USER_UNKNOWN);
+ }
+
+ if ((range = getuserrange(user)) == NULL) {
+ __pam_log(LOG_AUTH | LOG_ERR,
+ "pam_tsol_account: getuserrange(%s) failure", user);
+ return (PAM_SYSTEM_ERR);
+ }
+ if ((plabel = m_label_alloc(MAC_LABEL)) == NULL) {
+ __pam_log(LOG_AUTH | LOG_ERR,
+ "pam_tsol_account: out of memory");
+ free_labels(range, NULL);
+ return (PAM_BUF_ERR);
+ }
+ if (getplabel(plabel) < 0) {
+ __pam_log(LOG_AUTH | LOG_CRIT,
+ "pam_tsol_account: Unable to get process label %m");
+ free_labels(range, plabel);
+ return (PAM_SYSTEM_ERR);
+ }
+ if (!blinrange(plabel, range)) {
+ free_labels(range, plabel);
+ return (PAM_PERM_DENIED);
+ }
+
+ free_labels(range, plabel);
+
+ /* Remote Host Type Policy Check */
+
+ if ((allow_unlabeled == 0) &&
+ (getzoneid() == GLOBAL_ZONEID) &&
+ (rhost != NULL && *rhost != '\0')) {
+ tsol_host_type_t host_type;
+
+ host_type = tsol_getrhtype(rhost);
+ switch (host_type) {
+ case SUN_CIPSO:
+ break;
+
+ case UNLABELED:
+ default:
+ return (PAM_PERM_DENIED);
+ }
+ }
+ return (PAM_SUCCESS);
+}
diff --git a/usr/src/pkgdefs/Makefile b/usr/src/pkgdefs/Makefile
index 09641a9549..178ee54bc4 100644
--- a/usr/src/pkgdefs/Makefile
+++ b/usr/src/pkgdefs/Makefile
@@ -371,6 +371,9 @@ COMMON_SUBDIRS= \
SUNWtnfc \
SUNWtnfd \
SUNWtoo \
+ SUNWtsg \
+ SUNWtsr \
+ SUNWtsu \
SUNWudaplr \
SUNWudaplu \
SUNWuedg \
diff --git a/usr/src/pkgdefs/SUNW0on/prototype_com b/usr/src/pkgdefs/SUNW0on/prototype_com
index c268e5555b..5a44b8dd1c 100644
--- a/usr/src/pkgdefs/SUNW0on/prototype_com
+++ b/usr/src/pkgdefs/SUNW0on/prototype_com
@@ -257,6 +257,29 @@ f none usr/lib/help/auths/locale/DevCDRW.html 0444 root bin
f none usr/lib/help/auths/locale/IdmapRules.html 0444 root bin
f none usr/lib/help/auths/locale/SmfIdmapStates.html 0444 root bin
f none usr/lib/help/auths/locale/SmfValueIdmap.html 0444 root bin
+f none usr/lib/help/auths/locale/FileChown.html 444 root bin
+f none usr/lib/help/auths/locale/FileHeader.html 444 root bin
+f none usr/lib/help/auths/locale/FileOwner.html 444 root bin
+f none usr/lib/help/auths/locale/LabelHeader.html 444 root bin
+f none usr/lib/help/auths/locale/LabelFileDowngrade.html 444 root bin
+f none usr/lib/help/auths/locale/LabelFileUpgrade.html 444 root bin
+f none usr/lib/help/auths/locale/LabelPrint.html 444 root bin
+f none usr/lib/help/auths/locale/LabelRange.html 444 root bin
+f none usr/lib/help/auths/locale/LabelServer.html 444 root bin
+f none usr/lib/help/auths/locale/LabelWinDowngrade.html 444 root bin
+f none usr/lib/help/auths/locale/LabelWinNoView.html 444 root bin
+f none usr/lib/help/auths/locale/LabelWinUpgrade.html 444 root bin
+f none usr/lib/help/auths/locale/PrintHeader.html 444 root bin
+f none usr/lib/help/auths/locale/PrintAdmin.html 444 root bin
+f none usr/lib/help/auths/locale/PrintCancel.html 444 root bin
+f none usr/lib/help/auths/locale/PrintList.html 444 root bin
+f none usr/lib/help/auths/locale/PrintNoBanner.html 444 root bin
+f none usr/lib/help/auths/locale/PrintPs.html 444 root bin
+f none usr/lib/help/auths/locale/PrintUnlabeled.html 444 root bin
+f none usr/lib/help/auths/locale/TNDaemon.html 444 root bin
+f none usr/lib/help/auths/locale/TNctl.html 444 root bin
+f none usr/lib/help/auths/locale/ValueTND.html 444 root bin
+#
d none usr/lib/help/profiles 755 root bin
d none usr/lib/help/profiles/locale 755 root bin
f none usr/lib/help/profiles/locale/RtAll.html 444 root bin
@@ -302,6 +325,9 @@ f none usr/lib/help/profiles/locale/RtZFSStorageMngmnt.html 444 root bin
f none usr/lib/help/profiles/locale/RtZoneMngmnt.html 444 root bin
f none usr/lib/help/profiles/locale/RtIdmapMngmnt.html 444 root bin
f none usr/lib/help/profiles/locale/RtIdmapNameRulesMngmnt.html 444 root bin
+f none usr/lib/help/profiles/locale/RtInfoSec.html 444 root bin
+f none usr/lib/help/profiles/locale/RtObjectLabelMngmnt.html 444 root bin
+f none usr/lib/help/profiles/locale/RtOutsideAccred.html 444 root bin
#
#
# OCF Messages
diff --git a/usr/src/pkgdefs/SUNWtsg/Makefile b/usr/src/pkgdefs/SUNWtsg/Makefile
new file mode 100644
index 0000000000..5a6d52aea8
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWtsg/Makefile
@@ -0,0 +1,39 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+DATAFILES += i.devallocdefs i.initd i.renamenew r.renamenew
+CHKINSTALLSRC=checkinstall.initd
+
+.KEEP_STATE:
+
+all: $(FILES)
+install: pkg
+pkg: all
+
+include ../Makefile.targ
diff --git a/usr/src/pkgdefs/SUNWtsg/pkginfo.tmpl b/usr/src/pkgdefs/SUNWtsg/pkginfo.tmpl
new file mode 100644
index 0000000000..97f1b0733d
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWtsg/pkginfo.tmpl
@@ -0,0 +1,55 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWtsg"
+NAME="Trusted Extensions global"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="Trusted Extensions"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="root"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Solaris Trusted Extensions, globalzone-only files"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none devallocdefs initd renamenew manifest rbac"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="true"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWtsg/postinstall b/usr/src/pkgdefs/SUNWtsg/postinstall
new file mode 100644
index 0000000000..ce3094c10c
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWtsg/postinstall
@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+PATH=/usr/bin:/usr/sbin
+CLEANUP=/tmp/CLEANUP
+
+LBLMOD1=$BASEDIR/kernel/sys/lbl_edition
+LBLMOD2=$BASEDIR/kernel/sys/amd64/lbl_edition
+LBLMOD3=$BASEDIR/kernel/sys/sparcv9/lbl_edition
+
+if [ -f $LBLMOD1 -o -f $LBLMOD2 -o -f $LBLMOD3 ]; then
+ # Set sys_labeling in etc/system
+ grep -v "sys_labeling=" $BASEDIR/etc/system > /tmp/etc.system.$$
+ echo "set sys_labeling=1" >> /tmp/etc.system.$$
+ mv /tmp/etc.system.$$ $BASEDIR/etc/system
+ grep "set sys_labeling=1" ${BASEDIR}/etc/system > /dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ echo "cannot set sys_labeling in $BASEDIR/etc/system"
+ exit 1
+ fi
+
+ rm -f $LBLMOD1 > /dev/null 2>&1
+ rm -f $LBLMOD2 > /dev/null 2>&1
+ rm -f $LBLMOD3 > /dev/null 2>&1
+
+ cat >> $BASEDIR/var/svc/profile/upgrade <<\__SMF_ENABLE
+ /usr/sbin/svcadm enable -s svc:/system/labeld:default
+__SMF_ENABLE
+
+fi
+
+exit 0
diff --git a/usr/src/pkgdefs/SUNWtsg/prototype_com b/usr/src/pkgdefs/SUNWtsg/prototype_com
new file mode 100644
index 0000000000..30b0ce9d26
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWtsg/prototype_com
@@ -0,0 +1,106 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i checkinstall
+i postinstall
+i i.devallocdefs
+i i.renamenew
+i i.initd
+i r.renamenew
+
+#
+# source locations relative to the prototype file
+#
+# SUNWtsg
+#
+d none etc 755 root sys
+d none etc/zones 755 root sys
+f none etc/zones/SUNWtsoldef.xml 444 root bin
+#
+d none etc/security 755 root sys
+d none etc/security/tsol 755 root sys
+e renamenew etc/security/tsol/tnrhdb 644 root sys
+e renamenew etc/security/tsol/tnrhtp 644 root sys
+e renamenew etc/security/tsol/tnzonecfg 644 root sys
+#
+e renamenew etc/security/tsol/label_encodings 400 root sys
+f none etc/security/tsol/label_encodings.example 444 root sys
+f none etc/security/tsol/label_encodings.gfi.multi 444 root sys
+f none etc/security/tsol/label_encodings.gfi.single 444 root sys
+f none etc/security/tsol/label_encodings.multi 444 root sys
+f none etc/security/tsol/label_encodings.single 444 root sys
+#
+# Customizable script for relabeling files
+#
+e renamenew etc/security/tsol/relabel 755 root sys
+#
+# Default device allocation attributes of currently supported device classes.
+#
+e devallocdefs etc/security/tsol/devalloc_defaults 0644 root sys
+#
+# Device clean scripts for the window system.
+#
+d none etc/security/lib 755 root sys
+f none etc/security/lib/audio_clean_wrapper 555 root sys
+s none etc/security/lib/audio_clean_wrapper.windowing=./audio_clean_wrapper
+f none etc/security/lib/disk_clean 555 root sys
+s none etc/security/lib/disk_clean.windowing=./disk_clean
+s none etc/security/lib/st_clean.windowing=./st_clean
+f none etc/security/lib/wdwmsg 555 root sys
+f none etc/security/lib/wdwwrapper 555 root sys
+#
+# smf glue
+d none lib 755 root bin
+d none lib/svc 755 root bin
+d none lib/svc/method 755 root bin
+f none lib/svc/method/svc-labeld 555 root bin
+f none lib/svc/method/svc-tnctl 555 root bin
+f none lib/svc/method/svc-tnd 555 root bin
+d none var 755 root sys
+d none var/svc 755 root sys
+d none var/svc/manifest 755 root sys
+d none var/svc/manifest/system 755 root sys
+f manifest var/svc/manifest/system/labeld.xml 444 root sys
+d none var/svc/manifest/network 755 root sys
+f manifest var/svc/manifest/network/tnctl.xml 444 root sys
+f manifest var/svc/manifest/network/tnd.xml 444 root sys
+#
+# doors used by labeld and name services
+d none var/tsol 755 root sys
+d none var/tsol/doors 755 root sys
diff --git a/usr/src/pkgdefs/SUNWtsg/prototype_i386 b/usr/src/pkgdefs/SUNWtsg/prototype_i386
new file mode 100644
index 0000000000..ddb9c5da98
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWtsg/prototype_i386
@@ -0,0 +1,50 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWtsg
+#
diff --git a/usr/src/pkgdefs/SUNWtsg/prototype_sparc b/usr/src/pkgdefs/SUNWtsg/prototype_sparc
new file mode 100644
index 0000000000..6e8826b787
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWtsg/prototype_sparc
@@ -0,0 +1,50 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWtsg
+#
diff --git a/usr/src/pkgdefs/SUNWtsr/Makefile b/usr/src/pkgdefs/SUNWtsr/Makefile
new file mode 100644
index 0000000000..07706c2c76
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWtsr/Makefile
@@ -0,0 +1,36 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+.KEEP_STATE:
+
+all: $(FILES)
+install: pkg
+pkg: all
+
+include ../Makefile.targ
diff --git a/usr/src/pkgdefs/SUNWtsr/depend b/usr/src/pkgdefs/SUNWtsr/depend
new file mode 100644
index 0000000000..1d9ae8b0e4
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWtsr/depend
@@ -0,0 +1,47 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This package information file defines software dependencies associated
+# with the pkg. You can define three types of pkg dependencies with this file:
+# P indicates a prerequisite for installation
+# I indicates an incompatible package
+# R indicates a reverse dependency
+# <pkg.abbr> see pkginfo(4), PKG parameter
+# <name> see pkginfo(4), NAME parameter
+# <version> see pkginfo(4), VERSION parameter
+# <arch> see pkginfo(4), ARCH parameter
+# <type> <pkg.abbr> <name>
+# (<arch>)<version>
+# (<arch>)<version>
+# ...
+# <type> <pkg.abbr> <name>
+# ...
+#
+# If we do not declare dependency on SUNWcsr, we cannot always find
+# /etc/pam.conf to modify
+#
+P SUNWcsr Core Solaris, (Root)
+P SUNWtsu Trusted Extensions, (Usr)
diff --git a/usr/src/pkgdefs/SUNWtsr/pkginfo.tmpl b/usr/src/pkgdefs/SUNWtsr/pkginfo.tmpl
new file mode 100644
index 0000000000..bb4b1a64b9
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWtsr/pkginfo.tmpl
@@ -0,0 +1,55 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWtsr"
+NAME="Trusted Extensions, (Root)"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="Trusted Extensions"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="root"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Solaris Trusted Extensions, (Root)"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none manifest rbac"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWtsr/prototype_com b/usr/src/pkgdefs/SUNWtsr/prototype_com
new file mode 100644
index 0000000000..b59b5a3dea
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWtsr/prototype_com
@@ -0,0 +1,56 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+#
+# source locations relative to the prototype file
+#
+# SUNWtsr
+#
+d none lib 755 root bin
+d none lib/svc 755 root bin
+d none lib/svc/method 755 root bin
+f none lib/svc/method/svc-tsol-zones 555 root bin
+d none sbin 755 root sys
+f none sbin/tnctl 555 root sys
+d none var 755 root sys
+d none var/svc 755 root sys
+d none var/svc/manifest 755 root sys
+d none var/svc/manifest/system 755 root sys
+f manifest var/svc/manifest/system/tsol-zones.xml 444 root sys
diff --git a/usr/src/pkgdefs/SUNWtsr/prototype_i386 b/usr/src/pkgdefs/SUNWtsr/prototype_i386
new file mode 100644
index 0000000000..ba4334233e
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWtsr/prototype_i386
@@ -0,0 +1,50 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are I386 specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWtsr
+#
diff --git a/usr/src/pkgdefs/SUNWtsr/prototype_sparc b/usr/src/pkgdefs/SUNWtsr/prototype_sparc
new file mode 100644
index 0000000000..6667eb4d47
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWtsr/prototype_sparc
@@ -0,0 +1,50 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+#
+# SUNWtsr
+#
diff --git a/usr/src/pkgdefs/SUNWtsu/Makefile b/usr/src/pkgdefs/SUNWtsu/Makefile
new file mode 100644
index 0000000000..4cf40e099d
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWtsu/Makefile
@@ -0,0 +1,39 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.com
+
+DATAFILES += i.renamenew r.renamenew
+
+.KEEP_STATE:
+
+all: $(FILES)
+
+install: all pkg
+
+include ../Makefile.targ
+
diff --git a/usr/src/pkgdefs/SUNWtsu/depend b/usr/src/pkgdefs/SUNWtsu/depend
new file mode 100644
index 0000000000..9b425b5088
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWtsu/depend
@@ -0,0 +1,44 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This package information file defines software dependencies associated
+# with the pkg. You can define three types of pkg dependencies with this file:
+# P indicates a prerequisite for installation
+# I indicates an incompatible package
+# R indicates a reverse dependency
+# <pkg.abbr> see pkginfo(4), PKG parameter
+# <name> see pkginfo(4), NAME parameter
+# <version> see pkginfo(4), VERSION parameter
+# <arch> see pkginfo(4), ARCH parameter
+# <type> <pkg.abbr> <name>
+# (<arch>)<version>
+# (<arch>)<version>
+# ...
+# <type> <pkg.abbr> <name>
+# ...
+#
+
+P SUNWtsg Trusted Extensions global
diff --git a/usr/src/pkgdefs/SUNWtsu/pkginfo.tmpl b/usr/src/pkgdefs/SUNWtsu/pkginfo.tmpl
new file mode 100644
index 0000000000..505ba29c40
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWtsu/pkginfo.tmpl
@@ -0,0 +1,55 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file describes characteristics of the
+# package, such as package abbreviation, full package name, package version,
+# and package architecture.
+#
+PKG="SUNWtsu"
+NAME="Trusted Extensions, (Usr)"
+ARCH="ISA"
+VERSION="ONVERS,REV=0.0.0"
+SUNW_PRODNAME="Trusted Extensions"
+SUNW_PRODVERS="RELEASE/VERSION"
+SUNW_PKGTYPE="usr"
+MAXINST="1000"
+CATEGORY="system"
+DESC="Solaris Trusted Extensions, (Usr)"
+VENDOR="Sun Microsystems, Inc."
+HOTLINE="Please contact your local service provider"
+EMAIL=""
+CLASSES="none renamenew"
+BASEDIR=/
+SUNW_PKGVERS="1.0"
+SUNW_PKG_ALLZONES="true"
+SUNW_PKG_HOLLOW="false"
+#VSTOCK="<reserved by Release Engineering for package part #>"
+#ISTATES="<developer defined>"
+#RSTATES='<developer defined>'
+#ULIMIT="<developer defined>"
+#ORDER="<developer defined>"
+#PSTAMP="<developer defined>"
+#INTONLY="<developer defined>"
diff --git a/usr/src/pkgdefs/SUNWtsu/prototype_com b/usr/src/pkgdefs/SUNWtsu/prototype_com
new file mode 100644
index 0000000000..32ceb0f7a9
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWtsu/prototype_com
@@ -0,0 +1,137 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+#
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+# packaging files
+i pkginfo
+i copyright
+i depend
+i i.renamenew
+i r.renamenew
+#
+# source locations relative to the prototype file
+#
+# SUNWtsu
+#
+d none usr 755 root sys
+d none usr/bin 755 root bin
+f none usr/bin/getlabel 555 root bin
+f none usr/bin/getzonepath 555 root bin
+f none usr/bin/plabel 555 root bin
+f none usr/bin/setlabel 555 root bin
+f none usr/bin/updatehome 555 root bin
+d none usr/include 755 root bin
+d none usr/include/bsm 755 root bin
+d none usr/lib 755 root bin
+f none usr/lib/labeld 555 root bin
+d none usr/lib/lp 755 root lp
+d none usr/lib/lp/bin 755 root lp
+f none usr/lib/lp/bin/lp.tsol_separator 555 root lp
+d none usr/lib/lp/model 755 root lp
+f none usr/lib/lp/model/tsol_standard 555 root lp
+f none usr/lib/lp/model/tsol_netstandard 555 root lp
+f none usr/lib/lp/model/tsol_standard_foomatic 555 root lp
+f none usr/lib/lp/model/tsol_netstandard_foomatic 555 root lp
+d none usr/lib/lp/postscript 755 root lp
+f none usr/lib/lp/postscript/tsol_banner.ps 555 root lp
+e renamenew usr/lib/lp/postscript/tsol_separator.ps 555 root lp
+f none usr/lib/lp/postscript/tsol_trailer.ps 555 root lp
+f none usr/lib/lslabels 555 root sys
+d none usr/lib/security 755 root bin
+f none usr/lib/security/pam_tsol_account.so.1 755 root bin
+s none usr/lib/security/pam_tsol_account.so=./pam_tsol_account.so.1
+d none usr/sbin 755 root bin
+f none usr/sbin/add_allocatable 555 root bin
+f none usr/sbin/atohexlabel 555 root sys
+f none usr/sbin/chk_encodings 555 root sys
+f none usr/sbin/hextoalabel 555 root sys
+f none usr/sbin/txzonemgr 555 root sys
+l none usr/sbin/remove_allocatable=add_allocatable
+f none usr/sbin/tnchkdb 555 root sys
+s none usr/sbin/tnctl=../../sbin/tnctl
+f none usr/sbin/tnd 555 root sys
+f none usr/sbin/tninfo 555 root sys
+#
+d none usr/demo 755 root bin
+d none usr/demo/tsol 755 root bin
+f none usr/demo/tsol/clonebylabel.sh 555 root bin
+f none usr/demo/tsol/getmounts.sh 555 root bin
+f none usr/demo/tsol/runinzone.ksh 555 root bin
+f none usr/demo/tsol/runwlabel.ksh 555 root bin
+f none usr/demo/tsol/waitforzone.ksh 555 root bin
+#
+# Share and unshare scripts for zone exports
+#
+d none usr/lib/zones 755 root bin
+f none usr/lib/zones/zoneshare 555 root sys
+f none usr/lib/zones/zoneunshare 555 root sys
+#
+# RBAC html help files for authorizations and profiles
+#
+d none usr/lib/help 755 root bin
+d none usr/lib/help/auths 755 root bin
+d none usr/lib/help/auths/locale 755 root bin
+d none usr/lib/help/auths/locale/C 755 root bin
+#
+f none usr/lib/help/auths/locale/C/FileHeader.html 444 root bin
+f none usr/lib/help/auths/locale/C/FileChown.html 444 root bin
+f none usr/lib/help/auths/locale/C/FileOwner.html 444 root bin
+f none usr/lib/help/auths/locale/C/LabelHeader.html 444 root bin
+f none usr/lib/help/auths/locale/C/LabelFileDowngrade.html 444 root bin
+f none usr/lib/help/auths/locale/C/LabelFileUpgrade.html 444 root bin
+f none usr/lib/help/auths/locale/C/LabelPrint.html 444 root bin
+f none usr/lib/help/auths/locale/C/LabelRange.html 444 root bin
+f none usr/lib/help/auths/locale/C/LabelServer.html 444 root bin
+f none usr/lib/help/auths/locale/C/LabelWinDowngrade.html 444 root bin
+f none usr/lib/help/auths/locale/C/LabelWinNoView.html 444 root bin
+f none usr/lib/help/auths/locale/C/LabelWinUpgrade.html 444 root bin
+f none usr/lib/help/auths/locale/C/PrintHeader.html 444 root bin
+f none usr/lib/help/auths/locale/C/PrintAdmin.html 444 root bin
+f none usr/lib/help/auths/locale/C/PrintCancel.html 444 root bin
+f none usr/lib/help/auths/locale/C/PrintList.html 444 root bin
+f none usr/lib/help/auths/locale/C/PrintNoBanner.html 444 root bin
+f none usr/lib/help/auths/locale/C/PrintPs.html 444 root bin
+f none usr/lib/help/auths/locale/C/PrintUnlabeled.html 444 root bin
+f none usr/lib/help/auths/locale/C/TNDaemon.html 444 root bin
+f none usr/lib/help/auths/locale/C/TNctl.html 444 root bin
+f none usr/lib/help/auths/locale/C/ValueTND.html 444 root bin
+#
+d none usr/lib/help/profiles 755 root bin
+d none usr/lib/help/profiles/locale 755 root bin
+d none usr/lib/help/profiles/locale/C 755 root bin
+f none usr/lib/help/profiles/locale/C/RtInfoSec.html 444 root bin
+f none usr/lib/help/profiles/locale/C/RtObjectLabelMngmnt.html 444 root bin
+f none usr/lib/help/profiles/locale/C/RtOutsideAccred.html 444 root bin
diff --git a/usr/src/pkgdefs/SUNWtsu/prototype_i386 b/usr/src/pkgdefs/SUNWtsu/prototype_i386
new file mode 100644
index 0000000000..579a65c559
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWtsu/prototype_i386
@@ -0,0 +1,51 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+#
+# List files which are i386 specific here
+#
+# source locations relative to the prototype file
+#
+# SUNWtsu
+#
+d none usr/lib/security/amd64 755 root bin
+f none usr/lib/security/amd64/pam_tsol_account.so.1 755 root bin
+s none usr/lib/security/amd64/pam_tsol_account.so=./pam_tsol_account.so.1
diff --git a/usr/src/pkgdefs/SUNWtsu/prototype_sparc b/usr/src/pkgdefs/SUNWtsu/prototype_sparc
new file mode 100644
index 0000000000..f42004c207
--- /dev/null
+++ b/usr/src/pkgdefs/SUNWtsu/prototype_sparc
@@ -0,0 +1,51 @@
+#
+# 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 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+# This required package information file contains a list of package contents.
+# The 'pkgmk' command uses this file to identify the contents of a package
+# and their location on the development machine when building the package.
+# Can be created via a text editor or through use of the 'pkgproto' command.
+#
+
+#!search <pathname pathname ...> # where to find pkg objects
+#!include <filename> # include another 'prototype' file
+#!default <mode> <owner> <group> # default used if not specified on entry
+#!<param>=<value> # puts parameter in pkg environment
+
+#
+# Include ISA independent files (prototype_com)
+#
+!include prototype_com
+#
+# List files which are SPARC specific here
+#
+# source locations relative to the prototype file
+#
+# SUNWtsu
+#
+d none usr/lib/security/sparcv9 755 root bin
+f none usr/lib/security/sparcv9/pam_tsol_account.so.1 755 root bin
+s none usr/lib/security/sparcv9/pam_tsol_account.so=./pam_tsol_account.so.1
diff --git a/usr/src/pkgdefs/common_files/i.devallocdefs b/usr/src/pkgdefs/common_files/i.devallocdefs
new file mode 100644
index 0000000000..a776b0e360
--- /dev/null
+++ b/usr/src/pkgdefs/common_files/i.devallocdefs
@@ -0,0 +1,264 @@
+#
+# 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
+#
+#!/bin/sh
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# class action script for devalloc_defaults installed by pkgadd
+#
+# Files in "devallocdefs" class:
+#
+# /etc/security/tsol/devallloc_defs
+#
+# Allowable exit codes
+#
+# 0 - success
+# 2 - warning or possible error condition. Installation continues. A warning
+# message is displayed at the time of completion.
+#
+
+tmp_dir=/tmp
+
+cp_cmd=/usr/bin/cp
+egrep_cmd=/usr/bin/egrep
+mv_cmd=/usr/bin/mv
+nawk_cmd=/usr/bin/nawk
+rm_cmd=/usr/bin/rm
+sed_cmd=/usr/bin/sed
+sort_cmd=/usr/bin/sort
+
+# $1 is the "old/existing file"
+# $2 is the "new (to be merged)" file
+# $3 is the output file
+# returns 0 on success
+# returns 2 on failure if nawk fails with non-zero exit status
+#
+dbmerge() {
+#
+# If the new file has an ident string, remove the ident string from the old
+# file.
+#
+ newident=`${egrep_cmd} '^#[pragma ]*ident' $2 \
+ 2>/dev/null`
+ if [ -n "${newident}" ]; then
+ ${egrep_cmd} -v '^#[pragma ]*ident' $1 > $3.old 2>/dev/null
+ else
+ $cp_cmd $1 $3.old
+ fi
+#
+# If the new file has a Sun copyright, remove the Sun copyright from the old
+# file.
+#
+ newcr=`${egrep_cmd} '^# Copyright.*Sun Microsystems, Inc.' $2 \
+ 2>/dev/null`
+ if [ -n "${newcr}" ]; then
+ $sed_cmd -e '/^# Copyright.*Sun Microsystems, Inc./d' \
+ -e '/^# All rights reserved./d' \
+ -e '/^# Use is subject to license terms./d' \
+ $3.old > $3.$$ 2>/dev/null
+ $mv_cmd $3.$$ $3.old
+ fi
+#
+# Remove empty lines and multiple instances of these comments:
+#
+ $sed_cmd \
+ -e '/^#$/d' \
+ -e '/^# Default device allocation attributes for device types./d' \
+ -e '/^# Currently recognized types -/d' \
+ -e '/^# audio (audio), fd (floppy drives),/d' \
+ -e '/^# sr (CDROM drives), st (tape drives),/d' \
+ -e '/^# rdsk (removable disks, like JAZ)/d' \
+ -e '/^# Syntax -/d' \
+ -e '/^# device-type:/d' \
+ -e '/^# auths=comma separated device authorizations;/d' \
+ -e '/^# cleanscript=full path to clean script for this type/d' \
+ $3.old > $3.$$
+ $mv_cmd $3.$$ $3.old
+#
+# Retain old and new header comments.
+#
+ $sed_cmd -n -e '/^[^#]/,$d' -e '/^##/,$d' -e p $3.old > $3
+ $rm_cmd $3.old
+ $sed_cmd -n -e '/^[^#]/,$d' -e '/^##/,$d' -e p $2 >> $3
+#
+# Handle line continuations (trailing \)
+#
+ $sed_cmd \
+ -e '/\\$/{N;s/\\\n//;}' -e '/\\$/{N;s/\\\n//;}' \
+ -e '/\\$/{N;s/\\\n//;}' -e '/\\$/{N;s/\\\n//;}' \
+ -e '/\\$/{N;s/\\\n//;}' -e '/\\$/{N;s/\\\n//;}' \
+ $1 > $3.old
+ $sed_cmd \
+ -e '/\\$/{N;s/\\\n//;}' -e '/\\$/{N;s/\\\n//;}' \
+ -e '/\\$/{N;s/\\\n//;}' -e '/\\$/{N;s/\\\n//;}' \
+ -e '/\\$/{N;s/\\\n//;}' -e '/\\$/{N;s/\\\n//;}' \
+ $2 > $3.new
+#
+#!/usr/bin/nawk -f
+#
+# dbmerge old-file new-file
+#
+# Merge two versions of devalloc_defaults file. The output
+# consists of the lines from the new-file, while preserving
+# user customizations in the old-file. Specifically, the
+# keyword/value section of each record contains the union
+# of the entries found in both files. The value for each
+# keyword is the value from the new-file, except for "auths",
+# where the values from the old and new files are merged.
+#
+# The output is run through sort except for the comments
+# which will appear first in the output.
+#
+#
+ $nawk_cmd '
+
+BEGIN {
+ FS=":" \
+}
+
+/^#/ {
+ continue;
+}
+
+{
+ key = $1 ;
+ if (NR == FNR)
+ record[key] = $2;
+ else {
+ print key ":" merge_attrs(record[key], $2);
+ delete record[key];
+ }
+}
+
+END {
+ for (key in record) {
+ print key ":" record[key];
+ }
+}
+
+function merge_attrs(old, new, cnt, new_cnt, i, j, list, new_list, keyword)
+{
+ cnt = split(old, list, ";");
+ new_cnt = split(new, new_list, ";");
+ for (i = 1; i <= new_cnt; i++) {
+ keyword = substr(new_list[i], 1, index(new_list[i], "=")-1);
+ for (j = 1; j <= cnt; j++) {
+ if (match(list[j], "^" keyword "=")) {
+ list[j] = merge_values(keyword, list[j],
+ new_list[i]);
+ break;
+ }
+ }
+ if (j > cnt)
+ list[++cnt] = new_list[i];
+ }
+
+ return unsplit(list, cnt, ";"); \
+}
+
+function merge_values(keyword, old, new, cnt, new_cnt, i, j, list, new_list, d)
+{
+ if (keyword != "auths" && keyword != "profiles")
+ return new;
+
+ cnt = split(substr(old, length(keyword)+2), list, ",");
+ new_cnt = split(substr(new, length(keyword)+2), new_list, ",");
+
+ for (i = 1; i <= new_cnt; i++) {
+ for (j = 1; j <= cnt; j++) {
+ if (list[j] == new_list[i])
+ break;
+ }
+ if (j > cnt)
+ list[++cnt] = new_list[i];
+ }
+
+ return keyword "=" unsplit(list, cnt, ",");
+}
+
+function unsplit(list, cnt, delim, str)
+{
+ str = list[1];
+ for (i = 2; i <= cnt; i++)
+ str = str delim list[i];
+ return str;
+}' \
+ $3.old $3.new > $3.unsorted
+ rc=$?
+ $sort_cmd < $3.unsorted >> $3
+ return $rc
+}
+
+# $1 is the merged file
+# $2 is the target file
+#
+commit() {
+ $mv_cmd $1 $2
+ return $?
+}
+
+outfile=""
+set_outfile() {
+
+ outfile=$tmp_dir/devalloc_defaults_merge
+
+ return 0
+}
+
+cleanup() {
+ $rm_cmd -f $outfile $outfile.old $outfile.new $outfile.unsorted
+
+ return 0
+}
+
+exit_status=0
+
+# main
+
+while read newfile oldfile ; do
+ if [ ! -f $oldfile ]; then
+ cp $newfile $oldfile
+ else
+ set_outfile $newfile
+ dbmerge $oldfile $newfile $outfile
+ if [ $? -ne 0 ]; then
+ echo "$0 : failed to merge $newfile with $oldfile"
+ cleanup
+ exit_status=2
+ continue
+ fi
+
+ commit $outfile $oldfile
+ if [ $? -ne 0 ]; then
+ echo "$0 : failed to mv $outfile to $2"
+ cleanup
+ exit_status=2
+ continue
+ fi
+
+ cleanup
+ fi
+done
+
+exit $exit_status
diff --git a/usr/src/pkgdefs/common_files/i.pamconf b/usr/src/pkgdefs/common_files/i.pamconf
index c9676e71a8..f5b1e47cf0 100644
--- a/usr/src/pkgdefs/common_files/i.pamconf
+++ b/usr/src/pkgdefs/common_files/i.pamconf
@@ -30,6 +30,7 @@ PAM_TMP=/tmp/pam_conf.$$
KERB_ENTRIES=$PAM_TMP/scr.$$
PPP_ENTRIES=$PAM_TMP/scp.$$
CRON_ENTRIES=$PAM_TMP/scc.$$
+TX_ENTRIES=$PAM_TMP/sct.$$
mkdir $PAM_TMP || exit 1
PATH="/usr/bin:/usr/sbin:${PATH}"
@@ -70,10 +71,33 @@ cat > ${CRON_ENTRIES} << EOF
cron account required pam_unix_account.so.1
EOF
}
+
+setup_tx_changes(){
+#
+# No comments or blanks lines allowed in entries below
+#
+cat > ${TX_ENTRIES} << EOF
+dtlogin account requisite pam_roles.so.1
+dtlogin account required pam_unix_account.so.1
+dtsession account requisite pam_roles.so.1
+dtsession account required pam_unix_account.so.1
+gdm account requisite pam_roles.so.1
+gdm account required pam_unix_account.so.1
+xscreensaver account requisite pam_roles.so.1
+xscreensaver account required pam_unix_account.so.1
+passwd account requisite pam_roles.so.1
+passwd account required pam_unix_account.so.1
+dtpasswd account requisite pam_roles.so.1
+dtpasswd account required pam_unix_account.so.1
+other account required pam_tsol_account.so.1
+EOF
+}
+
#
setup_kerb_changes
setup_ppp_changes
setup_cron_changes
+setup_tx_changes
while read src dest
do
if [ ! -f $dest ] ; then
@@ -373,7 +397,46 @@ do
echo "refer to pam_ldap(5) documentation for more information" \
>> ${CLEANUP_FILE}
fi
+
+#
+# Update pam.conf to append Trusted Extensions entries if not
+# already present.
#
+ rm -f /tmp/pamconf.$$
+ while read e1 e2 e3 e4 e5
+ do
+ # If this is the 'other' entry, add it unless it already
+ # exists.
+ if [ $e1 = "other" ]; then
+ grep \
+"^[# ]*$e1[ ][ ]*$e2[ ][ ]*$e3[ ][ ]*$e4" \
+ $dest >/dev/null 2>&1
+ if [ $? = 1 ] ; then
+ # Doesn't exist, enter into pam.conf
+ echo "$e1\t$e2 $e3\t\t$e4 $e5" \
+ >> /tmp/pamconf.$$
+ fi
+ else
+ # Add other entries unless they already have a
+ # stack of their own.
+ grep "^[# ]*$e1[ ][ ]*$e2[ ]" \
+ $dest >/dev/null 2>&1
+ if [ $? = 1 ] ; then
+ echo "$e1\t$e2 $e3\t\t$e4 $e5" \
+ >> /tmp/pamconf.$$
+ fi
+ fi
+ done < ${TX_ENTRIES}
+ # Append TX lines if any were not present already.
+ if [ -f /tmp/pamconf.$$ ] ; then
+ cat /tmp/pamconf.$$ >> $dest
+ echo "${dest} updating entries for Trusted Extensions; \c" \
+ >> ${CLEANUP_FILE}
+ echo "please examine/update any new entries" \
+ >> ${CLEANUP_FILE}
+ rm -f /tmp/pamconf.$$
+ fi
+
fi
done
#
diff --git a/usr/src/pkgdefs/common_files/r.renamenew b/usr/src/pkgdefs/common_files/r.renamenew
new file mode 100644
index 0000000000..380c5a69bb
--- /dev/null
+++ b/usr/src/pkgdefs/common_files/r.renamenew
@@ -0,0 +1,36 @@
+#
+# 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
+#
+#!/bin/sh
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+TAG=new
+
+while read fname
+do
+ if [ -f $fname.$TAG ]; then
+ /usr/bin/rm $fname.$TAG
+ fi
+done
+exit 0
diff --git a/usr/src/tools/scripts/bfu.sh b/usr/src/tools/scripts/bfu.sh
index 54d422554e..53bbe8c928 100644
--- a/usr/src/tools/scripts/bfu.sh
+++ b/usr/src/tools/scripts/bfu.sh
@@ -210,6 +210,12 @@ global_zone_only_files="
etc/ppp/pap-secrets
etc/security/device_policy
etc/security/extra_privs
+ etc/security/tsol/tnrhdb
+ etc/security/tsol/tnrhtp
+ etc/security/tsol/tnzonecfg
+ etc/security/tsol/label_encodings
+ etc/security/tsol/relabel
+ etc/security/tsol/devalloc_defaults
etc/system
etc/zones/index
kernel/drv/elxl.conf
@@ -302,6 +308,7 @@ superfluous_nonglobal_zone_files="
lib/svc/method/svc-dumpadm
lib/svc/method/svc-intrd
lib/svc/method/svc-hal
+ lib/svc/method/svc-labeld
lib/svc/method/svc-mdmonitor
lib/svc/method/svc-metainit
lib/svc/method/svc-metasync
@@ -314,6 +321,8 @@ superfluous_nonglobal_zone_files="
lib/svc/method/svc-scheduler
lib/svc/method/svc-sckmd
lib/svc/method/svc-syseventd
+ lib/svc/method/svc-tnctl
+ lib/svc/method/svc-tnd
lib/svc/method/svc-vntsd
lib/svc/method/svc-zones
platform/*/kernel
@@ -350,6 +359,8 @@ superfluous_nonglobal_zone_files="
var/svc/manifest/network/rpc/meta.xml
var/svc/manifest/network/rpc/metamed.xml
var/svc/manifest/network/rpc/metamh.xml
+ var/svc/manifest/network/tnctl.xml
+ var/svc/manifest/network/tnd.xml
var/svc/manifest/platform/i86pc/eeprom.xml
var/svc/manifest/platform/sun4u/dcs.xml
var/svc/manifest/platform/sun4u/dscp.xml
@@ -363,6 +374,7 @@ superfluous_nonglobal_zone_files="
var/svc/manifest/system/fmd.xml
var/svc/manifest/system/hal.xml
var/svc/manifest/system/intrd.xml
+ var/svc/manifest/system/labeld.xml
var/svc/manifest/system/mdmonitor.xml
var/svc/manifest/system/metainit.xml
var/svc/manifest/system/metasync.xml
diff --git a/usr/src/uts/common/os/tlabel.c b/usr/src/uts/common/os/tlabel.c
index 26616cc2f2..f3a24f0457 100644
--- a/usr/src/uts/common/os/tlabel.c
+++ b/usr/src/uts/common/os/tlabel.c
@@ -49,7 +49,7 @@
#include <sys/dnlc.h>
-int sys_labeling = -1; /* initially unset */
+int sys_labeling = 0; /* the default is "off" */
static kmem_cache_t *tslabel_cache;
ts_label_t *l_admin_low;
@@ -69,14 +69,9 @@ label_init(void)
bslabel_t label;
/*
- * Use the value of "label_services" within the edition module.
- * If for some reason label_services is not found, this will
- * result in the appropriate default -- "off."
+ * sys_labeling will default to "off" unless it is overridden
+ * in /etc/system.
*/
- if (modgetsymvalue("label_services", B_FALSE) != 0)
- sys_labeling = 1;
- else
- sys_labeling = 0;
tslabel_cache = kmem_cache_create("tslabel_cache", sizeof (ts_label_t),
0, NULL, NULL, NULL, NULL, NULL, 0);