diff options
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); |
