diff options
| author | rica <none@none> | 2007-07-27 16:45:56 -0700 |
|---|---|---|
| committer | rica <none@none> | 2007-07-27 16:45:56 -0700 |
| commit | f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01 (patch) | |
| tree | a89bd9be4c155028f554c0df7142f5c3365fb6d0 /usr/src | |
| parent | 836fa82ea903ec0a04de2b008034c3816b75a739 (diff) | |
| download | illumos-gate-f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01.tar.gz | |
PSARC 2007/254 - Enabling method for Trusted Extensions
6432114 [tjds] cannot login via gdm unless clearance is set to admin_high
6533113 split install and enabling of Trusted Extensions
6533118 move TX source from TLC to ON gate
6542578 TLC putback requires i.pamconf change similar to the kerberos solution.
6552207 txzonemgr does not configure loopback mounts for /etc/passwd and /etc/shadow when creating zones
6552253 solaris.smf.manage.labels should allow for permanent as well as temporary enable/disable of labeld
6555057 txzonemgr assumes LANG is valid
6557684 pam_tsol_account could use a thorough house cleaning
6561392 txzonemgr should work from Zone Management profile
6565347 txzonemgr failed to add an interface to a zone
Diffstat (limited to 'usr/src')
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); |
