PSARC/2002/762 Layered Trusted Solaris
PSARC/2005/060 TSNET: Trusted Networking with Security Labels
PSARC/2005/259 Layered Trusted Solaris Label Interfaces
PSARC/2005/573 Solaris Trusted Extensions for Printing
PSARC/2005/691 Trusted Extensions for Device Allocation
PSARC/2005/723 Solaris Trusted Extensions Filesystem Labeling
PSARC/2006/009 Labeled Auditing
PSARC/2006/155 Trusted Extensions RBAC Changes
PSARC/2006/191 is_system_labeled
6293271 Zone processes should use zone_kcred instead of kcred
6394554 integrate Solaris Trusted Extensions
--HG--
rename : usr/src/cmd/dminfo/Makefile => deleted_files/usr/src/cmd/dminfo/Makefile
rename : usr/src/cmd/dminfo/dminfo.c => usr/src/cmd/allocate/dminfo.c
diff --git a/usr/src/cmd/dminfo/Makefile b/deleted_files/usr/src/cmd/dminfo/Makefile
similarity index 100%
rename from usr/src/cmd/dminfo/Makefile
rename to deleted_files/usr/src/cmd/dminfo/Makefile
diff --git a/usr/src/Makefile.lint b/usr/src/Makefile.lint
index 96414c9..39dcec7 100644
--- a/usr/src/Makefile.lint
+++ b/usr/src/Makefile.lint
@@ -350,6 +350,8 @@
lib/libsmbios \
lib/libsmedia \
lib/libthread \
+ lib/libtsnet \
+ lib/libtsol \
lib/libumem \
lib/libuutil \
lib/libwanboot \
diff --git a/usr/src/Targetdirs b/usr/src/Targetdirs
index b55eb30..2747344 100644
--- a/usr/src/Targetdirs
+++ b/usr/src/Targetdirs
@@ -200,6 +200,7 @@
/usr/include/kerberosv5 \
/usr/include/libmilter \
/usr/include/sasl \
+ /usr/include/tsol \
/usr/lib \
/usr/lib/abi \
/usr/lib/class \
@@ -860,6 +861,10 @@
$(ROOT)/usr/lib/libthread.so:= REALPATH=../../lib/libthread.so.1
$(ROOT)/usr/lib/libthread_db.so.1:= REALPATH=../../lib/libc_db.so.1
$(ROOT)/usr/lib/libthread_db.so:= REALPATH=../../lib/libc_db.so.1
+$(ROOT)/usr/lib/libtsnet.so.1:= REALPATH=../../lib/libtsnet.so.1
+$(ROOT)/usr/lib/libtsnet.so:= REALPATH=../../lib/libtsnet.so.1
+$(ROOT)/usr/lib/libtsol.so.2:= REALPATH=../../lib/libtsol.so.2
+$(ROOT)/usr/lib/libtsol.so:= REALPATH=../../lib/libtsol.so.2
$(ROOT)/usr/lib/libumem.so.1:= REALPATH=../../lib/libumem.so.1
$(ROOT)/usr/lib/libumem.so:= REALPATH=../../lib/libumem.so.1
$(ROOT)/usr/lib/libuuid.so.1:= REALPATH=../../lib/libuuid.so.1
@@ -960,6 +965,10 @@
$(ROOT)/usr/lib/llib-lthread:= REALPATH=../../lib/llib-lthread
$(ROOT)/usr/lib/llib-lthread_db.ln:= REALPATH=../../lib/llib-lc_db.ln
$(ROOT)/usr/lib/llib-lthread_db:= REALPATH=../../lib/llib-lc_db
+$(ROOT)/usr/lib/llib-ltsnet.ln:= REALPATH=../../lib/llib-ltsnet.ln
+$(ROOT)/usr/lib/llib-ltsnet:= REALPATH=../../lib/llib-ltsnet
+$(ROOT)/usr/lib/llib-ltsol.ln:= REALPATH=../../lib/llib-ltsol.ln
+$(ROOT)/usr/lib/llib-ltsol:= REALPATH=../../lib/llib-ltsol
$(ROOT)/usr/lib/llib-lumem.ln:= REALPATH=../../lib/llib-lumem.ln
$(ROOT)/usr/lib/llib-lumem:= REALPATH=../../lib/llib-lumem
$(ROOT)/usr/lib/llib-luuid.ln:= REALPATH=../../lib/llib-luuid.ln
@@ -1165,6 +1174,14 @@
REALPATH=../../../lib/$(MACH64)/libc_db.so.1
$(ROOT)/usr/lib/$(MACH64)/libthread_db.so:= \
REALPATH=../../../lib/$(MACH64)/libc_db.so.1
+$(ROOT)/usr/lib/$(MACH64)/libtsnet.so.1:= \
+ REALPATH=../../../lib/$(MACH64)/libtsnet.so.1
+$(ROOT)/usr/lib/$(MACH64)/libtsnet.so:= \
+ REALPATH=../../../lib/$(MACH64)/libtsnet.so.1
+$(ROOT)/usr/lib/$(MACH64)/libtsol.so.2:= \
+ REALPATH=../../../lib/$(MACH64)/libtsol.so.2
+$(ROOT)/usr/lib/$(MACH64)/libtsol.so:= \
+ REALPATH=../../../lib/$(MACH64)/libtsol.so.2
$(ROOT)/usr/lib/$(MACH64)/libumem.so.1:= \
REALPATH=../../../lib/$(MACH64)/libumem.so.1
$(ROOT)/usr/lib/$(MACH64)/libumem.so:= \
@@ -1275,6 +1292,10 @@
REALPATH=../../../lib/$(MACH64)/llib-lthread.ln
$(ROOT)/usr/lib/$(MACH64)/llib-lthread_db.ln:= \
REALPATH=../../../lib/$(MACH64)/llib-lc_db.ln
+$(ROOT)/usr/lib/$(MACH64)/llib-ltsnet.ln:= \
+ REALPATH=../../../lib/$(MACH64)/llib-ltsnet.ln
+$(ROOT)/usr/lib/$(MACH64)/llib-ltsol.ln:= \
+ REALPATH=../../../lib/$(MACH64)/llib-ltsol.ln
$(ROOT)/usr/lib/$(MACH64)/llib-lumem.ln:= \
REALPATH=../../../lib/$(MACH64)/llib-lumem.ln
$(ROOT)/usr/lib/$(MACH64)/llib-luuid.ln:= \
@@ -1402,6 +1423,8 @@
/usr/lib/libsendfile.so.1 \
/usr/lib/libsocket.so \
/usr/lib/libsocket.so.1 \
+ /usr/lib/libsysevent.so \
+ /usr/lib/libsysevent.so.1 \
/usr/lib/libtermcap.so \
/usr/lib/libtermcap.so.1 \
/usr/lib/libtermlib.so \
@@ -1410,8 +1433,10 @@
/usr/lib/libthread.so.1 \
/usr/lib/libthread_db.so \
/usr/lib/libthread_db.so.1 \
- /usr/lib/libsysevent.so \
- /usr/lib/libsysevent.so.1 \
+ /usr/lib/libtsnet.so \
+ /usr/lib/libtsnet.so.1 \
+ /usr/lib/libtsol.so \
+ /usr/lib/libtsol.so.2 \
/usr/lib/libumem.so \
/usr/lib/libumem.so.1 \
/usr/lib/libuuid.so \
@@ -1512,6 +1537,10 @@
/usr/lib/llib-lthread.ln \
/usr/lib/llib-lthread_db \
/usr/lib/llib-lthread_db.ln \
+ /usr/lib/llib-ltsnet \
+ /usr/lib/llib-ltsnet.ln \
+ /usr/lib/llib-ltsol \
+ /usr/lib/llib-ltsol.ln \
/usr/lib/llib-lumem \
/usr/lib/llib-lumem.ln \
/usr/lib/llib-luuid \
@@ -1633,6 +1662,10 @@
/usr/lib/$(MACH64)/libthread.so.1 \
/usr/lib/$(MACH64)/libthread_db.so \
/usr/lib/$(MACH64)/libthread_db.so.1 \
+ /usr/lib/$(MACH64)/libtsnet.so \
+ /usr/lib/$(MACH64)/libtsnet.so.1 \
+ /usr/lib/$(MACH64)/libtsol.so \
+ /usr/lib/$(MACH64)/libtsol.so.2 \
/usr/lib/$(MACH64)/libumem.so \
/usr/lib/$(MACH64)/libumem.so.1 \
/usr/lib/$(MACH64)/libuuid.so \
@@ -1688,6 +1721,8 @@
/usr/lib/$(MACH64)/llib-ltermlib.ln \
/usr/lib/$(MACH64)/llib-lthread.ln \
/usr/lib/$(MACH64)/llib-lthread_db.ln \
+ /usr/lib/$(MACH64)/llib-ltsnet.ln \
+ /usr/lib/$(MACH64)/llib-ltsol.ln \
/usr/lib/$(MACH64)/llib-lumem.ln \
/usr/lib/$(MACH64)/llib-luuid.ln \
/usr/lib/$(MACH64)/llib-lxnet.ln \
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile
index b72d2d2..645eb78 100644
--- a/usr/src/cmd/Makefile
+++ b/usr/src/cmd/Makefile
@@ -17,6 +17,8 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
+
+
#
#
# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
@@ -720,7 +722,6 @@
auditd \
auditreduce \
auditstat \
- dminfo \
praudit \
bsmconv \
bsmrecord \
diff --git a/usr/src/cmd/allocate/Makefile b/usr/src/cmd/allocate/Makefile
index 6b3055b..53cf843 100644
--- a/usr/src/cmd/allocate/Makefile
+++ b/usr/src/cmd/allocate/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.
@@ -19,8 +18,9 @@
#
# CDDL HEADER END
#
+
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -33,87 +33,123 @@
ROOTSECLIB = $(ROOTSEC)/lib
ROOTDIRS = $(ROOTSECDEV) $(ROOTSECLIB)
-PROG1 = allocate
-PROG2 = mkdevmaps mkdevalloc
-PROG3 = audio_clean
-PROG = $(PROG1) $(PROG2) $(PROG3)
-DEFILE = deallocate
-LISTFILE = list_devices
RTLCKS = audio fd0 sr0 st0 st1
-SCRIPTS = st_clean fd_clean sr_clean
+SCRIPTS = fd_clean sr_clean st_clean
ALLSCRIPTS = allscripts.sh
-POFILE= allocate_all.po
-POFILES= $(OBJS:%.o=%.po) $(ALLSCRIPTS:%.sh=%.po)
+PROGalloc = allocate
+PROGmkdevalloc = mkdevalloc
+PROGdminfo = dminfo
+PROGaudio = audio_clean
+PROG = $(PROGalloc) $(PROGmkdevalloc) $(PROGdminfo) $(PROGaudio)
-# make DFLAGS=-DDEBUG
+LINKPROGalloc = deallocate list_devices
+LINKPROGmkdevalloc = mkdevmaps
-DFLAGS=
+
+POFILE = allocate_all.po
+POFILES = $(OBJS:%.o=%.po) $(ALLSCRIPTS:%.sh=%.po)
+
+DFLAGS += -D_REENTRANT
CPPFLAGS += $(DFLAGS)
-ROOTPROG = $(PROG1:%=$(ROOTUSRSBIN)/%) $(PROG2:%=$(ROOTUSRSBIN)/%) \
- $(PROG3:%=$(ROOTSECLIB)/%)
-ROOTLOCKS= $(RTLCKS:%=$(ROOTSECDEV)/%)
-ROOTSCRIPTS= $(SCRIPTS:%=$(ROOTSECLIB)/%)
+ROOTLOCKS = $(RTLCKS:%=$(ROOTSECDEV)/%)
+ROOTSCRIPTS = $(SCRIPTS:%=$(ROOTSECLIB)/%)
-CLOBBERFILES += $(SCRIPTS)
+ROOTPROG = $(PROGallocate:%=$(ROOTUSRSBIN)/%) \
+ $(PROGmkdevalloc:%=$(ROOTUSRSBIN)/%) \
+ $(PROGdminfo:%=$(ROOTUSRSBIN)/%) \
+ $(PROGaudio:%=$(ROOTSECLIB)/%)
+ROOTLINKalloc = $(LINKPROGalloc:%=$(ROOTUSRSBIN)/%)
+ROOTLINKmkdevalloc = $(LINKPROGmkdevalloc:%=$(ROOTUSRSBIN)/%)
+ROOTLINKS = $(ROOTLINKalloc) $(ROOTLINKmkdevalloc)
-allocate := POBJS = allocate.o allocate3.o
-mkdevmaps := POBJS = mkdevmaps.o
-mkdevalloc := POBJS = mkdevalloc.o
-audio_clean := POBJS = audio_clean.o
+PROGallocOBJS = allocate.o allocate3.o
+PROGmkdevallocOBJS = mkdevalloc.o
+PROGdminfoOBJS = dminfo.o
+PROGaudioOBJS = audio_clean.o
-OBJS = allocate.o allocate3.o audio_clean.o mkdevmaps.o mkdevalloc.o
+OBJS = $(PROGallocOBJS) \
+ $(PROGmkdevallocOBJS) \
+ $(PROGdminfoOBJS) \
+ $(PROGaudioOBJS)
+
SRCS = $(OBJS:%.o=%.c)
-FILEMODE= 0755
-DIRMODE= 0755
-OWNER= root
-GROUP= sys
-
+$(ROOTUSRSBIN)/% := FILEMODE = 555
+$(ROOTUSRSBIN)/allocate := FILEMODE = 4555
$(ROOTUSRSBIN)/% := OWNER = root
$(ROOTUSRSBIN)/% := GROUP = bin
+$(ROOTSECDEV)/% := FILEMODE = 0400
+$(ROOTSECDEV)/% := OWNER = root
+$(ROOTSECDEV)/% := GROUP = bin
+$(ROOTSECLIB)/% := FILEMODE = 0555
+$(ROOTSECLIB)/% := OWNER = root
+$(ROOTSECLIB)/% := GROUP = sys
-$(ROOTUSRSBIN)/allocate := FILEMODE = 04755
-$(ROOTUSRSBIN)/deallocate := FILEMODE = 04755
-$(ROOTUSRSBIN)/list_devices := FILEMODE = 04755
+LAZYLIBS = $(ZLAZYLOAD) -ltsol -lgen $(ZNOLAZYLOAD)
+lint := LDLIBS += -lbsm -lsec -lsecdb -ltsol -lgen
+$(PROGalloc) := LDLIBS += -lbsm -lsec -lsecdb $(LAZYLIBS)
+$(PROGmkdevalloc) := LDLIBS += -lbsm
+$(PROGdminfo) := LDLIBS += -lbsm
+$(PROGaudio) := LDLIBS += -lbsm
-$(ROOTSECDEV)/% := FILEMODE = 0400
-$(ROOTSECDEV)/% := OWNER = root
-$(ROOTSECDEV)/% := GROUP = bin
-
-$(ROOTSECLIB)/% := FILEMODE = 0751
-
-allocate := LDLIBS += -lbsm -lsec -lsecdb
+CLOBBERFILES += $(SCRIPTS)
.KEEP_STATE:
all : $(PROG) $(RTLCKS) $(SCRIPTS)
-install : all $(ROOTDIRS) $(ROOTPROG) $(ROOTLOCKS) $(ROOTSCRIPTS)
- $(RM) $(ROOTUSRSBIN)/$(DEFILE)
- $(LN) $(ROOTUSRSBIN)/$(PROG1) $(ROOTUSRSBIN)/$(DEFILE)
- $(RM) $(ROOTUSRSBIN)/$(LISTFILE)
- $(LN) $(ROOTUSRSBIN)/$(PROG1) $(ROOTUSRSBIN)/$(LISTFILE)
-
-$(PROG) : $$(POBJS)
- $(LINK.c) $(POBJS) -o $@ $(LDLIBS)
- $(POST_PROCESS)
+install : $(PROG) $(ROOTDIRS) $(ROOTPROG) $(ROOTLOCKS) \
+ $(ROOTSCRIPTS) $(ROOTLINKS)
$(RTLCKS):
$(TOUCH) $@
-$(ROOTDIRS):
+$(ROOTSECLIB)/%: %.sh
+ $(INS.rename)
+
+$(PROGalloc) : $(PROGallocOBJS)
+ $(LINK.c) $(PROGallocOBJS) -o $@ $(LDLIBS)
+ $(POST_PROCESS)
+
+$(PROGmkdevalloc) : $(PROGmkdevallocOBJS)
+ $(LINK.c) $(PROGmkdevallocOBJS) -o $@ $(LDLIBS)
+ $(POST_PROCESS)
+
+$(PROGdminfo) : $(PROGdminfoOBJS)
+ $(LINK.c) $(PROGdminfoOBJS) -o $@ $(LDLIBS)
+ $(POST_PROCESS)
+
+$(PROGaudio) : $(PROGaudioOBJS)
+ $(LINK.c) $(PROGaudioOBJS) -o $@ $(LDLIBS)
+ $(POST_PROCESS)
+
+$(ROOTDIRS) :
$(INS.dir)
$(ROOTSECDEV)/%: %
$(INS.file)
$(ROOTSECLIB)/%: %
+ $(RM) $@
$(INS.file)
+$(ROOTSECLIB)/audio_clean : audio_clean
+ $(RM) $@
+ $(INS.file) $(@F)
+
+$(ROOTLINKalloc) : $(PROGalloc:%=$(ROOTUSRSBIN)/%)
+ $(RM) $@
+ $(LN) $(PROGalloc:%=$(ROOTUSRSBIN)/%) $@
+
+$(ROOTLINKmkdevalloc) : $(PROGmkdevalloc:%=$(ROOTUSRSBIN)/%)
+ $(RM) $@
+ $(LN) $(PROGmkdevalloc:%=$(ROOTUSRSBIN)/%) $@
+
$(POFILE): $(POFILES)
- $(RM) $@; $(CAT) $(POFILES) > $@; $(RM) $(POFILES)
+ $(RM) $@
+ $(CAT) $(POFILES) > $@
#
# Concatenate all the scripts into one before we build the catalogue.
@@ -124,7 +160,8 @@
$(CAT) $(SCRIPTS:%=%.sh) > $@
clean :
- $(RM) $(OBJS) $(RTLCKS) $(ALLSCRIPTS)
+ $(RM) $(PROG) $(RTLCKS) $(OBJS) \
+ $(SCRIPTS) $(ALLSCRIPTS) $(POFILE) $(POFILES)
lint : lint_SRCS
diff --git a/usr/src/cmd/allocate/allocate.c b/usr/src/cmd/allocate/allocate.c
index a2c1c96..36f0050 100644
--- a/usr/src/cmd/allocate/allocate.c
+++ b/usr/src/cmd/allocate/allocate.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,6 +18,7 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
@@ -33,140 +33,207 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-
+#include <ctype.h>
+#include <nss_dbdefs.h>
#include <sys/types.h>
-
+#include <sys/wait.h>
+#include <tsol/label.h>
+#include <zone.h>
+#include <bsm/devalloc.h>
#include "allocate.h"
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SUNW_OST_OSCMD"
#endif
+#define ALLOC "allocate"
+#define DEALLOC "deallocate"
+#define LIST "list_devices"
+
extern void audit_allocate_argv(int, int, char *[]);
extern int audit_allocate_record(int);
+int system_labeled = 0;
+static int windowing = 0;
+static int wdwmsg(char *name, char *msg);
+
static void
usage(int func)
{
- char *use[7];
+ if (system_labeled) {
+ char *use[9];
- use[0] = gettext("allocate [-s] [-U uname] [-F] device");
- use[1] = gettext("allocate [-s] [-U uname] -g dev_type");
- use[2] = gettext("deallocate [-s] [-F] device");
- use[3] = gettext("deallocate [-s] -I");
- use[4] = gettext("list_devices [-s] [-U uid] -l [device]");
- use[5] = gettext("list_devices [-s] [-U uid] -n [device]");
- use[6] = gettext("list_devices [-s] [-U uid] -u [device]");
+ use[0] = gettext("allocate [-s] [-w] [-U uname] [-z zonename] "
+ "[-F] device");
+ use[1] = gettext("allocate [-s] [-w] [-U uname] [-z zonename] "
+ "[-F] -g dev_type");
+ use[2] = gettext("deallocate [-s] [-w] [-z zonename] "
+ "[-F] device");
+ use[3] = gettext("deallocate [-s] [-w] [-z zonename] "
+ "[-F] -g dev_type");
+ use[4] = gettext("deallocate [-s] [-w] [-z zonename] -I");
+ use[5] = gettext("list_devices [-s] [-U uid] [-z zonename] "
+ "[-a] -l [device]");
+ use[6] = gettext("list_devices [-s] [-U uid] [-z zonename] "
+ "[-a] -n [device]");
+ use[7] = gettext("list_devices [-s] [-U uid] [-z zonename] "
+ "[-a] -u [device]");
+ use[8] = gettext("list_devices [-s] -d dev_type");
- switch (func) {
- case 0:
- (void) fprintf(stderr, "%s\n%s\n", use[0], use[1]);
- break;
- case 1:
- (void) fprintf(stderr, "%s\n%s\n", use[2], use[3]);
- break;
- case 2:
- (void) fprintf(stderr, "%s\n%s\n%s\n", use[4], use[5],
- use[6]);
- break;
- default:
- (void) fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
- use[0], use[1], use[2], use[3], use[4]);
+ switch (func) {
+ case 0:
+ (void) fprintf(stderr, "%s\n%s\n",
+ use[0], use[1]);
+ break;
+ case 1:
+ (void) fprintf(stderr, "%s\n%s\n%s\n",
+ use[2], use[3], use[4]);
+ break;
+ case 2:
+ (void) fprintf(stderr, "%s\n%s\n%s\n%s\n",
+ use[5], use[6], use[7], use[8]);
+ break;
+ default:
+ (void) fprintf(stderr,
+ "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
+ use[0], use[1], use[2], use[3], use[4],
+ use[5], use[6], use[7], use[8]);
+ }
+ } else {
+ char *use[7];
+
+ use[0] = gettext("allocate [-s] [-U uname] [-F] device");
+ use[1] = gettext("allocate [-s] [-U uname] -g dev_type");
+ use[2] = gettext("deallocate [-s] [-F] device");
+ use[3] = gettext("deallocate [-s] -I");
+ use[4] = gettext("list_devices [-s] [-U uid] -l [device]");
+ use[5] = gettext("list_devices [-s] [-U uid] -n [device]");
+ use[6] = gettext("list_devices [-s] [-U uid] -u [device]");
+
+ switch (func) {
+ case 0:
+ (void) fprintf(stderr, "%s\n%s\n",
+ use[0], use[1]);
+ break;
+ case 1:
+ (void) fprintf(stderr, "%s\n%s\n",
+ use[2], use[3]);
+ break;
+ case 2:
+ (void) fprintf(stderr, "%s\n%s\n%s\n",
+ use[4], use[5], use[6]);
+ break;
+ default:
+ (void) fprintf(stderr,
+ "%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
+ use[0], use[1], use[2], use[3], use[4],
+ use[5], use[6]);
+ }
}
exit(1);
}
-static void
+void
print_error(int error, char *name)
{
- char *msg;
+ char *msg;
+ char msgbuf[200];
switch (error) {
- case SYSERROR:
- msg = gettext("Unknown System error.");
- break;
- case IMPORT_ERR:
- msg = gettext(
- "User lacks authorization required for this operation.");
- break;
- case NODAENT:
- msg = gettext(
- "No device allocate file entry for specified device.");
- break;
- case NODMAPENT:
- msg = gettext(
- "No device maps file entry for specified device.");
- break;
- case DACLCK:
- msg = gettext("Concurrent operations for specified device, "
- "try later.");
- break;
- case DACACC:
- msg = gettext(
- "Can't access DAC file for the device specified.");
- break;
- case DEVLST:
- msg = gettext(
- "Could not use device list for the device specified.");
- break;
- case NALLOCU:
+ case ALLOCUERR:
msg = gettext("Specified device is allocated to another user.");
break;
- case NOTAUTH:
- msg = gettext("Not authorized for specified operation.");
+ case CHOWNERR:
+ msg = gettext("Failed to chown.");
break;
- case CNTFRC:
- msg = gettext("Can't force deallocate specified device.");
+ case CLEANERR:
+ msg = gettext("Unable to clean up device.");
break;
- case CNTDEXEC:
+ case CNTDEXECERR:
msg = gettext(
"Can't exec device-clean program for specified device.");
break;
- case NO_DEVICE:
- msg = gettext(
- "Can't find a device of type requested to allocate.");
+ case CNTFRCERR:
+ msg = gettext("Can't force deallocate specified device.");
break;
- case DSPMISS:
+ case DACACCERR:
+ msg = gettext(
+ "Can't access DAC file for the device specified.");
+ break;
+ case DAOFFERR:
+ msg = gettext(
+ "Device allocation feature is not activated "
+ "on this system.");
+ break;
+ case DAUTHERR:
+ msg = gettext("Device not allocatable.");
+ break;
+ case DEFATTRSERR:
+ msg = gettext("No default attributes for specified "
+ "device type.");
+ break;
+ case DEVLKERR:
+ msg = gettext("Concurrent operations for specified device, "
+ "try later.");
+ break;
+ case DEVLONGERR:
+ msg = gettext("Device name is too long.");
+ break;
+ case DEVNALLOCERR:
+ msg = gettext("Device not allocated.");
+ break;
+ case DEVNAMEERR:
+ msg = gettext("Device name error.");
+ break;
+ case DEVSTATEERR:
+ msg = gettext("Device specified is in allocate error state.");
+ break;
+ case DEVZONEERR:
+ msg = gettext("Can't find name of the zone to which "
+ "device is allocated.");
+ break;
+ case DSPMISSERR:
msg = gettext(
"Device special file(s) missing for specified device.");
break;
- case ALLOCERR:
- msg = gettext("Device specified is in allocate error state.");
+ case LABELRNGERR:
+ msg = gettext(
+ "Operation inconsistent with device's label range.");
break;
- case CHOWN_PERR:
- msg = gettext("Process lacks privilege required to chown().");
+ case LOGINDEVPERMERR:
+ msg = gettext("Device controlled by logindevperm(4)");
break;
- case ALLOC:
+ case NODAERR:
+ msg = gettext("No entry for specified device.");
+ break;
+ case NODMAPERR:
+ msg = gettext("No entry for specified device.");
+ break;
+ case PREALLOCERR:
msg = gettext("Device already allocated.");
break;
- case ALLOC_OTHER:
- msg = gettext("Device allocated to another user.");
+ case SETACLERR:
+ msg = gettext("Failed to set ACL.");
break;
- case NALLOC:
- msg = gettext("Device not allocated.");
+ case UAUTHERR:
+ msg = gettext(
+ "User lacks authorization required for this operation.");
break;
- case AUTHERR:
- msg = gettext("Device not allocatable.");
- break;
- case CLEAN_ERR:
- msg = gettext("Unable to clean up the device.");
- break;
- case SETACL_PERR:
- msg = gettext("Process lacks privilege required to set ACL.");
- break;
- case DEVNAME_ERR:
- msg = gettext("Error forming device name.");
- break;
- case DEVNAME_TOOLONG:
- msg = gettext("Device name is too long.");
+ case ZONEERR:
+ msg = gettext("Failed to configure device in zone.");
break;
default:
msg = gettext("Unknown error code.");
break;
}
- (void) fprintf(stderr, "%s: %s\n", name, msg);
- (void) fflush(stderr);
+ if (windowing) {
+ (void) snprintf(msgbuf, sizeof (msgbuf), "%s: %s\n", name, msg);
+ (void) wdwmsg(name, msgbuf);
+ } else {
+ (void) fprintf(stderr, "%s: %s\n", name, msg);
+ (void) fflush(stderr);
+ }
}
char *newenv[] = {"PATH=/usr/bin:/usr/sbin",
@@ -193,16 +260,21 @@
int
main(int argc, char *argv[], char *envp[])
{
- char *name, *env;
- int func = -1, optflg = 0, error = 0, c;
- uid_t uid = getuid();
- char *uname = NULL, *device = NULL;
- struct passwd *pw_ent;
- int env_num = 1; /* PATH= is 0 entry */
+ char *name, *env;
+ int func = -1, optflg = 0, error = 0, c;
+ zoneid_t zoneid;
+ uid_t uid;
+ char *uname = NULL, *device = NULL, *zonename = NULL;
+ char *zname;
+ char pw_buf[NSS_BUFLEN_PASSWD];
+ struct passwd pw_ent;
+ int env_num = 1; /* PATH= is 0 entry */
(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);
+ system_labeled = is_system_labeled();
+
/*
* get all enviroment variables
* which affect on internationalization.
@@ -234,43 +306,75 @@
else
name++;
- if (strcmp(name, "allocate") == 0)
+ if (strcmp(name, ALLOC) == 0)
func = 0;
- else if (strcmp(name, "deallocate") == 0)
+ else if (strcmp(name, DEALLOC) == 0)
func = 1;
- else if (strcmp(name, "list_devices") == 0)
+ else if (strcmp(name, LIST) == 0)
func = 2;
- else {
- usage(ALL);
- }
+ else
+ usage(-1);
audit_allocate_argv(func, argc, argv);
+ if (system_labeled) {
+ /*
+ * allocate, deallocate, list_devices run in
+ * global zone only.
+ */
+ zoneid = getzoneid();
+ if (zoneid != GLOBAL_ZONEID)
+ exit(GLOBALERR);
+ zname = GLOBAL_ZONENAME;
+ /*
+ * check if device allocation is activated.
+ */
+ if (da_is_on() == 0) {
+ (void) fprintf(stderr, "%s%s",
+ gettext("Turn device allocation on"),
+ gettext(" to use this feature.\n"));
+ exit(DAOFFERR);
+ }
+ }
+
if (func == 0) { /* allocate */
- while ((c = getopt(argc, argv, "sU:Fg")) != -1) {
+ while ((c = getopt(argc, argv, "gswz:FU:")) != -1) {
switch (c) {
+ case 'g':
+ optflg |= TYPE;
+ break;
case 's':
optflg |= SILENT;
break;
+ case 'w':
+ if (system_labeled) {
+ optflg |= WINDOWING;
+ windowing = 1;
+ } else {
+ usage(func);
+ }
+ break;
+ case 'z':
+ if (system_labeled) {
+ optflg |= ZONENAME;
+ zonename = optarg;
+ } else {
+ usage(func);
+ }
+ break;
+ case 'F':
+ optflg |= FORCE;
+ break;
case 'U':
optflg |= USERNAME;
uname = optarg;
break;
- case 'g':
- optflg |= TYPE;
- break;
- case 'F':
- optflg |= FORCE;
- break;
case '?':
default :
usage(func);
}
}
- if ((optflg & TYPE) && (optflg & FORCE))
- usage(func);
-
/*
* allocate(1) must be supplied with one device argument
*/
@@ -282,11 +386,33 @@
}
else if (func == 1) { /* deallocate */
- while ((c = getopt(argc, argv, "sFI")) != -1) {
+ while ((c = getopt(argc, argv, "gswz:FI")) != -1) {
switch (c) {
+ case 'g':
+ if (system_labeled)
+ optflg |= TYPE;
+ else
+ usage(func);
+ break;
case 's':
optflg |= SILENT;
break;
+ case 'w':
+ if (system_labeled) {
+ optflg |= WINDOWING;
+ windowing = 1;
+ } else {
+ usage(func);
+ }
+ break;
+ case 'z':
+ if (system_labeled) {
+ optflg |= ZONENAME;
+ zonename = optarg;
+ } else {
+ usage(func);
+ }
+ break;
case 'F':
optflg |= FORCE;
break;
@@ -302,6 +428,9 @@
if ((optflg & FORCE) && (optflg & FORCE_ALL))
usage(func);
+ if (system_labeled && ((optflg & FORCE_ALL) && (optflg & TYPE)))
+ usage(func);
+
/*
* deallocate(1) must be supplied with one device
* argument unless the '-I' argument is supplied
@@ -320,35 +449,86 @@
}
else if (func == 2) { /* list_devices */
- while ((c = getopt(argc, argv, "sU:lnu")) != -1) {
+ while ((c = getopt(argc, argv, "adlnsuwz:U:")) != -1) {
switch (c) {
+ case 'a':
+ if (system_labeled) {
+ /*
+ * list auths, cleaning programs,
+ * labels.
+ */
+ optflg |= LISTATTRS;
+ } else {
+ usage(func);
+ }
+ break;
+ case 'd':
+ if (system_labeled) {
+ /*
+ * list devalloc_defaults
+ */
+ optflg |= LISTDEFS;
+ } else {
+ usage(func);
+ }
+ break;
+ case 'l':
+ optflg |= LISTALL;
+ break;
+ case 'n':
+ optflg |= LISTFREE;
+ break;
case 's':
optflg |= SILENT;
break;
+ case 'u':
+ optflg |= LISTALLOC;
+ break;
+ case 'w':
+ if (system_labeled) {
+ /*
+ * Private interface for use by
+ * list_devices GUI
+ */
+ optflg |= WINDOWING;
+ } else {
+ usage(func);
+ }
+ break;
+ case 'z':
+ if (system_labeled) {
+ optflg |= ZONENAME;
+ zonename = optarg;
+ } else {
+ usage(func);
+ }
+ break;
case 'U':
optflg |= USERID;
uid = atoi(optarg);
break;
- case 'l':
- optflg |= LIST;
- break;
- case 'n':
- optflg |= FREE;
- break;
- case 'u':
- optflg |= CURRENT;
- break;
case '?':
default :
usage(func);
}
}
- if (((optflg & LIST) && (optflg & FREE)) ||
- ((optflg & LIST) && (optflg & CURRENT)) ||
- ((optflg & FREE) && (optflg & CURRENT)) ||
- (!(optflg & (LIST | FREE | CURRENT))))
+ if (system_labeled) {
+ if (((optflg & LISTALL) && (optflg & LISTFREE)) ||
+ ((optflg & LISTALL) && (optflg & LISTALLOC)) ||
+ ((optflg & LISTFREE) && (optflg & LISTALLOC)) ||
+ ((optflg & LISTDEFS) &&
+ (optflg & (LISTATTRS | LISTALL | LISTFREE |
+ LISTALLOC | USERID | WINDOWING | ZONENAME))) ||
+ (!(optflg & (LISTALL | LISTFREE | LISTALLOC |
+ LISTDEFS | WINDOWING))))
+ usage(func);
+ } else if (((optflg & LISTALL) && (optflg & LISTFREE)) ||
+ ((optflg & LISTALL) && (optflg & LISTALLOC)) ||
+ ((optflg & LISTFREE) && (optflg & LISTALLOC)) ||
+ (!(optflg & (LISTALL | LISTFREE | LISTALLOC)))) {
usage(func);
+ }
/*
* list_devices(1) takes an optional device argument
@@ -363,31 +543,47 @@
}
if (optflg & USERNAME) {
- if ((pw_ent = getpwnam(uname)) == NULL) {
- (void) fprintf(stderr, gettext(
- "Invalid user name -- %s -- \n"), uname);
+ if (getpwnam_r(uname, &pw_ent, pw_buf, sizeof (pw_buf)) ==
+ NULL) {
+ (void) fprintf(stderr,
+ gettext("Invalid user name -- %s -- \n"), uname);
exit(1);
}
- uid = pw_ent->pw_uid;
- }
-
- if (optflg & USERID) {
- if ((pw_ent = getpwuid(uid)) == NULL) {
- (void) fprintf(stderr, gettext(
- "Invalid user ID -- %d -- \n"), uid);
+ uid = pw_ent.pw_uid;
+ } else if (optflg & USERID) {
+ if (getpwuid_r(uid, &pw_ent, pw_buf, sizeof (pw_buf)) == NULL) {
+ (void) fprintf(stderr,
+ gettext("Invalid user ID -- %d -- \n"), uid);
exit(1);
}
- uid = pw_ent->pw_uid;
+ uid = pw_ent.pw_uid;
+ } else {
+ /*
+ * caller's uid is the default if no user specified.
+ */
+ uid = getuid();
}
- if (func == 0) {
- error = allocate(optflg, uid, device);
- } else if (func == 1) {
- error = deallocate(optflg, uid, device);
- } else if (func == 2) {
- error = list_devices(optflg, uid, device);
+ /*
+ * global zone is the default if no zonename specified.
+ */
+ if (zonename == NULL) {
+ zonename = zname;
+ } else {
+ if (zone_get_id(zonename, &zoneid) != 0) {
+ (void) fprintf(stderr,
+ gettext("Invalid zone name -- %s -- \n"), zonename);
+ exit(1);
+ }
}
+ if (func == 0)
+ error = allocate(optflg, uid, device, zonename);
+ else if (func == 1)
+ error = deallocate(optflg, uid, device, zonename);
+ else if (func == 2)
+ error = list_devices(optflg, uid, device, zonename);
+
(void) audit_allocate_record(error);
if (error) {
@@ -398,3 +594,41 @@
return (0);
}
+
+/*
+ * Display error message via /etc/security/lib/wdwmsg script
+ */
+static int
+wdwmsg(char *name, char *msg)
+{
+ pid_t child_pid;
+ pid_t wait_pid;
+ int child_status;
+
+ /* Fork a child */
+ switch (child_pid = fork()) {
+ case -1: /* FAILURE */
+ return (-1);
+ break;
+
+ case 0: /* CHILD */
+ (void) execl("/etc/security/lib/wdwmsg", "wdwmsg", msg,
+ name, "OK", NULL);
+ /* If exec failed, send message to stderr */
+ (void) fprintf(stderr, "%s", msg);
+ return (-1);
+
+ default: /* PARENT */
+ /* Wait for child to exit */
+ wait_pid = waitpid(child_pid, &child_status, 0);
+ if ((wait_pid < 0) && (errno == ECHILD))
+ return (0);
+ if ((wait_pid < 0) || (wait_pid != child_pid))
+ return (-1);
+ if (WIFEXITED(child_status))
+ return (WEXITSTATUS(child_status));
+ if (WIFSIGNALED(child_status))
+ return (WTERMSIG(child_status));
+ return (0);
+ }
+}
diff --git a/usr/src/cmd/allocate/allocate.h b/usr/src/cmd/allocate/allocate.h
index 29f222a..f6a7956 100644
--- a/usr/src/cmd/allocate/allocate.h
+++ b/usr/src/cmd/allocate/allocate.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,6 +18,7 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
@@ -34,59 +34,58 @@
#endif
/* Option Flags */
-#define SILENT 0001 /* -s */
-#define USERID 0002 /* -U <uid> for list_devices(1) */
-#define LIST 0004 /* -l */
-#define FREE 0010 /* -n */
-#define CURRENT 0020 /* -u */
-#define FORCE 0040 /* -F */
-#define FORCE_ALL 0100 /* -I */
-#define TYPE 0200 /* -g */
-#define USERNAME 0400 /* -U <username> for allocate(1) */
+#define LISTATTRS 0x00000001 /* -a */
+#define LISTDEFS 0x00000002 /* -d */
+#define TYPE 0x00000004 /* -g */
+#define LISTALL 0x00000008 /* -l */
+#define LISTFREE 0x00000010 /* -n */
+#define SILENT 0x00000020 /* -s */
+#define LISTALLOC 0x00000040 /* -u */
+#define WINDOWING 0x00000080 /* -w */
+#define ZONENAME 0x00000100 /* -z */
+#define BOOT 0x00000200 /* -B */
+#define FORCE 0x00000400 /* -F */
+#define FORCE_ALL 0x00000800 /* -I */
+#define USERID 0x00001000 /* -U for list_devices */
+#define USERNAME 0x00002000 /* -U for allocate */
/* Misc. */
-#define ALL -1
+#define CLEAN_MOUNT 11 /* Also defined in disk_clean.sh */
-/* Error returns start at 4 */
-#define SYSERROR 4
-#define DACLCK 5
-#define DACACC 6
-#define DEVLST 7
-#define NALLOCU 8
-#define NOTAUTH 9
-#define CNTFRC 10
-#define CNTDEXEC 11
-#define NO_DEVICE 12
-#define DSPMISS 13
-#define ALLOCERR 14
-#define IMPORT_ERR 15
-#define NODAENT 16
-#define NODMAPENT 17
-#define SETACL_PERR 18
-#define CHOWN_PERR 19
-#define ALLOC 20
-#define ALLOC_OTHER 21
-#define NALLOC 22
-#define AUTHERR 23
-#define CLEAN_ERR 24
-#define DEVNAME_ERR 25
-#define DEVNAME_TOOLONG 26
+#define ALLOCUERR 1
+#define CHOWNERR 2
+#define CLEANERR 3
+#define CNTDEXECERR 4
+#define CNTFRCERR 5
+#define DACACCERR 6
+#define DAOFFERR 7
+#define DAUTHERR 8
+#define DEFATTRSERR 9
+#define DEVLKERR 10
+#define DEVLONGERR 11
+#define DEVNALLOCERR 12
+#define DEVNAMEERR 13
+#define DEVSTATEERR 14
+#define DEVZONEERR 15
+#define DSPMISSERR 16
+#define GLOBALERR 17
+#define LABELRNGERR 18
+#define LOGINDEVPERMERR 19
+#define NODAERR 20
+#define NODMAPERR 21
+#define PREALLOCERR 22
+#define SETACLERR 23
+#define UAUTHERR 24
+#define ZONEERR 25
-/* Tunable Parameters */
-#define DEV_DIR "/dev"
-#define DAC_DIR "/etc/security/dev"
-#define SECLIB "/etc/security/lib"
-#define ALLOC_MODE 0600
-#define DEALLOC_MODE 0000
#define ALLOC_ERR_MODE 0100
-#define ALLOC_UID (uid_t)0 /* root */
-#define ALLOC_GID (gid_t)1 /* other */
+#define ALLOC_INVALID 0700
/* Functions */
-extern int allocate(int optflg, uid_t uid, char *device);
-extern int deallocate(int optflg, uid_t uid, char *device);
-extern int list_devices(int optflg, uid_t uid, char *device);
+extern int allocate(int optflg, uid_t uid, char *device, char *zonename);
+extern int deallocate(int optflg, uid_t uid, char *device, char *zonename);
+extern int list_devices(int optflg, uid_t uid, char *device, char *zonename);
#ifdef __cplusplus
}
diff --git a/usr/src/cmd/allocate/allocate3.c b/usr/src/cmd/allocate/allocate3.c
index 1e24722..7b4ef26 100644
--- a/usr/src/cmd/allocate/allocate3.c
+++ b/usr/src/cmd/allocate/allocate3.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,6 +18,7 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
@@ -38,11 +38,16 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <strings.h>
#include <unistd.h>
-
#include <bsm/devices.h>
-#include <bsm/audit_uevents.h>
-
+#include <sys/acl.h>
+#include <tsol/label.h>
+#include <syslog.h>
+#include <limits.h>
+#include <user_attr.h>
+#include <secdb.h>
+#include <sys/mkdev.h>
#include <sys/acl.h>
#include <sys/file.h>
#include <sys/procfs.h>
@@ -52,198 +57,510 @@
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
-
+#include <utime.h>
+#include <libgen.h>
+#include <zone.h>
+#include <nss_dbdefs.h>
+#include <bsm/devalloc.h>
#include "allocate.h"
-#ifdef DEBUG
+extern void print_error(int, char *);
+
+#if defined(DEBUG) || defined(lint)
#define dprintf(s, a) (void) fprintf(stderr, s, a)
#define dperror(s) perror(s)
#else /* !DEBUG */
-#define dprintf(s, a)
-#define dperror(s)
+#define dprintf(s, a) 0
+#define dperror(s) 0
#endif /* DEBUG */
-#define EXIT(number) { \
- if (optflg & FORCE) \
- error = number; \
- else \
- return (number); \
-}
-
+#define DEV_ERRORED(sbuf) (((sbuf).st_mode & ~S_IFMT) == ALLOC_ERR_MODE)
+#define DEV_INVALID(sbuf) (((sbuf).st_mode & ~S_IFMT) == ALLOC_INVALID)
#define DEV_ALLOCATED(sbuf) ((sbuf).st_uid != ALLOC_UID || \
- ((sbuf).st_mode & ~S_IFMT) == ALLOC_MODE)
+ !(((sbuf).st_mode & ~S_IFMT) == DEALLOC_MODE || \
+ DEV_ERRORED(sbuf) || DEV_INVALID(sbuf)))
+#define ALLOC_CLEAN "-A"
+#define DEALLOC_CLEAN "-D"
+#define DAC_DIR "/etc/security/dev"
#define DEVICE_AUTH_SEPARATOR ","
-#define PROCFS "/proc/"
+#define LOCALDEVICE "/dev/console"
+#define PROCFS "/proc/"
+#define SFF_NO_ERROR 0x1
+
+#define ALLOC_BY_NONE -1
+#define CHECK_DRANGE 1
+#define CHECK_URANGE 2
+#define CHECK_ZLABEL 3
extern void audit_allocate_list(char *);
extern void audit_allocate_device(char *);
+extern int system_labeled;
extern char *newenv[];
+struct state_file {
+ int sf_flags;
+ char sf_path[MAXPATHLEN];
+};
+
+struct file_info {
+ struct stat fi_stat;
+ char *fi_message;
+};
+
+struct zone_path {
+ int count;
+ char **path;
+};
+
+struct devnames {
+ char **dnames;
+};
+
+static int _dev_file_name(struct state_file *, devmap_t *);
+static int lock_dev(char *);
+static int _check_label(devalloc_t *, char *, uid_t, int);
+static int create_znode(char *, struct zone_path *, devmap_t *);
+static int remove_znode(char *, devmap_t *);
+static int update_device(char **, char *, int);
+
/*
- * Checks if the specified user has any of the authorizations in the
- * list of authorizations
+ * checks if the invoking user is local to the device
*/
-
-static int
-is_authorized(char *auth_list, uid_t uid)
+/*ARGSUSED*/
+int
+_is_local(uid_t uid)
{
- char *auth;
- struct passwd *pw;
+ struct stat statbuf;
- pw = getpwuid(uid);
- if (pw == NULL) {
- dprintf("Can't get user info for uid=%d\n", (int)uid);
+ if (stat(LOCALDEVICE, &statbuf) == 0 &&
+ statbuf.st_uid == uid)
+ return (1);
+
+ return (0);
+}
+
+/*
+ * Checks if the user with the specified uid has the specified authorization
+ */
+int
+_is_authorized(char *auths, uid_t uid)
+{
+ char *dcp, *authlist, *lasts;
+ char pw_buf[NSS_BUFLEN_PASSWD];
+ struct passwd pw_ent;
+
+ /*
+ * first, the easy cases
+ */
+ if (strcmp(auths, "@") == 0)
+ return (1);
+ if (strcmp(auths, "*") == 0)
+ return (ALLOC_BY_NONE);
+ if (getpwuid_r(uid, &pw_ent, pw_buf, sizeof (pw_buf)) == NULL)
return (0);
+ if (strpbrk(auths, DEVICE_AUTH_SEPARATOR) == NULL)
+ return (chkauthattr(auths, pw_ent.pw_name));
+ authlist = strdup(auths);
+ if (authlist == NULL)
+ return (0);
+ for (dcp = authlist;
+ (dcp = strtok_r(dcp, DEVICE_AUTH_SEPARATOR, &lasts)) != NULL;
+ dcp = NULL) {
+ if (chkauthattr(dcp, pw_ent.pw_name))
+ break;
}
+ free(authlist);
- auth = strtok(auth_list, DEVICE_AUTH_SEPARATOR);
- while (auth != NULL) {
- if (chkauthattr(auth, pw->pw_name))
- return (1);
- auth = strtok(NULL, DEVICE_AUTH_SEPARATOR);
- }
- return (0);
+ return (dcp != NULL);
}
-static int
-check_devs(char *list)
+/*
+ * Checks if the specified user has authorization for the device
+ */
+int
+_is_dev_authorized(devalloc_t *da, uid_t uid)
{
- char *file;
+ int ares;
+ char *auth_list, *dcp, *subauth = NULL;
- file = strtok(list, " ");
- while (file != NULL) {
+ auth_list = da->da_devauth;
+ if (auth_list == NULL)
+ return (0);
+ dcp = strpbrk(auth_list, KV_TOKEN_DELIMIT);
+ if (dcp == NULL)
+ return (_is_authorized(auth_list, uid));
+ if (_is_local(uid)) {
+ /* the local authorization is before the separator */
+ ares = dcp - auth_list;
+ subauth = malloc(ares + 1);
+ if (subauth == NULL)
+ return (0);
+ (void) strlcpy(subauth, auth_list, (ares + 1));
+ auth_list = subauth;
+ } else
+ auth_list = dcp + 1;
+ ares = _is_authorized(auth_list, uid);
+ if (subauth != NULL)
+ free(subauth);
- if (access(file, F_OK) == -1) {
- dprintf("Unable to access file %s\n", file);
- return (-1);
+ return (ares);
+}
+
+int
+check_devs(devmap_t *dm)
+{
+ int status = 0;
+ char **file;
+
+ if (dm->dmap_devarray == NULL)
+ return (NODMAPERR);
+ for (file = dm->dmap_devarray; *file != NULL; file++) {
+ if ((status = access(*file, F_OK)) == -1) {
+ dprintf("Unable to access file %s\n", *file);
+ break;
}
- file = strtok(NULL, " ");
}
+
+ return (status);
+}
+
+int
+print_da_defs(da_defs_t *da_defs)
+{
+ char optbuf[BUFSIZ];
+ char *p = NULL;
+
+ if (da_defs->devopts == NULL) {
+ dprintf("No default attributes for %s\n", da_defs->devtype);
+ return (DEFATTRSERR);
+ }
+ (void) printf("dev_type=%s\n", da_defs->devtype);
+ if (_kva2str(da_defs->devopts, optbuf, sizeof (optbuf), KV_ASSIGN,
+ KV_TOKEN_DELIMIT) == 0) {
+ if (p = rindex(optbuf, ':'))
+ *p = '\0';
+ (void) printf("\t%s\n", optbuf);
+ }
+
return (0);
}
-static void
-print_dev(devmap_t *dev_list)
+void
+print_dev_attrs(int optflag, devalloc_t *da, devmap_t *dm,
+ struct file_info *fip)
{
- char *file;
+ char *p = NULL;
+ char optbuf[BUFSIZ];
- (void) printf(gettext("device: %s "), dev_list->dmap_devname);
- (void) printf(gettext("type: %s "), dev_list->dmap_devtype);
- (void) printf(gettext("files: "));
+ (void) printf("device=%s%s", dm->dmap_devname, KV_DELIMITER);
+ (void) printf("type=%s%s", dm->dmap_devtype, KV_DELIMITER);
+ (void) printf("auths=%s%s",
+ (da->da_devauth ? da->da_devauth : ""), KV_DELIMITER);
+ (void) printf("clean=%s%s",
+ (da->da_devexec ? da->da_devexec : ""), KV_DELIMITER);
+ if (da->da_devopts != NULL) {
+ if (_kva2str(da->da_devopts, optbuf, sizeof (optbuf),
+ KV_ASSIGN, KV_TOKEN_DELIMIT) == 0) {
+ if (p = rindex(optbuf, ':'))
+ *p = '\0';
+ (void) printf("%s", optbuf);
+ }
+ }
+ (void) printf("%s", KV_DELIMITER);
+ if (optflag & WINDOWING) {
+ if (DEV_INVALID(fip->fi_stat))
+ (void) printf("owner=/INVALID:%s%s", fip->fi_message,
+ KV_DELIMITER);
+ else if (DEV_ERRORED(fip->fi_stat))
+ (void) printf("owner=/ERROR%s", KV_DELIMITER);
+ else if (!DEV_ALLOCATED(fip->fi_stat))
+ (void) printf("owner=/FREE%s", KV_DELIMITER);
+ else
+ (void) printf("owner=%ld%s", fip->fi_stat.st_uid,
+ KV_DELIMITER);
+ }
+ (void) printf("files=%s", dm->dmap_devlist);
+ (void) printf("\n");
+}
- file = strtok(dev_list->dmap_devlist, " ");
- while (file != NULL) {
- (void) printf("%s ", file);
- file = strtok(NULL, " ");
+void
+print_dev(devmap_t *dm)
+{
+ char **file;
+
+ (void) printf(gettext("device: %s "), dm->dmap_devname);
+ (void) printf(gettext("type: %s "), dm->dmap_devtype);
+ (void) printf(gettext("files:"));
+ file = dm->dmap_devarray;
+ if (file != NULL) {
+ for (; *file != NULL; file++)
+ (void) printf(" %s", *file);
}
(void) printf("\n");
}
-static int
-list_device(int optflg, uid_t uid, char *device)
+/* ARGSUSED */
+int
+_list_device(int optflag, uid_t uid, devalloc_t *da, char *zonename)
{
- devalloc_t *dev_ent;
- devmap_t *dev_list;
- char file_name[MAXPATHLEN];
- struct stat stat_buf;
- char *list;
- int bytes_formated;
+ int bytes = 0;
+ int error = 0;
+ int is_authorized = 0;
+ char *fname = NULL;
+ char file_name[MAXPATHLEN];
+ devmap_t *dm;
+ struct file_info fi;
+ struct state_file sf;
- if ((dev_ent = getdanam(device)) == NULL) {
- if ((dev_list = getdmapdev(device)) == NULL) {
- dprintf("Unable to find %s in the allocate database\n",
- device);
- return (NODMAPENT);
- } else if ((dev_ent = getdanam(dev_list->dmap_devname)) ==
- NULL) {
- dprintf("Unable to find %s in the allocate database\n",
- device);
- return (NODAENT);
+ setdmapent();
+ if ((dm = getdmapnam(da->da_devname)) == NULL) {
+ enddmapent();
+ dprintf("Unable to find %s in the maps database\n",
+ da->da_devname);
+ return (NODMAPERR);
+ }
+ enddmapent();
+ if (system_labeled) {
+ if ((error = _dev_file_name(&sf, dm)) != 0) {
+ freedmapent(dm);
+ dprintf("Unable to find %s device files\n",
+ da->da_devname);
+ error = NODMAPERR;
+ goto out;
}
- } else if ((dev_list = getdmapnam(device)) == NULL) {
- dprintf("Unable to find %s in the allocate database\n", device);
- return (NODMAPENT);
+ fname = sf.sf_path;
+ } else {
+ bytes = snprintf(file_name, MAXPATHLEN, "%s/%s", DAC_DIR,
+ da->da_devname);
+ if (bytes <= 0) {
+ error = DEVNAMEERR;
+ goto out;
+ } else if (bytes >= MAXPATHLEN) {
+ dprintf("device name %s is too long.\n",
+ da->da_devname);
+ error = DEVLONGERR;
+ goto out;
+ }
+ fname = file_name;
}
-
- bytes_formated = snprintf(file_name, MAXPATHLEN, "%s/%s", DAC_DIR,
- dev_ent->da_devname);
- if (bytes_formated <= 0) {
- return (DEVNAME_ERR);
- } else if (bytes_formated >= MAXPATHLEN) {
- dprintf("device name %s is too long.\n", dev_ent->da_devname);
- return (DEVNAME_TOOLONG);
- }
-
- if (stat(file_name, &stat_buf)) {
- dprintf("Unable to stat %s\n", file_name);
+ if (stat(fname, &fi.fi_stat) != 0) {
+ dprintf("Unable to stat %s\n", fname);
dperror("Error:");
- return (DACACC);
+ error = DACACCERR;
+ goto out;
}
-
- if ((optflg & FREE) && DEV_ALLOCATED(stat_buf))
- return (ALLOC);
-
- if ((optflg & LIST) && DEV_ALLOCATED(stat_buf) &&
- (stat_buf.st_uid != uid))
- return (ALLOC_OTHER);
-
- if ((optflg & CURRENT) && (stat_buf.st_uid != uid))
- return (NALLOC);
-
- if ((stat_buf.st_mode & ~S_IFMT) == ALLOC_ERR_MODE)
- return (ALLOCERR);
-
- if ((list = strdup(dev_list->dmap_devlist)) == NULL)
- return (SYSERROR);
-
- if (check_devs(list) == -1) {
- free(list);
- return (DSPMISS);
+ if (optflag & USERID)
+ is_authorized = 1;
+ else
+ is_authorized = _is_dev_authorized(da, uid);
+ if (optflag & LISTFREE) { /* list_devices -n */
+ /*
+ * list all free devices
+ */
+ if (DEV_ALLOCATED(fi.fi_stat)) {
+ error = PREALLOCERR;
+ goto out;
+ }
+ if (system_labeled) {
+ /*
+ * for this free device, check if -
+ * 1. user has authorization to allocate
+ * 2. the zone label is within the label range of the
+ * device
+ */
+ if (is_authorized == ALLOC_BY_NONE) {
+ error = DAUTHERR;
+ goto out;
+ } else if (is_authorized == 0) {
+ error = UAUTHERR;
+ goto out;
+ }
+ if (_check_label(da, zonename, uid,
+ CHECK_DRANGE) != 0) {
+ error = LABELRNGERR;
+ goto out;
+ }
+ }
+ } else if (optflag & LISTALLOC) { /* list_devices -u */
+ /*
+ * list all allocated devices
+ */
+ if (!DEV_ALLOCATED(fi.fi_stat)) {
+ error = DEVNALLOCERR;
+ goto out;
+ }
+ if (fi.fi_stat.st_uid != uid) {
+ error = DEVSTATEERR;
+ goto out;
+ }
+ if (system_labeled) {
+ /*
+ * check if the zone label equals the label at which
+ * the device is allocated.
+ */
+ if (_check_label(da, zonename, uid,
+ CHECK_ZLABEL) != 0) {
+ error = LABELRNGERR;
+ goto out;
+ }
+ }
+ } else if (optflag & LISTALL) { /* list_devices -l */
+ /*
+ * list all devices - free and allocated - available
+ */
+ if (DEV_ALLOCATED(fi.fi_stat)) {
+ if (optflag & WINDOWING &&
+ (is_authorized == ALLOC_BY_NONE)) {
+ /*
+ * don't complain if we're here for the GUI.
+ */
+ error = 0;
+ } else if (fi.fi_stat.st_uid != uid) {
+ if (!(optflag & WINDOWING)) {
+ error = ALLOCUERR;
+ goto out;
+ }
+ }
+ if (system_labeled && !(optflag & WINDOWING)) {
+ /*
+ * if we're not displaying in the GUI,
+ * check if the zone label equals the label
+ * at which the device is allocated.
+ */
+ if (_check_label(da, zonename, uid,
+ CHECK_ZLABEL) != 0) {
+ error = LABELRNGERR;
+ goto out;
+ }
+ }
+ } else if (system_labeled && !(optflag & WINDOWING)) {
+ /*
+ * if we're not displaying in the GUI,
+ * for this free device, check if -
+ * 1. user has authorization to allocate
+ * 2. the zone label is within the label range of the
+ * device
+ */
+ if (is_authorized == ALLOC_BY_NONE) {
+ error = DAUTHERR;
+ goto out;
+ } else if (is_authorized == 0) {
+ error = UAUTHERR;
+ goto out;
+ }
+ if (_check_label(da, zonename, uid,
+ CHECK_DRANGE) != 0) {
+ error = LABELRNGERR;
+ goto out;
+ }
+ }
}
+ if (system_labeled && DEV_ERRORED(fi.fi_stat) && !(optflag & LISTALL)) {
+ error = DEVSTATEERR;
+ goto out;
+ }
+ if (check_devs(dm) == -1) {
+ error = DSPMISSERR;
+ goto out;
+ }
+ if (optflag & LISTATTRS)
+ print_dev_attrs(optflag, da, dm, &fi);
+ else
+ print_dev(dm);
- print_dev(dev_list);
+ error = 0;
- free(list);
- return (0);
+out:
+ freedmapent(dm);
+ return (error);
}
+/* ARGSUSED */
int
-list_devices(int optflg, uid_t uid, char *device)
+list_devices(int optflag, uid_t uid, char *device, char *zonename)
{
- DIR * dev_dir;
- struct dirent *dac_file;
- int error = 0, ret_code = 1;
+ int error = 0;
+ da_defs_t *da_defs;
+ devalloc_t *da;
- if (optflg & USERID) {
- if (!is_authorized(DEVICE_REVOKE_AUTH, getuid()))
- return (NOTAUTH);
+ if (system_labeled && optflag & WINDOWING && !(optflag & LISTATTRS)) {
+ /*
+ * Private interface for GUI.
+ */
+ (void) lock_dev(NULL);
+ (void) puts(DA_DB_LOCK);
+ return (0);
}
- setdaent();
-
- if (device) {
- return (list_device(optflg, uid, device));
+ if (optflag & USERID) {
+ /*
+ * we need device.revoke to list someone else's devices
+ */
+ if (!_is_authorized(DEVICE_REVOKE_AUTH, getuid()))
+ return (UAUTHERR);
}
-
- if ((dev_dir = opendir(DAC_DIR)) == NULL) {
-
- dperror("Can't open DAC_DIR");
- return (DACACC);
- }
-
- while ((dac_file = readdir(dev_dir)) != NULL) {
- if ((strcmp(dac_file->d_name, ".") == 0) ||
- (strcmp(dac_file->d_name, "..") == 0)) {
- continue;
- } else {
- error = list_device(optflg, uid, dac_file->d_name);
- ret_code = ret_code ? error : ret_code;
+ if (system_labeled) {
+ if (!(optflag & USERID) &&
+ !_is_authorized(DEFAULT_DEV_ALLOC_AUTH, uid))
+ /*
+ * we need device.allocate to list our devices
+ */
+ return (UAUTHERR);
+ if (optflag & LISTDEFS) {
+ /*
+ * list default attrs from devalloc_defaults
+ */
+ setdadefent();
+ if (device) {
+ /*
+ * list default attrs for this device type
+ */
+ da_defs = getdadeftype(device);
+ if (da_defs == NULL) {
+ enddadefent();
+ dprintf("No default attributes for "
+ "%s\n", device);
+ return (DEFATTRSERR);
+ }
+ error = print_da_defs(da_defs);
+ freedadefent(da_defs);
+ } else {
+ /*
+ * list everything in devalloc_defaults
+ */
+ while ((da_defs = getdadefent()) != NULL) {
+ (void) print_da_defs(da_defs);
+ freedadefent(da_defs);
+ }
+ }
+ enddadefent();
+ return (error);
}
}
- (void) closedir(dev_dir);
+ setdaent();
+ if (device) {
+ /*
+ * list this device
+ */
+ if ((da = getdanam(device)) == NULL) {
+ enddaent();
+ return (NODAERR);
+ }
+ error = _list_device(optflag, uid, da, zonename);
+ freedaent(da);
+ } else {
+ /*
+ * list all devices
+ */
+ while ((da = getdaent()) != NULL) {
+ (void) _list_device(optflag, uid, da, zonename);
+ freedaent(da);
+ }
+ }
enddaent();
- return (ret_code);
+
+ return (error);
}
/*
@@ -251,24 +568,41 @@
* This uses a fancy chmod() by setting a minimal ACL which sets the mode
* and discards any existing ACL.
*/
-
-static int
-newdac(char *file, uid_t owner, gid_t group, o_mode_t mode)
+int
+_newdac(char *file, uid_t owner, gid_t group, o_mode_t mode)
{
- int err = 0;
+ int err = 0;
- do {
+ if (mode == ALLOC_MODE) {
if (chown(file, owner, group) == -1) {
- dperror("newdac, unable to chown");
- err = CHOWN_PERR;
+ dperror("newdac: unable to chown");
+ err = CHOWNERR;
+ }
+ } else do {
+ if (chown(file, owner, group) == -1) {
+ dperror("newdac: unable to chown");
+ err = CHOWNERR;
}
} while (fdetach(file) == 0);
- err = acl_strip(file, owner, group, (mode_t)mode);
+ if (err)
+ return (err);
+
+ if (strncmp(file, "/dev/", strlen("/dev/")) != 0) {
+ /*
+ * This could be a SunRay device that is in /tmp.
+ */
+ if (chmod(file, mode) == -1) {
+ dperror("newdac: unable to chmod");
+ err = SETACLERR;
+ }
+ } else {
+ err = acl_strip(file, owner, group, (mode_t)mode);
+ }
if (err != 0) {
- dperror("newdac, unable to setacl");
- err = SETACL_PERR;
+ dperror("newdac: unable to setacl");
+ err = SETACLERR;
}
return (err);
@@ -277,41 +611,60 @@
static int
lock_dev(char *file)
{
- int fd;
+ int lockfd = -1;
+ if ((file == NULL) || system_labeled)
+ file = DA_DEV_LOCK;
dprintf("locking %s\n", file);
- if ((fd = open(file, O_RDWR)) == -1) {
- dperror("lock_dev, cannot open DAC file");
- return (DACACC);
+ if ((lockfd = open(file, O_RDWR | O_CREAT, 0600)) == -1) {
+ dperror("lock_dev: cannot open lock file");
+ return (DEVLKERR);
}
-
- if (lockf(fd, F_TLOCK, 0) == -1) {
- dperror("lock_dev, cannot set lock");
- return (DACLCK);
+ if (lockf(lockfd, F_TLOCK, 0) == -1) {
+ dperror("lock_dev: cannot set lock");
+ return (DEVLKERR);
}
return (0);
}
-static int
-mk_alloc(char *list, uid_t uid)
+int
+mk_alloc(devmap_t *list, uid_t uid, struct zone_path *zpath)
{
- char *file;
- int err;
+ int i;
+ int error = 0;
+ char **file;
+ gid_t gid = getgid();
+ mode_t mode = ALLOC_MODE;
- file = strtok(list, " ");
- while (file != NULL) {
-
- dprintf("Allocating %s\n", file);
- if ((err = newdac(file, uid, getgid(), ALLOC_MODE)) != 0) {
- (void) newdac(file, ALLOC_UID, ALLOC_GID,
+ file = list->dmap_devarray;
+ if (file == NULL)
+ return (NODMAPERR);
+ for (; *file != NULL; file++) {
+ dprintf("Allocating %s\n", *file);
+ if ((error = _newdac(*file, uid, gid, mode)) != 0) {
+ (void) _newdac(*file, ALLOC_ERRID, ALLOC_GID,
ALLOC_ERR_MODE);
- return (err);
+ break;
}
-
- file = strtok(NULL, " ");
}
- return (0);
+ if (system_labeled && zpath->count && (error == 0)) {
+ /*
+ * mark as allocated any new device nodes that we
+ * created in local zone
+ */
+ for (i = 0; i < zpath->count; i++) {
+ dprintf("Allocating %s\n", zpath->path[i]);
+ if ((error = _newdac(zpath->path[i], uid, gid,
+ mode)) != 0) {
+ (void) _newdac(zpath->path[i], ALLOC_ERRID,
+ ALLOC_GID, ALLOC_ERR_MODE);
+ break;
+ }
+ }
+ }
+
+ return (error);
}
/*
@@ -319,33 +672,32 @@
* because "/usr/sbin/fuser -k file" kills all processes
* working with the file, even "vold" (bug #4095152).
*/
-static int
-mk_revoke(int optflg, char *file)
+int
+mk_revoke(int optflag, char *file)
{
- char buf[MAXPATHLEN];
- int r = 0, p[2], fp, lock;
- FILE *ptr;
- prpsinfo_t info;
- pid_t pid, c_pid;
+ int r = 0, p[2], fp, lock;
+ int fuserpid;
+ char buf[MAXPATHLEN];
+ FILE *ptr;
+ pid_t c_pid;
+ prpsinfo_t info;
(void) strcpy(buf, PROCFS);
-
/*
- * vfork() and execle() just to make the same output
+ * vfork() and execl() just to make the same output
* as before fixing of bug #4095152.
* The problem is that the "fuser" command prints
* one part of output into stderr and another into stdout,
* but user sees them mixed. Of course, better to change "fuser"
* or to intercept and not to print its output.
*/
- if (!(optflg & SILENT)) {
+ if (!(optflag & SILENT)) {
c_pid = vfork();
if (c_pid == -1)
return (-1);
if (c_pid == 0) {
dprintf("first exec fuser %s\n", file);
- (void) execle("/usr/sbin/fuser", "fuser", file, NULL,
- newenv);
+ (void) execl("/usr/sbin/fuser", "fuser", file, NULL);
dperror("first exec fuser");
_exit(1);
}
@@ -355,21 +707,18 @@
if (WEXITSTATUS(lock) != 0)
return (-1);
}
- dprintf("first continuing c_pid=%d\n", c_pid);
-
+ dprintf("first continuing c_pid=%d\n", (int)c_pid);
if (pipe(p)) {
dperror("pipe");
return (-1);
}
-
- /* vfork() and execle() to catch output and to process it */
+ /* vfork() and execl() to catch output and to process it */
c_pid = vfork();
if (c_pid == -1) {
dperror("second vfork");
return (-1);
}
- dprintf("second continuing c_pid=%d\n", c_pid);
-
+ dprintf("second continuing c_pid=%d\n", (int)c_pid);
if (c_pid == 0) {
(void) close(p[0]);
(void) close(1);
@@ -377,392 +726,1026 @@
(void) close(p[1]);
(void) close(2);
dprintf("second exec fuser %s\n", file);
- (void) execle("/usr/sbin/fuser", "fuser", file, NULL, newenv);
+ (void) execl("/usr/sbin/fuser", "fuser", file, NULL);
dperror("second exec fuser");
_exit(1);
}
-
(void) close(p[1]);
if ((ptr = fdopen(p[0], "r")) != NULL) {
while (!feof(ptr)) {
- if (fscanf(ptr, "%d", &pid) > 0) {
- (void) sprintf(buf + strlen(PROCFS), "%d", pid);
+ if (fscanf(ptr, "%d", &fuserpid) > 0) {
+ (void) sprintf(buf + strlen(PROCFS), "%d",
+ fuserpid);
if ((fp = open(buf, O_RDONLY)) == -1) {
dperror(buf);
continue;
}
- if (ioctl(fp, PIOCPSINFO, (char *)&info)
- == -1) {
- dprintf("%d psinfo failed", pid);
+ if (ioctl(fp, PIOCPSINFO,
+ (char *)&info) == -1) {
+ dprintf("%d psinfo failed", fuserpid);
dperror("");
(void) close(fp);
continue;
}
(void) close(fp);
if (strcmp(info.pr_fname, "vold") == NULL) {
- dprintf("%d matched vold name\n", pid);
+ dprintf("%d matched vold name\n",
+ fuserpid);
continue;
}
dprintf("killing %s", info.pr_fname);
- dprintf("(%d)\n", pid);
- if ((r = kill(pid, SIGKILL)) == -1) {
- dprintf("kill %d", pid);
+ dprintf("(%d)\n", fuserpid);
+ if ((r =
+ kill((pid_t)fuserpid, SIGKILL)) == -1) {
+ dprintf("kill %d", fuserpid);
dperror("");
break;
}
}
}
- dprintf("eof reached %x\n", ptr);
} else {
- dperror("fdopen(p[0])");
+ dperror("fdopen(p[0], r)");
r = -1;
}
-
(void) fclose(ptr);
+
return (r);
}
-static int
-mk_unalloc(int optflg, char *list)
+int
+mk_unalloc(int optflag, devmap_t *list)
{
- char *file;
int error = 0;
- int child, status;
+ int status;
+ char **file;
- audit_allocate_list(list);
+ audit_allocate_list(list->dmap_devlist);
+ file = list->dmap_devarray;
+ if (file == NULL)
+ return (NODMAPERR);
+ for (; *file != NULL; file++) {
+ dprintf("Deallocating %s\n", *file);
+ if (mk_revoke(optflag, *file) < 0) {
+ dprintf("mk_unalloc: unable to revoke %s\n", *file);
+ dperror("");
+ error = CNTFRCERR;
+ }
+ status = _newdac(*file, ALLOC_UID, ALLOC_GID, DEALLOC_MODE);
+ if (error == 0)
+ error = status;
- child = vfork();
- switch (child) {
- case -1:
- return (-1);
- case 0:
- (void) setuid(0);
- file = strtok(list, " ");
- while (file != NULL) {
- dprintf("Deallocating %s\n", file);
- if (mk_revoke(optflg, file) < 0) {
- dprintf("mk_unalloc: unable to revoke %s\n",
- file);
- dperror("");
- error = CNTFRC;
- break;
- }
- error = newdac(file, ALLOC_UID, ALLOC_GID,
- DEALLOC_MODE);
- file = strtok(NULL, " ");
- }
- exit(error);
- default:
- while (wait(&status) != child);
- if (WIFEXITED(status)) {
- return (WEXITSTATUS(status));
- }
- return (-1);
}
+
+ return (error);
}
-static int
-exec_clean(int optflg, char *name, char *path)
+int
+mk_error(devmap_t *list)
{
- char *mode, *cmd;
- int status;
- int c;
+ int status = 0;
+ char **file;
- if ((optflg & (FORCE_ALL | SILENT)) == (FORCE_ALL | SILENT))
+ audit_allocate_list(list->dmap_devlist);
+ file = list->dmap_devarray;
+ if (file == NULL)
+ return (NODMAPERR);
+ for (; *file != NULL; file++) {
+ dprintf("Putting %s in error state\n", *file);
+ status = _newdac(*file, ALLOC_ERRID, ALLOC_GID, ALLOC_ERR_MODE);
+ }
+
+ return (status);
+}
+
+int
+exec_clean(int optflag, char *devname, char *path, uid_t uid, char *zonename,
+ char *clean_arg)
+{
+ int c;
+ int status = 0, exit_status;
+ char *mode, *cmd, *wdwcmd, *zoneroot;
+ char *devzone = zonename;
+ char wdwpath[PATH_MAX];
+ char zonepath[MAXPATHLEN];
+ char title[100];
+ char pw_buf[NSS_BUFLEN_PASSWD];
+ struct passwd pw_ent;
+
+ zonepath[0] = '\0';
+ if (system_labeled) {
+ if ((zoneroot = getzonerootbyname(zonename)) == NULL) {
+ if (strcmp(clean_arg, ALLOC_CLEAN) == 0) {
+ return (-1);
+ } else if (optflag & FORCE) {
+ (void) strcpy(zonepath, "/");
+ devzone = GLOBAL_ZONENAME;
+ } else {
+ dprintf("unable to get label for %s zone\n",
+ zonename);
+ return (-1);
+ }
+ } else {
+ (void) strcpy(zonepath, zoneroot);
+ free(zoneroot);
+ }
+ }
+ if (getpwuid_r(uid, &pw_ent, pw_buf, sizeof (pw_buf)) == NULL)
+ return (-1);
+ if (optflag & FORCE_ALL)
mode = "-I";
- else if (optflg & FORCE_ALL)
- mode = "-i";
- else if (optflg & FORCE)
+ else if (optflag & FORCE)
mode = "-f";
else
mode = "-s";
+ if (path == NULL)
+ return (0);
if ((cmd = strrchr(path, '/')) == NULL)
cmd = path;
else
cmd++; /* skip leading '/' */
-
c = vfork();
switch (c) {
case -1:
return (-1);
case 0:
(void) setuid(0);
+ if (system_labeled && (optflag & WINDOWING)) {
+ /* First try .windowing version of script */
+ (void) strncpy(wdwpath, path, PATH_MAX);
+ (void) strncat(wdwpath, ".windowing", PATH_MAX);
+ if ((wdwcmd = strrchr(wdwpath, '/')) == NULL)
+ wdwcmd = wdwpath;
+ (void) execl(wdwpath, wdwcmd, mode, devname, clean_arg,
+ pw_ent.pw_name, devzone, zonepath, NULL);
+ /* If that failed, run regular version via dtterm */
+ (void) snprintf(title, sizeof (title),
+ "Device %s for %s",
+ strcmp(clean_arg, ALLOC_CLEAN) == 0 ?
+ "allocation" : "deallocation", devname);
+ (void) execl("/usr/dt/bin/dtterm", "dtterm",
+ "-title", title, "-geometry", "x10+100+400",
+ "-e", "/etc/security/lib/wdwwrapper",
+ path, mode, devname, clean_arg, pw_ent.pw_name,
+ devzone, zonepath, NULL);
+ /*
+ * And if that failed, continue on to try
+ * running regular version directly.
+ */
+ }
dprintf("clean script: %s, ", path);
dprintf("cmd=%s, ", cmd);
dprintf("mode=%s, ", mode);
- dprintf("name=%s\n", name);
- (void) execle(path, cmd, mode, name, NULL, newenv);
+ if (system_labeled) {
+ dprintf("devname=%s ", devname);
+ dprintf("zonename=%s ", devzone);
+ dprintf("zonepath=%s ", zonepath);
+ dprintf("username=%s\n", pw_ent.pw_name);
+ (void) execl(path, cmd, mode, devname, clean_arg,
+ pw_ent.pw_name, devzone, zonepath, NULL);
+ } else {
+ dprintf("devname=%s\n", devname);
+ (void) execle(path, cmd, mode, devname, NULL, newenv);
+ }
dprintf("Unable to execute clean up script %s\n", path);
dperror("");
- exit(CNTDEXEC);
+ exit(CNTDEXECERR);
default:
- while (wait(&status) != c);
- if (WIFEXITED(status))
- return (WEXITSTATUS(status));
- dprintf("exit status %d\n", status);
+ (void) waitpid(c, &status, 0);
+ dprintf("Child %d", c);
+ if (WIFEXITED(status)) {
+ exit_status = WEXITSTATUS(status);
+ dprintf(" exited, status: %d\n", exit_status);
+ return (exit_status);
+ } else if (WIFSIGNALED(status)) {
+ dprintf(" killed, signal %d\n", WTERMSIG(status));
+ } else {
+ dprintf(": exit status %d\n", status);
+ }
return (-1);
}
}
-static int
-deallocate_dev(int optflg, devalloc_t *dev_ent, uid_t uid)
+int
+_deallocate_dev(int optflag, devalloc_t *da, devmap_t *dm_in, uid_t uid,
+ char *zonename)
{
- devmap_t *dev_list;
- char file_name[MAXPATHLEN];
- struct stat stat_buf;
- char *list;
- int error = 0, err;
- int bytes_formated;
+ int bytes = 0;
+ int error = 0;
+ int is_authorized = 0;
+ uid_t nuid;
+ char *fname = NULL;
+ char file_name[MAXPATHLEN];
+ char *devzone = NULL;
+ devmap_t *dm = NULL, *dm_new = NULL;
+ struct stat stat_buf;
+ struct state_file sf;
- bytes_formated = snprintf(file_name, MAXPATHLEN, "%s/%s", DAC_DIR,
- dev_ent->da_devname);
- if (bytes_formated <= 0) {
- return (DEVNAME_ERR);
- } else if (bytes_formated >= MAXPATHLEN) {
- dprintf("device name %s is too long.\n", dev_ent->da_devname);
- return (DEVNAME_TOOLONG);
- }
-
- audit_allocate_device(file_name);
-
- if (stat(file_name, &stat_buf)) {
- dprintf("Unable to stat %s\n", file_name);
- dperror("Error:");
- return (DACACC);
- }
-
- if (!(optflg & FORCE) && stat_buf.st_uid != uid &&
- DEV_ALLOCATED(stat_buf)) {
- return (NALLOCU);
- }
-
- if (!(optflg & FORCE_ALL) && !DEV_ALLOCATED(stat_buf)) {
- if ((stat_buf.st_mode & ~S_IFMT) == ALLOC_ERR_MODE) {
- if (!(optflg & FORCE))
- return (ALLOCERR);
- } else
- return (NALLOC);
- }
-
- /* All checks passed, time to lock and deallocate */
- if ((error = lock_dev(file_name)) != 0)
- return (error);
-
- if ((err = newdac(file_name, ALLOC_UID, ALLOC_GID, DEALLOC_MODE))
- != 0) {
- (void) newdac(file_name, ALLOC_UID, ALLOC_GID, ALLOC_ERR_MODE);
- EXIT(err);
- }
-
- if ((dev_list = getdmapnam(dev_ent->da_devname)) == NULL) {
- dprintf("Unable to find %s in the device map database\n",
- dev_ent->da_devname);
- EXIT(NODMAPENT);
+ if (dm_in == NULL) {
+ setdmapent();
+ if ((dm_new = getdmapnam(da->da_devname)) == NULL) {
+ enddmapent();
+ dprintf("Unable to find %s in device map database\n",
+ da->da_devname);
+ return (NODMAPERR);
+ }
+ enddmapent();
+ dm = dm_new;
} else {
- if ((list = strdup(dev_list->dmap_devlist)) == NULL) {
- EXIT(SYSERROR)
+ dm = dm_in;
+ }
+ if (system_labeled) {
+ if (_dev_file_name(&sf, dm) != 0) {
+ if (dm_new)
+ freedmapent(dm_new);
+ dprintf("Unable to find %s device files\n",
+ da->da_devname);
+ error = NODMAPERR;
+ goto out;
+ }
+ fname = sf.sf_path;
+ } else {
+ bytes = snprintf(file_name, MAXPATHLEN, "%s/%s", DAC_DIR,
+ da->da_devname);
+ if (bytes <= 0) {
+ error = DEVNAMEERR;
+ goto out;
+ } else if (bytes >= MAXPATHLEN) {
+ dprintf("device name %s is too long.\n",
+ da->da_devname);
+ error = DEVLONGERR;
+ goto out;
+ }
+ fname = file_name;
+ }
+
+ audit_allocate_device(fname);
+
+ if (stat(fname, &stat_buf) != 0) {
+ dprintf("Unable to stat %s\n", fname);
+ error = DACACCERR;
+ goto out;
+ }
+ is_authorized = _is_dev_authorized(da, uid);
+ if (!(optflag & (FORCE | FORCE_ALL)) && !is_authorized) {
+ dprintf("User %d is unauthorized to deallocate\n", (int)uid);
+ error = UAUTHERR;
+ goto out;
+ }
+ if (system_labeled) {
+ /*
+ * unless we're here to deallocate by force, check if the
+ * label at which the device is currently allocated is
+ * within the user label range.
+ */
+ if (!(optflag & FORCE) &&
+ _check_label(da, zonename, uid, CHECK_URANGE) != 0) {
+ error = LABELRNGERR;
+ goto out;
+ }
+ }
+ if (!(optflag & FORCE) && stat_buf.st_uid != uid &&
+ DEV_ALLOCATED(stat_buf)) {
+ error = ALLOCUERR;
+ goto out;
+ }
+ if (!DEV_ALLOCATED(stat_buf)) {
+ if (DEV_ERRORED(stat_buf)) {
+ if (!(optflag & FORCE)) {
+ error = DEVSTATEERR;
+ goto out;
+ }
} else {
- if (mk_unalloc(optflg, list) != 0) {
- (void) newdac(file_name, ALLOC_UID, ALLOC_GID,
- ALLOC_ERR_MODE);
- free(list);
- list = NULL;
- EXIT(DEVLST);
+ error = DEVNALLOCERR;
+ goto out;
+ }
+ }
+ /* All checks passed, time to lock and deallocate */
+ if ((error = lock_dev(fname)) != 0)
+ goto out;
+ if (system_labeled) {
+ devzone = kva_match(da->da_devopts, DAOPT_ZONE);
+ if (devzone && (strcmp(devzone, GLOBAL_ZONENAME) != 0)) {
+ if ((remove_znode(devzone, dm) != 0) &&
+ !(optflag & FORCE)) {
+ error = ZONEERR;
+ goto out;
+ }
+ }
+ }
+ if ((error = mk_unalloc(optflag, dm)) != 0) {
+ if (!(optflag & FORCE))
+ goto out;
+ }
+ if (system_labeled == 0) {
+ if ((error = _newdac(fname, ALLOC_UID, ALLOC_GID,
+ DEALLOC_MODE)) != 0) {
+ (void) _newdac(file_name, ALLOC_UID, ALLOC_GID,
+ ALLOC_ERR_MODE);
+ goto out;
+ }
+ }
+ /*
+ * if we are deallocating device owned by someone else,
+ * pass the owner's uid to the cleaning script.
+ */
+ nuid = (stat_buf.st_uid == uid) ? uid : stat_buf.st_uid;
+ error = exec_clean(optflag, da->da_devname, da->da_devexec, nuid,
+ devzone, DEALLOC_CLEAN);
+ if (error != 0) {
+ if (!(optflag & (FORCE | FORCE_ALL))) {
+ error = CLEANERR;
+ (void) mk_error(dm);
+ } else {
+ error = 0;
+ }
+ }
+
+out:
+ if (dm_new)
+ freedmapent(dm_new);
+ return (error);
+}
+
+int
+_allocate_dev(int optflag, uid_t uid, devalloc_t *da, char *zonename)
+{
+ int i;
+ int bytes = 0;
+ int error = 0;
+ int is_authorized = 0;
+ int dealloc_optflag = 0;
+ char *fname = NULL;
+ char file_name[MAXPATHLEN];
+ devmap_t *dm;
+ struct stat stat_buf;
+ struct state_file sf;
+ struct zone_path zpath;
+
+ zpath.count = 0;
+ zpath.path = NULL;
+ setdmapent();
+ if ((dm = getdmapnam(da->da_devname)) == NULL) {
+ enddmapent();
+ dprintf("Unable to find %s in device map database\n",
+ da->da_devname);
+ return (NODMAPERR);
+ }
+ enddmapent();
+ if (system_labeled) {
+ if (_dev_file_name(&sf, dm) != 0) {
+ freedmapent(dm);
+ dprintf("Unable to find %s device files\n",
+ da->da_devname);
+ error = NODMAPERR;
+ goto out;
+ }
+ fname = sf.sf_path;
+ } else {
+ bytes = snprintf(file_name, MAXPATHLEN, "%s/%s", DAC_DIR,
+ da->da_devname);
+ if (bytes <= 0) {
+ error = DEVNAMEERR;
+ goto out;
+ } else if (bytes >= MAXPATHLEN) {
+ dprintf("device name %s is too long.\n",
+ da->da_devname);
+ error = DEVLONGERR;
+ goto out;
+ }
+ fname = file_name;
+ }
+
+ (void) audit_allocate_device(fname);
+
+ if (stat(fname, &stat_buf) != 0) {
+ dprintf("Unable to stat %s\n", fname);
+ dperror("Error:");
+ error = DACACCERR;
+ goto out;
+ }
+ if (DEV_ERRORED(stat_buf)) {
+ error = DEVSTATEERR;
+ goto out;
+ }
+ is_authorized = _is_dev_authorized(da, uid);
+ if (is_authorized == ALLOC_BY_NONE) {
+ dprintf("Device %s is not allocatable\n", da->da_devname);
+ error = UAUTHERR;
+ goto out;
+ } else if (!is_authorized && !(optflag & USERNAME)) {
+ dprintf("User %d is unauthorized to allocate\n", (int)uid);
+ error = UAUTHERR;
+ goto out;
+ }
+ if (system_labeled) {
+ /*
+ * check if label of the zone to which the device is being
+ * allocated is within the device label range.
+ */
+ if (_check_label(da, zonename, uid, CHECK_DRANGE) != 0) {
+ error = LABELRNGERR;
+ goto out;
+ }
+ }
+ if (check_devs(dm) == -1) {
+ error = DSPMISSERR;
+ goto out;
+ }
+ if (DEV_ALLOCATED(stat_buf)) {
+ if (optflag & FORCE) {
+ if (optflag & SILENT)
+ dealloc_optflag = FORCE|SILENT;
+ else
+ dealloc_optflag = FORCE;
+ if (_deallocate_dev(dealloc_optflag, da, dm, uid,
+ zonename)) {
+ dprintf("Couldn't force deallocate device %s\n",
+ da->da_devname);
+ error = CNTFRCERR;
+ goto out;
+ }
+ } else if (stat_buf.st_uid == uid) {
+ error = PREALLOCERR;
+ goto out;
+ } else {
+ error = ALLOCUERR;
+ goto out;
+ }
+ }
+ /* All checks passed, time to lock and allocate */
+ if ((error = lock_dev(fname)) != 0)
+ goto out;
+ if (system_labeled) {
+ /*
+ * Run the cleaning program; it also mounts allocated
+ * device if required.
+ */
+ error = exec_clean(optflag, da->da_devname, da->da_devexec, uid,
+ zonename, ALLOC_CLEAN);
+ if ((error != 0) && (error != CLEAN_MOUNT)) {
+ error = CLEANERR;
+ (void) mk_error(dm);
+ goto out;
+ }
+ /*
+ * If not mounted, create zonelinks, if this is not the
+ * global zone.
+ */
+ if ((strcmp(zonename, GLOBAL_ZONENAME) != 0) &&
+ (error != CLEAN_MOUNT)) {
+ if (create_znode(zonename, &zpath, dm) != 0) {
+ error = ZONEERR;
+ goto out;
}
}
}
- if (list != NULL)
- free(list);
- if (exec_clean(optflg, dev_ent->da_devname, dev_ent->da_devexec))
- EXIT(CLEAN_ERR);
+ (void) audit_allocate_list(dm->dmap_devlist);
+
+ if ((error = mk_alloc(dm, uid, &zpath)) != 0) {
+ (void) mk_unalloc(optflag, dm);
+ goto out;
+ }
+
+ if (system_labeled == 0) {
+ if ((error = _newdac(file_name, uid, getgid(),
+ ALLOC_MODE)) != 0) {
+ (void) _newdac(file_name, ALLOC_UID, ALLOC_GID,
+ ALLOC_ERR_MODE);
+ goto out;
+ }
+ }
+ error = 0;
+out:
+ if (zpath.count) {
+ for (i = 0; i < zpath.count; i++)
+ free(zpath.path[i]);
+ free(zpath.path);
+ }
+ freedmapent(dm);
+ return (error);
+}
+
+void
+_store_devnames(int *count, struct devnames *dnms, char *zonename,
+ devalloc_t *da, int flag)
+{
+ int i;
+
+ dnms->dnames = (char **)realloc(dnms->dnames,
+ (*count + 1) * sizeof (char *));
+ if (da) {
+ dnms->dnames[*count] = strdup(da->da_devname);
+ (*count)++;
+ } else {
+ dnms->dnames[*count] = NULL;
+ if (flag == DA_ADD_ZONE)
+ (void) update_device(dnms->dnames, zonename,
+ DA_ADD_ZONE);
+ else if (flag == DA_REMOVE_ZONE)
+ (void) update_device(dnms->dnames, NULL,
+ DA_REMOVE_ZONE);
+ for (i = 0; i < *count; i++)
+ free(dnms->dnames[i]);
+ free(dnms->dnames);
+ }
+}
+
+int
+allocate(int optflag, uid_t uid, char *device, char *zonename)
+{
+ int count = 0;
+ int error = 0;
+ devalloc_t *da;
+ struct devnames dnms;
+
+ if (optflag & (FORCE | USERID | USERNAME)) {
+ if (!_is_authorized(DEVICE_REVOKE_AUTH, getuid()))
+ return (UAUTHERR);
+ }
+ dnms.dnames = NULL;
+ setdaent();
+ if (optflag & TYPE) {
+ /*
+ * allocate devices of this type
+ */
+ while ((da = getdatype(device)) != NULL) {
+ if (system_labeled &&
+ da_check_logindevperm(da->da_devname)) {
+ freedaent(da);
+ continue;
+ }
+ dprintf("trying to allocate %s\n", da->da_devname);
+ error = _allocate_dev(optflag, uid, da, zonename);
+ if (system_labeled && (error == 0)) {
+ /*
+ * we need to record in device_allocate the
+ * label (zone name) at which this device is
+ * being allocated. store this device entry.
+ */
+ _store_devnames(&count, &dnms, zonename, da, 0);
+ }
+ freedaent(da);
+ error = 0;
+ }
+ } else {
+ /*
+ * allocate this device
+ */
+ if ((da = getdanam(device)) == NULL) {
+ enddaent();
+ return (NODAERR);
+ }
+ if (system_labeled && da_check_logindevperm(device)) {
+ freedaent(da);
+ return (LOGINDEVPERMERR);
+ }
+ dprintf("trying to allocate %s\n", da->da_devname);
+ error = _allocate_dev(optflag, uid, da, zonename);
+ /*
+ * we need to record in device_allocate the label (zone name)
+ * at which this device is being allocated. store this device
+ * entry.
+ */
+ if (system_labeled && (error == 0))
+ _store_devnames(&count, &dnms, zonename, da, 0);
+ freedaent(da);
+ }
+ enddaent();
+ /*
+ * add to device_allocate labels (zone names) for the devices we
+ * allocated.
+ */
+ if (dnms.dnames)
+ _store_devnames(&count, &dnms, zonename, NULL, DA_ADD_ZONE);
+
+ return (error);
+}
+
+/* ARGSUSED */
+int
+deallocate(int optflag, uid_t uid, char *device, char *zonename)
+{
+ int count = 0;
+ int error = 0;
+ devalloc_t *da;
+ struct devnames dnms;
+
+ if (optflag & (FORCE | FORCE_ALL)) {
+ if (!_is_authorized(DEVICE_REVOKE_AUTH, getuid()))
+ return (UAUTHERR);
+ }
+ if (optflag & FORCE_ALL)
+ optflag |= FORCE;
+ dnms.dnames = NULL;
+ setdaent();
+ if (optflag & FORCE_ALL) {
+ /*
+ * deallocate all devices
+ */
+ while ((da = getdaent()) != NULL) {
+ if (system_labeled &&
+ da_check_logindevperm(da->da_devname)) {
+ freedaent(da);
+ continue;
+ }
+ dprintf("trying to deallocate %s\n", da->da_devname);
+ error = _deallocate_dev(optflag, da, NULL, uid,
+ zonename);
+ if (system_labeled && (error == 0)) {
+ /*
+ * we need to remove this device's allocation
+ * label (zone name) from device_allocate.
+ * store this device name.
+ */
+ _store_devnames(&count, &dnms, zonename, da, 0);
+ }
+ freedaent(da);
+ error = 0;
+ }
+ } else if (system_labeled && optflag & TYPE) {
+ /*
+ * deallocate all devices of this type
+ */
+ while ((da = getdatype(device)) != NULL) {
+ if (da_check_logindevperm(da->da_devname)) {
+ freedaent(da);
+ continue;
+ }
+ dprintf("trying to deallocate %s\n", da->da_devname);
+ error = _deallocate_dev(optflag, da, NULL, uid,
+ zonename);
+ if (error == 0) {
+ /*
+ * we need to remove this device's allocation
+ * label (zone name) from device_allocate.
+ * store this device name.
+ */
+ _store_devnames(&count, &dnms, zonename, da, 0);
+ }
+ freedaent(da);
+ error = 0;
+ }
+ } else if (!(optflag & TYPE)) {
+ /*
+ * deallocate this device
+ */
+ if ((da = getdanam(device)) == NULL) {
+ enddaent();
+ return (NODAERR);
+ }
+ if (system_labeled && da_check_logindevperm(da->da_devname)) {
+ freedaent(da);
+ return (LOGINDEVPERMERR);
+ }
+ dprintf("trying to deallocate %s\n", da->da_devname);
+ error = _deallocate_dev(optflag, da, NULL, uid, zonename);
+ if (system_labeled && (error == 0)) {
+ /*
+ * we need to remove this device's allocation label
+ * (zone name) from device_allocate. store this
+ * device name.
+ */
+ _store_devnames(&count, &dnms, zonename, da, 0);
+ }
+ freedaent(da);
+ }
+ enddaent();
+ /*
+ * remove from device_allocate labels (zone names) for the devices we
+ * deallocated.
+ */
+ if (dnms.dnames)
+ _store_devnames(&count, &dnms, zonename, NULL, DA_REMOVE_ZONE);
+
return (error);
}
static int
-allocate_dev(int optflg, uid_t uid, devalloc_t *dev_ent)
+_dev_file_name(struct state_file *sfp, devmap_t *dm)
{
- devmap_t *dev_list;
- char file_name[MAXPATHLEN];
- struct stat stat_buf;
- char *list;
- int error = 0;
- int bytes_formated;
- int deallocate_optflg = 0;
-
- bytes_formated = snprintf(file_name, MAXPATHLEN, "%s/%s", DAC_DIR,
- dev_ent->da_devname);
- if (bytes_formated <= 0) {
- return (DEVNAME_ERR);
- } else if (bytes_formated >= MAXPATHLEN) {
- dprintf("device name %s is too long.\n", dev_ent->da_devname);
- return (DEVNAME_TOOLONG);
+ sfp->sf_flags = 0;
+ /* if devlist is generated, never leave device in error state */
+ if (dm->dmap_devlist[0] == '`')
+ sfp->sf_flags |= SFF_NO_ERROR;
+ if (dm->dmap_devarray == NULL ||
+ dm->dmap_devarray[0] == NULL)
+ return (NODMAPERR);
+ (void) strncpy(sfp->sf_path, dm->dmap_devarray[0],
+ sizeof (sfp->sf_path));
+ sfp->sf_path[sizeof (sfp->sf_path) - 1] = '\0';
+ if (sfp->sf_path[0] == '\0') {
+ dprintf("dev_file_name: no device list for %s\n",
+ dm->dmap_devname);
+ return (NODMAPERR);
}
- audit_allocate_device(file_name);
+ return (0);
+}
- if (stat(file_name, &stat_buf)) {
- dprintf("Unable to stat %s\n", file_name);
- dperror("Error:");
- return (DACACC);
+/*
+ * _check_label -
+ * checks the device label range against zone label, which is also
+ * user's current label.
+ * returns 0 if in range, -1 for all other conditions.
+ *
+ */
+
+static int
+_check_label(devalloc_t *da, char *zonename, uid_t uid, int flag)
+{
+ int err;
+ int in_range = 0;
+ char *alloczone, *lstr;
+ char pw_buf[NSS_BUFLEN_PASSWD];
+ blrange_t *range;
+ m_label_t *zlabel;
+ struct passwd pw_ent;
+
+ if ((da == NULL) || (zonename == NULL))
+ return (-1);
+
+ if ((zlabel = getzonelabelbyname(zonename)) == NULL) {
+ dprintf("unable to get label for %s zone\n", zonename);
+ return (-1);
}
+ if (flag == CHECK_DRANGE) {
+ blrange_t drange;
- if (DEV_ALLOCATED(stat_buf)) {
- if (optflg & FORCE) {
- if (optflg & SILENT)
- deallocate_optflg = FORCE|SILENT;
- else
- deallocate_optflg = FORCE;
+ drange.lower_bound = blabel_alloc();
+ lstr = kva_match(da->da_devopts, DAOPT_MINLABEL);
+ if (lstr == NULL) {
+ bsllow(drange.lower_bound);
+ } else if (stobsl(lstr, drange.lower_bound, NO_CORRECTION,
+ &err) == 0) {
+ dprintf("bad min_label for device %s\n",
+ da->da_devname);
+ free(zlabel);
+ blabel_free(drange.lower_bound);
+ return (-1);
+ }
+ drange.upper_bound = blabel_alloc();
+ lstr = kva_match(da->da_devopts, DAOPT_MAXLABEL);
+ if (lstr == NULL) {
+ bslhigh(drange.upper_bound);
+ } else if (stobsl(lstr, drange.upper_bound, NO_CORRECTION,
+ &err) == 0) {
+ dprintf("bad max_label for device %s\n",
+ da->da_devname);
+ free(zlabel);
+ blabel_free(drange.lower_bound);
+ blabel_free(drange.upper_bound);
+ return (-1);
+ }
+ if (blinrange(zlabel, &drange) == 0) {
+ char *zlbl = NULL, *min = NULL, *max = NULL;
- if (deallocate_dev(deallocate_optflg, dev_ent, uid)) {
- dprintf("Couldn't force deallocate device %s\n",
- dev_ent->da_devname);
- return (CNTFRC);
- }
- } else if (stat_buf.st_uid == uid) {
- return (ALLOC);
- } else
- return (ALLOC_OTHER);
- }
- if ((stat_buf.st_mode & ~S_IFMT) == ALLOC_ERR_MODE)
- return (ALLOCERR);
-
- if (strcmp(dev_ent->da_devauth, "*") == 0) {
- dprintf("Device %s is not allocatable\n", dev_ent->da_devname);
- return (AUTHERR);
- }
-
- if (strcmp(dev_ent->da_devauth, "@")) {
- if (!is_authorized(dev_ent->da_devauth, uid)) {
- dprintf("User %d is unauthorized to allocate\n",
+ (void) bsltos(zlabel, &zlbl, 0, 0);
+ (void) bsltos(drange.lower_bound, &min, 0, 0);
+ (void) bsltos(drange.upper_bound, &max, 0, 0);
+ dprintf("%s zone label ", zonename);
+ dprintf("%s outside device label range: ", zlbl);
+ dprintf("min - %s, ", min);
+ dprintf("max - %s\n", max);
+ free(zlabel);
+ blabel_free(drange.lower_bound);
+ blabel_free(drange.upper_bound);
+ return (-1);
+ }
+ } else if (flag == CHECK_URANGE) {
+ if (getpwuid_r(uid, &pw_ent, pw_buf, sizeof (pw_buf)) == NULL) {
+ dprintf("Unable to get passwd entry for userid %d\n",
(int)uid);
- return (IMPORT_ERR);
+ free(zlabel);
+ return (-1);
+ }
+ if ((range = getuserrange(pw_ent.pw_name)) == NULL) {
+ dprintf("Unable to get label range for userid %d\n",
+ (int)uid);
+ free(zlabel);
+ return (-1);
+ }
+ in_range = blinrange(zlabel, range);
+ free(zlabel);
+ blabel_free(range->lower_bound);
+ blabel_free(range->upper_bound);
+ free(range);
+ if (in_range == 0) {
+ dprintf("%s device label ", da->da_devname);
+ dprintf("out of user %d label range\n", (int)uid);
+ return (-1);
+ }
+ } else if (flag == CHECK_ZLABEL) {
+ alloczone = kva_match(da->da_devopts, DAOPT_ZONE);
+ if (alloczone == NULL) {
+ free(zlabel);
+ return (-1);
+ }
+ if (strcmp(zonename, alloczone) != 0) {
+ dprintf("%s zone is different than ", zonename);
+ dprintf("%s zone to which the device ", alloczone);
+ dprintf("%s is allocated\n", da->da_devname);
+ free(zlabel);
+ return (-1);
}
}
+ free(zlabel);
- if ((dev_list = getdmapnam(dev_ent->da_devname)) == NULL) {
- dprintf("Unable to find %s in device map database\n",
- dev_ent->da_devname);
- return (NODMAPENT);
- }
-
- if ((list = strdup(dev_list->dmap_devlist)) == NULL)
- return (SYSERROR);
-
- if (check_devs(list) == -1) {
- free(list);
- return (DSPMISS);
- }
-
- /* All checks passed, time to lock and allocate */
- if ((error = lock_dev(file_name)) != 0) {
- free(list);
- return (error);
- }
-
- if ((error = newdac(file_name, uid, getgid(), ALLOC_MODE)) != 0) {
- (void) newdac(file_name, ALLOC_UID, ALLOC_GID, ALLOC_ERR_MODE);
- free(list);
- return (error);
- }
-
- /* refresh list from check_devs overwritting it */
- (void) strcpy(list, dev_list->dmap_devlist);
- audit_allocate_list(list);
-
- if (mk_alloc(list, uid) != 0) {
- /* refresh list from mk_alloc overwritting it */
- (void) strcpy(list, dev_list->dmap_devlist);
- (void) mk_unalloc(optflg, list);
- free(list);
- return (DEVLST);
- }
-
- free(list);
return (0);
}
int
-allocate(int optflg, uid_t uid, char *device)
+create_znode(char *zonename, struct zone_path *zpath, devmap_t *list)
{
- devalloc_t *dev_ent;
- devmap_t *dev_list;
+ int i;
+ int size;
+ int len = 0;
+ int fcount = 0;
+ char *p, *tmpfile, *zoneroot;
+ char **file;
+ char zonepath[MAXPATHLEN];
+ struct stat statb;
- if (((optflg & FORCE) || uid != getuid()) &&
- !is_authorized(DEVICE_REVOKE_AUTH, getuid()))
- return (NOTAUTH);
-
- setdaent();
- setdmapent();
-
- if (!(optflg & TYPE)) {
- if ((dev_ent = getdanam(device)) == NULL) {
- if ((dev_list = getdmapdev(device)) == NULL)
- return (NODMAPENT);
- else if ((dev_ent = getdanam(dev_list->dmap_devname))
- == NULL)
- return (NODAENT);
+ file = list->dmap_devarray;
+ if (file == NULL)
+ return (NODMAPERR);
+ if ((zoneroot = getzonerootbyname(zonename)) == NULL) {
+ dprintf("unable to get label for %s zone\n", zonename);
+ return (1);
+ }
+ (void) strcpy(zonepath, zoneroot);
+ free(zoneroot);
+ if ((p = strstr(zonepath, "/root")) == NULL)
+ return (1);
+ *p = '\0';
+ len = strlen(zonepath);
+ size = sizeof (zonepath);
+ for (; *file != NULL; file++) {
+ if (stat(*file, &statb) == -1) {
+ dprintf("Couldn't stat the file %s\n", *file);
+ return (1);
}
- return (allocate_dev(optflg, uid, dev_ent));
+ /*
+ * First time initialization
+ */
+ tmpfile = strdup(*file);
+
+ /*
+ * Most devices have pathnames starting in /dev
+ * but SunRay devices do not. In SRRS 3.1 they use /tmp.
+ *
+ * If the device pathname is not in /dev then create
+ * a symbolic link to it and put the device in /dev
+ */
+ if (strncmp(tmpfile, "/dev/", strlen("/dev/")) != 0) {
+ char *linkdir;
+ char srclinkdir[MAXPATHLEN];
+ char dstlinkdir[MAXPATHLEN];
+
+ linkdir = strchr(tmpfile + 1, '/');
+ p = strchr(linkdir + 1, '/');
+ *p = '\0';
+ (void) strcpy(dstlinkdir, "/dev");
+ (void) strncat(dstlinkdir, linkdir, MAXPATHLEN);
+ (void) snprintf(srclinkdir, MAXPATHLEN, "%s/root%s",
+ zonepath, tmpfile);
+ (void) symlink(dstlinkdir, srclinkdir);
+ *p = '/';
+ (void) strncat(dstlinkdir, p, MAXPATHLEN);
+ free(tmpfile);
+ tmpfile = strdup(dstlinkdir);
+ }
+ if ((p = rindex(tmpfile, '/')) == NULL) {
+ dprintf("bad path in create_znode for %s\n",
+ tmpfile);
+ return (1);
+ }
+ *p = '\0';
+ (void) strcat(zonepath, tmpfile);
+ *p = '/';
+ if ((mkdirp(zonepath, 0755) != 0) && (errno != EEXIST)) {
+ dprintf("Unable to create directory %s\n", zonepath);
+ return (1);
+ }
+ zonepath[len] = '\0';
+ if (strlcat(zonepath, tmpfile, size) >= size) {
+ dprintf("Buffer overflow in create_znode for %s\n",
+ *file);
+ free(tmpfile);
+ return (1);
+ }
+ free(tmpfile);
+ fcount++;
+ if ((zpath->path = (char **)realloc(zpath->path,
+ (fcount * sizeof (char *)))) == NULL)
+ return (1);
+ zpath->path[zpath->count] = strdup(zonepath);
+ zpath->count = fcount;
+ if (mknod(zonepath, statb.st_mode, statb.st_rdev) == -1) {
+ switch (errno) {
+ case EEXIST:
+ break;
+ default:
+ dprintf("mknod error: %s\n",
+ strerror(errno));
+ for (i = 0; i <= fcount; i++)
+ free(zpath->path[i]);
+ free(zpath->path);
+ return (1);
+ }
+ }
+ zonepath[len] = '\0';
}
- while ((dev_ent = getdatype(device)) != NULL) {
- dprintf("trying to allocate %s\n", dev_ent->da_devname);
- if (!allocate_dev(optflg, uid, dev_ent)) {
- return (0);
- }
- }
- enddaent();
- return (NO_DEVICE);
+ return (0);
}
int
-deallocate(int optflg, uid_t uid, char *device)
+remove_znode(char *zonename, devmap_t *dm)
{
- DIR *dev_dir;
- struct dirent *dac_file;
- devalloc_t *dev_ent;
- devmap_t *dev_list;
- int error = NODAENT;
+ int len = 0;
+ char *zoneroot;
+ char **file;
+ char zonepath[MAXPATHLEN];
- if (optflg & (FORCE | FORCE_ALL) &&
- !is_authorized(DEVICE_REVOKE_AUTH, getuid()))
- return (NOTAUTH);
- if (optflg & FORCE_ALL)
- optflg |= FORCE;
+ file = dm->dmap_devarray;
+ if (file == NULL)
+ return (NODMAPERR);
+ if ((zoneroot = getzonerootbyname(zonename)) == NULL) {
+ (void) snprintf(zonepath, MAXPATHLEN, "/zone/%s", zonename);
+ } else {
+ char *p;
- setdaent();
- setdmapent();
+ if ((p = strstr(zoneroot, "/root")) == NULL)
+ return (1);
+ *p = '\0';
+ (void) strcpy(zonepath, zoneroot);
+ free(zoneroot);
+ }
+ /*
+ * To support SunRay we will just deal with the
+ * file in /dev, not the symlinks.
+ */
+ (void) strncat(zonepath, "/dev", MAXPATHLEN);
+ len = strlen(zonepath);
+ for (; *file != NULL; file++) {
+ char *devrelpath;
- if (!(optflg & FORCE_ALL)) {
- if ((dev_ent = getdanam(device)) == NULL) {
- if ((dev_list = getdmapdev(device)) == NULL)
- return (NODMAPENT);
- else if ((dev_ent = getdanam(dev_list->dmap_devname))
- == NULL)
- return (NODAENT);
+ /*
+ * remove device node from zone.
+ *
+ * SunRay devices don't start with /dev
+ * so skip over first directory to make
+ * sure it is /dev. SunRay devices in zones
+ * will have a symlink into /dev but
+ * we don't ever delete it.
+ */
+ devrelpath = strchr(*file + 1, '/');
+
+ if (strlcat(zonepath, devrelpath, MAXPATHLEN) >= MAXPATHLEN) {
+ dprintf("Buffer overflow in remove_znode for %s\n",
+ *file);
+ return (1);
}
-
- return (deallocate_dev(optflg, dev_ent, uid));
- }
-
- if ((dev_dir = opendir(DAC_DIR)) == NULL) {
- dperror("Can't open DAC_DIR");
- return (DACACC);
- }
-
- while ((dac_file = readdir(dev_dir)) != NULL) {
- if ((strcmp(dac_file->d_name, ".") == 0) ||
- (strcmp(dac_file->d_name, "..") == 0)) {
- continue;
- } else {
- if ((dev_ent = getdanam(dac_file->d_name)) == NULL) {
- continue;
- }
- error = deallocate_dev(optflg, dev_ent, uid);
+ errno = 0;
+ if ((unlink(zonepath) == -1) && (errno != ENOENT)) {
+ perror(zonepath);
+ return (1);
}
+ zonepath[len] = '\0';
}
- (void) closedir(dev_dir);
- enddaent();
- return (error);
+
+ return (0);
+}
+
+int
+update_device(char **devnames, char *zonename, int flag)
+{
+ int len, rc;
+ char *optstr = NULL;
+ da_args dargs;
+ devinfo_t devinfo;
+
+ dargs.optflag = flag;
+ dargs.optflag |= DA_UPDATE|DA_ALLOC_ONLY;
+ dargs.rootdir = NULL;
+ dargs.devnames = devnames;
+ devinfo.devname = devinfo.devtype = devinfo.devauths = devinfo.devexec =
+ devinfo.devlist = NULL;
+ if (dargs.optflag & DA_ADD_ZONE) {
+ len = strlen(DAOPT_ZONE) + strlen(zonename) + 3;
+ if ((optstr = (char *)malloc(len)) == NULL)
+ return (-1);
+ (void) snprintf(optstr, len, "%s%s%s", DAOPT_ZONE, KV_ASSIGN,
+ zonename);
+ devinfo.devopts = optstr;
+ }
+ dargs.devinfo = &devinfo;
+
+ rc = da_update_device(&dargs);
+
+ if (optstr)
+ free(optstr);
+
+ return (rc);
}
diff --git a/usr/src/cmd/allocate/audio_clean.c b/usr/src/cmd/allocate/audio_clean.c
index 4447fdf..24753b8 100644
--- a/usr/src/cmd/allocate/audio_clean.c
+++ b/usr/src/cmd/allocate/audio_clean.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -53,9 +53,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <strings.h>
#include <stropts.h>
#include <unistd.h>
-
+#include <bsm/devices.h>
#include <sys/audioio.h>
#include <sys/file.h>
#include <sys/ioctl.h>
@@ -67,54 +68,32 @@
#define TEXT_DOMAIN "SUNW_OST_OSCMD"
#endif
-#define BUF_SIZE 512
-#define DMINFO "dminfo -v -n" /* Cmd to xlate name to device */
-#define AUDIO "/dev/audio" /* Device name of audio device */
-
-static char *Audio_dev = AUDIO;
-
#ifdef DEBUG
static void print_info(audio_info_t *);
static void print_prinfo(audio_prinfo_t *);
#endif /* DEBUG */
static void
-usage(char *prog, int verbose)
+usage(char *prog)
{
- if (verbose)
- (void) fprintf(stderr,
- gettext("usage: %s [-I|-s|-f|-i] device\n"), prog);
-}
-
-/*
- * Return the first substring in string before the ':' in "item"
- */
-static void
-first_field(char *string, char *item)
-{
- item = string;
-
- while (*item != ':')
- item++;
- *item = 0;
+ (void) fprintf(stderr, "%s%s", prog,
+ gettext(" : usage:[-I|-s|-f|-i] device\n"));
}
int
-main(int argc, char *argv[])
+main(int argc, char **argv)
{
- int err = 0;
+ int err = 0;
+ int Audio_fd;
+ int forced = 0; /* Command line options */
+ int initial = 0;
+ int standard = 0;
+ int verbose = 1; /* default is to be verbose */
+ int c;
+ char *prog, *devname, *devpath;
+ devmap_t *dm;
struct stat st;
audio_info_t info;
- int i;
- char cmd_str[BUF_SIZE];
- char map[BUF_SIZE];
- char *prog;
- FILE *fp;
- int Audio_fd;
- int forced = 0; /* Command line options */
- int initial = 0;
- int standard = 0;
- int verbose = 1; /* default is to be verbose */
(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);
@@ -126,8 +105,8 @@
* the same thing.
*/
- while ((i = getopt(argc, argv, "Iifs")) != EOF) {
- switch (i) {
+ while ((c = getopt(argc, argv, "Iifs")) != -1) {
+ switch (c) {
case 'I':
verbose = 0;
initial++;
@@ -152,54 +131,49 @@
case '?':
err++;
break;
+ default:
+ err++;
+ break;
}
if (err) {
- usage(prog, verbose);
+ if (verbose)
+ usage(prog);
exit(1);
}
- argc -= optind;
- argv += optind;
}
- if (argv[0] == NULL) { /* no device name */
- usage(prog, verbose);
- exit(1);
- }
-
- if (strlen(argv[0]) > (BUF_SIZE - sizeof (DMINFO) - 2)) {
- (void) fprintf(stderr, gettext("device name %s too long\n"),
- argv[0]);
- exit(1);
- }
-
- (void) strcpy(cmd_str, DMINFO);
- (void) strcat(cmd_str, " ");
- (void) strcat(cmd_str, argv[0]); /* device name */
-
- if ((fp = popen(cmd_str, "r")) == NULL) {
+ if ((argc - optind) != 1) {
if (verbose)
- (void) fprintf(stderr,
- gettext("%s couldn't execute \"%s\"\n"), prog,
- cmd_str);
+ usage(prog);
exit(1);
+ } else {
+ devname = argv[optind];
}
- if (fread(map, 1, BUF_SIZE, fp) == 0) {
+ setdmapent();
+ if ((dm = getdmapnam(devname)) == NULL) {
+ enddmapent();
if (verbose)
- (void) fprintf(stderr,
- gettext("%s no results from \"%s\"\n"), prog,
- cmd_str);
- exit(1);
+ (void) fprintf(stderr, "%s%s",
+ devname,
+ gettext(" : No such allocatable device\n"));
+ exit(1);
}
-
- (void) pclose(fp);
-
- first_field(map, Audio_dev); /* Put the 1st field in dev */
+ enddmapent();
+ if (dm->dmap_devarray == NULL || dm->dmap_devarray[0] == NULL) {
+ if (verbose)
+ (void) fprintf(stderr, "%s%s",
+ devname,
+ gettext(" : No such allocatable device\n"));
+ exit(1);
+ }
+ devpath = strdup(dm->dmap_devarray[0]);
+ freedmapent(dm);
/*
* Validate and open the audio device
*/
- err = stat(Audio_dev, &st);
+ err = stat(devpath, &st);
if (err < 0) {
if (verbose) {
@@ -213,7 +187,7 @@
if (verbose)
(void) fprintf(stderr,
gettext("%s: %s is not an audio device\n"), prog,
- Audio_dev);
+ devpath);
exit(1);
}
@@ -222,26 +196,18 @@
* using it we check to see if we're going to hang before we
* do anything.
*/
- /* Try it quickly, first */
- Audio_fd = open(Audio_dev, O_WRONLY | O_NDELAY);
+ Audio_fd = open(devpath, O_WRONLY | O_NDELAY);
if ((Audio_fd < 0) && (errno == EBUSY)) {
if (verbose)
(void) fprintf(stderr, gettext("%s: waiting for %s..."),
- prog, Audio_dev);
-
- /* Now hang until it's open */
- Audio_fd = open(Audio_dev, O_WRONLY);
- if (Audio_fd < 0) {
- if (verbose)
- perror(Audio_dev);
- exit(1);
- }
+ prog, devpath);
+ exit(0);
} else if (Audio_fd < 0) {
if (verbose) {
(void) fprintf(stderr, gettext("%s: error opening "),
prog);
- perror(Audio_dev);
+ perror(devpath);
}
exit(1);
}
@@ -253,6 +219,7 @@
if (ioctl(Audio_fd, AUDIO_GETINFO, &info) != 0) {
perror("Ioctl AUDIO_GETINFO error");
+ (void) close(Audio_fd);
exit(1);
}
@@ -265,12 +232,14 @@
if (ioctl(Audio_fd, AUDIO_SETINFO, &info) != 0) {
if (verbose)
perror(gettext("Ioctl AUDIO_SETINFO error"));
+ (void) close(Audio_fd);
exit(1);
}
#ifdef DEBUG
if (ioctl(Audio_fd, AUDIO_GETINFO, &info) != 0) {
perror("Ioctl AUDIO_GETINFO-2 error");
+ (void) close(Audio_fd);
exit(1);
}
diff --git a/usr/src/cmd/dminfo/dminfo.c b/usr/src/cmd/allocate/dminfo.c
similarity index 90%
rename from usr/src/cmd/dminfo/dminfo.c
rename to usr/src/cmd/allocate/dminfo.c
index b1dc7ea..1a2d035 100644
--- a/usr/src/cmd/dminfo/dminfo.c
+++ b/usr/src/cmd/allocate/dminfo.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,19 +18,15 @@
*
* CDDL HEADER END
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
-#if !defined(lint) && defined(SCCSIDS)
-static char *bsm_sccsid =
- "@(#)dminfo.c 1.8 05/06/15 SMI; SunOS BSM";
-#endif
-
#include <locale.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <unistd.h>
@@ -70,7 +65,7 @@
{
(void) printf("%s:", dmapp->dmap_devname);
(void) printf("%s:", dmapp->dmap_devtype);
- (void) printf("%s:", dmapp->dmap_devlist);
+ (void) printf("%s", dmapp->dmap_devlist);
(void) printf("\n");
}
@@ -82,9 +77,7 @@
*
*/
static void
-dmapi_err(exit_code, err_msg)
-int exit_code;
-char *err_msg;
+dmapi_err(int exit_code, char *err_msg)
{
if (err_msg != NULL) {
(void) fprintf(stderr, "dmapinfo:%s\n", err_msg);
@@ -107,12 +100,12 @@
prog_name,
"[-u Entry]");
}
+
exit(exit_code);
}
-
int
-main(int argc, char *argv[])
+main(int argc, char **argv)
{
devmap_t *dmapp;
devmap_t dmap;
@@ -227,12 +220,12 @@
dmapi_err(EINVOKE,
gettext("Bad dmap_devname in entry argument"));
}
- if ((dmap.dmap_devtype = getdmapfield((char *)NULL)) ==
+ if ((dmap.dmap_devtype = getdmapfield(NULL)) ==
NULL) {
dmapi_err(EINVOKE,
gettext("Bad dmap_devtype in entry Argument"));
}
- if ((dmap.dmap_devlist = getdmapfield((char *)NULL)) ==
+ if ((dmap.dmap_devlist = getdmapfield(NULL)) ==
NULL) {
dmapi_err(EINVOKE,
gettext("Bad dmap_devlist in entry argument"));
@@ -319,21 +312,27 @@
nptr = getdmapdfield(nptr);
while (nptr) {
if (verbose) {
-(void) fprintf(stderr, gettext("dmapinfo: Check %s for device (%s).\n"),
- filename, nptr);
+ (void) fprintf(stderr,
+ gettext("dmapinfo: "
+ "Check %s for device (%s).\n"),
+ filename, nptr);
}
if (getdmapdev(nptr) != NULL) {
if (verbose) {
-(void) fprintf(stderr, gettext("dmapinfo: Device (%s) found in %s.\n"),
- nptr, filename);
+ (void) fprintf(stderr,
+ gettext("dmapinfo: "
+ "Device (%s) found in %s.\n"),
+ nptr, filename);
}
exit(1);
}
if (verbose) {
-(void) fprintf(stderr, gettext("dmapinfo: Device (%s) not found in %s.\n"),
- nptr, filename);
+ (void) fprintf(stderr,
+ gettext("dmapinfo: "
+ "Device (%s) not found in %s.\n"),
+ nptr, filename);
}
- nptr = getdmapdfield((char *)NULL);
+ nptr = getdmapdfield(NULL);
}
/*
* Good the entry is uniq. So lets find out how long it is
@@ -390,17 +389,21 @@
* of 1.
*/
if (device) {
+ setdmapent();
while (argc >= 1) {
if ((dmapp = getdmapdev(*argv)) != NULL) {
if (verbose) {
printdmapent(dmapp);
}
cntr++;
- } else if (any == 0)
+ } else if (any == 0) {
+ enddmapent();
exit(1);
+ }
argc--;
argv++;
}
+ enddmapent();
if (cntr != 0)
exit(0);
exit(1);
@@ -413,6 +416,7 @@
* of 1.
*/
if (name) {
+ setdmapent();
while (argc >= 1) {
if ((dmapp = getdmapnam(*argv)) != NULL) {
if (verbose) {
@@ -424,6 +428,7 @@
argc--;
argv++;
}
+ enddmapent();
if (cntr != 0)
exit(0);
exit(1);
@@ -438,20 +443,22 @@
*/
if (tp) {
cntr = 0;
+ setdmapent();
while (argc >= 1) {
- setdmapent();
while ((dmapp = getdmaptype(*argv)) != 0) {
cntr++;
if (verbose) {
printdmapent(dmapp);
}
}
- enddmapent();
- if ((any == 0) && (cntr == 0))
+ if ((any == 0) && (cntr == 0)) {
+ enddmapent();
exit(1);
+ }
argc--;
argv++;
}
+ enddmapent();
if (cntr == 0)
exit(1);
exit(0);
diff --git a/usr/src/cmd/allocate/mkdevalloc.c b/usr/src/cmd/allocate/mkdevalloc.c
index 50c58af..e423e37 100644
--- a/usr/src/cmd/allocate/mkdevalloc.c
+++ b/usr/src/cmd/allocate/mkdevalloc.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -49,27 +49,40 @@
* /dev/nsr*
* /dev/dsk/c?t?d0s?
* /dev/rdsk/c?t?d0s?
+ *
*/
+#include <errno.h>
+#include <fcntl.h>
#include <sys/types.h> /* for stat(2), etc. */
#include <sys/stat.h>
#include <dirent.h> /* for readdir(3), etc. */
#include <unistd.h> /* for readlink(2) */
+#include <stropts.h>
#include <string.h> /* for strcpy(3), etc. */
#include <strings.h> /* for bcopy(3C), etc. */
#include <stdio.h> /* for perror(3) */
#include <stdlib.h> /* for atoi(3) */
+#include <sys/dkio.h>
#include <locale.h>
#include <libintl.h>
+#include <libdevinfo.h>
+#include <secdb.h>
#include <auth_attr.h>
#include <auth_list.h>
-#include "allocate.h" /* for SECLIB */
+#include <bsm/devices.h>
+#include <bsm/devalloc.h>
+#include <tsol/label.h>
#ifndef TEXT_DOMAIN
#define TEXT_DOMAIN "SUNW_OST_OSCMD"
#endif
+#define MKDEVALLOC "mkdevalloc"
+#define MKDEVMAPS "mkdevmaps"
+
#define DELTA 5 /* array size delta when full */
+#define SECLIB "/etc/security/lib"
/* "/dev/rst...", "/dev/nrst...", "/dev/rmt/..." */
struct tape {
@@ -82,6 +95,7 @@
#define SIZE_OF_NRST 4 /* |nrmt| */
#define SIZE_OF_TMP 4 /* |/tmp| */
#define SIZE_OF_RMT 8 /* |/dev/rmt| */
+#define TAPE_CLEAN SECLIB"/st_clean"
/* "/dev/audio", "/dev/audioctl", "/dev/sound/..." */
struct audio {
@@ -91,6 +105,7 @@
} *audio;
#define DFLT_NAUDIO 10 /* size of initial array */
#define SIZE_OF_SOUND 10 /* |/dev/sound| */
+#define AUDIO_CLEAN SECLIB"/audio_clean"
/* "/dev/sr", "/dev/nsr", "/dev/dsk/c?t?d0s?", "/dev/rdsk/c?t?d0s?" */
struct cd {
@@ -105,7 +120,17 @@
#define SIZE_OF_RSR 3 /* |rsr| */
#define SIZE_OF_DSK 8 /* |/dev/dsk| */
#define SIZE_OF_RDSK 9 /* |/dev/rdsk| */
+#define CD_CLEAN SECLIB"/sr_clean"
+/* "/dev/sr", "/dev/nsr", "/dev/dsk/c?t?d0s?", "/dev/rdsk/c?t?d0s?" */
+struct rmdisk {
+ char *name;
+ char *device;
+ int id;
+ int controller;
+ int number;
+} *rmdisk, *rmdisk_r;
+#define DFLT_RMDISK 10 /* size of initial array */
/* "/dev/fd0*", "/dev/rfd0*", "/dev/fd1*", "/dev/rfd1*" */
struct fp {
@@ -116,30 +141,72 @@
#define DFLT_NFP 10 /* size of initial array */
#define SIZE_OF_FD0 3 /* |fd0| */
#define SIZE_OF_RFD0 4 /* |rfd0| */
+#define FLOPPY_CLEAN SECLIB"/fd_clean"
static void dotape();
static void doaudio();
static void dofloppy();
-static void docd();
+static int docd();
+static void dormdisk(int);
static void initmem();
static int expandmem(int, void **, int);
static void no_memory(void);
+int system_labeled = 0;
+int do_devalloc = 0;
+int do_devmaps = 0;
+int do_files = 0;
+devlist_t devlist;
+
int
-main(void)
+main(int argc, char **argv)
{
+ int cd_count = 0;
+ char *progname;
+ struct stat tx_stat;
+
(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);
+ if ((progname = strrchr(argv[0], '/')) == NULL)
+ progname = argv[0];
+ else
+ progname++;
+ if (strcmp(progname, MKDEVALLOC) == 0)
+ do_devalloc = 1;
+ else if (strcmp(progname, MKDEVMAPS) == 0)
+ do_devmaps = 1;
+ else
+ exit(1);
+
+ system_labeled = is_system_labeled();
+ 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;
+ }
+
+ if (system_labeled && do_devalloc && (argc == 2) &&
+ (strcmp(argv[1], DA_IS_LABELED) == 0)) {
+ /*
+ * write device entries to device_allocate and device_maps.
+ * default is to print them on stdout.
+ */
+ do_files = 1;
+ }
+
initmem(); /* initialize memory */
-
- dotape(); /* do tape */
-
- doaudio(); /* do audio */
-
- dofloppy(); /* do floppy */
-
- docd(); /* do cd */
+ dotape();
+ doaudio();
+ dofloppy();
+ cd_count = docd();
+ if (system_labeled)
+ dormdisk(cd_count);
return (0);
}
@@ -149,13 +216,18 @@
{
DIR *dirp;
struct dirent *dep; /* directory entry pointer */
- int i, j, n;
+ int i, j;
char *nm; /* name/device of special device */
char linkvalue[2048]; /* symlink value */
struct stat stat; /* determine if it's a symlink */
int sz; /* size of symlink value */
char *cp; /* pointer into string */
int ntape; /* max array size */
+ int tape_count;
+ int first = 0;
+ char *dname, *dtype, *dclean;
+ da_args dargs;
+ deventry_t *entry;
ntape = DFLT_NTAPE;
@@ -260,30 +332,92 @@
i++;
}
- n = i;
+ tape_count = i;
(void) closedir(dirp);
/* remove duplicate entries */
- for (i = 0; i < n - 1; i++) {
- for (j = i + 1; j < n; j++) {
+ for (i = 0; i < tape_count - 1; i++) {
+ for (j = i + 1; j < tape_count; j++) {
if (strcmp(tape[i].device, tape[j].device))
continue;
tape[j].number = -1;
}
}
- /* print out device_allocate entries for tape devices */
+ if (system_labeled) {
+ dname = DA_TAPE_NAME;
+ dtype = DA_TAPE_TYPE;
+ dclean = DA_DEFAULT_TAPE_CLEAN;
+ } else {
+ dname = "st";
+ dtype = "st";
+ dclean = TAPE_CLEAN;
+ }
for (i = 0; i < 8; i++) {
- for (j = 0; j < n; j++) {
- if (tape[j].number == i) {
- (void) printf(
- "st%d;st;reserved;reserved;%s;",
- i, DEFAULT_DEV_ALLOC_AUTH);
- (void) printf("%s%s\n", SECLIB, "/st_clean");
+ for (j = 0; j < tape_count; j++) {
+ if (tape[j].number != i)
+ continue;
+ if (do_files) {
+ (void) da_add_list(&devlist, tape[j].name, i,
+ DA_TAPE);
+ } else if (do_devalloc) {
+ /* print device_allocate for tape devices */
+ if (system_labeled) {
+ (void) printf("%s%d%s\\\n",
+ dname, i, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DA_TAPE_TYPE, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DA_RESERVED, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DA_RESERVED, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DEFAULT_DEV_ALLOC_AUTH,
+ KV_DELIMITER);
+ (void) printf("\t%s\n\n", dclean);
+ } else {
+ (void) printf(
+ "st%d;st;reserved;reserved;%s;",
+ i, DEFAULT_DEV_ALLOC_AUTH);
+ (void) printf("%s%s\n", SECLIB,
+ "/st_clean");
+ }
break;
+ } else if (do_devmaps) {
+ /* print device_maps for tape devices */
+ if (first) {
+ (void) printf(" ");
+ } else {
+ if (system_labeled) {
+ (void) printf("%s%d%s\\\n",
+ dname, i, KV_TOKEN_DELIMIT);
+ (void) printf("\t%s%s\\\n",
+ dtype, KV_TOKEN_DELIMIT);
+ (void) printf("\t");
+ } else {
+ (void) printf("st%d:\\\n", i);
+ (void) printf("\trmt:\\\n");
+ (void) printf("\t");
+ }
+ first++;
+ }
+ (void) printf("%s", tape[j].name);
}
}
+ if (do_devmaps && first) {
+ (void) printf("\n\n");
+ first = 0;
+ }
+ }
+ if (do_files && tape_count) {
+ dargs.rootdir = NULL;
+ dargs.devnames = NULL;
+ dargs.optflag = DA_ADD;
+ for (entry = devlist.tape; entry != NULL; entry = entry->next) {
+ dargs.devinfo = &(entry->devinfo);
+ (void) da_update_device(&dargs);
+ }
}
}
@@ -292,13 +426,20 @@
{
DIR *dirp;
struct dirent *dep; /* directory entry pointer */
- int i, j, n;
+ int i, j;
char *nm; /* name/device of special device */
char linkvalue[2048]; /* symlink value */
struct stat stat; /* determine if it's a symlink */
int sz; /* size of symlink value */
char *cp; /* pointer into string */
int naudio; /* max array size */
+ int audio_count = 0;
+ int len, slen;
+ int first = 0;
+ char dname[128];
+ char *dclean;
+ da_args dargs;
+ deventry_t *entry;
naudio = DFLT_NAUDIO;
@@ -397,28 +538,90 @@
(void) closedir(dirp);
skip:
- n = i;
+ audio_count = i;
/* remove duplicate entries */
- for (i = 0; i < n - 1; i++) {
- for (j = i + 1; j < n; j++) {
+ for (i = 0; i < audio_count - 1; i++) {
+ for (j = i + 1; j < audio_count; j++) {
if (strcmp(audio[i].device, audio[j].device))
continue;
audio[j].number = -1;
}
}
- /* print out device_allocate entries for tape devices */
+ /* print out device_allocate entries for audio devices */
+ (void) strcpy(dname, DA_AUDIO_NAME);
+ slen = strlen(DA_AUDIO_NAME);
+ len = sizeof (dname) - slen;
+ dclean = system_labeled ? DA_DEFAULT_AUDIO_CLEAN : AUDIO_CLEAN;
for (i = 0; i < 8; i++) {
- for (j = 0; j < n; j++) {
- if (audio[j].number == i) {
- (void) printf("audio;audio;");
- (void) printf("reserved;reserved;%s;",
- DEFAULT_DEV_ALLOC_AUTH);
- (void) printf("%s%s\n", SECLIB, "/audio_clean");
+ for (j = 0; j < audio_count; j++) {
+ if (audio[j].number != i)
+ continue;
+ if (system_labeled)
+ (void) snprintf(dname+slen, len, "%d", i);
+ if (do_files) {
+ (void) da_add_list(&devlist, audio[j].name,
+ i, DA_AUDIO);
+ } else if (do_devalloc) {
+ /* print device_allocate for audio devices */
+ if (system_labeled) {
+ (void) printf("%s%s\\\n",
+ dname, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DA_AUDIO_TYPE, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DA_RESERVED, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DA_RESERVED, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DEFAULT_DEV_ALLOC_AUTH,
+ KV_DELIMITER);
+ (void) printf("\t%s\n\n", dclean);
+ } else {
+ (void) printf("audio;audio;");
+ (void) printf("reserved;reserved;%s;",
+ DEFAULT_DEV_ALLOC_AUTH);
+ (void) printf("%s%s\n", SECLIB,
+ "/audio_clean");
+ }
break;
+ } else if (do_devmaps) {
+ /* print device_maps for audio devices */
+ if (first) {
+ (void) printf(" ");
+ } else {
+ if (system_labeled) {
+ (void) printf("%s%s\\\n",
+ dname, KV_TOKEN_DELIMIT);
+ (void) printf("\t%s%s\\\n",
+ DA_AUDIO_TYPE,
+ KV_TOKEN_DELIMIT);
+ (void) printf("\t");
+ } else {
+ (void) printf("audio:\\\n");
+ (void) printf("\taudio:\\\n");
+ (void) printf("\t");
+ }
+ first++;
+ }
+ (void) printf("%s", audio[j].name);
}
}
+ if (do_devmaps && first) {
+ (void) printf("\n\n");
+ first = 0;
+ }
+ }
+ if (do_files && audio_count) {
+ dargs.rootdir = NULL;
+ dargs.devnames = NULL;
+ dargs.optflag = DA_ADD;
+ for (entry = devlist.audio; entry != NULL;
+ entry = entry->next) {
+ dargs.devinfo = &(entry->devinfo);
+ (void) da_update_device(&dargs);
+ }
}
}
@@ -427,13 +630,18 @@
{
DIR *dirp;
struct dirent *dep; /* directory entry pointer */
- int i, j, n;
+ int i, j;
char *nm; /* name/device of special device */
char linkvalue[2048]; /* symlink value */
struct stat stat; /* determine if it's a symlink */
int sz; /* size of symlink value */
char *cp; /* pointer into string */
int nfp; /* max array size */
+ int floppy_count = 0;
+ int first = 0;
+ char *dname, *dclean;
+ da_args dargs;
+ deventry_t *entry;
nfp = DFLT_NFP;
@@ -500,27 +708,96 @@
(void) closedir(dirp);
- n = i;
+ floppy_count = i;
- /* print out device_allocate entries for tape devices */
+ /* print out device_allocate entries for floppy devices */
+ if (system_labeled) {
+ dname = DA_FLOPPY_NAME;
+ dclean = DA_DEFAULT_DISK_CLEAN;
+ } else {
+ dname = "fd";
+ dclean = FLOPPY_CLEAN;
+ }
for (i = 0; i < 8; i++) {
- for (j = 0; j < n; j++) {
- if (fp[j].number == i) {
- (void) printf("fd%d;fd;reserved;reserved;%s;",
- i, DEFAULT_DEV_ALLOC_AUTH);
- (void) printf("/etc/security/lib/fd_clean\n");
- break;
+ for (j = 0; j < floppy_count; j++) {
+ if (fp[j].number != i)
+ continue;
+ if (do_files) {
+ (void) da_add_list(&devlist, fp[j].name, i,
+ DA_FLOPPY);
+ } else if (do_devalloc) {
+ /* print device_allocate for floppy devices */
+ if (system_labeled) {
+ (void) printf("%s%d%s\\\n",
+ dname, i, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DA_FLOPPY_TYPE, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DA_RESERVED, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DA_RESERVED, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DEFAULT_DEV_ALLOC_AUTH,
+ KV_DELIMITER);
+ (void) printf("\t%s\n\n", dclean);
+ } else {
+ (void) printf(
+ "fd%d;fd;reserved;reserved;%s;",
+ i, DEFAULT_DEV_ALLOC_AUTH);
+ (void) printf("%s%s\n", SECLIB,
+ "/fd_clean");
+ }
+ break;
+ } else if (do_devmaps) {
+ /* print device_maps for floppy devices */
+ if (first) {
+ (void) printf(" ");
+ } else {
+ if (system_labeled) {
+ (void) printf("%s%d%s\\\n",
+ dname, i, KV_TOKEN_DELIMIT);
+ (void) printf("\t%s%s\\\n",
+ DA_FLOPPY_TYPE,
+ KV_TOKEN_DELIMIT);
+ (void) printf("\t");
+ } else {
+ (void) printf("fd%d:\\\n", i);
+ (void) printf("\tfd:\\\n");
+ (void) printf("\t");
+ }
+ if (i == 0) {
+ (void) printf("/dev/diskette ");
+ (void) printf(
+ "/dev/rdiskette ");
+ }
+ first++;
+ }
+ (void) printf("%s", fp[j].name);
+ }
}
- }
+ if (do_devmaps && first) {
+ (void) printf("\n\n");
+ first = 0;
+ }
+ }
+ if (do_files && floppy_count) {
+ dargs.rootdir = NULL;
+ dargs.devnames = NULL;
+ dargs.optflag = DA_ADD;
+ for (entry = devlist.floppy; entry != NULL;
+ entry = entry->next) {
+ dargs.devinfo = &(entry->devinfo);
+ (void) da_update_device(&dargs);
+ }
}
}
-static void
+static int
docd()
{
DIR *dirp;
struct dirent *dep; /* directory entry pointer */
- int i, j, n;
+ int i, j;
char *nm; /* name/device of special device */
char linkvalue[2048]; /* symlink value */
struct stat stat; /* determine if it's a symlink */
@@ -529,6 +806,11 @@
int id; /* disk id */
int ctrl; /* disk controller */
int ncd; /* max array size */
+ int cd_count = 0;
+ int first = 0;
+ char *dname, *dclean;
+ da_args dargs;
+ deventry_t *entry;
ncd = DFLT_NCD;
@@ -580,6 +862,7 @@
if ((sz = readlink(cd[i].name, linkvalue, sizeof (linkvalue))) <
0)
continue;
+
nm = (char *)malloc(sz + 1);
if (nm == NULL)
no_memory();
@@ -593,7 +876,7 @@
i++;
}
- n = i;
+ cd_count = i;
(void) closedir(dirp);
@@ -616,7 +899,7 @@
continue;
/* see if this is one of the cd special devices */
- for (j = 0; j < n; j++) {
+ for (j = 0; j < cd_count; j++) {
if (cd[j].number == id && cd[j].controller == ctrl)
goto found;
}
@@ -667,7 +950,7 @@
continue;
/* see if this is one of the cd special devices */
- for (j = 0; j < n; j++) {
+ for (j = 0; j < cd_count; j++) {
if (cd[j].number == id && cd[j].controller == ctrl)
goto found1;
}
@@ -701,18 +984,255 @@
(void) closedir(dirp);
- n = i;
+ cd_count = i;
- /* print out device_maps entries for tape devices */
+ if (system_labeled) {
+ dname = DA_CD_NAME;
+ dclean = DA_DEFAULT_DISK_CLEAN;
+ } else {
+ dname = "sr";
+ dclean = CD_CLEAN;
+ }
for (i = 0; i < 8; i++) {
- for (j = 0; j < n; j++) {
- if (cd[j].id == i) {
- (void) printf(
- "sr%d;sr;reserved;reserved;%s;",
- i, DEFAULT_DEV_ALLOC_AUTH);
- (void) printf("%s%s\n", SECLIB, "/sr_clean");
+ for (j = 0; j < cd_count; j++) {
+ if (cd[j].id != i)
+ continue;
+ if (do_files) {
+ (void) da_add_list(&devlist, cd[j].name, i,
+ DA_CD);
+ } else if (do_devalloc) {
+ /* print device_allocate for cd devices */
+ if (system_labeled) {
+ (void) printf("%s%d%s\\\n",
+ dname, i, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DA_CD_TYPE, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DA_RESERVED, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DA_RESERVED, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DEFAULT_DEV_ALLOC_AUTH,
+ KV_DELIMITER);
+ (void) printf("\t%s\n\n", dclean);
+ } else {
+ (void) printf(
+ "sr%d;sr;reserved;reserved;%s;",
+ i, DEFAULT_DEV_ALLOC_AUTH);
+ (void) printf("%s%s\n", SECLIB,
+ "/sr_clean");
+ }
+ break;
+ } else if (do_devmaps) {
+ /* print device_maps for cd devices */
+ if (first) {
+ (void) printf(" ");
+ } else {
+ if (system_labeled) {
+ (void) printf("%s%d%s\\\n",
+ dname, i, KV_TOKEN_DELIMIT);
+ (void) printf("\t%s%s\\\n",
+ DA_CD_TYPE,
+ KV_TOKEN_DELIMIT);
+ (void) printf("\t");
+ } else {
+ (void) printf("sr%d:\\\n", i);
+ (void) printf("\tsr:\\\n");
+ (void) printf("\t");
+ }
+ first++;
+ }
+ (void) printf("%s", cd[j].name);
+ }
+ }
+ if (do_devmaps && first) {
+ (void) printf("\n\n");
+ first = 0;
+ }
+ }
+ if (do_files && cd_count) {
+ dargs.rootdir = NULL;
+ dargs.devnames = NULL;
+ dargs.optflag = DA_ADD;
+ for (entry = devlist.cd; entry != NULL; entry = entry->next) {
+ dargs.devinfo = &(entry->devinfo);
+ (void) da_update_device(&dargs);
+ }
+ }
+
+ return (cd_count);
+}
+
+static void
+dormdisk(int cd_count)
+{
+ DIR *dirp;
+ struct dirent *dep; /* directory entry pointer */
+ int i, j;
+ char *nm; /* name/device of special device */
+ int id; /* disk id */
+ int ctrl; /* disk controller */
+ int nrmdisk; /* max array size */
+ int fd = -1;
+ int rmdisk_count;
+ int first = 0;
+ int is_cd;
+ int checked;
+ int removable;
+ char path[MAXPATHLEN];
+ da_args dargs;
+ deventry_t *entry;
+
+ nrmdisk = DFLT_RMDISK;
+ i = rmdisk_count = 0;
+
+ /*
+ * scan /dev/dsk for rmdisk devices
+ */
+ if ((dirp = opendir("/dev/dsk")) == NULL) {
+ perror("gettext(open /dev/dsk failure)");
+ exit(1);
+ }
+
+ while (dep = readdir(dirp)) {
+ is_cd = 0;
+ checked = 0;
+ removable = 0;
+ /* skip . .. etc... */
+ if (strncmp(dep->d_name, ".", 1) == NULL)
+ continue;
+
+ /* get device # (disk #) */
+ if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) <= 0)
+ continue;
+
+ /* see if we've already examined this device */
+ for (j = 0; j < i; j++) {
+ if (id == rmdisk[j].id &&
+ ctrl == rmdisk[j].controller &&
+ (strcmp(dep->d_name, rmdisk[j].name) == 0)) {
+ checked = 1;
break;
}
+ if (id == rmdisk[j].id && ctrl != rmdisk[j].controller)
+ /*
+ * c2t0d0s0 is a different rmdisk than c3t0d0s0.
+ */
+ id = rmdisk[j].id + 1;
+ }
+ if (checked)
+ continue;
+
+ /* ignore if this is a cd */
+ for (j = 0; j < cd_count; j++) {
+ if (id == cd[j].number && ctrl == cd[j].controller) {
+ is_cd = 1;
+ break;
+ }
+ }
+ if (is_cd)
+ continue;
+
+ /* see if device is removable */
+ (void) snprintf(path, sizeof (path), "%s%s", "/dev/rdsk/",
+ dep->d_name);
+ if ((fd = open(path, O_RDONLY | O_NONBLOCK)) < 0)
+ continue;
+ (void) ioctl(fd, DKIOCREMOVABLE, &removable);
+ (void) close(fd);
+ if (removable == 0)
+ continue;
+
+ /*
+ * add new entry to table (/dev/dsk + / + d_name + \0)
+ * if array full, then expand it
+ */
+ if (i == nrmdisk) {
+ /* will exit(1) if insufficient memory */
+ nrmdisk = expandmem(i, (void **)&rmdisk,
+ sizeof (struct rmdisk));
+ }
+ nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1);
+ if (nm == NULL)
+ no_memory();
+ (void) strcpy(nm, "/dev/dsk/");
+ (void) strcat(nm, dep->d_name);
+ rmdisk[i].name = nm;
+ rmdisk[i].id = id;
+ rmdisk[i].controller = ctrl;
+ rmdisk[i].device = "";
+ rmdisk[i].number = id;
+ rmdisk_r[i].name = strdup(path);
+ i++;
+ }
+
+ rmdisk_count = i;
+ (void) closedir(dirp);
+
+ for (i = 0, j = rmdisk_count; i < rmdisk_count; i++, j++) {
+ if (j == nrmdisk) {
+ /* will exit(1) if insufficient memory */
+ nrmdisk = expandmem(j, (void **)&rmdisk,
+ sizeof (struct rmdisk));
+ }
+ rmdisk[j].name = rmdisk_r[i].name;
+ rmdisk[j].id = rmdisk[i].id;
+ rmdisk[j].controller = rmdisk[i].controller;
+ rmdisk[j].device = rmdisk[i].device;
+ rmdisk[j].number = rmdisk[i].number;
+ }
+ rmdisk_count = j;
+
+ for (i = 0; i < 8; i++) {
+ for (j = 0; j < rmdisk_count; j++) {
+ if (rmdisk[j].id != i)
+ continue;
+ if (do_files) {
+ (void) da_add_list(&devlist, rmdisk[j].name, i,
+ DA_RMDISK);
+ } else if (do_devalloc) {
+ /* print device_allocate for rmdisk devices */
+ (void) printf("%s%d%s\\\n",
+ DA_RMDISK_NAME, i, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DA_RMDISK_TYPE, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DA_RESERVED, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DA_RESERVED, KV_DELIMITER);
+ (void) printf("\t%s%s\\\n",
+ DEFAULT_DEV_ALLOC_AUTH, KV_DELIMITER);
+ (void) printf("\t%s\n", DA_DEFAULT_DISK_CLEAN);
+ break;
+ } else if (do_devmaps) {
+ /* print device_maps for rmdisk devices */
+ if (first) {
+ (void) printf(" ");
+ } else {
+ (void) printf("%s%d%s\\\n",
+ DA_RMDISK_NAME, i,
+ KV_TOKEN_DELIMIT);
+ (void) printf("\t%s%s\\\n",
+ DA_RMDISK_TYPE, KV_TOKEN_DELIMIT);
+ (void) printf("\t");
+ first++;
+ }
+ (void) printf("%s", rmdisk[j].name);
+ }
+ }
+ if (do_devmaps && first) {
+ (void) printf("\n\n");
+ first = 0;
+ }
+ }
+ if (do_files && rmdisk_count) {
+ dargs.rootdir = NULL;
+ dargs.devnames = NULL;
+ dargs.optflag = DA_ADD;
+ for (entry = devlist.rmdisk; entry != NULL;
+ entry = entry->next) {
+ dargs.devinfo = &(entry->devinfo);
+ (void) da_update_device(&dargs);
}
}
}
@@ -725,9 +1245,22 @@
audio = (struct audio *)calloc(DFLT_NAUDIO, sizeof (struct audio));
cd = (struct cd *)calloc(DFLT_NCD, sizeof (struct cd));
fp = (struct fp *)calloc(DFLT_NFP, sizeof (struct fp));
+ if (system_labeled) {
+ rmdisk = (struct rmdisk *)calloc(DFLT_RMDISK,
+ sizeof (struct rmdisk));
+ if (rmdisk == NULL)
+ no_memory();
+ rmdisk_r = (struct rmdisk *)calloc(DFLT_RMDISK,
+ sizeof (struct rmdisk));
+ if (rmdisk_r == NULL)
+ no_memory();
+ }
if (tape == NULL || audio == NULL || cd == NULL || fp == NULL)
no_memory();
+
+ devlist.audio = devlist.cd = devlist.floppy = devlist.rmdisk =
+ devlist.tape = NULL;
}
/* note n will be # elments in array (and could be 0) */
diff --git a/usr/src/cmd/auditconfig/auditconfig.c b/usr/src/cmd/auditconfig/auditconfig.c
index 46d42cd..57c6f7d 100644
--- a/usr/src/cmd/auditconfig/auditconfig.c
+++ b/usr/src/cmd/auditconfig/auditconfig.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -52,6 +51,7 @@
#include <pwd.h>
#include <libintl.h>
#include <zone.h>
+#include <tsol/label.h>
#include <bsm/audit.h>
#include <bsm/audit_record.h>
@@ -117,6 +117,10 @@
#define AC_KERN_EVENT 0
#define AC_USER_EVENT 1
+/* defines for policy entry flags: */
+
+#define AC_TSOL 1 /* policy is TSOL-only */
+
#define NONE(s) (!strlen(s) ? gettext("none") : s)
#define ALL_POLICIES (AUDIT_AHLT|\
@@ -131,7 +135,9 @@
AUDIT_PATH|\
AUDIT_PUBLIC|\
AUDIT_ZONENAME|\
- AUDIT_PERZONE)
+ AUDIT_PERZONE|\
+ AUDIT_WINDATA_DOWN|\
+ AUDIT_WINDATA_UP)
#define NO_POLICIES (0)
@@ -153,6 +159,7 @@
struct policy_entry {
char *policy_str;
uint_t policy_mask;
+ uint_t policy_flags;
char *policy_desc;
};
@@ -236,27 +243,40 @@
#define ARG2_TBL_SZ (sizeof (arg2_table) / sizeof (struct arg_entry))
static struct policy_entry policy_table[] = {
- {"ahlt", AUDIT_AHLT, "halt machine if it can not record an "
- "async event"},
- {"arge", AUDIT_ARGE, "include exec environment args in audit recs"},
- {"argv", AUDIT_ARGV, "include exec command line args in audit recs"},
- {"cnt", AUDIT_CNT, "when no more space, drop recs and keep a cnt"},
- {"group", AUDIT_GROUP, "include supplementary groups in audit recs"},
- {"seq", AUDIT_SEQ, "include a sequence number in audit recs"},
- {"trail", AUDIT_TRAIL, "include trailer token in audit recs"},
- {"path", AUDIT_PATH, "allow multiple paths per event"},
- {"public", AUDIT_PUBLIC, "audit public files"},
- {"zonename", AUDIT_ZONENAME, "generate zonename token"},
- {"perzone", AUDIT_PERZONE, "use a separate queue and auditd per "
- "zone"},
- {"all", ALL_POLICIES, "all policies"},
- {"none", NO_POLICIES, "no policies"}
+ {"ahlt", AUDIT_AHLT, NULL,
+ "halt machine if it can not record an async event"},
+ {"arge", AUDIT_ARGE, NULL,
+ "include exec environment args in audit recs"},
+ {"argv", AUDIT_ARGV, NULL,
+ "include exec command line args in audit recs"},
+ {"cnt", AUDIT_CNT, NULL,
+ "when no more space, drop recs and keep a cnt"},
+ {"group", AUDIT_GROUP, NULL,
+ "include supplementary groups in audit recs"},
+ {"path", AUDIT_PATH, NULL,
+ "allow multiple paths per event"},
+ {"public", AUDIT_PUBLIC, NULL, "audit public files"},
+ {"seq", AUDIT_SEQ, NULL,
+ "include a sequence number in audit recs"},
+ {"trail", AUDIT_TRAIL, NULL,
+ "include trailer token in audit recs"},
+ {"windata_down", AUDIT_WINDATA_DOWN, AC_TSOL,
+ "include downgraded information in audit recs"},
+ {"windata_up", AUDIT_WINDATA_UP, AC_TSOL,
+ "include upgraded information in audit recs"},
+ {"zonename", AUDIT_ZONENAME, NULL, "generate zonename token"},
+ {"perzone", AUDIT_PERZONE, NULL,
+ "use a separate queue and auditd per zone"},
+ {"all", ALL_POLICIES, NULL, "all policies"},
+ {"none", NO_POLICIES, NULL, "no policies"}
};
#define POLICY_TBL_SZ (sizeof (policy_table) / sizeof (struct policy_entry))
static char *progname;
+int tsol_on; /* is TSOL installed? */
+
static au_event_ent_t *egetauevnam();
static au_event_ent_t *egetauevnum();
static char *strtolower();
@@ -368,6 +388,8 @@
strcmp(argv[1], "-?") == 0))
exit_usage(0);
+ tsol_on = is_system_labeled();
+
parse_args(argv);
do_args(argv);
@@ -1246,6 +1268,15 @@
"Could not allocate subject token\n"));
if (au_write(rd, tokp) == -1)
exit_error(gettext("Could not construct subject token of audit record\n"));
+
+ if (tsol_on) {
+ if ((tokp = au_to_mylabel()) == (token_t *)NULL)
+ exit_error(gettext(
+ "Could not allocate slabel token\n"));
+ if (au_write(rd, tokp) == -1)
+exit_error(gettext("Could not construct slabel token of audit record\n"));
+ }
+
if ((tokp = au_to_text(audit_str)) == (token_t *)NULL)
exit_error(gettext("Could not allocate text token\n"));
if (au_write(rd, tokp) == -1)
@@ -1634,10 +1665,12 @@
* Print a properly aligned header.
*/
(void) printf(gettext("policy string description:\n"));
- for (i = 0; i < POLICY_TBL_SZ; i++)
- (void) printf("%-17s%s\n",
- policy_table[i].policy_str,
- gettext(policy_table[i].policy_desc));
+ for (i = 0; i < POLICY_TBL_SZ; i++) {
+ if ((policy_table[i].policy_flags & AC_TSOL) && !tsol_on)
+ continue; /* skip this entry */
+ (void) printf("%-17s%s\n", policy_table[i].policy_str,
+ gettext(policy_table[i].policy_desc));
+ }
}
static void
@@ -2295,10 +2328,12 @@
{
int i;
- for (i = 0; i < POLICY_TBL_SZ; i++)
- if (strcmp(strtolower(policy),
- policy_table[i].policy_str) == 0)
+ for (i = 0; i < POLICY_TBL_SZ; i++) {
+ if ((policy_table[i].policy_flags & AC_TSOL) && !tsol_on)
+ continue; /* skip this entry */
+ if (strcmp(strtolower(policy), policy_table[i].policy_str) == 0)
return (&policy_table[i]);
+ }
return ((struct policy_entry *)NULL);
}
@@ -2389,7 +2424,9 @@
*policy_str = '\0';
- for (i = 0, j = 0; i < POLICY_TBL_SZ; i++)
+ for (i = 0, j = 0; i < POLICY_TBL_SZ; i++) {
+ if ((policy_table[i].policy_flags & AC_TSOL) && !tsol_on)
+ continue; /* skip this entry */
if (policy & policy_table[i].policy_mask &&
policy_table[i].policy_mask != ALL_POLICIES) {
if (j++)
@@ -2397,6 +2434,7 @@
(void) strlcat(policy_str,
policy_table[i].policy_str, len);
}
+ }
if (*policy_str)
return (0);
diff --git a/usr/src/cmd/auditreduce/Makefile b/usr/src/cmd/auditreduce/Makefile
index 7d10fd2..b63b6c9 100644
--- a/usr/src/cmd/auditreduce/Makefile
+++ b/usr/src/cmd/auditreduce/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -18,9 +17,11 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
+
+
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -39,7 +40,9 @@
POFILES=main.po option.po proc.po time.po token.po
CPPFLAGS += -I$(TABLEDIR) -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
-LDLIBS += -lnsl -lbsm
+LAZYLIBS = $(ZLAZYLOAD) -ltsol $(ZNOLAZYLOAD)
+lint := LAZYLIBS = -ltsol
+LDLIBS += -lnsl -lbsm $(LAZYLIBS)
.KEEP_STATE:
diff --git a/usr/src/cmd/auditreduce/auditr.h b/usr/src/cmd/auditreduce/auditr.h
index 6146203..de5e26b 100644
--- a/usr/src/cmd/auditreduce/auditr.h
+++ b/usr/src/cmd/auditreduce/auditr.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1987 - 2000 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#ifndef _AUDITR_H
@@ -62,6 +61,9 @@
#include <bsm/audit_record.h>
#include <bsm/libbsm.h>
+#include <tsol/label.h>
+#include <sys/tsol/label_macro.h>
+
#include "auditrt.h"
/*
diff --git a/usr/src/cmd/auditreduce/auditrd.h b/usr/src/cmd/auditreduce/auditrd.h
index 22f65b7..bcd498c 100644
--- a/usr/src/cmd/auditreduce/auditrd.h
+++ b/usr/src/cmd/auditreduce/auditrd.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -51,9 +50,7 @@
time_t m_before; /* 'b' before a time */
audit_state_t mask; /* used with m_class */
char *zonename; /* 'z' zonename */
-#ifdef TSOL
-brange_t m_label; /* 'l' mandatory label range */
-#endif /* TSOL */
+m_range_t *m_label; /* 'l' mandatory label range */
int flags;
int checkflags;
int socket_flag;
diff --git a/usr/src/cmd/auditreduce/auditrt.h b/usr/src/cmd/auditreduce/auditrt.h
index d929030..f013cbf 100644
--- a/usr/src/cmd/auditreduce/auditrt.h
+++ b/usr/src/cmd/auditreduce/auditrt.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -175,9 +174,7 @@
extern audit_state_t mask; /* used with m_class */
extern char *zonename; /* 'z' zonename */
-#ifdef TSOL
-extern brange_t m_label; /* 'l' mandatory label range */
-#endif /* TSOL */
+extern m_range_t *m_label; /* 'l' mandatory label range */
extern int flags;
extern int checkflags;
extern int socket_flag;
diff --git a/usr/src/cmd/auditreduce/option.c b/usr/src/cmd/auditreduce/option.c
index 181a383..f4aaa9d 100644
--- a/usr/src/cmd/auditreduce/option.c
+++ b/usr/src/cmd/auditreduce/option.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,11 +33,6 @@
#include <locale.h>
#include <sys/zone.h> /* for max zonename length */
-
-#ifdef TSOL
-#include <tsol/label.h>
-#endif /* TSOL */
-
#include "auditr.h"
/*
@@ -95,9 +89,7 @@
static int proc_id(char *, int);
static int proc_object(char *);
static void proc_pcb(audit_pcb_t *, char *, int);
-#ifdef TSOL
static int proc_slabel(char *);
-#endif /* TSOL */
static int proc_subject(char *);
static int proc_sid(char *);
static int proc_type(char *);
@@ -203,12 +195,16 @@
if (proc_id(optarg, opt))
error = TRUE;
break;
-#ifdef TSOL
case 'l': /* label range -- reserved for TX */
+ if (!is_system_labeled()) {
+ (void) fprintf(stderr,
+ gettext("%s option 'l' requires "
+ "Trusted Extensions.\n"), ar);
+ return (-1);
+ }
if (proc_slabel(optarg))
error = TRUE;
break;
-#endif /* TSOL */
case 's': /* session ID */
if (proc_sid(optarg))
error = TRUE;
@@ -1137,7 +1133,6 @@
}
-#ifdef TSOL
/*
* .func proc_slabel - process sensitivity label range argument.
* .desc Parse sensitivity label range sl:sl
@@ -1157,67 +1152,101 @@
error_str = gettext("'l' option specified multiple times");
return (-1);
}
-
flags |= M_LABEL;
- p = strchr(optstr, ':');
+
+ if ((m_label = malloc(sizeof (m_range_t))) == NULL) {
+ return (-1);
+ }
+ m_label->lower_bound = NULL;
+ m_label->upper_bound = NULL;
+
+ p = strchr(optstr, ';');
if (p == NULL) {
/* exact label match, lower and upper range bounds the same */
- if (stobsl(optstr, &m_slabel.lower_bound, NO_CORRECTION,
- &error) == 0) {
+ if (str_to_label(optstr, &m_label->lower_bound, MAC_LABEL,
+ L_NO_CORRECTION, &error) == -1) {
(void) sprintf(errbuf,
gettext("invalid sensitivity label (%s) err %d"),
optstr, error);
error_str = errbuf;
- return (-1);
+ goto errout;
}
- m_slabel.upper_bound = m_slabel.lower_bound;
+ m_label->upper_bound = m_label->lower_bound;
return (0);
}
if (p == optstr) {
/* lower bound is not specified .. default is admin_low */
- bsllow(&m_slabel.lower_bound);
- if (stobsl(p + 1, &m_slabel.upper_bound, NO_CORRECTION,
- &error) == 0) {
- (void) sprintf(errbuf,
- gettext("invalid sensitivity label (%s) err %d"),
- p + 1, error);
- error_str = errbuf;
+ if (str_to_label(ADMIN_LOW, &m_label->lower_bound, MAC_LABEL,
+ L_NO_CORRECTION, &error) == -1) {
+ free(m_label);
return (-1);
}
+
+ p++;
+ if (*p == '\0') {
+ /* upper bound not specified .. default is admin_high */
+ if (str_to_label(ADMIN_HIGH, &m_label->upper_bound,
+ MAC_LABEL, L_NO_CORRECTION, &error) == -1) {
+ m_label_free(m_label->lower_bound);
+ free(m_label);
+ return (-1);
+ }
+ } else {
+ if (str_to_label(p, &m_label->upper_bound, MAC_LABEL,
+ L_NO_CORRECTION, &error) == -1) {
+ (void) sprintf(errbuf, gettext(
+ "invalid sensitivity label (%s) err %d"),
+ p, error);
+ error_str = errbuf;
+ goto errout;
+ }
+ }
return (0);
}
*p++ = '\0';
- if (stobsl(optstr, &m_slabel.lower_bound, NO_CORRECTION, &error) == 0) {
+ if (str_to_label(optstr, &m_label->lower_bound, MAC_LABEL,
+ L_NO_CORRECTION, &error) == -1) {
(void) sprintf(errbuf,
gettext("invalid sensitivity label (%s) err %d"), optstr,
error);
error_str = errbuf;
- return (-1);
+ goto errout;
}
- if (*p == '\0')
+ if (*p == '\0') {
/* upper bound is not specified .. default is admin_high */
- bslhigh(&m_slabel.upper_bound);
- else {
- if (stobsl(p, &m_slabel.upper_bound, NO_CORRECTION, &error) ==
- 0) {
+ if (str_to_label(ADMIN_HIGH, &m_label->upper_bound,
+ MAC_LABEL, L_NO_CORRECTION, &error) == -1) {
+ m_label_free(m_label->lower_bound);
+ free(m_label);
+ return (-1);
+ }
+ } else {
+ if (str_to_label(p, &m_label->upper_bound, MAC_LABEL,
+ L_NO_CORRECTION, &error) == -1) {
(void) sprintf(errbuf,
gettext("invalid sensitivity label (%s) err %d"),
p, error);
error_str = errbuf;
- return (-1);
+ goto errout;
}
}
/* make sure that upper bound dominates the lower bound */
- if (!bldominates(&m_slabel.upper_bound, &m_slabel.lower_bound)) {
- *--p = ':';
+ if (!bldominates(m_label->upper_bound, m_label->lower_bound)) {
+ *--p = ';';
(void) sprintf(errbuf,
gettext("invalid sensitivity label range (%s)"), optstr);
error_str = errbuf;
- return (-1);
+ goto errout;
}
return (0);
+
+errout:
+ m_label_free(m_label->upper_bound);
+ m_label_free(m_label->lower_bound);
+ free(m_label);
+
+ return (-1);
}
-#endif /* !TSOL */
/*
* proc_zonename - pick up zone name.
diff --git a/usr/src/cmd/auditreduce/token.c b/usr/src/cmd/auditreduce/token.c
index 7b3c75e..f47c1e4 100644
--- a/usr/src/cmd/auditreduce/token.c
+++ b/usr/src/cmd/auditreduce/token.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1868,48 +1867,6 @@
}
/*
- * Format of clearance token:
- * clearance adr_char*(sizeof (bclear_t))
- */
-#ifndef TSOL
-/* ARGSUSED */
-#endif /* !TSOL */
-int
-clearance_token(adr_t *adr)
-{
-#ifdef TSOL
- bclear_t clearance;
-
- adrm_char(adr, (char *)&clearance, sizeof (bclear_t));
- return (-1);
-#else /* !TSOL */
- return (-2);
-#endif /* TSOL */
-}
-
-
-/*
- * Format of ilabel token:
- * ilabel adr_char*(sizeof (bilabel_t))
- */
-#ifndef TSOL
-/* ARGSUSED */
-#endif /* !TSOL */
-int
-ilabel_token(adr_t *adr)
-{
-#ifdef TSOL
- bilabel_t ilabel;
-
- adrm_char(adr, (char *)&ilabel, sizeof (ilabel));
-
- return (-1);
-#else /* !TSOL */
- return (-2);
-#endif /* TSOL */
-}
-
-/*
* Format of privilege set token:
* priv_set type string
* priv_set string
@@ -1927,26 +1884,19 @@
* Format of slabel token:
* slabel adr_char*(sizeof (bslabel_t))
*/
-#ifndef TSOL
-/* ARGSUSED */
-#endif /* !TSOL */
int
slabel_token(adr_t *adr)
{
-#ifdef TSOL
bslabel_t slabel;
adrm_char(adr, (char *)&slabel, sizeof (slabel));
- if (flags & M_SLABEL) {
- if (blinrange(&slabel, &m_slabel))
- checkflags = checkflags | M_SLABEL;
+ if (flags & M_LABEL) {
+ if (blinrange(&slabel, m_label))
+ checkflags = checkflags | M_LABEL;
}
return (-1);
-#else /* !TSOL */
- return (-2);
-#endif /* TSOL */
}
diff --git a/usr/src/cmd/bsmconv/bsmconv.sh b/usr/src/cmd/bsmconv/bsmconv.sh
index ca0856d..db037c5 100644
--- a/usr/src/cmd/bsmconv/bsmconv.sh
+++ b/usr/src/cmd/bsmconv/bsmconv.sh
@@ -1,11 +1,11 @@
#! /bin/sh
#
+#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,8 +20,7 @@
#
# CDDL HEADER END
#
-#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -143,18 +142,25 @@
printf "${form}\n" $PROG
fi
-# Initial device allocation files
+# Initialize device allocation
-form=`gettext "%s: INFO: initializing device allocation files."`
+form=`gettext "%s: INFO: initializing device allocation."`
printf "${form}\n" $PROG
-if [ ! -f ${ROOT}/$DEVALLOC ]
+if [ -x /usr/bin/plabel ]
then
- mkdevalloc > ${ROOT}/$DEVALLOC
+ # Trusted Extensions is installed.
+ /usr/sbin/devfsadm -e
+else
+ if [ ! -f ${ROOT}/${DEVALLOC} ]
+ then
+ mkdevalloc > ${ROOT}/$DEVALLOC
+ fi
+ if [ ! -f ${ROOT}/${DEVMAPS} ]
+ then
+ mkdevmaps > ${ROOT}/$DEVMAPS
+ fi
fi
-if [ ! -f $DEVMAPS ]
-then
- mkdevmaps > ${ROOT}/$DEVMAPS
-fi
+
# enable auditd. Since we're running as single user, auditd won't
# actually start until reboot.
diff --git a/usr/src/cmd/bsmunconv/bsmunconv.sh b/usr/src/cmd/bsmunconv/bsmunconv.sh
index 0e06c46..85661b6 100644
--- a/usr/src/cmd/bsmunconv/bsmunconv.sh
+++ b/usr/src/cmd/bsmunconv/bsmunconv.sh
@@ -1,11 +1,12 @@
#! /bin/sh
#
+#
+#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,8 +21,7 @@
#
# CDDL HEADER END
#
-#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -84,8 +84,7 @@
bsmunconvert()
{
-# deallocate user allocatable devices and turn off device allocation
-/usr/sbin/deallocate -Is
+# turn off device allocation
/usr/sbin/devfsadm -d
# disable auditd service
diff --git a/usr/src/cmd/cmd-inet/usr.bin/netstat/Makefile b/usr/src/cmd/cmd-inet/usr.bin/netstat/Makefile
index e4fdbd8..5e52d8c 100644
--- a/usr/src/cmd/cmd-inet/usr.bin/netstat/Makefile
+++ b/usr/src/cmd/cmd-inet/usr.bin/netstat/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -18,11 +17,13 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
+
+
#
#
#ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 1996-2003 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# Copyright (c) 1990 Mentat Inc.
@@ -43,8 +44,9 @@
SRCS= $(LOCALSRCS) $(COMMONSRCS)
CPPFLAGS += -DNDEBUG -I$(CMDINETCOMMONDIR)
-LDLIBS += -ldhcpagent -lcmd -lsocket -lnsl -lkstat
-LINTFLAGS += -m
+LAZYLIBS = $(ZLAZYLOAD) -ltsol $(ZNOLAZYLOAD)
+lint := LAZYLIBS = -ltsol
+LDLIBS += -ldhcpagent -lcmd -lsocket -lnsl -lkstat -ltsnet $(LAZYLIBS)
.KEEP_STATE:
diff --git a/usr/src/cmd/cmd-inet/usr.bin/netstat/netstat.c b/usr/src/cmd/cmd-inet/usr.bin/netstat/netstat.c
index f978ae4..8218eac 100644
--- a/usr/src/cmd/cmd-inet/usr.bin/netstat/netstat.c
+++ b/usr/src/cmd/cmd-inet/usr.bin/netstat/netstat.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -66,7 +65,6 @@
#include <sys/stream.h>
#include <stropts.h>
#include <sys/strstat.h>
-#include <sys/sysmacros.h>
#include <sys/tihdr.h>
#include <sys/socket.h>
@@ -94,9 +92,10 @@
#include <dhcpagent_util.h>
#include <compat.h>
+#include <libtsnet.h>
+#include <tsol/label.h>
+
extern void unixpr(kstat_ctl_t *kc);
-extern void setifdhcp(const char *caller, const char *ifname,
- int argc, char *argv[]);
#define STR_EXPAND 4
@@ -141,7 +140,7 @@
static void mib_item_destroy(mib_item_t **item);
static boolean_t octetstrmatch(const Octet_t *a, const Octet_t *b);
-static char *octetstr(Octet_t *op, int code,
+static char *octetstr(const Octet_t *op, int code,
char *dst, uint_t dstlen);
static char *pr_addr(uint_t addr,
char *dst, uint_t dstlen);
@@ -150,8 +149,8 @@
char *dst, uint_t dstlen);
static char *pr_mask(uint_t addr,
char *dst, uint_t dstlen);
-static char *pr_prefix6(struct in6_addr *addr, uint_t prefixlen,
- char *dst, uint_t dstlen);
+static char *pr_prefix6(const struct in6_addr *addr,
+ uint_t prefixlen, char *dst, uint_t dstlen);
static char *pr_ap(uint_t addr, uint_t port,
char *proto, char *dst, uint_t dstlen);
static char *pr_ap6(const in6_addr_t *addr, uint_t port,
@@ -166,7 +165,10 @@
static char *portname(uint_t port, char *proto,
char *dst, uint_t dstlen);
-static char *mitcp_state(int code);
+static const char *mitcp_state(int code,
+ const mib2_transportMLPEntry_t *attr);
+static const char *miudp_state(int code,
+ const mib2_transportMLPEntry_t *attr);
static void stat_report(mib_item_t *item);
static void mrt_stat_report(mib_item_t *item);
@@ -183,9 +185,9 @@
static void if_report_ip6(mib2_ipv6AddrEntry_t *ap6,
char ifname[], char logintname[],
struct ifstat *statptr, boolean_t ksp_not_null);
-static void ire_report(mib_item_t *item);
-static void tcp_report(mib_item_t *item);
-static void udp_report(mib_item_t *item);
+static void ire_report(const mib_item_t *item);
+static void tcp_report(const mib_item_t *item);
+static void udp_report(const mib_item_t *item);
static void group_report(mib_item_t *item);
static void print_ip_stats(mib2_ip_t *ip);
static void print_icmp_stats(mib2_icmp_t *icmp);
@@ -197,7 +199,7 @@
static void print_rawip_stats(mib2_rawip_t *rawip);
static void print_igmp_stats(struct igmpstat *igps);
static void print_mrt_stats(struct mrtstat *mrts);
-static void sctp_report(mib_item_t *item);
+static void sctp_report(const mib_item_t *item);
static void sum_ip6_stats(mib2_ipv6IfStatsEntry_t *ip6,
mib2_ipv6IfStatsEntry_t *sum6);
static void sum_icmp6_stats(mib2_ipv6IfIcmpEntry_t *icmp6,
@@ -232,6 +234,7 @@
static boolean_t Mflag = B_FALSE; /* STREAMS Memory Statistics */
static boolean_t Nflag = B_FALSE; /* Numeric Network Addresses */
static boolean_t Rflag = B_FALSE; /* Routing Tables */
+static boolean_t RSECflag = B_FALSE; /* Security attributes */
static boolean_t Sflag = B_FALSE; /* Per-protocol Statistics */
static boolean_t Vflag = B_FALSE; /* Verbose */
static boolean_t Pflag = B_FALSE; /* Net to Media Tables */
@@ -254,6 +257,7 @@
static int ipNetToMediaEntrySize;
static int ipMemberEntrySize;
static int ipGroupSourceEntrySize;
+static int ipRouteAttributeSize;
static int vifctlSize;
static int mfcctlSize;
@@ -265,6 +269,7 @@
static int ipv6MemberEntrySize;
static int ipv6GroupSourceEntrySize;
+static int transportMLPSize;
static int tcpConnEntrySize;
static int tcp6ConnEntrySize;
static int udpEntrySize;
@@ -362,7 +367,7 @@
default_ip_str, DEFAULT_IP, INET_DEFAULT_FILE);
free(default_ip_str);
- while ((c = getopt(argc, argv, "adimnrspMgvf:P:I:D")) != -1) {
+ while ((c = getopt(argc, argv, "adimnrspMgvf:P:I:DR")) != -1) {
switch ((char)c) {
case 'a': /* all connections */
Aflag = B_TRUE;
@@ -391,6 +396,11 @@
IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
break;
+ case 'R': /* security attributes */
+ RSECflag = B_TRUE;
+ IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
+ break;
+
case 's': /* per-protocol statistics */
Sflag = B_TRUE;
IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
@@ -467,6 +477,14 @@
}
/*
+ * Make sure -R option is set only on a labeled system.
+ */
+ if (RSECflag && !is_system_labeled()) {
+ (void) fprintf(stderr, "-R set but labeling is not enabled\n");
+ usage(name);
+ }
+
+ /*
* Handle other arguments: find interval, count; the
* flags that accept 'interval' and 'count' are OR'd
* in the outermost 'if'; more flags may be added as
@@ -1460,7 +1478,7 @@
/* If octetstr() changes make an appropriate change to STR_EXPAND */
static char *
-octetstr(Octet_t *op, int code, char *dst, uint_t dstlen)
+octetstr(const Octet_t *op, int code, char *dst, uint_t dstlen)
{
int i;
char *cp;
@@ -1504,11 +1522,11 @@
return (dst);
}
-static char *
-mitcp_state(int state)
+static const char *
+mitcp_state(int state, const mib2_transportMLPEntry_t *attr)
{
-static char tcpsbuf[50];
- char *cp;
+ static char tcpsbuf[50];
+ const char *cp;
switch (state) {
case TCPS_CLOSED:
@@ -1556,6 +1574,55 @@
cp = tcpsbuf;
break;
}
+
+ if (RSECflag && attr != NULL && attr->tme_flags != 0) {
+ if (cp != tcpsbuf) {
+ (void) strlcpy(tcpsbuf, cp, sizeof (tcpsbuf));
+ cp = tcpsbuf;
+ }
+ if (attr->tme_flags & MIB2_TMEF_PRIVATE)
+ (void) strlcat(tcpsbuf, " P", sizeof (tcpsbuf));
+ if (attr->tme_flags & MIB2_TMEF_SHARED)
+ (void) strlcat(tcpsbuf, " S", sizeof (tcpsbuf));
+ }
+
+ return (cp);
+}
+
+static const char *
+miudp_state(int state, const mib2_transportMLPEntry_t *attr)
+{
+ static char udpsbuf[50];
+ const char *cp;
+
+ switch (state) {
+ case MIB2_UDP_unbound:
+ cp = "Unbound";
+ break;
+ case MIB2_UDP_idle:
+ cp = "Idle";
+ break;
+ case MIB2_UDP_connected:
+ cp = "Connected";
+ break;
+ default:
+ (void) snprintf(udpsbuf, sizeof (udpsbuf),
+ "Unknown State(%d)", state);
+ cp = udpsbuf;
+ break;
+ }
+
+ if (RSECflag && attr != NULL && attr->tme_flags != 0) {
+ if (cp != udpsbuf) {
+ (void) strlcpy(udpsbuf, cp, sizeof (udpsbuf));
+ cp = udpsbuf;
+ }
+ if (attr->tme_flags & MIB2_TMEF_PRIVATE)
+ (void) strlcat(udpsbuf, " P", sizeof (udpsbuf));
+ if (attr->tme_flags & MIB2_TMEF_SHARED)
+ (void) strlcat(udpsbuf, " S", sizeof (udpsbuf));
+ }
+
return (cp);
}
@@ -1637,6 +1704,8 @@
ipNetToMediaEntrySize = ip->ipNetToMediaEntrySize;
ipMemberEntrySize = ip->ipMemberEntrySize;
ipGroupSourceEntrySize = ip->ipGroupSourceEntrySize;
+ ipRouteAttributeSize = ip->ipRouteAttributeSize;
+ transportMLPSize = ip->transportMLPSize;
assert(IS_P2ALIGNED(ipAddrEntrySize,
sizeof (mib2_ipAddrEntry_t *)) &&
IS_P2ALIGNED(ipRouteEntrySize,
@@ -1646,7 +1715,11 @@
IS_P2ALIGNED(ipMemberEntrySize,
sizeof (ip_member_t *)) &&
IS_P2ALIGNED(ipGroupSourceEntrySize,
- sizeof (ip_grpsrc_t *)));
+ sizeof (ip_grpsrc_t *)) &&
+ IS_P2ALIGNED(ipRouteAttributeSize,
+ sizeof (mib2_ipAttributeEntry_t *)) &&
+ IS_P2ALIGNED(transportMLPSize,
+ sizeof (mib2_transportMLPEntry_t *)));
break;
}
case EXPER_DVMRP: {
@@ -1737,6 +1810,8 @@
(void) printf("\tipNetToMediaEntrySize %d\n",
ipNetToMediaEntrySize);
(void) printf("\tipMemberEntrySize %d\n", ipMemberEntrySize);
+ (void) printf("\tipRouteAttributeSize %d\n",
+ ipRouteAttributeSize);
(void) printf("\tvifctlSize %d\n", vifctlSize);
(void) printf("\tmfcctlSize %d\n", mfcctlSize);
@@ -1748,6 +1823,7 @@
ipv6MemberEntrySize);
(void) printf("\tipv6IfIcmpEntrySize %d\n",
ipv6IfIcmpEntrySize);
+ (void) printf("\ttransportMLPSize %d\n", transportMLPSize);
(void) printf("\ttcpConnEntrySize %d\n", tcpConnEntrySize);
(void) printf("\ttcp6ConnEntrySize %d\n", tcp6ConnEntrySize);
(void) printf("\tudpEntrySize %d\n", udpEntrySize);
@@ -3656,23 +3732,102 @@
/* ------------------------- ire_report (netstat -r) ------------------------ */
-static boolean_t ire_report_item_v4(mib2_ipRouteEntry_t *rp, boolean_t first);
-static boolean_t ire_report_item_v4src(mib2_ipRouteEntry_t *rp,
- boolean_t first);
-static boolean_t ire_report_item_v6(mib2_ipv6RouteEntry_t *rp6,
- boolean_t first);
+typedef struct sec_attr_list_s {
+ struct sec_attr_list_s *sal_next;
+ const mib2_ipAttributeEntry_t *sal_attr;
+} sec_attr_list_t;
+
+static boolean_t ire_report_item_v4(const mib2_ipRouteEntry_t *, boolean_t,
+ const sec_attr_list_t *);
+static boolean_t ire_report_item_v4src(const mib2_ipRouteEntry_t *, boolean_t,
+ const sec_attr_list_t *);
+static boolean_t ire_report_item_v6(const mib2_ipv6RouteEntry_t *, boolean_t,
+ const sec_attr_list_t *);
+static const char *pr_secattr(const sec_attr_list_t *);
static void
-ire_report(mib_item_t *item)
+ire_report(const mib_item_t *item)
{
int jtemp = 0;
boolean_t print_hdr_once_v4 = B_TRUE;
boolean_t print_hdr_once_v6 = B_TRUE;
mib2_ipRouteEntry_t *rp;
mib2_ipv6RouteEntry_t *rp6;
+ sec_attr_list_t **v4_attrs, **v4a;
+ sec_attr_list_t **v6_attrs, **v6a;
+ sec_attr_list_t *all_attrs, *aptr;
+ const mib_item_t *iptr;
+ int ipv4_route_count, ipv6_route_count;
+ int route_attrs_count;
+
+ /*
+ * Preparation pass: the kernel returns separate entries for IP routing
+ * table entries and security attributes. We loop through the
+ * attributes first and link them into lists.
+ */
+ ipv4_route_count = ipv6_route_count = route_attrs_count = 0;
+ for (iptr = item; iptr != NULL; iptr = iptr->next_item) {
+ if (iptr->group == MIB2_IP6 && iptr->mib_id == MIB2_IP6_ROUTE)
+ ipv6_route_count += iptr->length / ipv6RouteEntrySize;
+ if (iptr->group == MIB2_IP && iptr->mib_id == MIB2_IP_ROUTE)
+ ipv4_route_count += iptr->length / ipRouteEntrySize;
+ if ((iptr->group == MIB2_IP || iptr->group == MIB2_IP6) &&
+ iptr->mib_id == EXPER_IP_RTATTR)
+ route_attrs_count += iptr->length /
+ ipRouteAttributeSize;
+ }
+ v4_attrs = v6_attrs = NULL;
+ all_attrs = NULL;
+ if (family_selected(AF_INET) && ipv4_route_count > 0) {
+ v4_attrs = calloc(ipv4_route_count, sizeof (*v4_attrs));
+ if (v4_attrs == NULL) {
+ perror("ire_report calloc v4_attrs failed");
+ return;
+ }
+ }
+ if (family_selected(AF_INET6) && ipv6_route_count > 0) {
+ v6_attrs = calloc(ipv6_route_count, sizeof (*v6_attrs));
+ if (v6_attrs == NULL) {
+ perror("ire_report calloc v6_attrs failed");
+ goto ire_report_done;
+ }
+ }
+ if (route_attrs_count > 0) {
+ all_attrs = malloc(route_attrs_count * sizeof (*all_attrs));
+ if (all_attrs == NULL) {
+ perror("ire_report malloc all_attrs failed");
+ goto ire_report_done;
+ }
+ }
+ aptr = all_attrs;
+ for (iptr = item; iptr != NULL; iptr = iptr->next_item) {
+ mib2_ipAttributeEntry_t *iae;
+ sec_attr_list_t **alp;
+
+ if (v4_attrs != NULL && iptr->group == MIB2_IP &&
+ iptr->mib_id == EXPER_IP_RTATTR) {
+ alp = v4_attrs;
+ } else if (v6_attrs != NULL && iptr->group == MIB2_IP6 &&
+ iptr->mib_id == EXPER_IP_RTATTR) {
+ alp = v6_attrs;
+ } else {
+ continue;
+ }
+ for (iae = iptr->valp;
+ (char *)iae < (char *)iptr->valp + iptr->length;
+ /* LINTED: (note 1) */
+ iae = (mib2_ipAttributeEntry_t *)((char *)iae +
+ ipRouteAttributeSize)) {
+ aptr->sal_next = alp[iae->iae_routeidx];
+ aptr->sal_attr = iae;
+ alp[iae->iae_routeidx] = aptr++;
+ }
+ }
/* 'for' loop 1: */
- for (; item; item = item->next_item) {
+ v4a = v4_attrs;
+ v6a = v6_attrs;
+ for (; item != NULL; item = item->next_item) {
if (Dflag) {
(void) printf("\n--- Entry %d ---\n", ++jtemp);
(void) printf("Group = %d, mib_id = %d, "
@@ -3710,17 +3865,21 @@
/* LINTED: (note 1) */
rp = (mib2_ipRouteEntry_t *)((char *)rp +
ipRouteEntrySize)) {
+ aptr = v4a == NULL ? NULL : *v4a++;
print_hdr_once_v4 = ire_report_item_v4(rp,
- print_hdr_once_v4);
+ print_hdr_once_v4, aptr);
}
+ if (v4a != NULL)
+ v4a -= item->length / ipRouteEntrySize;
print_hdr_once_v4 = B_TRUE;
for (rp = (mib2_ipRouteEntry_t *)item->valp;
(char *)rp < (char *)item->valp + item->length;
/* LINTED: (note 1) */
rp = (mib2_ipRouteEntry_t *)((char *)rp +
ipRouteEntrySize)) {
+ aptr = v4a == NULL ? NULL : *v4a++;
print_hdr_once_v4 = ire_report_item_v4src(rp,
- print_hdr_once_v4);
+ print_hdr_once_v4, aptr);
}
} else {
for (rp6 = (mib2_ipv6RouteEntry_t *)item->valp;
@@ -3728,12 +3887,20 @@
/* LINTED: (note 1) */
rp6 = (mib2_ipv6RouteEntry_t *)((char *)rp6 +
ipv6RouteEntrySize)) {
+ aptr = v6a == NULL ? NULL : *v6a++;
print_hdr_once_v6 = ire_report_item_v6(rp6,
- print_hdr_once_v6);
+ print_hdr_once_v6, aptr);
}
}
} /* 'for' loop 1 ends */
(void) fflush(stdout);
+ire_report_done:
+ if (v4_attrs != NULL)
+ free(v4_attrs);
+ if (v6_attrs != NULL)
+ free(v6_attrs);
+ if (all_attrs != NULL)
+ free(all_attrs);
}
/*
@@ -3809,7 +3976,7 @@
* of each type matches, then display the route.
*/
static boolean_t
-ire_filter_match_v4(mib2_ipRouteEntry_t *rp, uint_t flag_b)
+ire_filter_match_v4(const mib2_ipRouteEntry_t *rp, uint_t flag_b)
{
filter_t *fp;
int idx;
@@ -3865,7 +4032,7 @@
* route.
*/
static uint_t
-form_v4_route_flags(mib2_ipRouteEntry_t *rp, char *flags)
+form_v4_route_flags(const mib2_ipRouteEntry_t *rp, char *flags)
{
uint_t flag_b;
@@ -3910,8 +4077,23 @@
return (flag_b);
}
+static const char ire_hdr_v4[] =
+"\n%s Table: IPv4\n";
+static const char ire_hdr_v4_compat[] =
+"\n%s Table:\n";
+static const char ire_hdr_v4_verbose[] =
+" Destination Mask Gateway Device Mxfrg "
+"Rtt Ref Flg Out In/Fwd %s\n"
+"-------------------- --------------- -------------------- ------ ----- "
+"----- --- --- ----- ------ %s\n";
+
+static const char ire_hdr_v4_normal[] =
+" Destination Gateway Flags Ref Use Interface %s\n"
+"-------------------- -------------------- ----- ----- ------ --------- %s\n";
+
static boolean_t
-ire_report_item_v4(mib2_ipRouteEntry_t *rp, boolean_t first)
+ire_report_item_v4(const mib2_ipRouteEntry_t *rp, boolean_t first,
+ const sec_attr_list_t *attrs)
{
char dstbuf[MAXHOSTNAMELEN + 1];
char maskbuf[MAXHOSTNAMELEN + 1];
@@ -3934,29 +4116,11 @@
return (first);
if (first) {
- if (Vflag) {
- (void) puts(v4compat ?
- "\nIRE Table:" :
- "\nIRE Table: IPv4");
- (void) puts(" Destination Mask "
- " Gateway "
- "Device Mxfrg Rtt Ref Flg Out "
- "In/Fwd");
- (void) puts("-------------------- --------------- "
- "-------------------- "
- "------ ----- ----- --- --- ----- "
- "------");
- } else {
- (void) puts(v4compat ?
- "\nRouting Table:" :
- "\nRouting Table: IPv4");
- (void) puts(" Destination "
- " Gateway Flags Ref Use "
- "Interface");
- (void) puts("-------------------- "
- "-------------------- ----- ----- ------ "
- "---------");
- }
+ (void) printf(v4compat ? ire_hdr_v4_compat : ire_hdr_v4,
+ Vflag ? "IRE" : "Routing");
+ (void) printf(Vflag ? ire_hdr_v4_verbose : ire_hdr_v4_normal,
+ RSECflag ? " Gateway security attributes " : "",
+ RSECflag ? "-------------------------------" : "");
first = B_FALSE;
}
@@ -3968,7 +4132,7 @@
}
if (Vflag) {
(void) printf("%-20s %-15s %-20s %-6s %5u%c %4u %3u "
- "%-4s%6u%6u\n",
+ "%-4s%6u%6u %s\n",
dstbuf,
pr_mask(rp->ipRouteMask, maskbuf, sizeof (maskbuf)),
pr_addrnz(rp->ipRouteNextHop, gwbuf, sizeof (gwbuf)),
@@ -3979,25 +4143,43 @@
rp->ipRouteInfo.re_ref,
flags,
rp->ipRouteInfo.re_obpkt,
- rp->ipRouteInfo.re_ibpkt);
+ rp->ipRouteInfo.re_ibpkt,
+ pr_secattr(attrs));
} else {
- (void) printf("%-20s %-20s %-5s %4u%7u %s\n",
+ (void) printf("%-20s %-20s %-5s %4u%7u %-9s %s\n",
dstbuf,
pr_addrnz(rp->ipRouteNextHop, gwbuf, sizeof (gwbuf)),
flags,
rp->ipRouteInfo.re_ref,
rp->ipRouteInfo.re_obpkt + rp->ipRouteInfo.re_ibpkt,
octetstr(&rp->ipRouteIfIndex, 'a',
- ifname, sizeof (ifname)));
+ ifname, sizeof (ifname)),
+ pr_secattr(attrs));
}
return (first);
}
+static const char ire_hdr_src_v4[] =
+"\n%s Table: IPv4 Source-Specific\n";
+static const char ire_hdr_src_v4_compat[] =
+"\n%s Table: Source-Specific\n";
+static const char ire_hdr_src_v4_verbose[] =
+" Destination In If Source Gateway "
+" Out If Mxfrg Rtt Ref Flg Out In/Fwd %s\n"
+"------------------ ----------- ----------------- ----------------- "
+"----------- ----- ----- --- --- ----- ------ %s\n";
+static const char ire_hdr_src_v4_normal[] =
+" Destination In If Source Gateway Flags Use "
+" Out If %s\n"
+"--------------- -------- --------------- --------------- ----- ------ "
+"-------- %s\n";
+
/*
* Report a source-specific route.
*/
static boolean_t
-ire_report_item_v4src(mib2_ipRouteEntry_t *rp, boolean_t first)
+ire_report_item_v4src(const mib2_ipRouteEntry_t *rp, boolean_t first,
+ const sec_attr_list_t *attrs)
{
char dstbuf[MAXHOSTNAMELEN + 1];
char srcbuf[MAXHOSTNAMELEN + 1];
@@ -4025,25 +4207,12 @@
return (first);
if (first) {
- if (Vflag) {
- (void) printf("\nIRE Table: %sSource-Specific\n",
- v4compat ? "" : "IPv4 ");
- (void) puts(" Destination In If "
- " Source Gateway "
- " Out If Mxfrg Rtt Ref Flg Out In/Fwd");
- (void) puts("------------------ ----------- "
- "----------------- ----------------- "
- "----------- ----- ----- --- --- ----- ------");
- } else {
- (void) printf("\nRouting Table: %sSource-Specific\n",
- v4compat ? "" : "IPv4 ");
- (void) puts(" Destination In If "
- " Source Gateway Flags Use "
- " Out If");
- (void) puts("--------------- -------- "
- "--------------- --------------- ----- ------ "
- "--------");
- }
+ (void) printf(v4compat ? ire_hdr_src_v4_compat :
+ ire_hdr_src_v4, Vflag ? "IRE" : "Routing");
+ (void) printf(Vflag ? ire_hdr_src_v4_verbose :
+ ire_hdr_src_v4_normal,
+ RSECflag ? " Gateway security attributes " : "",
+ RSECflag ? "-------------------------------" : "");
first = B_FALSE;
}
@@ -4065,17 +4234,18 @@
(void) pr_addrnz(rp->ipRouteNextHop, gwbuf, sizeof (gwbuf));
if (Vflag) {
(void) printf("%-18s %-11s %-17s %-17s %-11s %4u%c %5u %3u "
- "%-3s %5u %6u\n",
+ "%-3s %5u %6u %s\n",
dstbuf, inif, srcbuf, gwbuf, outif,
rp->ipRouteInfo.re_max_frag,
rp->ipRouteInfo.re_frag_flag ? '*' : ' ',
rp->ipRouteInfo.re_rtt, rp->ipRouteInfo.re_ref, flags,
- rp->ipRouteInfo.re_obpkt, rp->ipRouteInfo.re_ibpkt);
+ rp->ipRouteInfo.re_obpkt, rp->ipRouteInfo.re_ibpkt,
+ pr_secattr(attrs));
} else {
- (void) printf("%-15s %-8s %-15s %-15s %-5s %6u %-8s\n", dstbuf,
- inif, srcbuf, gwbuf, flags,
- rp->ipRouteInfo.re_obpkt + rp->ipRouteInfo.re_ibpkt,
- outif);
+ (void) printf("%-15s %-8s %-15s %-15s %-5s %6u %-8s %s\n",
+ dstbuf, inif, srcbuf, gwbuf, flags,
+ rp->ipRouteInfo.re_obpkt + rp->ipRouteInfo.re_ibpkt, outif,
+ pr_secattr(attrs));
}
return (first);
}
@@ -4145,7 +4315,7 @@
* types, then the route is selected and displayed.
*/
static boolean_t
-ire_filter_match_v6(mib2_ipv6RouteEntry_t *rp6, uint_t flag_b)
+ire_filter_match_v6(const mib2_ipv6RouteEntry_t *rp6, uint_t flag_b)
{
filter_t *fp;
int idx;
@@ -4201,8 +4371,22 @@
return (B_TRUE);
}
+static const char ire_hdr_v6[] =
+"\n%s Table: IPv6\n";
+static const char ire_hdr_v6_verbose[] =
+" Destination/Mask Gateway If PMTU Rtt "
+"Ref Flags Out In/Fwd %s\n"
+"--------------------------- --------------------------- ----- ------ ----- "
+"--- ----- ------ ------ %s\n";
+static const char ire_hdr_v6_normal[] =
+" Destination/Mask Gateway Flags Ref Use "
+" If %s\n"
+"--------------------------- --------------------------- ----- --- ------ "
+"----- %s\n";
+
static boolean_t
-ire_report_item_v6(mib2_ipv6RouteEntry_t *rp6, boolean_t first)
+ire_report_item_v6(const mib2_ipv6RouteEntry_t *rp6, boolean_t first,
+ const sec_attr_list_t *attrs)
{
char dstbuf[MAXHOSTNAMELEN + 1];
char gwbuf[MAXHOSTNAMELEN + 1];
@@ -4256,29 +4440,16 @@
return (first);
if (first) {
- if (Vflag) {
- (void) puts("\nIRE Table: IPv6");
- (void) puts(" Destination/Mask "
- " Gateway "
- " If PMTU Rtt Ref Flags Out In/Fwd");
- (void) puts("--------------------------- "
- "--------------------------- "
- "----- ------ ----- --- ----- ------ ------");
- } else {
- (void) puts("\nRouting Table: IPv6");
- (void) puts(" Destination/Mask "
- " Gateway Flags Ref Use "
- " If ");
- (void) puts("--------------------------- "
- "--------------------------- ----- --- ------ "
- "-----");
- }
+ (void) printf(ire_hdr_v6, Vflag ? "IRE" : "Routing");
+ (void) printf(Vflag ? ire_hdr_v6_verbose : ire_hdr_v6_normal,
+ RSECflag ? " Gateway security attributes " : "",
+ RSECflag ? "-------------------------------" : "");
first = B_FALSE;
}
if (Vflag) {
(void) printf("%-27s %-27s %-5s %5u%c %5u %3u "
- "%-5s %6u %6u\n",
+ "%-5s %6u %6u %s\n",
pr_prefix6(&rp6->ipv6RouteDest,
rp6->ipv6RoutePfxLength, dstbuf, sizeof (dstbuf)),
IN6_IS_ADDR_UNSPECIFIED(&rp6->ipv6RouteNextHop) ?
@@ -4292,9 +4463,10 @@
rp6->ipv6RouteInfo.re_ref,
flags,
rp6->ipv6RouteInfo.re_obpkt,
- rp6->ipv6RouteInfo.re_ibpkt);
+ rp6->ipv6RouteInfo.re_ibpkt,
+ pr_secattr(attrs));
} else {
- (void) printf("%-27s %-27s %-5s %3u %6u %-5s\n",
+ (void) printf("%-27s %-27s %-5s %3u %6u %-5s %s\n",
pr_prefix6(&rp6->ipv6RouteDest,
rp6->ipv6RoutePfxLength, dstbuf, sizeof (dstbuf)),
IN6_IS_ADDR_UNSPECIFIED(&rp6->ipv6RouteNextHop) ?
@@ -4304,11 +4476,59 @@
rp6->ipv6RouteInfo.re_ref,
rp6->ipv6RouteInfo.re_obpkt + rp6->ipv6RouteInfo.re_ibpkt,
octetstr(&rp6->ipv6RouteIfIndex, 'a',
- ifname, sizeof (ifname)));
+ ifname, sizeof (ifname)),
+ pr_secattr(attrs));
}
return (first);
}
+/*
+ * Common attribute-gathering routine for all transports.
+ */
+static mib2_transportMLPEntry_t **
+gather_attrs(const mib_item_t *item, int group, int mib_id, int esize)
+{
+ int transport_count = 0;
+ const mib_item_t *iptr;
+ mib2_transportMLPEntry_t **attrs, *tme;
+
+ for (iptr = item; iptr != NULL; iptr = iptr->next_item) {
+ if (iptr->group == group && iptr->mib_id == mib_id)
+ transport_count += iptr->length / esize;
+ }
+ if (transport_count <= 0)
+ return (NULL);
+ attrs = calloc(transport_count, sizeof (*attrs));
+ if (attrs == NULL) {
+ perror("gather_attrs calloc failed");
+ return (NULL);
+ }
+ for (iptr = item; iptr != NULL; iptr = iptr->next_item) {
+ if (iptr->group == group && iptr->mib_id == EXPER_XPORT_MLP) {
+ for (tme = iptr->valp;
+ (char *)tme < (char *)iptr->valp + iptr->length;
+ /* LINTED: (note 1) */
+ tme = (mib2_transportMLPEntry_t *)((char *)tme +
+ transportMLPSize)) {
+ attrs[tme->tme_connidx] = tme;
+ }
+ }
+ }
+ return (attrs);
+}
+
+static void
+print_transport_label(const mib2_transportMLPEntry_t *attr)
+{
+ if (!RSECflag || attr == NULL)
+ return;
+
+ if (bisinvalid(&attr->tme_label))
+ (void) printf(" INVALID\n");
+ else
+ (void) printf(" %s\n", sl_to_str(&attr->tme_label));
+}
+
/* ------------------------------ TCP_REPORT------------------------------- */
static const char tcp_hdr_v4[] =
@@ -4317,43 +4537,65 @@
"\nTCP\n";
static const char tcp_hdr_v4_verbose[] =
"Local/Remote Address Swind Snext Suna Rwind Rnext Rack "
-" Rto Mss State\n"
+" Rto Mss State\n"
"-------------------- ----- -------- -------- ----- -------- -------- "
-"----- ----- -----\n";
+"----- ----- -----------\n";
static const char tcp_hdr_v4_normal[] =
-" Local Address Remote Address Swind Send-Q Rwind Recv-Q State\n"
-"-------------------- -------------------- ----- ------ ----- ------ -------\n";
+" Local Address Remote Address Swind Send-Q Rwind Recv-Q "
+" State\n"
+"-------------------- -------------------- ----- ------ ----- ------ "
+"-----------\n";
static const char tcp_hdr_v6[] =
"\nTCP: IPv6\n";
static const char tcp_hdr_v6_verbose[] =
"Local/Remote Address Swind Snext Suna Rwind Rnext "
-" Rack Rto Mss State If \n"
+" Rack Rto Mss State If\n"
"--------------------------------- ----- -------- -------- ----- -------- "
"-------- ----- ----- ----------- -----\n";
static const char tcp_hdr_v6_normal[] =
" Local Address Remote Address "
-"Swind Send-Q Rwind Recv-Q State If \n"
+"Swind Send-Q Rwind Recv-Q State If\n"
"--------------------------------- --------------------------------- "
"----- ------ ----- ------ ----------- -----\n";
-static boolean_t tcp_report_item_v4(mib2_tcpConnEntry_t *tp, boolean_t first);
-static boolean_t tcp_report_item_v6(mib2_tcp6ConnEntry_t *tp6, boolean_t first);
+static boolean_t tcp_report_item_v4(const mib2_tcpConnEntry_t *,
+ boolean_t first, const mib2_transportMLPEntry_t *);
+static boolean_t tcp_report_item_v6(const mib2_tcp6ConnEntry_t *,
+ boolean_t first, const mib2_transportMLPEntry_t *);
static void
-tcp_report(mib_item_t *item)
+tcp_report(const mib_item_t *item)
{
int jtemp = 0;
boolean_t print_hdr_once_v4 = B_TRUE;
boolean_t print_hdr_once_v6 = B_TRUE;
mib2_tcpConnEntry_t *tp;
mib2_tcp6ConnEntry_t *tp6;
+ mib2_transportMLPEntry_t **v4_attrs, **v6_attrs;
+ mib2_transportMLPEntry_t **v4a, **v6a;
+ mib2_transportMLPEntry_t *aptr;
if (!protocol_selected(IPPROTO_TCP))
return;
+ /*
+ * Preparation pass: the kernel returns separate entries for TCP
+ * connection table entries and Multilevel Port attributes. We loop
+ * through the attributes first and set up an array for each address
+ * family.
+ */
+ v4_attrs = family_selected(AF_INET) && RSECflag ?
+ gather_attrs(item, MIB2_TCP, MIB2_TCP_CONN, tcpConnEntrySize) :
+ NULL;
+ v6_attrs = family_selected(AF_INET6) && RSECflag ?
+ gather_attrs(item, MIB2_TCP6, MIB2_TCP6_CONN, tcp6ConnEntrySize) :
+ NULL;
+
/* 'for' loop 1: */
- for (; item; item = item->next_item) {
+ v4a = v4_attrs;
+ v6a = v6_attrs;
+ for (; item != NULL; item = item->next_item) {
if (Dflag) {
(void) printf("\n--- Entry %d ---\n", ++jtemp);
(void) printf("Group = %d, mib_id = %d, "
@@ -4379,8 +4621,9 @@
/* LINTED: (note 1) */
tp = (mib2_tcpConnEntry_t *)((char *)tp +
tcpConnEntrySize)) {
+ aptr = v4a == NULL ? NULL : *v4a++;
print_hdr_once_v4 = tcp_report_item_v4(tp,
- print_hdr_once_v4);
+ print_hdr_once_v4, aptr);
}
} else {
for (tp6 = (mib2_tcp6ConnEntry_t *)item->valp;
@@ -4388,16 +4631,23 @@
/* LINTED: (note 1) */
tp6 = (mib2_tcp6ConnEntry_t *)((char *)tp6 +
tcp6ConnEntrySize)) {
+ aptr = v6a == NULL ? NULL : *v6a++;
print_hdr_once_v6 = tcp_report_item_v6(tp6,
- print_hdr_once_v6);
+ print_hdr_once_v6, aptr);
}
}
} /* 'for' loop 1 ends */
(void) fflush(stdout);
+
+ if (v4_attrs != NULL)
+ free(v4_attrs);
+ if (v6_attrs != NULL)
+ free(v6_attrs);
}
static boolean_t
-tcp_report_item_v4(mib2_tcpConnEntry_t *tp, boolean_t first)
+tcp_report_item_v4(const mib2_tcpConnEntry_t *tp, boolean_t first,
+ const mib2_transportMLPEntry_t *attr)
{
/*
* lname and fname below are for the hostname as well as the portname
@@ -4411,10 +4661,8 @@
return (first); /* Nothing to print */
if (first) {
- (void) fputs(v4compat ? tcp_hdr_v4_compat : tcp_hdr_v4, stdout);
- (void) fputs(Vflag ? tcp_hdr_v4_verbose : tcp_hdr_v4_normal,
- stdout);
- first = B_FALSE;
+ (void) printf(v4compat ? tcp_hdr_v4_compat : tcp_hdr_v4);
+ (void) printf(Vflag ? tcp_hdr_v4_verbose : tcp_hdr_v4_normal);
}
if (Vflag) {
@@ -4432,7 +4680,7 @@
tp->tcpConnEntryInfo.ce_rack,
tp->tcpConnEntryInfo.ce_rto,
tp->tcpConnEntryInfo.ce_mss,
- mitcp_state(tp->tcpConnEntryInfo.ce_state));
+ mitcp_state(tp->tcpConnEntryInfo.ce_state, attr));
} else {
int sq = (int)tp->tcpConnEntryInfo.ce_snxt -
(int)tp->tcpConnEntryInfo.ce_suna - 1;
@@ -4448,13 +4696,17 @@
(sq >= 0) ? sq : 0,
tp->tcpConnEntryInfo.ce_rwnd,
(rq >= 0) ? rq : 0,
- mitcp_state(tp->tcpConnEntryInfo.ce_state));
+ mitcp_state(tp->tcpConnEntryInfo.ce_state, attr));
}
- return (first);
+
+ print_transport_label(attr);
+
+ return (B_FALSE);
}
static boolean_t
-tcp_report_item_v6(mib2_tcp6ConnEntry_t *tp6, boolean_t first)
+tcp_report_item_v6(const mib2_tcp6ConnEntry_t *tp6, boolean_t first,
+ const mib2_transportMLPEntry_t *attr)
{
/*
* lname and fname below are for the hostname as well as the portname
@@ -4470,18 +4722,18 @@
return (first); /* Nothing to print */
if (first) {
- (void) fputs(tcp_hdr_v6, stdout);
- (void) fputs(Vflag ? tcp_hdr_v6_verbose : tcp_hdr_v6_normal,
- stdout);
- first = B_FALSE;
+ (void) printf(tcp_hdr_v6);
+ (void) printf(Vflag ? tcp_hdr_v6_verbose : tcp_hdr_v6_normal);
}
ifnamep = (tp6->tcp6ConnIfIndex != 0) ?
if_indextoname(tp6->tcp6ConnIfIndex, ifname) : NULL;
+ if (ifnamep == NULL)
+ ifnamep = "";
if (Vflag) {
(void) printf("%-33s\n%-33s %5u %08x %08x %5u %08x %08x "
- "%5u %5u %-11s %-5s\n",
+ "%5u %5u %-11s %s\n",
pr_ap6(&tp6->tcp6ConnLocalAddress,
tp6->tcp6ConnLocalPort, "tcp", lname, sizeof (lname)),
pr_ap6(&tp6->tcp6ConnRemAddress,
@@ -4494,15 +4746,15 @@
tp6->tcp6ConnEntryInfo.ce_rack,
tp6->tcp6ConnEntryInfo.ce_rto,
tp6->tcp6ConnEntryInfo.ce_mss,
- mitcp_state(tp6->tcp6ConnEntryInfo.ce_state),
- (ifnamep == NULL) ? "" : ifnamep);
+ mitcp_state(tp6->tcp6ConnEntryInfo.ce_state, attr),
+ ifnamep);
} else {
int sq = (int)tp6->tcp6ConnEntryInfo.ce_snxt -
(int)tp6->tcp6ConnEntryInfo.ce_suna - 1;
int rq = (int)tp6->tcp6ConnEntryInfo.ce_rnxt -
(int)tp6->tcp6ConnEntryInfo.ce_rack;
- (void) printf("%-33s %-33s %5u %6d %5u %6d %-11s %-5s\n",
+ (void) printf("%-33s %-33s %5u %6d %5u %6d %-11s %s\n",
pr_ap6(&tp6->tcp6ConnLocalAddress,
tp6->tcp6ConnLocalPort, "tcp", lname, sizeof (lname)),
pr_ap6(&tp6->tcp6ConnRemAddress,
@@ -4511,35 +4763,61 @@
(sq >= 0) ? sq : 0,
tp6->tcp6ConnEntryInfo.ce_rwnd,
(rq >= 0) ? rq : 0,
- mitcp_state(tp6->tcp6ConnEntryInfo.ce_state),
- (ifnamep == NULL) ? "" : ifnamep);
+ mitcp_state(tp6->tcp6ConnEntryInfo.ce_state, attr),
+ ifnamep);
}
- return (first);
+
+ print_transport_label(attr);
+
+ return (B_FALSE);
}
/* ------------------------------- UDP_REPORT------------------------------- */
-static boolean_t udp_report_item_v4(mib2_udpEntry_t *ude, boolean_t first);
-static boolean_t udp_report_item_v6(mib2_udp6Entry_t *ude6, boolean_t first);
+static boolean_t udp_report_item_v4(const mib2_udpEntry_t *ude,
+ boolean_t first, const mib2_transportMLPEntry_t *attr);
+static boolean_t udp_report_item_v6(const mib2_udp6Entry_t *ude6,
+ boolean_t first, const mib2_transportMLPEntry_t *attr);
-static char *udp_hdr_v6 =
+static const char udp_hdr_v4[] =
+" Local Address Remote Address State\n"
+"-------------------- -------------------- ----------\n";
+
+static const char udp_hdr_v6[] =
" Local Address Remote Address "
-" State If \n"
+" State If\n"
"--------------------------------- --------------------------------- "
"---------- -----\n";
static void
-udp_report(mib_item_t *item)
+udp_report(const mib_item_t *item)
{
int jtemp = 0;
boolean_t print_hdr_once_v4 = B_TRUE;
boolean_t print_hdr_once_v6 = B_TRUE;
mib2_udpEntry_t *ude;
mib2_udp6Entry_t *ude6;
+ mib2_transportMLPEntry_t **v4_attrs, **v6_attrs;
+ mib2_transportMLPEntry_t **v4a, **v6a;
+ mib2_transportMLPEntry_t *aptr;
if (!protocol_selected(IPPROTO_UDP))
return;
+ /*
+ * Preparation pass: the kernel returns separate entries for UDP
+ * connection table entries and Multilevel Port attributes. We loop
+ * through the attributes first and set up an array for each address
+ * family.
+ */
+ v4_attrs = family_selected(AF_INET) && RSECflag ?
+ gather_attrs(item, MIB2_UDP, MIB2_UDP_ENTRY, udpEntrySize) : NULL;
+ v6_attrs = family_selected(AF_INET6) && RSECflag ?
+ gather_attrs(item, MIB2_UDP6, MIB2_UDP6_ENTRY, udp6EntrySize) :
+ NULL;
+
+ v4a = v4_attrs;
+ v6a = v6_attrs;
/* 'for' loop 1: */
for (; item; item = item->next_item) {
if (Dflag) {
@@ -4567,8 +4845,9 @@
/* LINTED: (note 1) */
ude = (mib2_udpEntry_t *)((char *)ude +
udpEntrySize)) {
+ aptr = v4a == NULL ? NULL : *v4a++;
print_hdr_once_v4 = udp_report_item_v4(ude,
- print_hdr_once_v4);
+ print_hdr_once_v4, aptr);
}
} else {
for (ude6 = (mib2_udp6Entry_t *)item->valp;
@@ -4576,109 +4855,91 @@
/* LINTED: (note 1) */
ude6 = (mib2_udp6Entry_t *)((char *)ude6 +
udp6EntrySize)) {
+ aptr = v6a == NULL ? NULL : *v6a++;
print_hdr_once_v6 = udp_report_item_v6(ude6,
- print_hdr_once_v6);
+ print_hdr_once_v6, aptr);
}
}
} /* 'for' loop 1 ends */
(void) fflush(stdout);
+
+ if (v4_attrs != NULL)
+ free(v4_attrs);
+ if (v6_attrs != NULL)
+ free(v6_attrs);
}
static boolean_t
-udp_report_item_v4(mib2_udpEntry_t *ude, boolean_t first)
+udp_report_item_v4(const mib2_udpEntry_t *ude, boolean_t first,
+ const mib2_transportMLPEntry_t *attr)
{
char lname[MAXHOSTNAMELEN + MAXHOSTNAMELEN + 1];
/* hostname + portname */
- char *cp;
if (!(Aflag || ude->udpEntryInfo.ue_state >= MIB2_UDP_connected))
return (first); /* Nothing to print */
if (first) {
- (void) puts(v4compat ? "\nUDP" : "\nUDP: IPv4");
- (void) puts(
- " Local Address Remote Address State");
- (void) puts(
- "-------------------- -------------------- -------");
+ (void) printf(v4compat ? "\nUDP\n" : "\nUDP: IPv4\n");
+ (void) printf(udp_hdr_v4);
first = B_FALSE;
}
- switch (ude->udpEntryInfo.ue_state) {
- case MIB2_UDP_unbound:
- cp = "Unbound";
- break;
- case MIB2_UDP_idle:
- cp = "Idle";
- break;
- case MIB2_UDP_connected:
- cp = "Connected";
- break;
- default:
- cp = "Unknown";
- break;
- }
(void) printf("%-20s ",
pr_ap(ude->udpLocalAddress, ude->udpLocalPort, "udp",
lname, sizeof (lname)));
- if (ude->udpEntryInfo.ue_state == MIB2_UDP_connected) {
- (void) printf("%-20s ",
- pr_ap(ude->udpEntryInfo.ue_RemoteAddress,
- ude->udpEntryInfo.ue_RemotePort, "udp",
- lname, sizeof (lname)));
- } else {
- (void) printf("%-20s ", "");
- }
- (void) printf(" %s\n", cp);
+ (void) printf("%-20s %s\n",
+ ude->udpEntryInfo.ue_state == MIB2_UDP_connected ?
+ pr_ap(ude->udpEntryInfo.ue_RemoteAddress,
+ ude->udpEntryInfo.ue_RemotePort, "udp", lname, sizeof (lname)) :
+ "",
+ miudp_state(ude->udpEntryInfo.ue_state, attr));
+
+ /*
+ * UDP sockets don't have remote attributes, so there's no need to
+ * print them here.
+ */
+
return (first);
}
static boolean_t
-udp_report_item_v6(mib2_udp6Entry_t *ude6, boolean_t first)
+udp_report_item_v6(const mib2_udp6Entry_t *ude6, boolean_t first,
+ const mib2_transportMLPEntry_t *attr)
{
char lname[MAXHOSTNAMELEN + MAXHOSTNAMELEN + 1];
/* hostname + portname */
- char *cp;
char ifname[LIFNAMSIZ + 1];
+ const char *ifnamep;
if (!(Aflag || ude6->udp6EntryInfo.ue_state >= MIB2_UDP_connected))
return (first); /* Nothing to print */
if (first) {
- (void) printf("\nUDP: IPv6\n%s", udp_hdr_v6);
+ (void) printf("\nUDP: IPv6\n");
+ (void) printf(udp_hdr_v6);
first = B_FALSE;
}
- switch (ude6->udp6EntryInfo.ue_state) {
- case MIB2_UDP_unbound:
- cp = "Unbound";
- break;
- case MIB2_UDP_idle:
- cp = "Idle";
- break;
- case MIB2_UDP_connected:
- cp = "Connected";
- break;
- default:
- cp = "Unknown";
- break;
- }
+ ifnamep = (ude6->udp6IfIndex != 0) ?
+ if_indextoname(ude6->udp6IfIndex, ifname) : NULL;
+
(void) printf("%-33s ",
pr_ap6(&ude6->udp6LocalAddress,
ude6->udp6LocalPort, "udp", lname, sizeof (lname)));
- if (ude6->udp6EntryInfo.ue_state == MIB2_UDP_connected) {
- (void) printf("%-33s ",
- pr_ap6(&ude6->udp6EntryInfo.ue_RemoteAddress,
- ude6->udp6EntryInfo.ue_RemotePort, "udp",
- lname, sizeof (lname)));
- } else {
- (void) printf("%-33s ", "");
- }
- if (ude6->udp6IfIndex != 0 &&
- (if_indextoname(ude6->udp6IfIndex, ifname) != NULL)) {
- (void) printf("%-10s %-5s\n", cp, ifname);
- } else {
- (void) printf("%-10s\n", cp);
- }
+ (void) printf("%-33s %-10s %s\n",
+ ude6->udp6EntryInfo.ue_state == MIB2_UDP_connected ?
+ pr_ap6(&ude6->udp6EntryInfo.ue_RemoteAddress,
+ ude6->udp6EntryInfo.ue_RemotePort, "udp", lname, sizeof (lname)) :
+ "",
+ miudp_state(ude6->udp6EntryInfo.ue_state, attr),
+ ifnamep == NULL ? "" : ifnamep);
+
+ /*
+ * UDP sockets don't have remote attributes, so there's no need to
+ * print them here.
+ */
+
return (first);
}
@@ -4693,38 +4954,66 @@
"------ ------ ------ ------ ------- -----------";
static const char *
-nssctp_state(int state)
+nssctp_state(int state, const mib2_transportMLPEntry_t *attr)
{
+ static char sctpsbuf[50];
+ const char *cp;
+
switch (state) {
case MIB2_SCTP_closed:
- return ("CLOSED");
+ cp = "CLOSED";
+ break;
case MIB2_SCTP_cookieWait:
- return ("COOKIE_WAIT");
+ cp = "COOKIE_WAIT";
+ break;
case MIB2_SCTP_cookieEchoed:
- return ("COOKIE_ECHOED");
+ cp = "COOKIE_ECHOED";
+ break;
case MIB2_SCTP_established:
- return ("ESTABLISHED");
+ cp = "ESTABLISHED";
+ break;
case MIB2_SCTP_shutdownPending:
- return ("SHUTDOWN_PENDING");
+ cp = "SHUTDOWN_PENDING";
+ break;
case MIB2_SCTP_shutdownSent:
- return ("SHUTDOWN_SENT");
+ cp = "SHUTDOWN_SENT";
+ break;
case MIB2_SCTP_shutdownReceived:
- return ("SHUTDOWN_RECEIVED");
+ cp = "SHUTDOWN_RECEIVED";
+ break;
case MIB2_SCTP_shutdownAckSent:
- return ("SHUTDOWN_ACK_SENT");
+ cp = "SHUTDOWN_ACK_SENT";
+ break;
case MIB2_SCTP_listen:
- return ("LISTEN");
+ cp = "LISTEN";
+ break;
default:
- return ("UNKNOWN STATE");
+ (void) snprintf(sctpsbuf, sizeof (sctpsbuf),
+ "UNKNOWN STATE(%d)", state);
+ cp = sctpsbuf;
+ break;
}
+
+ if (RSECflag && attr != NULL && attr->tme_flags != 0) {
+ if (cp != sctpsbuf) {
+ (void) strlcpy(sctpsbuf, cp, sizeof (sctpsbuf));
+ cp = sctpsbuf;
+ }
+ if (attr->tme_flags & MIB2_TMEF_PRIVATE)
+ (void) strlcat(sctpsbuf, " P", sizeof (sctpsbuf));
+ if (attr->tme_flags & MIB2_TMEF_SHARED)
+ (void) strlcat(sctpsbuf, " S", sizeof (sctpsbuf));
+ }
+
+ return (cp);
}
-static mib2_sctpConnRemoteEntry_t *
-sctp_getnext_rem(mib_item_t **itemp, mib2_sctpConnRemoteEntry_t *current,
- uint32_t associd)
+static const mib2_sctpConnRemoteEntry_t *
+sctp_getnext_rem(const mib_item_t **itemp,
+ const mib2_sctpConnRemoteEntry_t *current, uint32_t associd)
{
- mib_item_t *item = *itemp;
- mib2_sctpConnRemoteEntry_t *sre;
+ const mib_item_t *item = *itemp;
+ const mib2_sctpConnRemoteEntry_t *sre;
for (; item != NULL; item = item->next_item, current = NULL) {
if (!(item->group == MIB2_SCTP &&
@@ -4734,15 +5023,15 @@
if (current != NULL) {
/* LINTED: (note 1) */
- sre = (mib2_sctpConnRemoteEntry_t *)((char *)current +
- sctpRemoteEntrySize);
+ sre = (const mib2_sctpConnRemoteEntry_t *)
+ ((const char *)current + sctpRemoteEntrySize);
} else {
sre = item->valp;
}
for (; (char *)sre < (char *)item->valp + item->length;
- /* LINTED: (note 1) */
- sre = (mib2_sctpConnRemoteEntry_t *)((char *)sre +
- sctpRemoteEntrySize)) {
+ /* LINTED: (note 1) */
+ sre = (const mib2_sctpConnRemoteEntry_t *)
+ ((const char *)sre + sctpRemoteEntrySize)) {
if (sre->sctpAssocId != associd) {
continue;
}
@@ -4754,12 +5043,12 @@
return (NULL);
}
-static mib2_sctpConnLocalEntry_t *
-sctp_getnext_local(mib_item_t **itemp, mib2_sctpConnLocalEntry_t *current,
- uint32_t associd)
+static const mib2_sctpConnLocalEntry_t *
+sctp_getnext_local(const mib_item_t **itemp,
+ const mib2_sctpConnLocalEntry_t *current, uint32_t associd)
{
- mib_item_t *item = *itemp;
- mib2_sctpConnLocalEntry_t *sle;
+ const mib_item_t *item = *itemp;
+ const mib2_sctpConnLocalEntry_t *sle;
for (; item != NULL; item = item->next_item, current = NULL) {
if (!(item->group == MIB2_SCTP &&
@@ -4769,15 +5058,15 @@
if (current != NULL) {
/* LINTED: (note 1) */
- sle = (mib2_sctpConnLocalEntry_t *)((char *)current +
- sctpLocalEntrySize);
+ sle = (const mib2_sctpConnLocalEntry_t *)
+ ((const char *)current + sctpLocalEntrySize);
} else {
sle = item->valp;
}
for (; (char *)sle < (char *)item->valp + item->length;
- /* LINTED: (note 1) */
- sle = (mib2_sctpConnLocalEntry_t *)((char *)sle +
- sctpLocalEntrySize)) {
+ /* LINTED: (note 1) */
+ sle = (const mib2_sctpConnLocalEntry_t *)
+ ((const char *)sle + sctpLocalEntrySize)) {
if (sle->sctpAssocId != associd) {
continue;
}
@@ -4830,14 +5119,15 @@
}
static void
-sctp_conn_report_item(mib_item_t *head, mib2_sctpConnEntry_t *sp)
+sctp_conn_report_item(const mib_item_t *head, const mib2_sctpConnEntry_t *sp,
+ const mib2_transportMLPEntry_t *attr)
{
char lname[MAXHOSTNAMELEN + MAXHOSTNAMELEN + 1];
char fname[MAXHOSTNAMELEN + MAXHOSTNAMELEN + 1];
- mib2_sctpConnRemoteEntry_t *sre = NULL;
- mib2_sctpConnLocalEntry_t *sle = NULL;
- mib_item_t *local = head;
- mib_item_t *remote = head;
+ const mib2_sctpConnRemoteEntry_t *sre = NULL;
+ const mib2_sctpConnLocalEntry_t *sle = NULL;
+ const mib_item_t *local = head;
+ const mib_item_t *remote = head;
uint32_t id = sp->sctpAssocId;
boolean_t printfirst = B_TRUE;
@@ -4853,7 +5143,9 @@
sp->sctpConnEntryInfo.ce_rwnd,
sp->sctpConnEntryInfo.ce_recvq,
sp->sctpAssocInStreams, sp->sctpAssocOutStreams,
- nssctp_state(sp->sctpAssocState));
+ nssctp_state(sp->sctpAssocState, attr));
+
+ print_transport_label(attr);
if (!Vflag) {
return;
@@ -4902,12 +5194,25 @@
}
static void
-sctp_report(mib_item_t *item)
+sctp_report(const mib_item_t *item)
{
- mib_item_t *head;
- mib2_sctpConnEntry_t *sp;
+ const mib_item_t *head;
+ const mib2_sctpConnEntry_t *sp;
boolean_t first = B_TRUE;
+ mib2_transportMLPEntry_t **attrs, **aptr;
+ mib2_transportMLPEntry_t *attr;
+ /*
+ * Preparation pass: the kernel returns separate entries for SCTP
+ * connection table entries and Multilevel Port attributes. We loop
+ * through the attributes first and set up an array for each address
+ * family.
+ */
+ attrs = RSECflag ?
+ gather_attrs(item, MIB2_SCTP, MIB2_SCTP_CONN, sctpEntrySize) :
+ NULL;
+
+ aptr = attrs;
head = item;
for (; item != NULL; item = item->next_item) {
@@ -4916,11 +5221,10 @@
continue;
for (sp = item->valp;
- (char *)sp < (char *)item->valp + item->length;
- /* LINTED: (note 1) */
- sp = (mib2_sctpConnEntry_t *)((char *)sp +
- sctpEntrySize)) {
-
+ (char *)sp < (char *)item->valp + item->length;
+ /* LINTED: (note 1) */
+ sp = (mib2_sctpConnEntry_t *)((char *)sp + sctpEntrySize)) {
+ attr = aptr == NULL ? NULL : *aptr++;
if (Aflag ||
sp->sctpAssocState >= MIB2_SCTP_established) {
if (first == B_TRUE) {
@@ -4928,10 +5232,12 @@
(void) puts(sctp_hdr_normal);
first = B_FALSE;
}
- sctp_conn_report_item(head, sp);
+ sctp_conn_report_item(head, sp, attr);
}
}
}
+ if (attrs != NULL)
+ free(attrs);
}
static char *
@@ -5330,7 +5636,8 @@
* Does not print /128 to save space in printout. H flag carries this notion.
*/
static char *
-pr_prefix6(struct in6_addr *addr, uint_t prefixlen, char *dst, uint_t dstlen)
+pr_prefix6(const struct in6_addr *addr, uint_t prefixlen, char *dst,
+ uint_t dstlen)
{
char *cp;
@@ -5634,6 +5941,53 @@
}
}
+#define MAX_STRING_SIZE 256
+
+static const char *
+pr_secattr(const sec_attr_list_t *attrs)
+{
+ int i;
+ char buf[MAX_STRING_SIZE + 1], *cp;
+ static char *sbuf;
+ static size_t sbuf_len;
+ struct rtsa_s rtsa;
+ const sec_attr_list_t *aptr;
+
+ if (!RSECflag || attrs == NULL)
+ return ("");
+
+ for (aptr = attrs, i = 1; aptr != NULL; aptr = aptr->sal_next)
+ i += MAX_STRING_SIZE;
+ if (i > sbuf_len) {
+ cp = realloc(sbuf, i);
+ if (cp == NULL) {
+ perror("realloc security attribute buffer");
+ return ("");
+ }
+ sbuf_len = i;
+ sbuf = cp;
+ }
+
+ cp = sbuf;
+ while (attrs != NULL) {
+ const mib2_ipAttributeEntry_t *iae = attrs->sal_attr;
+
+ /* note: effectively hard-coded in rtsa_keyword */
+ rtsa.rtsa_mask = RTSA_CIPSO | RTSA_SLRANGE | RTSA_DOI;
+ rtsa.rtsa_slrange = iae->iae_slrange;
+ rtsa.rtsa_doi = iae->iae_doi;
+
+ (void) snprintf(cp, MAX_STRING_SIZE,
+ "<%s>%s ", rtsa_to_str(&rtsa, buf, sizeof (buf)),
+ attrs->sal_next == NULL ? "" : ",");
+ cp += strlen(cp);
+ attrs = attrs->sal_next;
+ }
+ *cp = '\0';
+
+ return (sbuf);
+}
+
/*
* Pretty print a port number. If the Nflag was
* specified, use numbers instead of names.
@@ -5936,7 +6290,8 @@
*/
/*PRINTFLIKE2*/
static void
-fatal(int errcode, char *format, ...) {
+fatal(int errcode, char *format, ...)
+{
va_list argp;
if (format == NULL)
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/Makefile b/usr/src/cmd/cmd-inet/usr.sbin/Makefile
index af9d3a9..efb96c7 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/Makefile
+++ b/usr/src/cmd/cmd-inet/usr.sbin/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -18,9 +17,11 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
+
+
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -58,6 +59,7 @@
CMDPROG= in.telnetd
IPSECUTILPROG= ikeadm ipsecalgs ipsecconf ipseckey
K5PROGS= in.telnetd in.rlogind in.rshd
+TSNETPROG= route
DEFAULTFILES= telnetd.dfl
PROGSRCS= $(PROG:%=%.c)
@@ -148,6 +150,7 @@
-I$(SRC)/lib/pam_modules/krb5
LDLIBS += $(K5LIBS)
$(IPSECUTILPROG) := LDLIBS += -lipsecutil
+$(TSNETPROG) := LDLIBS += -ltsnet
in.rarpd := LDLIBS += -linetutil
route := CPPFLAGS += -DNDEBUG
@@ -246,7 +249,7 @@
$(LINT.c) ipsecconf.c $(LDLIBS) -lsocket -lnsl -lipsecutil
$(LINT.c) ipseckey.c $(LDLIBS) -lsocket -lnsl -lipsecutil
$(LINT.c) ikeadm.c $(LDLIBS) -lnsl -lipsecutil
- $(LINT.c) route.c $(LDLIBS) -lsocket -lnsl
+ $(LINT.c) route.c $(LDLIBS) -lsocket -lnsl -ltsnet
$(LINT.c) routeadm.c $(LDLIBS) -lsocket
$(LINT.c) syncinit.c $(LDLIBS) -ldlpi
$(LINT.c) syncloop.c $(LDLIBS) -ldlpi
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/ifconfig/ifconfig.c b/usr/src/cmd/cmd-inet/usr.sbin/ifconfig/ifconfig.c
index ee57766..162a64a 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/ifconfig/ifconfig.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/ifconfig/ifconfig.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
@@ -162,6 +162,7 @@
static int clr_tun_encap_limit(char *arg, int64_t param);
static int set_tun_hop_limit(char *arg, int64_t param);
static int setzone(char *arg, int64_t param);
+static int setallzones(char *arg, int64_t param);
static int setifsrc(char *arg, int64_t param);
#ifdef DEBUG
@@ -307,6 +308,7 @@
{ "destination", NEXTARG, setifdstaddr, 0, AF_ANY },
{ "zone", NEXTARG, setzone, 0, AF_ANY },
{ "-zone", 0, setzone, 0, AF_ANY },
+ { "all-zones", 0, setallzones, 0, AF_ANY },
{ "ether", OPTARG, setifether, 0, AF_ANY },
{ "usesrc", NEXTARG, setifsrc, 0, AF_ANY },
{ 0, 0, setifaddr, 0, AF_ANY },
@@ -2858,6 +2860,18 @@
return (0);
}
+/* Put interface into all zones */
+/* ARGSUSED */
+static int
+setallzones(char *arg, int64_t param)
+{
+ (void) strlcpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
+ lifr.lifr_zoneid = ALL_ZONES;
+ if (ioctl(s, SIOCSLIFZONE, (caddr_t)&lifr) == -1)
+ Perror0_exit("SIOCSLIFZONE");
+ return (0);
+}
+
/* Set source address to use */
/* ARGSUSED */
static int
@@ -2958,7 +2972,9 @@
lifr.lifr_zoneid != getzoneid()) {
char zone_name[ZONENAME_MAX];
- if (getzonenamebyid(lifr.lifr_zoneid, zone_name,
+ if (lifr.lifr_zoneid == ALL_ZONES) {
+ (void) printf("\n\tall-zones");
+ } else if (getzonenamebyid(lifr.lifr_zoneid, zone_name,
sizeof (zone_name)) < 0) {
(void) printf("\n\tzone %d", lifr.lifr_zoneid);
} else {
@@ -4765,7 +4781,8 @@
"\t[ standby | -standby ]\n"
"\t[ failover | -failover ]\n"
"\t[ zone <zonename> | -zone ]\n"
- "\t[ usesrc <interface> ]\n");
+ "\t[ usesrc <interface> ]\n"
+ "\t[ all-zones ]\n");
(void) fprintf(stderr, "or\n");
(void) fprintf(stderr,
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.routed/table.c b/usr/src/cmd/cmd-inet/usr.sbin/in.routed/table.c
index 1c81d64..d23133c 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/in.routed/table.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/in.routed/table.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Copyright (c) 1983, 1988, 1993
@@ -1692,6 +1692,8 @@
* ss is a pointer to the beginning of the data following the
* rt_msghdr contained in the routing socket message, which consists
* of a string of concatenated sockaddr structure of different types.
+ *
+ * Extended attributes can be appended at the end of the list.
*/
static int
rt_xaddrs(struct rt_addrinfo *info,
@@ -1766,11 +1768,35 @@
goto xaddr_done;
}
}
+
+ while (((char *)ss + sizeof (rtm_ext_t)) <= lim) {
+ rtm_ext_t *tp;
+ char *nxt;
+
+ /* LINTED: alignment */
+ tp = (rtm_ext_t *)ss;
+ nxt = (char *)(tp + 1) + tp->rtmex_len;
+
+ if (!IS_P2ALIGNED(tp->rtmex_len, sizeof (uint32_t)) ||
+ nxt > lim) {
+ break;
+ }
+
+ /* LINTED: alignment */
+ ss = (struct sockaddr_storage *)nxt;
+ }
+
if ((char *)ss != lim) {
- if (!(prev_complaints & XBAD_LONG))
+ if ((char *)ss > lim) {
+ if (!(prev_complaints & XBAD_SHORT))
+ msglog("routing message too short by %d bytes",
+ (char *)ss - lim);
+ complaints |= XBAD_SHORT;
+ } else if (!(prev_complaints & XBAD_LONG)) {
msglog("%d bytes of routing message left over",
lim - (char *)ss);
- complaints |= XBAD_LONG;
+ complaints |= XBAD_LONG;
+ }
retv = -1;
}
xaddr_done:
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/route.c b/usr/src/cmd/cmd-inet/usr.sbin/route.c
index 18044d9..431d92d 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/route.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/route.c
@@ -74,11 +74,16 @@
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stddef.h>
#include <string.h>
#include <stropts.h>
#include <fcntl.h>
#include <stdarg.h>
#include <assert.h>
+#include <strings.h>
+
+#include <libtsnet.h>
+#include <tsol/label.h>
static struct keytab {
char *kt_cp;
@@ -168,6 +173,8 @@
{"setsrc", K_SETSRC},
#define K_SHOW 43
{"show", K_SHOW},
+#define K_SECATTR 43
+ {"secattr", K_SECATTR},
{0, 0}
};
@@ -206,14 +213,16 @@
su_t ri_ifa;
su_t ri_ifp;
char *ri_ifp_str;
+ int ri_rtsa_cnt; /* number of gateway security attributes */
+ struct rtsa_s ri_rtsa; /* enough space for one attribute */
} rtcmd_irep_t;
typedef struct mib_item_s {
- struct mib_item_s *next_item;
- long group;
- long mib_id;
- long length;
- intmax_t *valp;
+ struct mib_item_s *next_item;
+ long group;
+ long mib_id;
+ long length;
+ intmax_t *valp;
} mib_item_t;
typedef enum {
@@ -257,18 +266,18 @@
static char *netname(struct sockaddr *sa);
static int newroute(char **argv);
static rtcmd_irep_t *new_rtcmd_irep(void);
-static void pmsg_addrs(char *cp, int addrs);
-static void pmsg_common(struct rt_msghdr *rtm);
+static void pmsg_addrs(const char *cp, size_t len, uint_t addrs);
+static void pmsg_common(const struct rt_msghdr *rtm, size_t len);
static void print_getmsg(rtcmd_irep_t *req_rt,
struct rt_msghdr *rtm, int msglen);
static void print_rtcmd_short(FILE *to, rtcmd_irep_t *rcip,
boolean_t gw_good, boolean_t to_saved);
static void print_rtmsg(struct rt_msghdr *rtm, int msglen);
static void quit(char *s, int err) __NORETURN;
-static char *routename(struct sockaddr *sa);
+static char *routename(const struct sockaddr *sa);
static void rtmonitor(int argc, char *argv[]);
static int rtmsg(rtcmd_irep_t *rcip);
-static int salen(struct sockaddr *sa);
+static int salen(const struct sockaddr *sa);
static void save_route(int argc, char **argv, int do_flush);
static void save_string(char **dst, char *src);
static int search_rtfile(FILE *fp, FILE *temp_fp, rtcmd_irep_t *rt,
@@ -283,6 +292,7 @@
static void syntax_error(char *err, ...);
static void usage(char *cp);
static void write_to_rtfile(FILE *fp, int argc, char **argv);
+static void pmsg_secattr(const char *, size_t, const char *);
static pid_t pid;
static int s;
@@ -315,7 +325,7 @@
static struct {
struct rt_msghdr m_rtm;
- char m_space[512];
+ char m_space[BUF_SIZE];
} m_rtmsg;
/*
@@ -337,7 +347,6 @@
#define BAD_ADDR -1 /* prefix is invalid */
#define NO_PREFIX -2 /* no prefix was found */
-
void
usage(char *cp)
{
@@ -408,7 +417,7 @@
(void) textdomain(TEXT_DOMAIN);
if (argc < 2)
- usage((char *)NULL);
+ usage(NULL);
while ((ch = getopt(argc, argv, "R:nqdtvfp")) != EOF) {
switch (ch) {
@@ -438,7 +447,7 @@
break;
case '?':
default:
- usage((char *)NULL);
+ usage(NULL);
/* NOTREACHED */
}
}
@@ -815,7 +824,7 @@
* Return the name of the host whose address is given.
*/
char *
-routename(struct sockaddr *sa)
+routename(const struct sockaddr *sa)
{
char *cp;
static char line[MAXHOSTNAMELEN + 1];
@@ -1362,6 +1371,31 @@
}
rcip->ri_flags |= RTF_SETSRC;
break;
+ case K_SECATTR:
+ if (!NEXTTOKEN) {
+ syntax_arg_missing(keyword_str);
+ return (B_FALSE);
+ }
+ if ((rcip->ri_cmd == RTM_ADD ||
+ rcip->ri_cmd == RTM_CHANGE) &&
+ rcip->ri_rtsa_cnt++ < 1 && is_system_labeled()) {
+ int err;
+
+ if (!rtsa_keyword(tok, &rcip->ri_rtsa, &err,
+ NULL)) {
+ (void) fprintf(stderr, gettext("route: "
+ "bad security attribute: %s\n"),
+ tsol_strerror(err, errno));
+ return (B_FALSE);
+ }
+ }
+ if (rcip->ri_rtsa_cnt > 1) {
+ (void) fprintf(stderr,
+ gettext("route: can't specify more "
+ "than one security attribute\n"));
+ return (B_FALSE);
+ }
+ break;
default:
if (dash_keyword) {
syntax_bad_keyword(tok + 1);
@@ -2428,7 +2462,25 @@
*/
NEXTADDR(RTA_SRC, newrt->ri_src);
#undef NEXTADDR
+
+ if (newrt->ri_rtsa_cnt > 0) {
+ /* LINTED: aligned */
+ rtm_ext_t *rtm_ext = (rtm_ext_t *)cp;
+ tsol_rtsecattr_t *rtsecattr;
+
+ rtm_ext->rtmex_type = RTMEX_GATEWAY_SECATTR;
+ rtm_ext->rtmex_len = TSOL_RTSECATTR_SIZE(1);
+
+ rtsecattr = (tsol_rtsecattr_t *)(rtm_ext + 1);
+ rtsecattr->rtsa_cnt = 1;
+
+ bcopy(&newrt->ri_rtsa, rtsecattr->rtsa_attr,
+ sizeof (newrt->ri_rtsa));
+ cp = (char *)(rtsecattr->rtsa_attr + 1);
+ }
+
rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
+
if (verbose)
print_rtmsg(&rtm, l);
if (debugonly)
@@ -2522,10 +2574,12 @@
rtm->rtm_version);
return;
}
- if (rtm->rtm_msglen > (ushort_t)msglen) {
+ if (rtm->rtm_msglen != msglen) {
(void) printf("message length mismatch, in packet %d, "
"returned %d\n",
rtm->rtm_msglen, msglen);
+ if (msglen > rtm->rtm_msglen)
+ msglen = rtm->rtm_msglen;
}
/*
* Since rtm->rtm_type is unsigned, we'll just check the case of zero
@@ -2536,26 +2590,29 @@
rtm->rtm_type);
return;
}
- (void) printf("%s: len %d, ", msgtypes[rtm->rtm_type], rtm->rtm_msglen);
+ (void) printf("%s: len %d, ", msgtypes[rtm->rtm_type], msglen);
switch (rtm->rtm_type) {
case RTM_IFINFO:
ifm = (struct if_msghdr *)rtm;
(void) printf("if# %d, flags:", ifm->ifm_index);
bprintf(stdout, ifm->ifm_flags, ifnetflags);
- pmsg_addrs((char *)(ifm + 1), ifm->ifm_addrs);
+ pmsg_addrs((const char *)(ifm + 1), msglen - sizeof (*ifm),
+ ifm->ifm_addrs);
break;
case RTM_NEWADDR:
case RTM_DELADDR:
ifam = (struct ifa_msghdr *)rtm;
(void) printf("metric %d, flags:", ifam->ifam_metric);
bprintf(stdout, ifam->ifam_flags, routeflags);
- pmsg_addrs((char *)(ifam + 1), ifam->ifam_addrs);
+ pmsg_addrs((const char *)(ifam + 1), msglen - sizeof (*ifam),
+ ifam->ifam_addrs);
break;
default:
(void) printf("pid: %ld, seq %d, errno %d, flags:",
rtm->rtm_pid, rtm->rtm_seq, rtm->rtm_errno);
bprintf(stdout, rtm->rtm_flags, routeflags);
- pmsg_common(rtm);
+ pmsg_common(rtm, msglen);
+ break;
}
}
@@ -2665,50 +2722,76 @@
(void) printf("%8d%c ", rtm->rtm_rmx.rmx_mtu, lock(MTU));
if (rtm->rtm_rmx.rmx_expire)
rtm->rtm_rmx.rmx_expire -= time(0);
- (void) printf("%8d%c\n", rtm->rtm_rmx.rmx_expire, lock(EXPIRE));
+ (void) printf("%8d%c", rtm->rtm_rmx.rmx_expire, lock(EXPIRE));
#undef lock
#undef msec
#define RTA_IGN \
(RTA_DST|RTA_GATEWAY|RTA_NETMASK|RTA_IFP|RTA_IFA|RTA_BRD|RTA_SRC)
if (verbose) {
- pmsg_common(rtm);
- } else if (rtm->rtm_addrs &~ RTA_IGN) {
- (void) printf("sockaddrs: ");
- bprintf(stdout, rtm->rtm_addrs, addrnames);
+ pmsg_common(rtm, msglen);
+ } else {
+ const char *sptr, *endptr;
+ const struct sockaddr *sa;
+ uint_t addrs;
+
+ /* Not verbose; just print out the exceptional cases */
+ if (rtm->rtm_addrs &~ RTA_IGN) {
+ (void) printf("\nsockaddrs: ");
+ bprintf(stdout, rtm->rtm_addrs, addrnames);
+ }
+ sptr = (const char *)(rtm + 1);
+ endptr = (const char *)rtm + msglen;
+ addrs = rtm->rtm_addrs;
+ while (addrs != 0 && sptr + sizeof (*sa) <= endptr) {
+ addrs &= addrs - 1;
+ /* LINTED */
+ sa = (const struct sockaddr *)sptr;
+ ADVANCE(sptr, sa);
+ }
+ if (addrs == 0)
+ pmsg_secattr(sptr, endptr - sptr, " secattr: ");
(void) putchar('\n');
}
#undef RTA_IGN
}
-void
-pmsg_common(struct rt_msghdr *rtm)
+static void
+pmsg_common(const struct rt_msghdr *rtm, size_t msglen)
{
(void) printf("\nlocks: ");
bprintf(stdout, (int)rtm->rtm_rmx.rmx_locks, metricnames);
(void) printf(" inits: ");
bprintf(stdout, (int)rtm->rtm_inits, metricnames);
- pmsg_addrs(((char *)(rtm + 1)), rtm->rtm_addrs);
+ pmsg_addrs((const char *)(rtm + 1), msglen - sizeof (*rtm),
+ rtm->rtm_addrs);
}
-void
-pmsg_addrs(char *cp, int addrs)
+static void
+pmsg_addrs(const char *cp, size_t msglen, uint_t addrs)
{
- struct sockaddr *sa;
+ const struct sockaddr *sa;
+ const char *maxptr;
int i;
- if (addrs == 0)
- return;
- (void) printf("\nsockaddrs: ");
- bprintf(stdout, addrs, addrnames);
- (void) putchar('\n');
- for (i = 1; i != 0; i <<= 1) {
- if (i & addrs) {
- /* LINTED */
- sa = (struct sockaddr *)cp;
- (void) printf(" %s", routename(sa));
- ADVANCE(cp, sa);
+ if (addrs != 0) {
+ (void) printf("\nsockaddrs: ");
+ bprintf(stdout, addrs, addrnames);
+ (void) putchar('\n');
+ maxptr = cp + msglen;
+ for (i = 1; i != 0 && cp + sizeof (*sa) <= maxptr; i <<= 1) {
+ if (i & addrs) {
+ /* LINTED */
+ sa = (const struct sockaddr *)cp;
+ (void) printf(" %s", routename(sa));
+ ADVANCE(cp, sa);
+ }
}
+ if (i != 0)
+ msglen = 0;
+ else
+ msglen = maxptr - cp;
}
+ pmsg_secattr(cp, msglen, "secattr: ");
(void) putchar('\n');
(void) fflush(stdout);
}
@@ -2834,7 +2917,7 @@
}
int
-salen(struct sockaddr *sa)
+salen(const struct sockaddr *sa)
{
switch (sa->sa_family) {
case AF_INET:
@@ -3094,3 +3177,57 @@
}
return (NULL);
}
+
+/*
+ * print label security attributes for gateways.
+ */
+static void
+pmsg_secattr(const char *sptr, size_t msglen, const char *labelstr)
+{
+ rtm_ext_t rtm_ext;
+ tsol_rtsecattr_t sp;
+ struct rtsa_s *rtsa = &sp.rtsa_attr[0];
+ const char *endptr;
+ char buf[256];
+ int i;
+
+ if (!is_system_labeled())
+ return;
+
+ endptr = sptr + msglen;
+
+ for (;;) {
+ if (sptr + sizeof (rtm_ext_t) + sizeof (sp) > endptr)
+ return;
+
+ bcopy(sptr, &rtm_ext, sizeof (rtm_ext));
+ sptr += sizeof (rtm_ext);
+ if (rtm_ext.rtmex_type == RTMEX_GATEWAY_SECATTR)
+ break;
+ sptr += rtm_ext.rtmex_len;
+ }
+
+ /* bail if this entry is corrupt or overruns buffer length */
+ if (rtm_ext.rtmex_len < sizeof (sp) ||
+ sptr + rtm_ext.rtmex_len > endptr)
+ return;
+
+ /* run up just to the end of this extension */
+ endptr = sptr + rtm_ext.rtmex_len;
+
+ bcopy(sptr, &sp, sizeof (sp));
+ sptr += sizeof (sp);
+
+ if (sptr + (sp.rtsa_cnt - 1) * sizeof (*rtsa) != endptr)
+ return;
+
+ for (i = 0; i < sp.rtsa_cnt; i++) {
+ if (i > 0) {
+ /* first element is part of sp initalized above */
+ bcopy(sptr, rtsa, sizeof (*rtsa));
+ sptr += sizeof (*rtsa);
+ }
+ (void) printf("\n%s%s", labelstr, rtsa_to_str(rtsa, buf,
+ sizeof (buf)));
+ }
+}
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/Makefile b/usr/src/cmd/cmd-inet/usr.sbin/snoop/Makefile
index e9dc9a3..d853d7f 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/Makefile
+++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -18,9 +17,11 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
+
+
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -46,7 +47,8 @@
include ../../../Makefile.cmd
CPPFLAGS += -I. -I$(SRC)/common/net/dhcp
-LDLIBS += -ldhcputil -ldlpi -lsocket -lnsl
+LDLIBS += -ldhcputil -ldlpi -lsocket -lnsl \
+ -z lazyload -ltsol -z nolazyload
.KEEP_STATE:
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.c b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.c
index 3b5e49b..386fcbc 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.c
@@ -53,7 +53,7 @@
#include "snoop.h"
-int snaplen;
+static int snaplen;
char *device = NULL;
/* Global error recovery variables */
@@ -61,12 +61,9 @@
int snoop_nrecover; /* number of recoveries on curr pkt */
int quitting; /* user termination flag */
-extern int encap_levels; /* variables needing reset on error */
-extern unsigned int total_encap_levels;
-
-struct snoop_handler *snoop_hp; /* global alarm handler head */
-struct snoop_handler *snoop_tp; /* global alarm handler tail */
-time_t snoop_nalarm; /* time of next alarm */
+static struct snoop_handler *snoop_hp; /* global alarm handler head */
+static struct snoop_handler *snoop_tp; /* global alarm handler tail */
+static time_t snoop_nalarm; /* time of next alarm */
/* protected interpreter output areas */
#define MAXSUM 8
@@ -76,10 +73,10 @@
static char *line;
static char *encap;
-int audio;
+static int audio;
int maxcount; /* maximum no of packets to capture */
int count; /* count of packets captured */
-int sumcount;
+static int sumcount;
int x_offset = -1;
int x_length = 0x7fffffff;
FILE *namefile;
@@ -91,17 +88,15 @@
#endif
struct Pf_ext_packetfilt pf;
-void usage();
+static void usage(void);
void show_count();
-void snoop_sigrecover(int sig, siginfo_t *info, void *p);
+static void snoop_sigrecover(int sig, siginfo_t *info, void *p);
static char *protmalloc(size_t);
static void resetperm(void);
int
main(int argc, char **argv)
{
- extern char *optarg;
- extern int optind;
int c;
int filter = 0;
int flags = F_SUM;
@@ -120,8 +115,6 @@
char self[MAXHOSTNAMELEN + 1];
char *argstr = NULL;
void (*proc)();
- extern void cap_write();
- extern void process_pkt();
char *audiodev;
int ret;
struct sigaction sigact;
@@ -170,7 +163,7 @@
/* Initialize a master signal handler */
sigact.sa_handler = NULL;
sigact.sa_sigaction = snoop_sigrecover;
- sigemptyset(&sigact.sa_mask);
+ (void) sigemptyset(&sigact.sa_mask);
sigact.sa_flags = SA_ONSTACK|SA_SIGINFO;
/* Register master signal handler */
@@ -231,7 +224,7 @@
if (sigsetjmp(jmp_env, 1)) {
exit(1);
}
- setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
+ (void) setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
while ((c = getopt(argc, argv, "at:CPDSi:o:Nn:s:d:vVp:f:c:x:?rqz"))
!= EOF) {
@@ -491,7 +484,7 @@
net_read(chunksize, filter, proc, flags);
if (!(flags & F_NOW))
- printf("\n");
+ (void) printf("\n");
}
if (ocapfile)
@@ -500,7 +493,7 @@
return (0);
}
-int tone[] = {
+static int tone[] = {
0x076113, 0x153333, 0x147317, 0x144311, 0x147315, 0x050353, 0x037103, 0x051106,
0x157155, 0x142723, 0x133273, 0x134664, 0x051712, 0x024465, 0x026447, 0x072473,
0x136715, 0x126257, 0x135256, 0x047344, 0x034476, 0x027464, 0x036062, 0x133334,
@@ -524,7 +517,7 @@
len = len ? len : 4;
if (audio) {
- write(audio, tone, len);
+ (void) write(audio, tone, len);
}
}
@@ -561,16 +554,16 @@
int i, start;
if (flags & F_NUM) {
- sprintf(lp, "%3d ", num);
+ (void) sprintf(lp, "%3d ", num);
lp += strlen(lp);
}
tm = localtime(&tvp->tv_sec);
if (flags & F_TIME) {
if (flags & F_ATIME) {
- sprintf(lp, "%d:%02d:%d.%05d ",
+ (void) sprintf(lp, "%d:%02d:%d.%05d ",
tm->tm_hour, tm->tm_min, tm->tm_sec,
- tvp->tv_usec / 10);
+ (int)tvp->tv_usec / 10);
lp += strlen(lp);
} else {
if (flags & F_RTIME) {
@@ -586,44 +579,44 @@
usec += 1000000;
sec -= 1;
}
- sprintf(lp, "%3d.%05d ", sec, usec / 10);
+ (void) sprintf(lp, "%3d.%05d ", sec, usec / 10);
lp += strlen(lp);
}
}
if (flags & F_WHO) {
- sprintf(lp, "%12s -> %-12s ", src, dst);
+ (void) sprintf(lp, "%12s -> %-12s ", src, dst);
lp += strlen(lp);
}
if (flags & F_DROPS) {
- sprintf(lp, "drops: %d ", drops);
+ (void) sprintf(lp, "drops: %d ", drops);
lp += strlen(lp);
}
if (flags & F_LEN) {
- sprintf(lp, "length: %4d ", len);
+ (void) sprintf(lp, "length: %4d ", len);
lp += strlen(lp);
}
if (flags & F_SUM) {
if (flags & F_ALLSUM)
- printf("________________________________\n");
+ (void) printf("________________________________\n");
start = flags & F_ALLSUM ? 0 : sumcount - 1;
- sprintf(encap, " (%d encap)", total_encap_levels - 1);
- printf("%s%s%s\n", line, sumline[start],
+ (void) sprintf(encap, " (%d encap)", total_encap_levels - 1);
+ (void) printf("%s%s%s\n", line, sumline[start],
((flags & F_ALLSUM) || (total_encap_levels == 1)) ? "" :
encap);
for (i = start + 1; i < sumcount; i++)
- printf("%s%s\n", line, sumline[i]);
+ (void) printf("%s%s\n", line, sumline[i]);
sumcount = 0;
}
if (flags & F_DTAIL) {
- printf("%s\n\n", detail_line);
+ (void) printf("%s\n\n", detail_line);
detail_line[0] = '\0';
}
}
@@ -658,7 +651,7 @@
int off, len;
{
if (detail_line[0]) {
- printf("%s\n", detail_line);
+ (void) printf("%s\n", detail_line);
detail_line[0] = '\0';
}
return (detail_line);
@@ -667,27 +660,32 @@
/*
* Print an error.
* Works like printf (fmt string and variable args)
- * except that it will subsititute an error message
+ * except that it will substitute an error message
* for a "%m" string (like syslog) and it calls
* long_jump - it doesn't return to where it was
* called from - it goes to the last setjmp().
*/
+/* VARARGS1 */
void
-pr_err(char *fmt, ...)
+pr_err(const char *fmt, ...)
{
va_list ap;
- char buf[BUFSIZ], *p2;
- char *p1;
+ char buf[1024], *p2;
+ const char *p1;
- strcpy(buf, "snoop: ");
+ (void) strcpy(buf, "snoop: ");
p2 = buf + strlen(buf);
- for (p1 = fmt; *p1; p1++) {
+ /*
+ * Note that we terminate the buffer with '\n' and '\0'.
+ */
+ for (p1 = fmt; *p1 != '\0' && p2 < buf + sizeof (buf) - 2; p1++) {
if (*p1 == '%' && *(p1+1) == 'm') {
- char *errstr;
+ const char *errstr;
- if ((errstr = strerror(errno)) != (char *)NULL) {
- (void) strcpy(p2, errstr);
+ if ((errstr = strerror(errno)) != NULL) {
+ *p2 = '\0';
+ (void) strlcat(buf, errstr, sizeof (buf));
p2 += strlen(p2);
}
p1++;
@@ -700,6 +698,7 @@
*p2 = '\0';
va_start(ap, fmt);
+ /* LINTED: E_SEC_PRINTF_VAR_FMT */
(void) vfprintf(stderr, buf, ap);
va_end(ap);
snoop_sigrecover(-1, NULL, NULL); /* global error recovery */
@@ -710,8 +709,8 @@
* PLEASE keep this up to date!
* Naive users *love* this stuff.
*/
-void
-usage()
+static void
+usage(void)
{
(void) fprintf(stderr, "\nUsage: snoop\n");
(void) fprintf(stderr,
@@ -793,8 +792,8 @@
volatile sigset_t s_mask;
volatile int ret = -1;
- sigemptyset((sigset_t *)&s_mask);
- sigaddset((sigset_t *)&s_mask, SIGALRM);
+ (void) sigemptyset((sigset_t *)&s_mask);
+ (void) sigaddset((sigset_t *)&s_mask, SIGALRM);
if (s_sec < 0)
return (-1);
@@ -812,7 +811,7 @@
snoop_hp = snoop_tp = (struct snoop_handler *)sh;
snoop_nalarm = sh->s_time;
- alarm(sh->s_time - now);
+ (void) alarm(sh->s_time - now);
} else {
snoop_tp->s_next = (struct snoop_handler *)sh;
snoop_tp = (struct snoop_handler *)sh;
@@ -905,7 +904,7 @@
* out the signal blocking.
*/
/*ARGSUSED*/
-void
+static void
snoop_sigrecover(int sig, siginfo_t *info, void *p)
{
volatile time_t now;
@@ -934,7 +933,7 @@
/* Setup next alarm */
if (nalarm) {
snoop_nalarm = nalarm;
- alarm(nalarm - now);
+ (void) alarm(nalarm - now);
} else {
snoop_nalarm = 0;
}
@@ -979,7 +978,7 @@
return;
}
if (snoop_nrecover >= SNOOP_MAXRECOVER) {
- fprintf(stderr,
+ (void) fprintf(stderr,
"snoop: WARNING: skipping from packet %d\n",
count);
snoop_nrecover = 0;
@@ -988,13 +987,13 @@
return;
}
} else if (snoop_nrecover >= SNOOP_MAXRECOVER) {
- fprintf(stderr,
+ (void) fprintf(stderr,
"snoop: ERROR: cannot recover from packet %d\n", count);
exit(1);
}
#ifdef DEBUG
- fprintf(stderr, "snoop_sigrecover(%d, %p, %p)\n", sig, info, p);
+ (void) fprintf(stderr, "snoop_sigrecover(%d, %p, %p)\n", sig, info, p);
#endif /* DEBUG */
/*
@@ -1006,7 +1005,8 @@
return;
} else if (sig != -1 && sig != SIGALRM) {
/* Inform user that snoop has taken a fault */
- fprintf(stderr, "WARNING: received signal %d from packet %d\n",
+ (void) fprintf(stderr,
+ "WARNING: received signal %d from packet %d\n",
sig, count);
}
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.h b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.h
index c78f3c9..fe9bf31 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.h
+++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,6 +34,7 @@
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/bufmod.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
@@ -127,6 +127,7 @@
extern char *get_sum_line(void);
extern char *get_detail_line(int, int);
extern struct timeval prev_time;
+extern void process_pkt(struct sb_hdr *, char *, int, int);
extern char *getflag(int, int, char *, char *);
extern void show_header(char *, char *, int);
extern void xdr_init(char *, int);
@@ -173,6 +174,7 @@
extern int pf_compile(char *, int);
extern void compile(char *, int);
extern void load_names(char *);
+extern void cap_write(struct sb_hdr *, char *, int, int);
extern void cap_open_read(char *);
extern void cap_open_write(char *);
extern void cap_read(int, int, int, void (*)(), int);
@@ -187,9 +189,9 @@
extern void show_line(char *);
extern char *getxdr_time(void);
extern char *showxdr_time(char *);
-extern char *addrtoname(int, void *);
+extern char *addrtoname(int, const void *);
extern char *show_string(const char *, int, int);
-extern void pr_err(char *, ...);
+extern void pr_err(const char *, ...);
extern void check_retransmit(char *, ulong_t);
extern char *nameof_prog(int);
extern char *getproto(int);
@@ -219,14 +221,40 @@
extern void interpret_ldap(int, char *, int, int, int);
extern void interpret_icmp(int, struct icmp *, int, int);
extern void interpret_icmpv6(int, icmp6_t *, int, int);
-extern int interpret_ip(int, struct ip *, int);
-extern int interpret_ipv6(int, ip6_t *, int);
+extern int interpret_ip(int, const struct ip *, int);
+extern int interpret_ipv6(int, const ip6_t *, int);
extern int interpret_ppp(int, uchar_t *, int);
extern int interpret_pppoe(int, poep_t *, int);
+struct tcphdr;
+extern int interpret_tcp(int, struct tcphdr *, int, int);
+struct udphdr;
+extern int interpret_udp(int, struct udphdr *, int, int);
+extern int interpret_esp(int, uint8_t *, int, int);
+extern int interpret_ah(int, uint8_t *, int, int);
+struct sctp_hdr;
+extern void interpret_sctp(int, struct sctp_hdr *, int, int);
+extern void interpret_mip_cntrlmsg(int, uchar_t *, int);
+struct dhcp;
+extern int interpret_dhcp(int, struct dhcp *, int);
+struct tftphdr;
+extern int interpret_tftp(int, struct tftphdr *, int);
+extern int interpret_http(int, char *, int);
+struct ntpdata;
+extern int interpret_ntp(int, struct ntpdata *, int);
+extern void interpret_netbios_ns(int, uchar_t *, int);
+extern void interpret_netbios_datagram(int, uchar_t *, int);
+extern void interpret_netbios_ses(int, uchar_t *, int);
+extern void interpret_slp(int, char *, int);
+struct rip;
+extern int interpret_rip(int, struct rip *, int);
+struct rip6;
+extern int interpret_rip6(int, struct rip6 *, int);
+extern int interpret_socks_call(int, char *, int);
+extern int interpret_socks_reply(int, char *, int);
extern void init_ldap(void);
extern boolean_t arp_for_ether(char *, struct ether_addr *);
extern char *ether_ouiname(uint32_t);
-char *tohex(char *p, int len);
+extern char *tohex(char *p, int len);
extern char *printether(struct ether_addr *);
extern char *print_ethertype(int);
@@ -257,6 +285,17 @@
extern char *dlc_header;
+extern char *src_name, *dst_name;
+
+extern char *prot_prefix;
+extern char *prot_nest_prefix;
+extern char *prot_title;
+
+/* Keep track of how many nested IP headers we have. */
+extern unsigned int encap_levels, total_encap_levels;
+
+extern int quitting;
+
/*
* Global error recovery routine: used to reset snoop variables after
* catastrophic failure.
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_capture.c b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_capture.c
index 2270229..e3e7bd7 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_capture.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_capture.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -57,27 +56,37 @@
#include "snoop.h"
-void scan();
+/*
+ * Old header format.
+ * Actually two concatenated structs: nit_bufhdr + nit_head
+ */
+struct ohdr {
+ /* nit_bufhdr */
+ int o_msglen;
+ int o_totlen;
+ /* nit_head */
+ struct timeval o_time;
+ int o_drops;
+ int o_len;
+};
+
+static void scan(char *, int, int, int, int, void (*)(), int, int, int);
void convert_to_network();
void convert_from_network();
-void convert_old();
-extern int quitting;
+static void convert_old(struct ohdr *);
extern sigjmp_buf jmp_env, ojmp_env;
-int netfd;
-union DL_primitives netdl; /* info_ack for interface */
-char *bufp; /* pointer to read buffer */
+static int netfd;
+static union DL_primitives netdl; /* info_ack for interface */
+static char *bufp; /* pointer to read buffer */
-extern unsigned int encap_levels;
-
-static int strioctl(int, int, int, int, char *);
+static int strioctl(int, int, int, int, void *);
/*
* Convert a device id to a ppa value
* e.g. "le0" -> 0
*/
-int
-device_ppa(device)
- char *device;
+static int
+device_ppa(char *device)
{
char *p;
char *tp;
@@ -97,9 +106,8 @@
* Level 1 devices: "le0" -> "/dev/le0".
* Level 2 devices: "le0" -> "/dev/le".
*/
-char *
-device_path(device)
- char *device;
+static char *
+device_path(char *device)
{
static char buff[IF_NAMESIZE + 1];
struct stat st;
@@ -223,8 +231,9 @@
/* allow limited functionality even is interface isn't known */
if (interface->mac_type == -1) {
- fprintf(stderr, "snoop: WARNING: Mac Type = %x not supported\n",
- netdl.info_ack.dl_mac_type);
+ fprintf(stderr,
+ "snoop: WARNING: Mac Type = %lx not supported\n",
+ netdl.info_ack.dl_mac_type);
}
/* for backward compatibility, allow known interface mtu_sizes */
@@ -244,6 +253,7 @@
* push the streams buffer module and packet filter module, set various buffer
* parameters.
*/
+/* ARGSUSED */
void
initdevice(device, snaplen, chunksize, timeout, fp, ppa)
char *device;
@@ -252,7 +262,6 @@
struct Pf_ext_packetfilt *fp;
int ppa;
{
- union DL_primitives dl;
extern int Pflg;
/*
@@ -281,7 +290,7 @@
dlpromiscon(netfd, DL_PROMISC_SAP);
if (ioctl(netfd, DLIOCRAW, 0) < 0) {
- close(netfd);
+ (void) close(netfd);
pr_err("ioctl: DLIOCRAW: %s: %m", device_path(device));
}
@@ -290,38 +299,38 @@
* push and configure the packet filtering module
*/
if (ioctl(netfd, I_PUSH, "pfmod") < 0) {
- close(netfd);
+ (void) close(netfd);
pr_err("ioctl: I_PUSH pfmod: %s: %m",
device_path(device));
}
if (strioctl(netfd, PFIOCSETF, -1, sizeof (*fp),
(char *)fp) < 0) {
- close(netfd);
+ (void) close(netfd);
pr_err("PFIOCSETF: %s: %m", device_path(device));
}
}
if (ioctl(netfd, I_PUSH, "bufmod") < 0) {
- close(netfd);
+ (void) close(netfd);
pr_err("push bufmod: %s: %m", device_path(device));
}
if (strioctl(netfd, SBIOCSTIME, -1, sizeof (struct timeval),
(char *)timeout) < 0) {
- close(netfd);
+ (void) close(netfd);
pr_err("SBIOCSTIME: %s: %m", device_path(device));
}
if (strioctl(netfd, SBIOCSCHUNK, -1, sizeof (uint_t),
(char *)&chunksize) < 0) {
- close(netfd);
+ (void) close(netfd);
pr_err("SBIOCGCHUNK: %s: %m", device_path(device));
}
if (strioctl(netfd, SBIOCSSNAP, -1, sizeof (uint_t),
(char *)&snaplen) < 0) {
- close(netfd);
+ (void) close(netfd);
pr_err("SBIOCSSNAP: %s: %m", device_path(device));
}
@@ -330,7 +339,7 @@
* accumulated before the device reached its final configuration.
*/
if (ioctl(netfd, I_FLUSH, FLUSHR) < 0) {
- close(netfd);
+ (void) close(netfd);
pr_err("I_FLUSH: %s: %m", device_path(device));
}
}
@@ -383,7 +392,7 @@
}
free(bufp);
- close(netfd);
+ (void) close(netfd);
if (!quitting) {
if (r < 0)
@@ -422,13 +431,9 @@
}
#endif /* DEBUG */
-void
-scan(buf, len, filter, cap, old, proc, first, last, flags)
- char *buf;
- int len, filter, cap, old;
- void (*proc)();
- int first, last;
- int flags;
+static void
+scan(char *buf, int len, int filter, int cap, int old, void (*proc)(),
+ int first, int last, int flags)
{
volatile char *bp, *bufstop;
volatile struct sb_hdr *hdrp;
@@ -481,7 +486,7 @@
* capture file, convert the header.
*/
if (old) {
- convert_old(hdrp);
+ convert_old((struct ohdr *)hdrp);
}
nhdrp = &nhdr;
@@ -685,34 +690,33 @@
* | word 0 | word 1 | word 2 | word 3
*
*/
-const char *snoop_id = "snoop\0\0\0";
-const int snoop_idlen = 8;
-const int snoop_version = 2;
+static const char *snoop_id = "snoop\0\0\0";
+static const int snoop_idlen = 8;
+static const int snoop_version = 2;
void
cap_open_write(name)
char *name;
{
int vers;
- int rc;
capfile_out = open(name, O_CREAT | O_TRUNC | O_RDWR, 0666);
if (capfile_out < 0)
pr_err("%s: %m", name);
vers = htonl(snoop_version);
- if ((rc = nwrite(capfile_out, snoop_id, snoop_idlen)) == -1)
+ if (nwrite(capfile_out, snoop_id, snoop_idlen) == -1)
cap_write_error("snoop_id");
- if ((rc = nwrite(capfile_out, &vers, sizeof (int))) == -1)
+ if (nwrite(capfile_out, &vers, sizeof (int)) == -1)
cap_write_error("version");
}
void
-cap_close()
+cap_close(void)
{
- close(capfile_out);
+ (void) close(capfile_out);
}
static char *cap_buffp = NULL;
@@ -737,7 +741,7 @@
cap_len = st.st_size;
cap_buffp = mmap(0, cap_len, PROT_READ, MAP_PRIVATE, capfile_in, 0);
- close(capfile_in);
+ (void) close(capfile_in);
if ((int)cap_buffp == -1)
pr_err("couldn't mmap %s: %m", name);
@@ -810,9 +814,10 @@
scan(cap_buffp, cap_len, filter, 1, !cap_new, proc, first, last, flags);
- munmap(cap_buffp, cap_len);
+ (void) munmap(cap_buffp, cap_len);
}
+/* ARGSUSED */
void
cap_write(hdrp, pktp, num, flags)
struct sb_hdr *hdrp;
@@ -823,7 +828,6 @@
static int first = 1;
struct sb_hdr nhdr;
extern boolean_t qflg;
- int rc;
if (hdrp == NULL)
return;
@@ -831,7 +835,7 @@
if (first) {
first = 0;
mac = htonl(interface->mac_type);
- if ((rc = nwrite(capfile_out, &mac, sizeof (int))) == -1)
+ if (nwrite(capfile_out, &mac, sizeof (int)) == -1)
cap_write_error("mac_type");
}
@@ -847,10 +851,10 @@
nhdr.sbh_timestamp.tv_sec = htonl(hdrp->sbh_timestamp.tv_sec);
nhdr.sbh_timestamp.tv_usec = htonl(hdrp->sbh_timestamp.tv_usec);
- if ((rc = nwrite(capfile_out, &nhdr, sizeof (nhdr))) == -1)
+ if (nwrite(capfile_out, &nhdr, sizeof (nhdr)) == -1)
cap_write_error("packet header");
- if ((rc = nwrite(capfile_out, pktp, pktlen)) == -1)
+ if (nwrite(capfile_out, pktp, pktlen) == -1)
cap_write_error("packet");
if (! qflg)
@@ -858,26 +862,11 @@
}
/*
- * Old header format.
- * Actually two concatenated structs: nit_bufhdr + nit_head
- */
-struct ohdr {
- /* nit_bufhdr */
- int o_msglen;
- int o_totlen;
- /* nit_head */
- struct timeval o_time;
- int o_drops;
- int o_len;
-};
-
-/*
* Convert a packet header from
* old to new format.
*/
-void
-convert_old(ohdrp)
- struct ohdr *ohdrp;
+static void
+convert_old(struct ohdr *ohdrp)
{
struct sb_hdr nhdr;
@@ -891,7 +880,7 @@
}
static int
-strioctl(int fd, int cmd, int timout, int len, char *dp)
+strioctl(int fd, int cmd, int timout, int len, void *dp)
{
struct strioctl sioc;
int rc;
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_dhcp.c b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_dhcp.c
index 3ca7d44..f188a24 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_dhcp.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_dhcp.c
@@ -135,7 +135,7 @@
#define OPTIONS_ARRAY_SIZE 78
int
-interpret_dhcp(int flags, PKT *dp, int len)
+interpret_dhcp(int flags, struct dhcp *dp, int len)
{
if (flags & F_SUM) {
if ((memcmp(dp->cookie, bootmagic, sizeof (bootmagic)) == 0) &&
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ip.c b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ip.c
index 8421ecc..be6440a 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ip.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ip.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -28,7 +27,6 @@
#include <stdio.h>
-#include <ctype.h>
#include <string.h>
#include <fcntl.h>
#include <string.h>
@@ -37,7 +35,6 @@
#include <sys/stropts.h>
#include <sys/socket.h>
-#include <sys/sockio.h>
#include <net/if.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
@@ -46,10 +43,14 @@
#include <netinet/ip_icmp.h>
#include <netinet/icmp6.h>
#include <netinet/if_ether.h>
+#include <inet/ip.h>
#include <inet/ip6.h>
-#include <inet/ipsecah.h>
#include <arpa/inet.h>
#include <netdb.h>
+#include <tsol/label.h>
+#include <sys/tsol/tndb.h>
+#include <sys/tsol/label_macro.h>
+
#include "snoop.h"
@@ -67,34 +68,29 @@
#define SNOOP_ESP 0x20U
#define SNOOP_IPV6 0x40U
-extern char *dlc_header;
-
-static void prt_routing_hdr();
-static void prt_fragment_hdr();
-static void prt_hbh_options();
-static void prt_dest_options();
-static void print_route();
-static void print_ipoptions();
-char *getproto();
+static void prt_routing_hdr(int, const struct ip6_rthdr *);
+static void prt_fragment_hdr(int, const struct ip6_frag *);
+static void prt_hbh_options(int, const struct ip6_hbh *);
+static void prt_dest_options(int, const struct ip6_dest *);
+static void print_route(const uchar_t *);
+static void print_ipoptions(const uchar_t *, int);
+static void print_ripso(const uchar_t *);
+static void print_cipso(const uchar_t *);
/* Keep track of how many nested IP headers we have. */
unsigned int encap_levels;
unsigned int total_encap_levels = 1;
int
-interpret_ip(flags, ip, fraglen)
- int flags;
- struct ip *ip;
- int fraglen;
+interpret_ip(int flags, const struct ip *ip, int fraglen)
{
- char *data;
+ uchar_t *data;
char buff[24];
boolean_t isfrag = B_FALSE;
boolean_t morefrag;
uint16_t fragoffset;
int hdrlen;
uint16_t iplen, uitmp;
- extern char *src_name, *dst_name;
if (ip->ip_v == IPV6_VERSION) {
iplen = interpret_ipv6(flags, (ip6_t *)ip, fraglen);
@@ -108,7 +104,7 @@
total_encap_levels++;
hdrlen = ip->ip_hl * 4;
- data = ((char *)ip) + hdrlen;
+ data = ((uchar_t *)ip) + hdrlen;
iplen = ntohs(ip->ip_len) - hdrlen;
fraglen -= hdrlen;
if (fraglen > iplen)
@@ -163,80 +159,74 @@
if (flags & F_DTAIL) {
show_header("IP: ", "IP Header", iplen);
show_space();
- (void) snprintf(get_line((char *)ip - dlc_header, 1),
- get_line_remain(), "Version = %d", ip->ip_v);
- (void) snprintf(get_line((char *)ip - dlc_header, 1),
- get_line_remain(), "Header length = %d bytes", hdrlen);
- (void) snprintf(get_line((char *)&ip->ip_tos - dlc_header, 1),
- get_line_remain(), "Type of service = 0x%02x", ip->ip_tos);
- (void) snprintf(get_line((char *)&ip->ip_tos - dlc_header, 1),
- get_line_remain(), " xxx. .... = %d (precedence)",
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Version = %d", ip->ip_v);
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Header length = %d bytes", hdrlen);
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Type of service = 0x%02x", ip->ip_tos);
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ " xxx. .... = %d (precedence)",
ip->ip_tos >> 5);
- (void) snprintf(get_line((char *)&ip->ip_tos - dlc_header, 1),
- get_line_remain(), " %s",
- getflag(ip->ip_tos, IPTOS_LOWDELAY,
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ " %s", getflag(ip->ip_tos, IPTOS_LOWDELAY,
"low delay", "normal delay"));
- (void) snprintf(get_line((char *)&ip->ip_tos - dlc_header, 1),
- get_line_remain(), " %s",
+ (void) snprintf(get_line(0, 0), get_line_remain(), " %s",
getflag(ip->ip_tos, IPTOS_THROUGHPUT,
"high throughput", "normal throughput"));
- (void) snprintf(get_line((char *)&ip->ip_tos - dlc_header, 1),
- get_line_remain(), " %s",
+ (void) snprintf(get_line(0, 0), get_line_remain(), " %s",
getflag(ip->ip_tos, IPTOS_RELIABILITY,
"high reliability", "normal reliability"));
- (void) snprintf(get_line((char *)&ip->ip_tos - dlc_header, 1),
- get_line_remain(), " %s",
+ (void) snprintf(get_line(0, 0), get_line_remain(), " %s",
getflag(ip->ip_tos, IPTOS_ECT,
"ECN capable transport", "not ECN capable transport"));
- (void) snprintf(get_line((char *)&ip->ip_tos - dlc_header, 1),
- get_line_remain(), " %s",
+ (void) snprintf(get_line(0, 0), get_line_remain(), " %s",
getflag(ip->ip_tos, IPTOS_CE,
"ECN congestion experienced",
"no ECN congestion experienced"));
/* warning: ip_len is signed in netinet/ip.h */
uitmp = ntohs(ip->ip_len);
- (void) snprintf(get_line((char *)&ip->ip_len - dlc_header, 2),
- get_line_remain(), "Total length = %u bytes%s", uitmp,
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Total length = %u bytes%s", uitmp,
iplen > fraglen ? " -- truncated" : "");
- (void) snprintf(get_line((char *)&ip->ip_id - dlc_header, 2),
- get_line_remain(), "Identification = %d", ntohs(ip->ip_id));
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Identification = %d", ntohs(ip->ip_id));
/* warning: ip_off is signed in netinet/ip.h */
uitmp = ntohs(ip->ip_off);
- (void) snprintf(get_line((char *)&ip->ip_off - dlc_header, 1),
- get_line_remain(), "Flags = 0x%x", uitmp >> 12);
- (void) snprintf(get_line((char *)&ip->ip_off - dlc_header, 1),
- get_line_remain(), " %s",
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Flags = 0x%x", uitmp >> 12);
+ (void) snprintf(get_line(0, 0), get_line_remain(), " %s",
getflag(uitmp >> 8, IP_DF >> 8,
"do not fragment", "may fragment"));
- (void) snprintf(get_line((char *)&ip->ip_off - dlc_header, 1),
- get_line_remain(), " %s",
+ (void) snprintf(get_line(0, 0), get_line_remain(), " %s",
getflag(uitmp >> 8, IP_MF >> 8,
"more fragments", "last fragment"));
- (void) snprintf(get_line((char *)&ip->ip_off - dlc_header, 2),
- get_line_remain(), "Fragment offset = %u bytes",
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Fragment offset = %u bytes",
fragoffset);
- (void) snprintf(get_line((char *)&ip->ip_ttl - dlc_header, 1),
- get_line_remain(), "Time to live = %d seconds/hops",
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Time to live = %d seconds/hops",
ip->ip_ttl);
- (void) snprintf(get_line((char *)&ip->ip_p - dlc_header, 1),
- get_line_remain(), "Protocol = %d (%s)", ip->ip_p,
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Protocol = %d (%s)", ip->ip_p,
getproto(ip->ip_p));
/*
* XXX need to compute checksum and print whether it's correct
*/
- (void) snprintf(get_line((char *)&ip->ip_sum - dlc_header, 1),
- get_line_remain(), "Header checksum = %04x",
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Header checksum = %04x",
ntohs(ip->ip_sum));
- (void) snprintf(get_line((char *)&ip->ip_src - dlc_header, 1),
- get_line_remain(), "Source address = %s, %s",
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Source address = %s, %s",
inet_ntoa(ip->ip_src), addrtoname(AF_INET, &ip->ip_src));
- (void) snprintf(get_line((char *)&ip->ip_dst - dlc_header, 1),
- get_line_remain(), "Destination address = %s, %s",
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Destination address = %s, %s",
inet_ntoa(ip->ip_dst), addrtoname(AF_INET, &ip->ip_dst));
/* Print IP options - if any */
- print_ipoptions(ip + 1, hdrlen - sizeof (struct ip));
+ print_ipoptions((const uchar_t *)(ip + 1),
+ hdrlen - sizeof (struct ip));
show_space();
}
@@ -248,8 +238,7 @@
* of a fragmented packet.
*/
if (flags & F_DTAIL && fragoffset != 0) {
- (void) snprintf(get_detail_line(data - dlc_header, iplen),
- MAXLINE,
+ (void) snprintf(get_detail_line(0, 0), MAXLINE,
"%s: [%d byte(s) of data, continuation of IP ident=%d]",
getproto(ip->ip_p),
iplen,
@@ -262,12 +251,14 @@
case IPPROTO_IP:
break;
case IPPROTO_ENCAP:
- (void) interpret_ip(flags, (struct ip *)data,
- fraglen);
+ (void) interpret_ip(flags,
+ /* LINTED: alignment */
+ (const struct ip *)data, fraglen);
break;
case IPPROTO_ICMP:
- interpret_icmp(flags, (struct icmp *)data,
- iplen, fraglen);
+ (void) interpret_icmp(flags,
+ /* LINTED: alignment */
+ (struct icmp *)data, iplen, fraglen);
break;
case IPPROTO_IGMP:
interpret_igmp(flags, data, iplen, fraglen);
@@ -275,14 +266,17 @@
case IPPROTO_GGP:
break;
case IPPROTO_TCP:
- interpret_tcp(flags, data, iplen, fraglen);
+ (void) interpret_tcp(flags,
+ (struct tcphdr *)data, iplen, fraglen);
break;
case IPPROTO_ESP:
- interpret_esp(flags, data, iplen, fraglen);
+ (void) interpret_esp(flags, data, iplen,
+ fraglen);
break;
case IPPROTO_AH:
- interpret_ah(flags, data, iplen, fraglen);
+ (void) interpret_ah(flags, data, iplen,
+ fraglen);
break;
case IPPROTO_OSPF:
@@ -293,7 +287,8 @@
case IPPROTO_PUP:
break;
case IPPROTO_UDP:
- interpret_udp(flags, data, iplen, fraglen);
+ (void) interpret_udp(flags,
+ (struct udphdr *)data, iplen, fraglen);
break;
case IPPROTO_IDP:
@@ -302,11 +297,13 @@
case IPPROTO_RAW:
break;
case IPPROTO_IPV6: /* IPV6 encap */
+ /* LINTED: alignment */
(void) interpret_ipv6(flags, (ip6_t *)data,
iplen);
break;
case IPPROTO_SCTP:
- interpret_sctp(flags, data, iplen, fraglen);
+ (void) interpret_sctp(flags,
+ (struct sctp_hdr *)data, iplen, fraglen);
break;
}
}
@@ -317,14 +314,10 @@
}
int
-interpret_ipv6(flags, ip6h, fraglen)
- int flags;
- ip6_t *ip6h;
- int fraglen;
+interpret_ipv6(int flags, const ip6_t *ip6h, int fraglen)
{
uint8_t *data;
int hdrlen, iplen;
- extern char *src_name, *dst_name;
int version, flow, class;
uchar_t proto;
boolean_t isfrag = B_FALSE;
@@ -365,8 +358,8 @@
* will not affect the detailed printing of the packet.
*/
if (flags & F_SUM) {
- (void) sprintf(get_sum_line(), "IPv6 S=%s D=%s LEN=%d "
- "HOPS=%d CLASS=0x%x FLOW=0x%x",
+ (void) snprintf(get_sum_line(), MAXLINE,
+ "IPv6 S=%s D=%s LEN=%d HOPS=%d CLASS=0x%x FLOW=0x%x",
src_name, dst_name, iplen, ip6h->ip6_hops, class, flow);
} else if (flags & F_DTAIL) {
@@ -392,22 +385,22 @@
show_header("IPv6: ", "IPv6 Header", iplen);
show_space();
- (void) sprintf(get_line((char *)ip6h - dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Version = %d", version);
- (void) sprintf(get_line((char *)ip6h - dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Traffic Class = %d", class);
- (void) sprintf(get_line((char *)&ip6h->ip6_vcf - dlc_header, 4),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Flow label = 0x%x", flow);
- (void) sprintf(get_line((char *)&ip6h->ip6_plen -
- dlc_header, 2), "Payload length = %d", iplen);
- (void) sprintf(get_line((char *)&ip6h->ip6_nxt -
- dlc_header, 1), "Next Header = %d (%s)", proto,
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Payload length = %d", iplen);
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Next Header = %d (%s)", proto,
getproto(proto));
- (void) sprintf(get_line((char *)&ip6h->ip6_hops -
- dlc_header, 1), "Hop Limit = %d", ip6h->ip6_hops);
- (void) sprintf(get_line((char *)&ip6h->ip6_src - dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Hop Limit = %d", ip6h->ip6_hops);
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Source address = %s%s", src_addrstr, print_srcname);
- (void) sprintf(get_line((char *)&ip6h->ip6_dst - dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Destination address = %s%s", dst_addrstr, print_dstname);
show_space();
@@ -440,10 +433,13 @@
case IPPROTO_IP:
break;
case IPPROTO_ENCAP:
- (void) interpret_ip(flags, (struct ip *)data, fraglen);
+ /* LINTED: alignment */
+ (void) interpret_ip(flags, (const struct ip *)data,
+ fraglen);
break;
case IPPROTO_ICMPV6:
- interpret_icmpv6(flags, (icmp6_t *)data, iplen,
+ /* LINTED: alignment */
+ (void) interpret_icmpv6(flags, (icmp6_t *)data, iplen,
fraglen);
break;
case IPPROTO_IGMP:
@@ -452,19 +448,21 @@
case IPPROTO_GGP:
break;
case IPPROTO_TCP:
- interpret_tcp(flags, data, iplen, fraglen);
+ (void) interpret_tcp(flags, (struct tcphdr *)data,
+ iplen, fraglen);
break;
case IPPROTO_ESP:
- interpret_esp(flags, data, iplen, fraglen);
+ (void) interpret_esp(flags, data, iplen, fraglen);
break;
case IPPROTO_AH:
- interpret_ah(flags, data, iplen, fraglen);
+ (void) interpret_ah(flags, data, iplen, fraglen);
break;
case IPPROTO_EGP:
case IPPROTO_PUP:
break;
case IPPROTO_UDP:
- interpret_udp(flags, data, iplen, fraglen);
+ (void) interpret_udp(flags, (struct udphdr *)data,
+ iplen, fraglen);
break;
case IPPROTO_IDP:
case IPPROTO_HELLO:
@@ -472,10 +470,13 @@
case IPPROTO_RAW:
break;
case IPPROTO_IPV6:
- (void) interpret_ipv6(flags, (ip6_t *)data, iplen);
+ /* LINTED: alignment */
+ (void) interpret_ipv6(flags, (const ip6_t *)data,
+ iplen);
break;
case IPPROTO_SCTP:
- interpret_sctp(flags, data, iplen, fraglen);
+ (void) interpret_sctp(flags, (struct sctp_hdr *)data,
+ iplen, fraglen);
break;
case IPPROTO_OSPF:
interpret_ospf6(flags, data, iplen, fraglen);
@@ -518,7 +519,6 @@
* header.
*/
if (*fraglen < 2) {
- proto = IPPROTO_NONE;
return (extmask);
}
@@ -527,7 +527,6 @@
ipv6ext_hbh = (struct ip6_hbh *)data_ptr;
exthdrlen = 8 + ipv6ext_hbh->ip6h_len * 8;
if (*fraglen <= exthdrlen) {
- proto = IPPROTO_NONE;
return (extmask);
}
prt_hbh_options(flags, ipv6ext_hbh);
@@ -538,7 +537,6 @@
ipv6ext_dest = (struct ip6_dest *)data_ptr;
exthdrlen = 8 + ipv6ext_dest->ip6d_len * 8;
if (*fraglen <= exthdrlen) {
- proto = IPPROTO_NONE;
return (extmask);
}
prt_dest_options(flags, ipv6ext_dest);
@@ -549,7 +547,6 @@
ipv6ext_rthdr = (struct ip6_rthdr *)data_ptr;
exthdrlen = 8 + ipv6ext_rthdr->ip6r_len * 8;
if (*fraglen <= exthdrlen) {
- proto = IPPROTO_NONE;
return (extmask);
}
prt_routing_hdr(flags, ipv6ext_rthdr);
@@ -557,10 +554,10 @@
proto = ipv6ext_rthdr->ip6r_nxt;
break;
case IPPROTO_FRAGMENT:
+ /* LINTED: alignment */
ipv6ext_frag = (struct ip6_frag *)data_ptr;
exthdrlen = sizeof (struct ip6_frag);
if (*fraglen <= exthdrlen) {
- proto = IPPROTO_NONE;
return (extmask);
}
prt_fragment_hdr(flags, ipv6ext_frag);
@@ -593,66 +590,81 @@
}
static void
-print_ipoptions(opt, optlen)
- uchar_t *opt;
- int optlen;
+print_ipoptions(const uchar_t *opt, int optlen)
{
int len;
+ int remain;
char *line;
+ const char *truncstr;
if (optlen <= 0) {
- (void) sprintf(get_line((char *)&opt - dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"No options");
return;
}
- (void) sprintf(get_line((char *)&opt - dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Options: (%d bytes)", optlen);
while (optlen > 0) {
- line = get_line((char *)&opt - dlc_header, 1);
+ line = get_line(0, 0);
+ remain = get_line_remain();
len = opt[1];
+ truncstr = len > optlen ? "?" : "";
switch (opt[0]) {
case IPOPT_EOL:
- (void) strcpy(line, " - End of option list");
+ (void) strlcpy(line, " - End of option list", remain);
return;
case IPOPT_NOP:
- (void) strcpy(line, " - No op");
+ (void) strlcpy(line, " - No op", remain);
len = 1;
break;
case IPOPT_RR:
- (void) sprintf(line, " - Record route (%d bytes)",
- len);
+ (void) snprintf(line, remain,
+ " - Record route (%d bytes%s)", len, truncstr);
print_route(opt);
break;
case IPOPT_TS:
- (void) sprintf(line, " - Time stamp (%d bytes)", len);
+ (void) snprintf(line, remain,
+ " - Time stamp (%d bytes%s)", len, truncstr);
break;
case IPOPT_SECURITY:
- (void) sprintf(line, " - Security (%d bytes)", len);
+ (void) snprintf(line, remain, " - RIPSO (%d bytes%s)",
+ len, truncstr);
+ print_ripso(opt);
+ break;
+ case IPOPT_COMSEC:
+ (void) snprintf(line, remain, " - CIPSO (%d bytes%s)",
+ len, truncstr);
+ print_cipso(opt);
break;
case IPOPT_LSRR:
- (void) sprintf(line,
- " - Loose source route (%d bytes)", len);
+ (void) snprintf(line, remain,
+ " - Loose source route (%d bytes%s)", len,
+ truncstr);
print_route(opt);
break;
case IPOPT_SATID:
- (void) sprintf(line, " - SATNET Stream id (%d bytes)",
- len);
+ (void) snprintf(line, remain,
+ " - SATNET Stream id (%d bytes%s)",
+ len, truncstr);
break;
case IPOPT_SSRR:
- (void) sprintf(line,
- " - Strict source route, (%d bytes)", len);
+ (void) snprintf(line, remain,
+ " - Strict source route, (%d bytes%s)", len,
+ truncstr);
print_route(opt);
break;
default:
- sprintf(line, " - Option %d (unknown - %d bytes) %s",
- opt[0], len, tohex((char *)&opt[2], len - 2));
+ (void) snprintf(line, remain,
+ " - Option %d (unknown - %d bytes%s) %s",
+ opt[0], len, truncstr,
+ tohex((char *)&opt[2], len - 2));
break;
}
if (len <= 0) {
- (void) sprintf(line, " - Incomplete option len %d",
- len);
+ (void) snprintf(line, remain,
+ " - Incomplete option len %d", len);
break;
}
opt += len;
@@ -661,17 +673,16 @@
}
static void
-print_route(opt)
- uchar_t *opt;
+print_route(const uchar_t *opt)
{
- int len, pointer;
+ int len, pointer, remain;
struct in_addr addr;
char *line;
len = opt[1];
pointer = opt[2];
- (void) sprintf(get_line((char *)(&opt + 2) - dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
" Pointer = %d", pointer);
pointer -= IPOPT_MINOFF;
@@ -679,15 +690,16 @@
len -= (IPOPT_OFFSET + 1);
while (len > 0) {
- line = get_line((char *)&(opt) - dlc_header, 4);
+ line = get_line(0, 0);
+ remain = get_line_remain();
memcpy((char *)&addr, opt, sizeof (addr));
if (addr.s_addr == INADDR_ANY)
- (void) strcpy(line, " -");
+ (void) strlcpy(line, " -", remain);
else
- (void) sprintf(line, " %s",
+ (void) snprintf(line, remain, " %s",
addrtoname(AF_INET, &addr));
if (pointer == 0)
- (void) strcat(line, " <-- (current)");
+ (void) strlcat(line, " <-- (current)", remain);
opt += sizeof (addr);
len -= sizeof (addr);
@@ -696,8 +708,7 @@
}
char *
-getproto(p)
- int p;
+getproto(int p)
{
switch (p) {
case IPPROTO_HOPOPTS: return ("IPv6-HopOpts");
@@ -728,9 +739,7 @@
}
static void
-prt_routing_hdr(flags, ipv6ext_rthdr)
- int flags;
- struct ip6_rthdr *ipv6ext_rthdr;
+prt_routing_hdr(int flags, const struct ip6_rthdr *ipv6ext_rthdr)
{
uint8_t nxt_hdr;
uint8_t type;
@@ -755,13 +764,13 @@
show_header("IPv6-Route: ", "IPv6 Routing Header", 0);
show_space();
- (void) sprintf(get_line((char *)ipv6ext_rthdr - dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Next header = %d (%s)", nxt_hdr, getproto(nxt_hdr));
- (void) sprintf(get_line((char *)ipv6ext_rthdr - dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Header length = %d", len);
- (void) sprintf(get_line((char *)ipv6ext_rthdr - dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Routing type = %d", type);
- (void) sprintf(get_line((char *)ipv6ext_rthdr - dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Segments left = %d", segleft);
if (type == IPV6_RTHDR_TYPE_0) {
@@ -774,14 +783,14 @@
* XXX to differentiate between the hops yet to do
* XXX and the hops already taken.
*/
+ /* LINTED: alignment */
ipv6ext_rthdr0 = (struct ip6_rthdr0 *)ipv6ext_rthdr;
numaddrs = ipv6ext_rthdr0->ip6r0_len / 2;
addrs = (struct in6_addr *)(ipv6ext_rthdr0 + 1);
for (i = 0; i < numaddrs; i++) {
(void) inet_ntop(AF_INET6, &addrs[i], addr,
INET6_ADDRSTRLEN);
- (void) sprintf(get_line((char *)ipv6ext_rthdr -
- dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"address[%d]=%s", i, addr);
}
}
@@ -790,9 +799,7 @@
}
static void
-prt_fragment_hdr(flags, ipv6ext_frag)
- int flags;
- struct ip6_frag *ipv6ext_frag;
+prt_fragment_hdr(int flags, const struct ip6_frag *ipv6ext_frag)
{
boolean_t morefrag;
uint16_t fragoffset;
@@ -807,7 +814,7 @@
fragident = ntohl(ipv6ext_frag->ip6f_ident);
if (flags & F_SUM) {
- (void) sprintf(get_sum_line(),
+ (void) snprintf(get_sum_line(), MAXLINE,
"IPv6 fragment ID=%d Offset=%-4d MF=%d",
fragident,
fragoffset,
@@ -816,13 +823,13 @@
show_header("IPv6-Frag: ", "IPv6 Fragment Header", 0);
show_space();
- (void) sprintf(get_line((char *)ipv6ext_frag - dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Next Header = %d (%s)", nxt_hdr, getproto(nxt_hdr));
- (void) sprintf(get_line((char *)ipv6ext_frag - dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Fragment Offset = %d", fragoffset);
- (void) sprintf(get_line((char *)ipv6ext_frag - dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"More Fragments Flag = %s", morefrag ? "true" : "false");
- (void) sprintf(get_line((char *)ipv6ext_frag - dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Identification = %d", fragident);
show_space();
@@ -830,12 +837,131 @@
}
static void
-prt_hbh_options(flags, ipv6ext_hbh)
- int flags;
- struct ip6_hbh *ipv6ext_hbh;
+print_ip6opt_ls(const uchar_t *data, unsigned int op_len)
{
- uint8_t *data;
- uint32_t len, olen;
+ uint32_t doi;
+ uint8_t sotype, solen;
+ uint16_t value, value2;
+ char *cp;
+ int remlen;
+ boolean_t printed;
+
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Labeled Security Option len = %u bytes%s", op_len,
+ op_len < sizeof (uint32_t) || (op_len & 1) != 0 ? "?" : "");
+ if (op_len < sizeof (uint32_t))
+ return;
+ GETINT32(doi, data);
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ " DOI = %d (%s)", doi, doi == IP6LS_DOI_V4 ? "IPv4" : "???");
+ op_len -= sizeof (uint32_t);
+ while (op_len > 0) {
+ GETINT8(sotype, data);
+ if (op_len < 2) {
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ " truncated %u suboption (no len)", sotype);
+ break;
+ }
+ GETINT8(solen, data);
+ if (solen < 2 || solen > op_len) {
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ " bad %u suboption (len 2 <= %u <= %u)",
+ sotype, solen, op_len);
+ if (solen < 2)
+ solen = 2;
+ if (solen > op_len)
+ solen = op_len;
+ }
+ op_len -= solen;
+ solen -= 2;
+ cp = get_line(0, 0);
+ remlen = get_line_remain();
+ (void) strlcpy(cp, " ", remlen);
+ cp += 4;
+ remlen -= 4;
+ printed = B_TRUE;
+ switch (sotype) {
+ case IP6LS_TT_LEVEL:
+ if (solen != 2) {
+ printed = B_FALSE;
+ break;
+ }
+ GETINT16(value, data);
+ (void) snprintf(cp, remlen, "Level %u", value);
+ solen = 0;
+ break;
+ case IP6LS_TT_VECTOR:
+ (void) strlcpy(cp, "Bit-Vector: ", remlen);
+ remlen -= strlen(cp);
+ cp += strlen(cp);
+ while (solen > 1) {
+ GETINT16(value, data);
+ solen -= 2;
+ (void) snprintf(cp, remlen, "%04x", value);
+ remlen -= strlen(cp);
+ cp += strlen(cp);
+ }
+ break;
+ case IP6LS_TT_ENUM:
+ (void) strlcpy(cp, "Enumeration:", remlen);
+ remlen -= strlen(cp);
+ cp += strlen(cp);
+ while (solen > 1) {
+ GETINT16(value, data);
+ solen -= 2;
+ (void) snprintf(cp, remlen, " %u", value);
+ remlen -= strlen(cp);
+ cp += strlen(cp);
+ }
+ break;
+ case IP6LS_TT_RANGES:
+ (void) strlcpy(cp, "Ranges:", remlen);
+ remlen -= strlen(cp);
+ cp += strlen(cp);
+ while (solen > 3) {
+ GETINT16(value, data);
+ GETINT16(value2, data);
+ solen -= 4;
+ (void) snprintf(cp, remlen, " %u-%u", value,
+ value2);
+ remlen -= strlen(cp);
+ cp += strlen(cp);
+ }
+ break;
+ case IP6LS_TT_V4:
+ (void) strlcpy(cp, "IPv4 Option", remlen);
+ print_ipoptions(data, solen);
+ solen = 0;
+ break;
+ case IP6LS_TT_DEST:
+ (void) snprintf(cp, remlen,
+ "Destination-Only Data length %u", solen);
+ solen = 0;
+ break;
+ default:
+ (void) snprintf(cp, remlen,
+ " unknown %u suboption (len %u)", sotype, solen);
+ solen = 0;
+ break;
+ }
+ if (solen != 0) {
+ if (printed) {
+ cp = get_line(0, 0);
+ remlen = get_line_remain();
+ }
+ (void) snprintf(cp, remlen,
+ " malformed %u suboption (remaining %u)",
+ sotype, solen);
+ data += solen;
+ }
+ }
+}
+
+static void
+prt_hbh_options(int flags, const struct ip6_hbh *ipv6ext_hbh)
+{
+ const uint8_t *data, *ndata;
+ uint32_t len;
uint8_t op_type;
uint8_t op_len;
uint8_t nxt_hdr;
@@ -854,85 +980,84 @@
*/
len = ipv6ext_hbh->ip6h_len * 8 + 8;
- data = (uint8_t *)ipv6ext_hbh + 2;
+ ndata = (const uint8_t *)ipv6ext_hbh + 2;
len -= 2;
nxt_hdr = ipv6ext_hbh->ip6h_nxt;
- (void) sprintf(get_line((char *)ipv6ext_hbh - dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Next Header = %u (%s)", nxt_hdr, getproto(nxt_hdr));
while (len > 0) {
+ data = ndata;
GETINT8(op_type, data);
- olen = len;
- switch (op_type) {
- case IP6OPT_PAD1:
- (void) sprintf(get_line((char *)ipv6ext_hbh -
- dlc_header, 1),
+ /* This is the only one-octet IPv6 option */
+ if (op_type == IP6OPT_PAD1) {
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"pad1 option ");
len--;
- break;
+ ndata = data;
+ continue;
+ }
+ GETINT8(op_len, data);
+ if (len < 2 || op_len + 2 > len) {
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Error: option %u truncated (%u + 2 > %u)",
+ op_type, op_len, len);
+ op_len = len - 2;
+ /*
+ * Continue processing the malformed option so that we
+ * can display as much as possible.
+ */
+ }
+
+ /* advance pointers to the next option */
+ len -= op_len + 2;
+ ndata = data + op_len;
+
+ /* process this option */
+ switch (op_type) {
case IP6OPT_PADN:
- GETINT8(op_len, data);
- (void) sprintf(get_line((char *)ipv6ext_hbh -
- dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"padN option len = %u", op_len);
- data += op_len; /* skip pads */
- len -= (op_len + 2);
break;
case IP6OPT_JUMBO: {
uint32_t payload_len;
- GETINT8(op_len, data);
- (void) sprintf(get_line((char *)ipv6ext_hbh -
- dlc_header, 1),
- "Jumbo Payload Option len = %u bytes", op_len);
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Jumbo Payload Option len = %u bytes%s", op_len,
+ op_len == sizeof (uint32_t) ? "" : "?");
if (op_len == sizeof (uint32_t)) {
GETINT32(payload_len, data);
- (void) sprintf(get_line((char *)ipv6ext_hbh -
- dlc_header, 1),
+ (void) snprintf(get_line(0, 0),
+ get_line_remain(),
"Jumbo Payload Length = %u bytes",
payload_len);
- } else {
- data += op_len;
}
- len -= (op_len + 2);
break;
}
case IP6OPT_ROUTER_ALERT: {
uint16_t value;
const char *label[] = {"MLD", "RSVP", "AN"};
- GETINT8(op_len, data);
- (void) snprintf(get_line((char *)ipv6ext_hbh -
- dlc_header, 1), get_line_remain(),
- "Router Alert Option len = %u bytes", op_len);
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Router Alert Option len = %u bytes%s", op_len,
+ op_len == sizeof (uint16_t) ? "" : "?");
if (op_len == sizeof (uint16_t)) {
GETINT16(value, data);
- (void) snprintf(get_line((char *)ipv6ext_hbh -
- dlc_header, 1), get_line_remain(),
+ (void) snprintf(get_line(0, 0),
+ get_line_remain(),
"Alert Type = %d (%s)", value,
value < sizeof (label) / sizeof (label[0]) ?
label[value] : "???");
- } else {
- data += op_len;
}
- len -= (op_len + 2);
break;
}
+ case IP6OPT_LS:
+ print_ip6opt_ls(data, op_len);
+ break;
default:
- GETINT8(op_len, data);
- (void) sprintf(get_line((char *)ipv6ext_hbh -
- dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Option type = %u, len = %u", op_type, op_len);
- data += op_len;
- len -= (op_len + 2);
- }
- /* check for corrupt length */
- if (olen <= len) {
- (void) sprintf(get_line((char *)ipv6ext_hbh -
- dlc_header, 1),
- "Incomplete option len = %u, len = %u", op_type,
- len);
break;
}
}
@@ -941,12 +1066,10 @@
}
static void
-prt_dest_options(flags, ipv6ext_dest)
- int flags;
- struct ip6_dest *ipv6ext_dest;
+prt_dest_options(int flags, const struct ip6_dest *ipv6ext_dest)
{
- uint8_t *data;
- uint32_t len, olen;
+ const uint8_t *data, *ndata;
+ uint32_t len;
uint8_t op_type;
uint32_t op_len;
uint8_t nxt_hdr;
@@ -966,57 +1089,405 @@
*/
len = ipv6ext_dest->ip6d_len * 8 + 8;
- data = (uint8_t *)ipv6ext_dest + 2; /* skip hdr/len */
+ ndata = (const uint8_t *)ipv6ext_dest + 2; /* skip hdr/len */
len -= 2;
nxt_hdr = ipv6ext_dest->ip6d_nxt;
- (void) sprintf(get_line((char *)ipv6ext_dest - dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Next Header = %u (%s)", nxt_hdr, getproto(nxt_hdr));
while (len > 0) {
+ data = ndata;
GETINT8(op_type, data);
- olen = len;
- switch (op_type) {
- case IP6OPT_PAD1:
- (void) sprintf(get_line((char *)ipv6ext_dest -
- dlc_header, 1),
+ if (op_type == IP6OPT_PAD1) {
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"pad1 option ");
len--;
- break;
+ ndata = data;
+ continue;
+ }
+ GETINT8(op_len, data);
+ if (len < 2 || op_len + 2 > len) {
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Error: option %u truncated (%u + 2 > %u)",
+ op_type, op_len, len);
+ op_len = len - 2;
+ /*
+ * Continue processing the malformed option so that we
+ * can display as much as possible.
+ */
+ }
+
+ /* advance pointers to the next option */
+ len -= op_len + 2;
+ ndata = data + op_len;
+
+ /* process this option */
+ switch (op_type) {
case IP6OPT_PADN:
- GETINT8(op_len, data);
- (void) sprintf(get_line((char *)ipv6ext_dest -
- dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"padN option len = %u", op_len);
- data += op_len;
- len -= (op_len + 2);
break;
case IP6OPT_TUNNEL_LIMIT:
- GETINT8(op_len, data);
GETINT8(value, data);
- (void) sprintf(get_line((char *)ipv6ext_dest -
- dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"tunnel encapsulation limit len = %d, value = %d",
op_len, value);
- len -= (op_len + 2);
+ break;
+ case IP6OPT_LS:
+ print_ip6opt_ls(data, op_len);
break;
default:
- GETINT8(op_len, data);
- (void) sprintf(get_line((char *)ipv6ext_dest -
- dlc_header, 1),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Option type = %u, len = %u", op_type, op_len);
- data += op_len;
- len -= (op_len + 2);
- }
- /* check for corrupt length */
- if (olen <= len) {
- (void) sprintf(get_line((char *)ipv6ext_dest -
- dlc_header, 1),
- "Incomplete option len = %u, len = %u", op_type,
- len);
break;
}
}
show_space();
}
+
+#define ALABEL_MAXLEN 256
+
+static char ascii_label[ALABEL_MAXLEN];
+static char *plabel = ascii_label;
+
+struct snoop_pair {
+ int val;
+ const char *name;
+};
+
+static struct snoop_pair ripso_class_tbl[] = {
+ TSOL_CL_TOP_SECRET, "TOP SECRET",
+ TSOL_CL_SECRET, "SECRET",
+ TSOL_CL_CONFIDENTIAL, "CONFIDENTIAL",
+ TSOL_CL_UNCLASSIFIED, "UNCLASSIFIED",
+ -1, NULL
+};
+
+static struct snoop_pair ripso_prot_tbl[] = {
+ TSOL_PA_GENSER, "GENSER",
+ TSOL_PA_SIOP_ESI, "SIOP-ESI",
+ TSOL_PA_SCI, "SCI",
+ TSOL_PA_NSA, "NSA",
+ TSOL_PA_DOE, "DOE",
+ 0x04, "UNASSIGNED",
+ 0x02, "UNASSIGNED",
+ -1, NULL
+};
+
+static struct snoop_pair *
+get_pair_byval(struct snoop_pair pairlist[], int val)
+{
+ int i;
+
+ for (i = 0; pairlist[i].name != NULL; i++)
+ if (pairlist[i].val == val)
+ return (&pairlist[i]);
+ return (NULL);
+}
+
+static void
+print_ripso(const uchar_t *opt)
+{
+ struct snoop_pair *ripso_class;
+ int i, index, prot_len;
+ boolean_t first_prot;
+ char line[100], *ptr;
+
+ prot_len = opt[1] - 3;
+ if (prot_len < 0)
+ return;
+
+ show_header("RIPSO: ", "Revised IP Security Option", 0);
+ show_space();
+
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Type = Basic Security Option (%d), Length = %d", opt[0], opt[1]);
+
+ /*
+ * Display Classification Level
+ */
+ ripso_class = get_pair_byval(ripso_class_tbl, (int)opt[2]);
+ if (ripso_class != NULL)
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Classification = Unknown (0x%02x)", opt[2]);
+ else
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Classification = %s (0x%02x)",
+ ripso_class->name, ripso_class->val);
+
+ /*
+ * Display Protection Authority Flags
+ */
+ (void) snprintf(line, sizeof (line), "Protection Authority = ");
+ ptr = line;
+ first_prot = B_TRUE;
+ for (i = 0; i < prot_len; i++) {
+ index = 0;
+ while (ripso_prot_tbl[index].name != NULL) {
+ if (opt[3 + i] & ripso_prot_tbl[index].val) {
+ ptr = strchr(ptr, 0);
+ if (!first_prot) {
+ (void) strlcpy(ptr, ", ",
+ sizeof (line) - (ptr - line));
+ ptr = strchr(ptr, 0);
+ }
+ (void) snprintf(ptr,
+ sizeof (line) - (ptr - line),
+ "%s (0x%02x)",
+ ripso_prot_tbl[index].name,
+ ripso_prot_tbl[index].val);
+ }
+ index++;
+ }
+ if ((opt[3 + i] & 1) == 0)
+ break;
+ }
+ if (!first_prot)
+ (void) snprintf(get_line(0, 0), get_line_remain(), "%s", line);
+ else
+ (void) snprintf(get_line(0, 0), get_line_remain(), "%sNone",
+ line);
+}
+
+#define CIPSO_GENERIC_ARRAY_LEN 200
+
+/*
+ * Return 1 if CIPSO SL and Categories are all 1's; 0 otherwise.
+ *
+ * Note: opt starts with "Tag Type":
+ *
+ * |tag_type(1)|tag_length(1)|align(1)|sl(1)|categories(variable)|
+ *
+ */
+static boolean_t
+cipso_high(const uchar_t *opt)
+{
+ int i;
+
+ if (((int)opt[1] + 6) < IP_MAX_OPT_LENGTH)
+ return (B_FALSE);
+ for (i = 0; i < ((int)opt[1] - 3); i++)
+ if (opt[3 + i] != 0xff)
+ return (B_FALSE);
+ return (B_TRUE);
+}
+
+/*
+ * Converts CIPSO label to SL.
+ *
+ * Note: opt starts with "Tag Type":
+ *
+ * |tag_type(1)|tag_length(1)|align(1)|sl(1)|categories(variable)|
+ *
+ */
+static void
+cipso2sl(const uchar_t *opt, bslabel_t *sl, int *high)
+{
+ int i, taglen;
+ uchar_t *q = (uchar_t *)&((_bslabel_impl_t *)sl)->compartments;
+
+ *high = 0;
+ taglen = opt[1];
+ memset((caddr_t)sl, 0, sizeof (bslabel_t));
+
+ if (cipso_high(opt)) {
+ BSLHIGH(sl);
+ *high = 1;
+ } else {
+ LCLASS_SET((_bslabel_impl_t *)sl, opt[3]);
+ for (i = 0; i < taglen - TSOL_TT1_MIN_LENGTH; i++)
+ q[i] = opt[TSOL_TT1_MIN_LENGTH + i];
+ }
+ SETBLTYPE(sl, SUN_SL_ID);
+}
+
+static int
+interpret_cipso_tagtype1(const uchar_t *opt)
+{
+ int i, taglen, ishigh;
+ bslabel_t sl;
+ char line[CIPSO_GENERIC_ARRAY_LEN], *ptr;
+
+ taglen = opt[1];
+ if (taglen < TSOL_TT1_MIN_LENGTH ||
+ taglen > TSOL_TT1_MAX_LENGTH)
+ return (taglen);
+
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Tag Type = %d, Tag Length = %d", opt[0], opt[1]);
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Sensitivity Level = 0x%02x", opt[3]);
+ ptr = line;
+ for (i = 0; i < taglen - TSOL_TT1_MIN_LENGTH; i++) {
+ (void) snprintf(ptr, sizeof (line) - (ptr - line), "%02x",
+ opt[TSOL_TT1_MIN_LENGTH + i]);
+ ptr = strchr(ptr, 0);
+ }
+ if (i != 0) {
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Categories = ");
+ (void) snprintf(get_line(0, 0), get_line_remain(), "\t%s",
+ line);
+ } else {
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Categories = None");
+ }
+ cipso2sl(opt, &sl, &ishigh);
+ if (is_system_labeled) {
+ if (bsltos(&sl, &plabel, ALABEL_MAXLEN,
+ LONG_CLASSIFICATION|LONG_WORDS|VIEW_INTERNAL) < 0) {
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "The Sensitivity Level and Categories can't be "
+ "mapped to a valid SL");
+ } else {
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "The Sensitivity Level and Categories are mapped "
+ "to the SL:");
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "\t%s", ascii_label);
+ }
+ }
+ return (taglen);
+}
+
+/*
+ * The following struct definition #define's are copied from TS1.x. They are
+ * not used here (except TTYPE_3_MAX_TOKENS), but included as a reference for
+ * the tag type 3 packet format.
+ */
+#define TTYPE_3_MAX_TOKENS 7
+
+/*
+ * Display CIPSO tag type 3 which is defined by MAXSIX.
+ */
+static int
+interpret_cipso_tagtype3(const uchar_t *opt)
+{
+ uchar_t tagtype;
+ int index, numtokens, taglen;
+ uint16_t mask;
+ uint32_t token;
+ static const char *name[] = {
+ "SL",
+ "NCAV",
+ "INTEG",
+ "SID",
+ "undefined",
+ "undefined",
+ "IL",
+ "PRIVS",
+ "LUID",
+ "PID",
+ "IDS",
+ "ACL"
+ };
+
+ tagtype = *opt++;
+ (void) memcpy(&mask, opt + 3, sizeof (mask));
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Tag Type = %d (MAXSIX)", tagtype);
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Generation = 0x%02x%02x%02x, Mask = 0x%04x", opt[0], opt[1],
+ opt[2], mask);
+ opt += 3 + sizeof (mask);
+
+ /*
+ * Display tokens
+ */
+ numtokens = 0;
+ index = 0;
+ while (mask != 0 && numtokens < TTYPE_3_MAX_TOKENS) {
+ if (mask & 0x0001) {
+ (void) memcpy(&token, opt, sizeof (token));
+ opt += sizeof (token);
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Attribute = %s, Token = 0x%08x",
+ index < sizeof (name) / sizeof (*name) ?
+ name[index] : "unknown", token);
+ numtokens++;
+ }
+ mask = mask >> 1;
+ index++;
+ }
+
+ taglen = 6 + numtokens * 4;
+ return (taglen);
+}
+
+static void
+print_cipso(const uchar_t *opt)
+{
+ int optlen, taglen, tagnum;
+ uint32_t doi;
+ char line[CIPSO_GENERIC_ARRAY_LEN];
+ char *oldnest;
+
+ optlen = opt[1];
+ if (optlen < TSOL_CIPSO_MIN_LENGTH || optlen > TSOL_CIPSO_MAX_LENGTH)
+ return;
+
+ oldnest = prot_nest_prefix;
+ prot_nest_prefix = prot_prefix;
+ show_header("CIPSO: ", "Common IP Security Option", 0);
+ show_space();
+
+ /*
+ * Display CIPSO Header
+ */
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Type = CIPSO (%d), Length = %d", opt[0], opt[1]);
+ (void) memcpy(&doi, opt + 2, sizeof (doi));
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Domain of Interpretation = %u", (unsigned)ntohl(doi));
+
+ if (opt[1] == TSOL_CIPSO_MIN_LENGTH) { /* no tags */
+ show_space();
+ prot_prefix = prot_nest_prefix;
+ prot_nest_prefix = oldnest;
+ return;
+ }
+ optlen -= TSOL_CIPSO_MIN_LENGTH;
+ opt += TSOL_CIPSO_MIN_LENGTH;
+
+ /*
+ * Display Each Tag
+ */
+ tagnum = 1;
+ while (optlen >= TSOL_TT1_MIN_LENGTH) {
+ (void) snprintf(line, sizeof (line), "Tag# %d", tagnum);
+ show_header("CIPSO: ", line, 0);
+ /*
+ * We handle tag type 1 and 3 only. Note, tag type 3
+ * is MAXSIX defined.
+ */
+ switch (opt[0]) {
+ case 1:
+ taglen = interpret_cipso_tagtype1(opt);
+ break;
+ case 3:
+ taglen = interpret_cipso_tagtype3(opt);
+ break;
+ default:
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Unknown Tag Type %d", opt[0]);
+ show_space();
+ prot_prefix = prot_nest_prefix;
+ prot_nest_prefix = oldnest;
+ return;
+ }
+
+ /*
+ * Move to the next tag
+ */
+ if (taglen <= 0)
+ break;
+ optlen -= taglen;
+ opt += taglen;
+ tagnum++;
+ }
+ show_space();
+ prot_prefix = prot_nest_prefix;
+ prot_nest_prefix = oldnest;
+}
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ipaddr.c b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ipaddr.c
index 45061e5..1f7a743 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ipaddr.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ipaddr.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,13 +19,14 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI" /* SunOS */
#include <stdio.h>
+#include <stdlib.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
@@ -40,8 +40,10 @@
#include <string.h>
#include <signal.h>
#include <setjmp.h>
+#include <arpa/inet.h>
+#include "snoop.h"
-sigjmp_buf nisjmp;
+static sigjmp_buf nisjmp;
#define MAXHASH 1024 /* must be a power of 2 */
@@ -70,16 +72,16 @@
struct in6_addr h6_addr;
};
-static struct hostdata *addhost(int, void *, char *, char **);
+static struct hostdata *addhost(int, const void *, const char *, char **);
-struct hostdata4 *h_table4[MAXHASH];
-struct hostdata6 *h_table6[MAXHASH];
+static struct hostdata4 *h_table4[MAXHASH];
+static struct hostdata6 *h_table6[MAXHASH];
#define iphash(e) ((e) & (MAXHASH-1))
+/* ARGSUSED */
static void
-wakeup(n)
- int n;
+wakeup(int n)
{
siglongjmp(nisjmp, 1);
}
@@ -135,7 +137,7 @@
}
static struct hostdata *
-ip6lookup(struct in6_addr *ip6addr)
+ip6lookup(const struct in6_addr *ip6addr)
{
struct hostdata6 *h;
struct hostent *hp = NULL;
@@ -182,9 +184,9 @@
}
static struct hostdata *
-addhost(int family, void *ipaddr, char *name, char **aliases)
+addhost(int family, const void *ipaddr, const char *name, char **aliases)
{
- register struct hostdata **hp, *n = NULL;
+ struct hostdata **hp, *n = NULL;
extern FILE *namefile;
int hashval;
static char aname[128];
@@ -203,7 +205,8 @@
if (n->h_hostname == NULL)
goto alloc_failed;
- ((struct hostdata4 *)n)->h4_addr = *(struct in_addr *)ipaddr;
+ ((struct hostdata4 *)n)->h4_addr =
+ *(const struct in_addr *)ipaddr;
hashval = ((struct in_addr *)ipaddr)->s_addr;
hp = (struct hostdata **)&h_table4[iphash(hashval)];
break;
@@ -219,7 +222,7 @@
memcpy(&((struct hostdata6 *)n)->h6_addr, ipaddr,
sizeof (struct in6_addr));
- hashval = ((int *)ipaddr)[3];
+ hashval = ((const int *)ipaddr)[3];
hp = (struct hostdata **)&h_table6[iphash(hashval)];
break;
default:
@@ -233,7 +236,7 @@
if (namefile != NULL) {
if (family == AF_INET) {
- np = inet_ntoa(*(struct in_addr *)ipaddr);
+ np = inet_ntoa(*(const struct in_addr *)ipaddr);
if (np) {
(void) fprintf(namefile, "%s\t%s", np, name);
if (aliases) {
@@ -280,22 +283,18 @@
}
char *
-addrtoname(family, ipaddr)
- int family;
- void *ipaddr;
+addrtoname(int family, const void *ipaddr)
{
switch (family) {
case AF_INET:
- return (iplookup(*(struct in_addr *)ipaddr)->h_hostname);
+ return (iplookup(*(const struct in_addr *)ipaddr)->h_hostname);
case AF_INET6:
- return (ip6lookup((struct in6_addr *)ipaddr)->h_hostname);
- default:
- fprintf(stderr, "snoop: ERROR: unknown address family: %d\n",
- family);
- exit(1);
+ return (ip6lookup((const struct in6_addr *)ipaddr)->h_hostname);
}
- /* Never reached... */
- return (NULL);
+ (void) fprintf(stderr, "snoop: ERROR: unknown address family: %d\n",
+ family);
+ exit(1);
+ /* NOTREACHED */
}
void
@@ -324,14 +323,15 @@
if (inet_pton(AF_INET6, addr, (void *)&addrv6) == 1) {
family = AF_INET6;
naddr = (void *)&addrv6;
- } else if ((addrv4 = inet_addr(addr)) != -1) {
+ } else if ((addrv4 = inet_addr(addr)) != (ulong_t)-1) {
family = AF_INET;
naddr = (void *)&addrv4;
}
name = strtok(NULL, SEPARATORS);
if (name == NULL)
continue;
- while ((alias = strtok(NULL, SEPARATORS)) && (*alias != '#')) {
+ while ((alias = strtok(NULL, SEPARATORS)) != NULL &&
+ (*alias != '#')) {
(void) addhost(family, naddr, alias, NULL);
}
(void) addhost(family, naddr, name, NULL);
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ipsec.c b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ipsec.c
index a8c248c..76ec01f 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ipsec.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ipsec.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -32,6 +31,7 @@
#include <string.h>
#include <fcntl.h>
#include <string.h>
+#include <strings.h>
#include <sys/types.h>
#include <sys/sysmacros.h>
#include <sys/time.h>
@@ -49,11 +49,11 @@
#include <inet/ipsecah.h>
#include "snoop.h"
-extern char *dlc_header;
-
+/* ARGSUSED */
int
interpret_esp(int flags, uint8_t *hdr, int iplen, int fraglen)
{
+ /* LINTED: alignment */
esph_t *esph = (esph_t *)hdr;
esph_t *aligned_esph;
esph_t storage; /* In case hdr isn't aligned. */
@@ -104,6 +104,7 @@
int
interpret_ah(int flags, uint8_t *hdr, int iplen, int fraglen)
{
+ /* LINTED: alignment */
ah_t *ah = (ah_t *)hdr;
ah_t *aligned_ah;
ah_t storage; /* In case hdr isn't aligned. */
@@ -118,7 +119,7 @@
if (!IS_P2ALIGNED(hdr, 4)) {
aligned_ah = (ah_t *)&storage;
- bcopy(hdr, storage, sizeof (ah_t));
+ bcopy(hdr, &storage, sizeof (ah_t));
} else {
aligned_ah = ah;
}
@@ -197,6 +198,7 @@
if (fraglen > 0)
switch (proto) {
case IPPROTO_ENCAP:
+ /* LINTED: alignment */
(void) interpret_ip(flags, (struct ip *)data,
new_iplen);
break;
@@ -205,27 +207,33 @@
new_iplen);
break;
case IPPROTO_ICMP:
- interpret_icmp(flags, (struct icmp *)data,
- new_iplen, fraglen);
+ (void) interpret_icmp(flags,
+ /* LINTED: alignment */
+ (struct icmp *)data, new_iplen, fraglen);
break;
case IPPROTO_ICMPV6:
- interpret_icmpv6(flags, (icmp6_t *)data,
+ /* LINTED: alignment */
+ (void) interpret_icmpv6(flags, (icmp6_t *)data,
new_iplen, fraglen);
break;
case IPPROTO_TCP:
- interpret_tcp(flags, data, new_iplen, fraglen);
+ (void) interpret_tcp(flags,
+ (struct tcphdr *)data, new_iplen, fraglen);
break;
case IPPROTO_ESP:
- interpret_esp(flags, data, new_iplen, fraglen);
- break;
- case IPPROTO_AH:
- interpret_ah(flags, data, new_iplen, fraglen);
+ (void) interpret_esp(flags, data, new_iplen,
+ fraglen);
break;
+ case IPPROTO_AH:
+ (void) interpret_ah(flags, data, new_iplen,
+ fraglen);
+ break;
case IPPROTO_UDP:
- interpret_udp(flags, data, new_iplen, fraglen);
+ (void) interpret_udp(flags,
+ (struct udphdr *)data, new_iplen, fraglen);
break;
/* default case is to not print anything else */
}
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_rip.c b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_rip.c
index 91ff5be..c8a897c 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_rip.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_rip.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,7 +37,10 @@
#include <protocols/routed.h>
#include "snoop.h"
-static char *show_cmd(int);
+static const char *show_cmd(int);
+static int get_numtokens(unsigned int);
+static const struct rip_sec_entry *rip_next_sec_entry(
+ const struct rip_sec_entry *, int);
int
interpret_rip(int flags, struct rip *rip, int fraglen)
@@ -46,6 +48,9 @@
const struct netinfo *nip;
const struct entryinfo *ep;
const struct netauth *nap;
+ const struct rip_sec_entry *rsep, *rsn;
+ const struct rip_emetric *rep;
+ const uint32_t *tokp;
int len, count;
const char *cmdstr, *auth;
struct in_addr dst;
@@ -68,6 +73,8 @@
case RIPCMD_TRACEOFF: cmdstr = "Traceoff"; break;
case RIPCMD_POLL: cmdstr = "Poll"; break;
case RIPCMD_POLLENTRY: cmdstr = "Poll entry"; break;
+ case RIPCMD_SEC_RESPONSE: cmdstr = "R - SEC"; break;
+ case RIPCMD_SEC_T_RESPONSE: cmdstr = "R - SEC_T"; break;
default: cmdstr = "?"; break;
}
@@ -108,6 +115,26 @@
len = 0;
break;
+ case RIPCMD_SEC_RESPONSE:
+ case RIPCMD_SEC_T_RESPONSE:
+ if (len < sizeof (rip->rip_tsol.rip_generation))
+ break;
+ len -= sizeof (rip->rip_tsol.rip_generation);
+ count = 0;
+ rsep = rip->rip_tsol.rip_sec_entry;
+ while (len > 0) {
+ rsn = rip_next_sec_entry(rsep, len);
+ if (rsn == NULL)
+ break;
+ len -= (const char *)rsn - (const char *)rsep;
+ rsep = rsn;
+ count++;
+ }
+ (void) snprintf(get_sum_line(), MAXLINE,
+ "%s %s (%d destinations%s)", ripvers, cmdstr,
+ count, (len != 0 ? "?" : ""));
+ break;
+
default:
(void) snprintf(get_sum_line(), MAXLINE,
"%s %d (%s)", ripvers, rip->rip_cmd, cmdstr);
@@ -121,12 +148,11 @@
len = fraglen - 4;
show_header("RIP: ", "Routing Information Protocol", fraglen);
show_space();
- (void) snprintf(get_line((char *)(uintptr_t)rip->rip_cmd -
- dlc_header, 1), get_line_remain(), "Opcode = %d (%s)",
- rip->rip_cmd, show_cmd(rip->rip_cmd));
- (void) snprintf(get_line((char *)(uintptr_t)rip->rip_vers -
- dlc_header, 1), get_line_remain(), "Version = %d",
- rip->rip_vers);
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Opcode = %d (%s)", rip->rip_cmd,
+ show_cmd(rip->rip_cmd));
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Version = %d", rip->rip_vers);
switch (rip->rip_cmd) {
case RIPCMD_REQUEST:
@@ -156,9 +182,7 @@
nap->au.au_pw);
} else if (nap->a_type ==
RIP_AUTH_MD5) {
- (void) snprintf(get_line
- ((char *)nip - dlc_header,
- sizeof (*nip)),
+ (void) snprintf(get_line(0, 0),
get_line_remain(),
" *** Auth MD5 pkt len %d, "
"keyid %d, sequence %08lX, "
@@ -166,7 +190,7 @@
ntohs(nap->au.a_md5.
md5_pkt_len),
nap->au.a_md5.md5_keyid,
- ntohl(nap->au.a_md5.
+ (long)ntohl(nap->au.a_md5.
md5_seqno),
ntohs(nap->au.a_md5.
md5_auth_len));
@@ -189,15 +213,13 @@
}
if (nip->n_family == RIP_AF_UNSPEC &&
rip->rip_cmd == RIPCMD_REQUEST) {
- (void) snprintf(get_line((char *)nip -
- dlc_header, sizeof (*nip)),
+ (void) snprintf(get_line(0, 0),
get_line_remain(),
" *** All routes");
continue;
}
if (nip->n_family != RIP_AF_INET) {
- (void) snprintf(get_line((char *)nip -
- dlc_header, sizeof (*nip)),
+ (void) snprintf(get_line(0, 0),
get_line_remain(),
" *** Address Family %d?",
ntohs(nip->n_family));
@@ -231,8 +253,7 @@
}
dst.s_addr = nip->n_nhop;
mval = ntohl(nip->n_metric);
- (void) snprintf(get_line((char *)nip -
- dlc_header, sizeof (*nip)),
+ (void) snprintf(get_line(0, 0),
get_line_remain(),
"%-31s %-15s %-6d %d%s",
addrstr,
@@ -252,44 +273,105 @@
ep = (const struct entryinfo *)rip->rip_nets;
/* LINTED */
sin = (const struct sockaddr_in *)&ep->rtu_dst;
- (void) snprintf(get_line((char *)sin - dlc_header,
- sizeof (struct sockaddr)), get_line_remain(),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Destination = %s %s",
inet_ntoa(sin->sin_addr),
addrtoname(AF_INET, (void *)&sin->sin_addr));
/* LINTED */
sin = (const struct sockaddr_in *)&ep->rtu_router;
- (void) snprintf(get_line((char *)sin - dlc_header,
- sizeof (struct sockaddr)), get_line_remain(),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Router = %s %s",
inet_ntoa(sin->sin_addr),
addrtoname(AF_INET, (void *)&sin->sin_addr));
- (void) snprintf(get_line((char *)&ep->rtu_flags -
- dlc_header, 2), get_line_remain(),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Flags = %4x", (unsigned)ep->rtu_flags);
- (void) snprintf(get_line((char *)&ep->rtu_state -
- dlc_header, 2), get_line_remain(),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"State = %d", ep->rtu_state);
- (void) snprintf(get_line((char *)&ep->rtu_timer -
- dlc_header, 4), get_line_remain(),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Timer = %d", ep->rtu_timer);
- (void) snprintf(get_line((char *)&ep->rtu_metric -
- dlc_header, 4), get_line_remain(),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Metric = %d", ep->rtu_metric);
- (void) snprintf(get_line((char *)&ep->int_flags -
- dlc_header, 4), get_line_remain(),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Int flags = %8x", ep->int_flags);
- (void) snprintf(get_line((char *)ep->int_name -
- dlc_header, sizeof (ep->int_name)),
- get_line_remain(),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Int name = \"%.*s\"", sizeof (ep->int_name),
ep->int_name);
break;
+ case RIPCMD_SEC_RESPONSE:
+ case RIPCMD_SEC_T_RESPONSE:
+ if (len < sizeof (rip->rip_tsol.rip_generation))
+ break;
+ len -= sizeof (rip->rip_tsol.rip_generation);
+ show_space();
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Generation = %u",
+ (unsigned)ntohl(rip->rip_tsol.rip_generation));
+ rsep = rip->rip_tsol.rip_sec_entry;
+ (void) snprintf(get_line(0, 0), get_line_remain(),
+ "Address E-METRIC");
+ rsep = rip->rip_tsol.rip_sec_entry;
+ while (len > 0) {
+ char *cp;
+ int blen, num;
+
+ rsn = rip_next_sec_entry(rsep, len);
+ if (rsn == NULL)
+ break;
+ dst.s_addr = rsep->rip_dst;
+ cp = get_line(0, 0);
+ blen = get_line_remain();
+ (void) snprintf(cp, blen, "%-16s ",
+ inet_ntoa(dst));
+ cp += 17;
+ blen -= 17;
+ rep = rsep->rip_emetric;
+ for (count = ntohl(rsep->rip_count); count > 0;
+ count--) {
+ (void) snprintf(cp, blen, "metric=%d",
+ ntohs(rep->rip_metric));
+ blen -= strlen(cp);
+ cp += strlen(cp);
+ tokp = rep->rip_token;
+ num = get_numtokens(
+ ntohs(rep->rip_mask));
+ /* advance to the next emetric */
+ rep = (const struct rip_emetric *)
+ &rep->rip_token[num];
+ if (num > 0) {
+ (void) snprintf(cp, blen,
+ ",tokens=%lx",
+ (long)ntohl(*tokp));
+ tokp++;
+ num--;
+ } else {
+ (void) strlcpy(cp, ",no tokens",
+ blen);
+ }
+ while (num > 0) {
+ blen -= strlen(cp);
+ cp += strlen(cp);
+ (void) snprintf(cp, blen,
+ ",%lx",
+ (long)ntohl(*tokp));
+ tokp++;
+ num--;
+ }
+ blen -= strlen(cp);
+ cp += strlen(cp);
+ }
+ if (rsep->rip_count == 0) {
+ (void) strlcpy(cp,
+ "NULL (not reachable)", blen);
+ }
+ len -= (const char *)rsn - (const char *)rsep;
+ rsep = rsn;
+ }
+ break;
+
case RIPCMD_TRACEON:
case RIPCMD_TRACEOFF:
- (void) snprintf(get_line((char *)rip->rip_tracefile -
- dlc_header, 2), get_line_remain(),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"Trace file = %.*s", len, rip->rip_tracefile);
len = 0;
break;
@@ -299,7 +381,7 @@
return (fraglen - len);
}
-static char *
+static const char *
show_cmd(int c)
{
switch (c) {
@@ -315,6 +397,44 @@
return ("route poll");
case RIPCMD_POLLENTRY:
return ("route poll entry");
+ case RIPCMD_SEC_RESPONSE:
+ return ("route sec response");
+ case RIPCMD_SEC_T_RESPONSE:
+ return ("route sec_t response");
}
return ("?");
}
+
+static int
+get_numtokens(unsigned int mask)
+{
+ int num = 0;
+
+ while (mask != 0) {
+ num++;
+ mask &= mask - 1;
+ }
+ return (num);
+}
+
+static const struct rip_sec_entry *
+rip_next_sec_entry(const struct rip_sec_entry *rsep, int len)
+{
+ const struct rip_emetric *rep;
+ const char *limit = (const char *)rsep + len;
+ long count;
+
+ if ((const char *)(rep = rsep->rip_emetric) > limit)
+ return (NULL);
+ count = ntohl(rsep->rip_count);
+ while (count > 0) {
+ if ((const char *)rep->rip_token > limit)
+ return (NULL);
+ rep = (struct rip_emetric *)
+ &rep->rip_token[get_numtokens(ntohs(rep->rip_mask))];
+ if ((const char *)rep > limit)
+ return (NULL);
+ count--;
+ }
+ return ((const struct rip_sec_entry *)rep);
+}
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_rport.c b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_rport.c
index 8a65afd..9722ee2 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_rport.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_rport.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,14 +19,17 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI" /* SunOS */
+#include <stdio.h>
+#include <stdlib.h>
#include <ctype.h>
+#include <strings.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <sys/errno.h>
@@ -40,114 +42,106 @@
#include <netinet/if_ether.h>
#include "snoop.h"
-#define NULL 0
-
-extern void interpret_mip_cntrlmsg(int, uchar_t *, int);
-
struct porttable {
int pt_num;
char *pt_short;
- char *pt_long;
};
-struct porttable pt_udp[] = {
- 7, "ECHO", "Echo",
- 9, "DISCARD", "Discard",
- 13, "DAYTIME", "Daytime",
- 19, "CHARGEN", "Character generator",
- 37, "TIME", "Time",
- 42, "NAME", "Host name server",
- 53, "DNS", "Domain Name Server",
- 67, "BOOTPS", "Bootstrap Protocol Server",
- 68, "BOOTPC", "Boostrap Protocol Client",
- 69, "TFTP", "Trivial File Transfer Protocol",
- 79, "FINGER", "Finger",
-/* 111, "PORTMAP", "Portmapper", Just Sun RPC */
- 123, "NTP", "Network Time Protocol",
- 137, "NBNS", "Netbios name service",
- 138, "NBDG", "Netbios datagram service",
- 389, "LDAP", "Lightweight Directory Access Protocol",
- 427, "SLP", "Service Location Protocol",
+static const struct porttable pt_udp[] = {
+ { IPPORT_ECHO, "ECHO" },
+ { IPPORT_DISCARD, "DISCARD" },
+ { IPPORT_DAYTIME, "DAYTIME" },
+ { 19, "CHARGEN" },
+ { IPPORT_TIMESERVER, "TIME" },
+ { IPPORT_NAMESERVER, "NAME" },
+ { 53, "DNS" },
+ { IPPORT_BOOTPS, "BOOTPS" },
+ { IPPORT_BOOTPC, "BOOTPC" },
+ { IPPORT_TFTP, "TFTP" },
+ { IPPORT_FINGER, "FINGER" },
+/* { 111, "PORTMAP" }, Just Sun RPC */
+ { 123, "NTP" },
+ { 137, "NBNS" },
+ { 138, "NBDG" },
+ { 389, "LDAP" },
+ { 427, "SLP" },
/* Mobile IP defines a set of new control messages sent over UDP port 434 */
- 434, "Mobile IP", "Mobile IP Control Messages",
- 512, "BIFF", "BIFF",
- 513, "WHO", "WHO",
- 514, "SYSLOG", "SYSLOG",
- 517, "TALK", "TALK",
- 520, "RIP", "Routing Information Protocol",
- 550, "NEW-RWHO", "NEW-RWHO",
- 560, "RMONITOR", "RMONITOR",
- 561, "MONITOR", "MONITOR",
- 521, "RIPng", "Routing Information Protocol for IPv6",
- 1080, "SOCKS", "SOCKS Gateway",
- 0, NULL, "",
+ { 434, "Mobile IP" },
+ { IPPORT_BIFFUDP, "BIFF" },
+ { IPPORT_WHOSERVER, "WHO" },
+ { 514, "SYSLOG" },
+ { 517, "TALK" },
+ { IPPORT_ROUTESERVER, "RIP" },
+ { 521, "RIPng" },
+ { 550, "NEW-RWHO" },
+ { 560, "RMONITOR" },
+ { 561, "MONITOR" },
+ { 1080, "SOCKS" },
+ { 0, NULL }
};
-struct porttable pt_tcp[] = {
- 1, "TCPMUX", "TCPMUX",
- 7, "ECHO", "Echo",
- 9, "DISCARD", "Discard",
- 11, "SYSTAT", "Active users",
- 13, "DAYTIME", "Daytime",
- 15, "NETSTAT", "Who is up",
- 19, "CHARGEN", "Character generator",
- 20, "FTP-DATA", "File Transfer Protocol (data)",
- 21, "FTP", "File Transfer Protocol",
- 23, "TELNET", "Terminal connection",
- 25, "SMTP", "Simple Mail Transport Protocol",
- 37, "TIME", "Time",
- 39, "RLP", "Resource Location Protocol",
- 42, "NAMESERVER", "Host Name Server",
- 43, "NICNAME", "Who is",
- 53, "DNS", "Domain Name Server",
- 67, "BOOTPS", "Bootstrap Protocol Server",
- 68, "BOOTPC", "Bootstrap Protocol Client",
- 69, "TFTP", "Trivial File Transfer Protocol",
- 70, "GOPHER", "Internet Gopher Protocol",
- 77, "RJE", "RJE service (private)",
- 79, "FINGER", "Finger",
- 80, "HTTP", "HyperText Transfer Protocol",
- 87, "LINK", "Link",
- 95, "SUPDUP", "SUPDUP Protocol",
- 101, "HOSTNAME", "NIC Host Name Server",
- 102, "ISO-TSAP", "ISO-TSAP",
- 103, "X400", "X400 Mail service",
- 104, "X400-SND", "X400 Mail service",
- 105, "CSNET-NS", "CSNET-NS",
- 109, "POP-2", "POP-2",
-/* 111, "PORTMAP", "Portmapper", Just Sun RPC */
- 113, "AUTH", "Authentication Service",
- 117, "UUCP-PATH", "UUCP Path Service",
- 119, "NNTP", "Network News Transfer Protocol",
- 123, "NTP", "Network Time Protocol",
- 139, "NBT", "Netbios over TCP",
- 143, "IMAP", "Internet Message Access Protocol",
- 144, "NeWS", "Network extensible Window System",
- 389, "LDAP", "Lightweight Directory Access Protocol",
- 427, "SLP", "Service Location Protocol",
- 443, "HTTPS", "HTTP over SSL",
- 445, "SMB", "Direct Hosted Server Message Block",
- 512, "EXEC", "EXEC",
- 513, "RLOGIN", "RLOGIN",
- 514, "RSHELL", "RSHELL",
- 515, "PRINTER", "PRINTER",
- 530, "COURIER", "COURIER",
- 540, "UUCP", "UUCP",
- 600, "PCSERVER", "PCSERVER",
- 1524, "INGRESLOCK", "INGRESLOCK",
- 1080, "SOCKS", "SOCKS Gateway",
- 2904, "M2UA", "SS7 MTP2 User Adaption Layer",
- 2905, "M3UA", "SS7 MTP3 User Adaption Layer",
- 6000, "XWIN", "X Window System",
- 8080, "HTTP (proxy)", "HyperText Transfer Protocol (proxy)",
- 9900, "IUA", "ISDN Q.921 User Adaption Layer",
- 0, NULL, "",
+static struct porttable pt_tcp[] = {
+ { 1, "TCPMUX" },
+ { IPPORT_ECHO, "ECHO" },
+ { IPPORT_DISCARD, "DISCARD" },
+ { IPPORT_SYSTAT, "SYSTAT" },
+ { IPPORT_DAYTIME, "DAYTIME" },
+ { IPPORT_NETSTAT, "NETSTAT" },
+ { 19, "CHARGEN" },
+ { 20, "FTP-DATA" },
+ { IPPORT_FTP, "FTP" },
+ { IPPORT_TELNET, "TELNET" },
+ { IPPORT_SMTP, "SMTP" },
+ { IPPORT_TIMESERVER, "TIME" },
+ { 39, "RLP" },
+ { IPPORT_NAMESERVER, "NAMESERVER" },
+ { IPPORT_WHOIS, "NICNAME" },
+ { 53, "DNS" },
+ { 70, "GOPHER" },
+ { IPPORT_RJE, "RJE" },
+ { IPPORT_FINGER, "FINGER" },
+ { 80, "HTTP" },
+ { IPPORT_TTYLINK, "LINK" },
+ { IPPORT_SUPDUP, "SUPDUP" },
+ { 101, "HOSTNAME" },
+ { 102, "ISO-TSAP" },
+ { 103, "X400" },
+ { 104, "X400-SND" },
+ { 105, "CSNET-NS" },
+ { 109, "POP-2" },
+/* { 111, "PORTMAP" }, Just Sun RPC */
+ { 113, "AUTH" },
+ { 117, "UUCP-PATH" },
+ { 119, "NNTP" },
+ { 123, "NTP" },
+ { 139, "NBT" },
+ { 143, "IMAP" },
+ { 144, "NeWS" },
+ { 389, "LDAP" },
+ { 427, "SLP" },
+ { 443, "HTTPS" },
+ { 445, "SMB" },
+ { IPPORT_EXECSERVER, "EXEC" },
+ { IPPORT_LOGINSERVER, "RLOGIN" },
+ { IPPORT_CMDSERVER, "RSHELL" },
+ { 515, "PRINTER" },
+ { 530, "COURIER" },
+ { 540, "UUCP" },
+ { 600, "PCSERVER" },
+ { 1080, "SOCKS" },
+ { 1524, "INGRESLOCK" },
+ { 2904, "M2UA" },
+ { 2905, "M3UA" },
+ { 6000, "XWIN" },
+ { 8080, "HTTP (proxy)" },
+ { 9900, "IUA" },
+ { 0, NULL },
};
char *
getportname(int proto, in_port_t port)
{
- struct porttable *p, *pt;
+ const struct porttable *p, *pt;
switch (proto) {
case IPPROTO_SCTP: /* fallthru */
@@ -166,7 +160,7 @@
int
reservedport(int proto, int port)
{
- struct porttable *p, *pt;
+ const struct porttable *p, *pt;
switch (proto) {
case IPPROTO_TCP: pt = pt_tcp; break;
@@ -186,13 +180,13 @@
* See TFTP interpreter.
*/
#define MAXTRANS 64
-struct ttable {
+static struct ttable {
int t_port;
- int (*t_proc)();
+ int (*t_proc)(int, char *, int);
} transients [MAXTRANS];
int
-add_transient(int port, int (*proc)())
+add_transient(int port, int (*proc)(int, char *, int))
{
static struct ttable *next = transients;
@@ -266,7 +260,7 @@
data++;
datalen--;
- strlcpy(buffer, data, sizeof (buffer));
+ (void) strlcpy(buffer, data, sizeof (buffer));
composit = strtoul(buffer, &end, 0);
data += end - buffer;
if (*data == '>') {
@@ -306,11 +300,11 @@
static char syslog[] = "SYSLOG: ";
show_header(syslog, syslog, dlen);
show_space();
- (void) sprintf(get_detail_line(0, 80),
+ (void) snprintf(get_detail_line(0, 0), MAXLINE,
"%s%sPriority: %.*s%s(%s.%s)", prot_nest_prefix, syslog,
priostrlen, syslogstr, bogus ? "" : " ",
facilstr, pristr);
- (void) sprintf(get_line(0, 0),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"\"%s\"",
show_string(syslogstr, dlen, 60));
show_trailer();
@@ -323,7 +317,7 @@
interpret_reserved(int flags, int proto, in_port_t src, in_port_t dst,
char *data, int dlen)
{
- char *pn;
+ const char *pn;
int dir, port, which;
char pbuff[16], hbuff[32];
struct ttable *ttabp;
@@ -373,25 +367,29 @@
if (dlen > 0) {
switch (which) {
- case 67:
- case 68:
- interpret_dhcp(flags, data, dlen);
+ case IPPORT_BOOTPS:
+ case IPPORT_BOOTPC:
+ (void) interpret_dhcp(flags, (struct dhcp *)data,
+ dlen);
return (1);
- case 69:
- interpret_tftp(flags, data, dlen);
+ case IPPORT_TFTP:
+ (void) interpret_tftp(flags, (struct tftphdr *)data,
+ dlen);
return (1);
case 80:
case 8080:
- interpret_http(flags, data, dlen);
+ (void) interpret_http(flags, data, dlen);
return (1);
case 123:
- interpret_ntp(flags, data, dlen);
+ (void) interpret_ntp(flags, (struct ntpdata *)data,
+ dlen);
return (1);
case 137:
- interpret_netbios_ns(flags, data, dlen);
+ interpret_netbios_ns(flags, (uchar_t *)data, dlen);
return (1);
case 138:
- interpret_netbios_datagram(flags, data, dlen);
+ interpret_netbios_datagram(flags, (uchar_t *)data,
+ dlen);
return (1);
case 139:
case 445:
@@ -400,7 +398,7 @@
* on port 139. The same interpreter can be used
* for both.
*/
- interpret_netbios_ses(flags, data, dlen);
+ interpret_netbios_ses(flags, (uchar_t *)data, dlen);
return (1);
case 389:
interpret_ldap(flags, data, dlen, src, dst);
@@ -411,34 +409,36 @@
case 434:
interpret_mip_cntrlmsg(flags, (uchar_t *)data, dlen);
return (1);
- case 520:
- interpret_rip(flags, data, dlen);
+ case IPPORT_ROUTESERVER:
+ (void) interpret_rip(flags, (struct rip *)data, dlen);
return (1);
case 521:
- interpret_rip6(flags, data, dlen);
+ (void) interpret_rip6(flags, (struct rip6 *)data,
+ dlen);
return (1);
case 1080:
if (dir == 'C')
- interpret_socks_call(flags, data, dlen);
+ (void) interpret_socks_call(flags, data, dlen);
else
- interpret_socks_reply(flags, data, dlen);
+ (void) interpret_socks_reply(flags, data,
+ dlen);
return (1);
}
}
if (flags & F_SUM) {
- (void) sprintf(get_sum_line(),
+ (void) snprintf(get_sum_line(), MAXLINE,
"%s %c port=%d %s",
pn, dir, port,
show_string(data, dlen, 20));
}
if (flags & F_DTAIL) {
- (void) sprintf(pbuff, "%s: ", pn);
- (void) sprintf(hbuff, "%s: ", pn);
+ (void) snprintf(pbuff, sizeof (pbuff), "%s: ", pn);
+ (void) snprintf(hbuff, sizeof (hbuff), "%s: ", pn);
show_header(pbuff, hbuff, dlen);
show_space();
- (void) sprintf(get_line(0, 0),
+ (void) snprintf(get_line(0, 0), get_line_remain(),
"\"%s\"",
show_string(data, dlen, 60));
show_trailer();
@@ -479,7 +479,7 @@
*pp++ = c;
printable++;
} else {
- (void) sprintf(pp,
+ (void) snprintf(pp, TBSIZE - (pp - tbuff),
isdigit(*(p + 1)) ?
"\\%03o" : "\\%o", c);
pp += strlen(pp);
diff --git a/usr/src/cmd/devfsadm/Makefile.com b/usr/src/cmd/devfsadm/Makefile.com
index a07e703..247e1cb 100644
--- a/usr/src/cmd/devfsadm/Makefile.com
+++ b/usr/src/cmd/devfsadm/Makefile.com
@@ -32,12 +32,15 @@
DEVFSADM_MOD = devfsadm
+DEVALLOCSRC = devalloc.c
+
PLCYSRC = devpolicy.c plcysubr.c
MODLOADDIR = $(COMMON)/../modload
-DEVFSADM_SRC = $(COMMON)/$(DEVFSADM_MOD:%=%.c) $(PLCYSRC:%=$(COMMON)/%)
-DEVFSADM_OBJ = $(DEVFSADM_MOD:%=%.o) $(PLCYSRC:%.c=%.o)
+DEVFSADM_SRC = $(COMMON)/$(DEVFSADM_MOD:%=%.c) \
+ $(DEVALLOCSRC:%=$(COMMON)/%) $(PLCYSRC:%=$(COMMON)/%)
+DEVFSADM_OBJ = $(DEVFSADM_MOD:%=%.o) $(DEVALLOCSRC:%.c=%.o) $(PLCYSRC:%.c=%.o)
DEVFSADM_DAEMON = devfsadmd
@@ -118,9 +121,9 @@
LINTFLAGS += -erroff=E_NAME_DEF_NOT_USED2
LINTFLAGS += -erroff=E_NAME_MULTIPLY_DEF2
-LAZYLIBS = -z lazyload -lzonecfg -z nolazyload
-lint := LAZYLIBS = -lzonecfg
-LDLIBS += -ldevinfo -lgen -lsysevent -lnvpair -lcmd $(LAZYLIBS)
+LAZYLIBS = $(ZLAZYLOAD) -lzonecfg -lbsm $(ZNOLAZYLOAD)
+lint := LAZYLIBS = -lzonecfg -lbsm
+LDLIBS += -ldevinfo -lgen -lsysevent -lnvpair -lcmd -ldoor $(LAZYLIBS) -lnsl
SRCS = $(DEVFSADM_SRC) $(LINK_SRCS)
OBJS = $(DEVFSADM_OBJ) $(LINK_OBJS)
diff --git a/usr/src/cmd/devfsadm/audio_link.c b/usr/src/cmd/devfsadm/audio_link.c
index 2f898e3..75568ff 100644
--- a/usr/src/cmd/devfsadm/audio_link.c
+++ b/usr/src/cmd/devfsadm/audio_link.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -32,10 +31,13 @@
#include <stdlib.h>
#include <limits.h>
#include <stdio.h>
+#include <bsm/devalloc.h>
#define MAX_AUDIO_LINK 100
#define RE_SIZE 64
+extern int system_labeled;
+
static void check_audio_link(char *secondary_link,
const char *primary_link_format);
static int audio_process(di_minor_t minor, di_node_t node);
@@ -117,6 +119,7 @@
static int
audio_process(di_minor_t minor, di_node_t node)
{
+ int flags = 0;
char path[PATH_MAX + 1];
char *buf;
char *mn;
@@ -209,7 +212,10 @@
return (DEVFSADM_CONTINUE);
}
- (void) devfsadm_mklink(path, node, minor, 0);
+ if (system_labeled)
+ flags = DA_ADD|DA_AUDIO;
+
+ (void) devfsadm_mklink(path, node, minor, flags);
return (DEVFSADM_CONTINUE);
}
@@ -219,17 +225,21 @@
{
char primary_link[PATH_MAX + 1];
int i;
+ int flags = 0;
/* if link is present, return */
if (devfsadm_link_valid(secondary_link) == DEVFSADM_TRUE) {
return;
}
+ if (system_labeled)
+ flags = DA_ADD|DA_AUDIO;
+
for (i = 0; i < MAX_AUDIO_LINK; i++) {
(void) sprintf(primary_link, primary_link_format, i);
if (devfsadm_link_valid(primary_link) == DEVFSADM_TRUE) {
(void) devfsadm_secondary_link(secondary_link,
- primary_link, 0);
+ primary_link, flags);
break;
}
}
diff --git a/usr/src/cmd/devfsadm/devalloc.c b/usr/src/cmd/devfsadm/devalloc.c
new file mode 100644
index 0000000..413d617
--- /dev/null
+++ b/usr/src/cmd/devfsadm/devalloc.c
@@ -0,0 +1,253 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Device allocation related work.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/dkio.h>
+#include <sys/wait.h>
+#include <bsm/devalloc.h>
+
+#define DEALLOCATE "/usr/sbin/deallocate"
+#define MKDEVALLOC "/usr/sbin/mkdevalloc"
+
+static void _update_dev(deventry_t *, int, char *);
+static int _make_db();
+
+
+/*
+ * _da_check_for_usb
+ * returns 1 if device pointed by 'link' is a removable hotplugged
+ * else returns 0.
+ */
+int
+_da_check_for_usb(char *link, char *root_dir)
+{
+ int fd = -1;
+ int len, dstsize;
+ int removable = 0;
+ char *p = NULL;
+ char path[MAXPATHLEN];
+
+ dstsize = sizeof (path);
+ if (strcmp(root_dir, "") != 0) {
+ if (strlcat(path, root_dir, dstsize) >= dstsize)
+ return (0);
+ len = strlen(path);
+ } else {
+ len = 0;
+ }
+ if (strstr(link, "rdsk")) {
+ (void) snprintf(path, dstsize - len, "%s", link);
+ } else if (strstr(link, "dsk")) {
+ p = rindex(link, '/');
+ if (p == NULL)
+ return (0);
+ p++;
+ (void) snprintf(path, dstsize - len, "%s%s", "/dev/rdsk/", p);
+ } else {
+ return (0);
+ }
+
+ if ((fd = open(path, O_RDONLY | O_NONBLOCK)) < 0)
+ return (0);
+ (void) ioctl(fd, DKIOCREMOVABLE, &removable);
+ (void) close(fd);
+
+ return (removable);
+}
+
+/*
+ * _reset_devalloc
+ * If device allocation is being turned on, creates device_allocate
+ * device_maps if they do not exist.
+ * Puts DEVICE_ALLOCATION=ON/OFF in device_allocate to indicate if
+ * device allocation is on/off.
+ */
+void
+_reset_devalloc(int action)
+{
+ da_args dargs;
+
+ if (action == DA_ON)
+ (void) _make_db();
+ else if ((action == DA_OFF) && (open(DEVALLOC, O_RDONLY) == -1))
+ return;
+
+ if (action == DA_ON)
+ dargs.optflag = DA_ON;
+ else if (action == DA_OFF)
+ dargs.optflag = DA_OFF | DA_ALLOC_ONLY;
+
+ dargs.rootdir = NULL;
+ dargs.devnames = NULL;
+ dargs.devinfo = NULL;
+
+ (void) da_update_device(&dargs);
+}
+
+/*
+ * _make_db
+ * execs /usr/sbin/mkdevalloc to create device_allocate and
+ * device_maps.
+ */
+static int
+_make_db()
+{
+ int status;
+ pid_t pid, wpid;
+
+ pid = vfork();
+ switch (pid) {
+ case -1:
+ return (1);
+ case 0:
+ if (execl(MKDEVALLOC, MKDEVALLOC, DA_IS_LABELED, NULL) == -1)
+ exit((errno == ENOENT) ? 0 : 1);
+ default:
+ for (;;) {
+ wpid = waitpid(pid, &status, 0);
+ if (wpid == (pid_t)-1) {
+ if (errno == EINTR)
+ continue;
+ else
+ return (1);
+ } else {
+ break;
+ }
+ }
+ break;
+ }
+
+ return ((WIFEXITED(status) == 0) ? 1 : WEXITSTATUS(status));
+}
+
+
+/*
+ * _update_devalloc_db
+ * Forms allocatable device entries to be written to device_allocate and
+ * device_maps.
+ */
+/* ARGSUSED */
+void
+_update_devalloc_db(devlist_t *devlist, int devflag, int action, char *devname,
+ char *root_dir)
+{
+ int i;
+ deventry_t *entry = NULL, *dentry = NULL;
+
+ if (action == DA_ADD) {
+ for (i = 0; i < DA_COUNT; i++) {
+ switch (i) {
+ case 0:
+ dentry = devlist->audio;
+ break;
+ case 1:
+ dentry = devlist->cd;
+ break;
+ case 2:
+ dentry = devlist->floppy;
+ break;
+ case 3:
+ dentry = devlist->tape;
+ break;
+ case 4:
+ dentry = devlist->rmdisk;
+ break;
+ default:
+ return;
+ }
+ if (dentry)
+ _update_dev(dentry, action, NULL);
+ }
+ } else if (action == DA_REMOVE) {
+ if (devflag & DA_AUDIO)
+ dentry = devlist->audio;
+ else if (devflag & DA_CD)
+ dentry = devlist->cd;
+ else if (devflag & DA_FLOPPY)
+ dentry = devlist->floppy;
+ else if (devflag & DA_TAPE)
+ dentry = devlist->tape;
+ else if (devflag & DA_RMDISK)
+ dentry = devlist->rmdisk;
+ else
+ return;
+
+ for (entry = dentry; entry != NULL; entry = entry->next) {
+ if (strcmp(entry->devinfo.devname, devname) == 0)
+ break;
+ }
+ _update_dev(entry, action, devname);
+ }
+}
+
+static void
+_update_dev(deventry_t *dentry, int action, char *devname)
+{
+ da_args dargs;
+ deventry_t newentry, *entry;
+
+ dargs.rootdir = NULL;
+ dargs.devnames = NULL;
+
+ if (action == DA_ADD) {
+ dargs.optflag = DA_ADD | DA_FORCE;
+ for (entry = dentry; entry != NULL; entry = entry->next) {
+ dargs.devinfo = &(entry->devinfo);
+ (void) da_update_device(&dargs);
+ }
+ } else if (action == DA_REMOVE) {
+ dargs.optflag = DA_REMOVE;
+ if (dentry) {
+ entry = dentry;
+ } else {
+ newentry.devinfo.devname = strdup(devname);
+ newentry.devinfo.devtype =
+ newentry.devinfo.devauths =
+ newentry.devinfo.devexec =
+ newentry.devinfo.devopts =
+ newentry.devinfo.devlist = NULL;
+ newentry.devinfo.instance = 0;
+ newentry.next = NULL;
+ entry = &newentry;
+ }
+ dargs.devinfo = &(entry->devinfo);
+ (void) da_update_device(&dargs);
+ }
+}
diff --git a/usr/src/cmd/devfsadm/devfsadm.c b/usr/src/cmd/devfsadm/devfsadm.c
index 75ed42f..c390479 100644
--- a/usr/src/cmd/devfsadm/devfsadm.c
+++ b/usr/src/cmd/devfsadm/devfsadm.c
@@ -36,10 +36,18 @@
* reconfiguration for hotplugging support.
*/
-#include "devfsadm_impl.h"
+#include <string.h>
+#include <tsol/label.h>
+#include <bsm/devices.h>
+#include <bsm/devalloc.h>
#include <utime.h>
+#include "devfsadm_impl.h"
-/* globals */
+/* externs from devalloc.c */
+
+extern void _reset_devalloc(int);
+extern void _update_devalloc_db(devlist_t *, int, int, char *, char *);
+extern int _da_check_for_usb(char *, char *);
/* create or remove nodes or links. unset with -n */
static int file_mods = TRUE;
@@ -50,12 +58,26 @@
/* devlinks -d compatibility */
static int devlinks_debug = FALSE;
-/* turn off device allocation with devfsadm -d */
-static int devalloc_off = FALSE;
+/* flag to check if system is labeled */
+int system_labeled = FALSE;
-/* devices to be deallocated with -d */
-static char *devalloc[5] =
- {DDI_NT_AUDIO, DDI_NT_CD, DDI_NT_FD, DDI_NT_TAPE, NULL};
+/* flag to enable/disable device allocation with -e/-d */
+static int devalloc_flag = 0;
+
+/* flag to update device allocation database for this device type */
+static int update_devdb = 0;
+
+/*
+ * devices to be deallocated with -d :
+ * audio, floppy, cd, floppy, tape, rmdisk.
+ */
+static char *devalloc_list[10] = {DDI_NT_AUDIO, DDI_NT_CD, DDI_NT_CD_CHAN,
+ DDI_NT_FD, DDI_NT_TAPE, DDI_NT_BLOCK_CHAN,
+ DDI_NT_UGEN, DDI_NT_USB_ATTACHMENT_POINT,
+ DDI_NT_SCSI_NEXUS, NULL};
+
+/* list of allocatable devices */
+static devlist_t devlist;
/* load a single driver only. set with -i */
static int single_drv = FALSE;
@@ -210,6 +232,7 @@
int
main(int argc, char *argv[])
{
+ struct stat tx_stat;
struct passwd *pw;
struct group *gp;
pid_t pid;
@@ -251,10 +274,26 @@
(void) umask(0);
+ system_labeled = is_system_labeled();
+ if (system_labeled == FALSE) {
+ /*
+ * 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 = TRUE;
+ }
+
parse_args(argc, argv);
(void) sema_init(&dev_sema, 1, USYNC_THREAD, NULL);
+ /* Initialize device allocation list */
+ devlist.audio = devlist.cd = devlist.floppy = devlist.tape =
+ devlist.rmdisk = NULL;
+
if (daemon_mode == TRUE) {
/*
* Build /dev and /devices before daemonizing if
@@ -311,7 +350,6 @@
(void) rcm_init();
login_dev_enable = TRUE;
}
-
daemon_update();
} else {
err_print(DAEMON_RUNNING, pid);
@@ -322,6 +360,9 @@
} else {
/* not a daemon, so just build /dev and /devices */
process_devinfo_tree();
+ if (devalloc_flag != 0)
+ /* Enable/disable device allocation */
+ _reset_devalloc(devalloc_flag);
}
return (0);
}
@@ -607,7 +648,7 @@
devlinktab_file = DEVLINKTAB_FILE;
while ((opt = getopt(argc, argv,
- "Cc:dIi:l:np:PR:r:st:vV:x:z:Z:")) != EOF) {
+ "Cc:deIi:l:np:PR:r:st:vV:x:z:Z:")) != EOF) {
if (opt == 'I' || opt == 'P') {
if (public_mode)
usage();
@@ -626,9 +667,21 @@
sizeof (char *));
classes[num_classes - 1] = optarg;
break;
- case 'd':
+ case 'd':
if (daemon_mode == FALSE) {
- devalloc_off = TRUE;
+ /*
+ * Device allocation to be disabled.
+ */
+ devalloc_flag = DA_OFF;
+ build_dev = FALSE;
+ }
+ break;
+ case 'e':
+ if (daemon_mode == FALSE) {
+ /*
+ * Device allocation to be enabled.
+ */
+ devalloc_flag = DA_ON;
build_dev = FALSE;
}
break;
@@ -909,6 +962,12 @@
if ((dcip->dci_flags & DCA_NOTIFY_RCM) && rcm_hdl)
(void) notify_rcm(node, dcip->dci_minor);
+ /* Add new device to device allocation database */
+ if (system_labeled && update_devdb) {
+ _update_devalloc_db(&devlist, 0, DA_ADD, NULL, root_dir);
+ update_devdb = 0;
+ }
+
di_fini(node);
}
@@ -986,7 +1045,7 @@
} else if (load_attach_drv == TRUE) {
/*
- * load and attach all drivers, then walk the entire tree.
+ * Load and attach all drivers, then walk the entire tree.
* If the cache flag is set, use DINFOCACHE to get cached
* data.
*/
@@ -2825,11 +2884,33 @@
== DEVFSADM_SUCCESS) {
linknew = TRUE;
add_link_to_cache(link, acontents);
+ if (system_labeled && (flags & DA_ADD)) {
+ /*
+ * Add this device to the list of allocatable devices.
+ */
+ int instance = di_instance(node);
+
+ (void) da_add_list(&devlist, devlink, instance, flags);
+ update_devdb = flags;
+ }
} else {
linknew = FALSE;
}
if (link_exists == TRUE) {
+ if (system_labeled && (flags & DA_CD)) {
+ /*
+ * if this is a removable disk, add it
+ * as that to device allocation database.
+ */
+ if (_da_check_for_usb(devlink, root_dir) == 1) {
+ int instance = di_instance(node);
+
+ (void) da_add_list(&devlist, devlink, instance,
+ DA_ADD|DA_RMDISK);
+ update_devdb = DA_RMDISK;
+ }
+ }
/* Link exists or was just created */
(void) di_devlink_add_link(devlink_cache, link, rcontents,
DI_PRIMARY_LINK);
@@ -2935,6 +3016,19 @@
*/
add_link_to_cache(link, lphy_path);
linknew = TRUE;
+ if (system_labeled &&
+ ((flags & DA_AUDIO) && (flags & DA_ADD))) {
+ /*
+ * Add this device to the list of allocatable devices.
+ */
+ int instance = 0;
+
+ op = strrchr(contents, '/');
+ op++;
+ (void) sscanf(op, "%d", &instance);
+ (void) da_add_list(&devlist, devlink, instance, flags);
+ update_devdb = flags;
+ }
} else {
linknew = FALSE;
}
@@ -3228,6 +3322,7 @@
static void
reset_node_permissions(di_node_t node, di_minor_t minor)
{
+ int devalloc_is_on = 0;
int spectype;
char phy_path[PATH_MAX + 1];
mode_t mode;
@@ -3281,32 +3376,52 @@
}
/*
- * If we are here for deactivating device allocation, set
- * default permissions. Otherwise, set default permissions
- * only if this is a new device because we want to preserve
- * modified user permissions.
- * Devfs indicates a new device by faking an access time
- * of zero.
+ * If we are here for a new device
+ * If device allocation is on
+ * then
+ * set ownership to root:other and permissions to 0000
+ * else
+ * set ownership and permissions as specified in minor_perm
+ * If we are here for an existing device
+ * If device allocation is to be turned on
+ * then
+ * reset ownership to root:other and permissions to 0000
+ * else if device allocation is to be turned off
+ * reset ownership and permissions to those specified in
+ * minor_perm
+ * else
+ * preserve exsisting/user-modified ownership and
+ * permissions
+ *
+ * devfs indicates a new device by faking access time to be zero.
*/
+ devalloc_is_on = da_is_on();
if (sb.st_atime != 0) {
int i;
char *nt;
- if (devalloc_off == FALSE)
+ if ((devalloc_flag == 0) && (devalloc_is_on != 1))
+ /*
+ * Leave existing devices as they are if we are not
+ * turning device allocation on/off.
+ */
return;
nt = di_minor_nodetype(minor);
+
if (nt == NULL)
return;
- for (i = 0; devalloc[i]; i++) {
- if (strcmp(nt, devalloc[i]) == 0)
+
+ for (i = 0; devalloc_list[i]; i++) {
+ if (strcmp(nt, devalloc_list[i]) == 0)
+ /*
+ * One of the types recognized by devalloc,
+ * reset attrs.
+ */
break;
}
-
- if (devalloc[i] == NULL)
+ if (devalloc_list[i] == NULL)
return;
-
- /* One of the types recognized by devalloc, reset perms */
}
if (file_mods == FALSE) {
@@ -3315,12 +3430,24 @@
return;
}
- if (sb.st_mode != mode) {
+ if ((devalloc_flag == DA_ON) || (devalloc_is_on == 1)) {
+ /*
+ * we are here either to turn device allocation on
+ * or to add a new device while device allocation in on
+ */
+ mode = DEALLOC_MODE;
+ uid = DA_UID;
+ gid = DA_GID;
+ }
+
+ if ((devalloc_is_on == 1) || (devalloc_flag == DA_ON) ||
+ (sb.st_mode != mode)) {
if (chmod(phy_path, mode) == -1)
vprint(VERBOSE_MID, CHMOD_FAILED,
phy_path, strerror(errno));
}
- if (sb.st_uid != uid || sb.st_gid != gid) {
+ if ((devalloc_is_on == 1) || (devalloc_flag == DA_ON) ||
+ (sb.st_uid != uid || sb.st_gid != gid)) {
if (chown(phy_path, uid, gid) == -1)
vprint(VERBOSE_MID, CHOWN_FAILED,
phy_path, strerror(errno));
@@ -4483,6 +4610,27 @@
}
}
+ /* update device allocation database */
+ if (system_labeled) {
+ int ret = 0;
+ int devtype = 0;
+ char devname[MAXNAMELEN];
+
+ devname[0] = '\0';
+ if (strstr(node_path, DA_SOUND_NAME))
+ devtype = DA_AUDIO;
+ else if (strstr(node_path, "disk"))
+ devtype = DA_RMDISK;
+ else
+ goto out;
+ ret = da_remove_list(&devlist, NULL, devtype, devname,
+ sizeof (devname));
+ if (ret != -1)
+ (void) _update_devalloc_db(&devlist, devtype, DA_REMOVE,
+ devname, root_dir);
+ }
+
+out:
/* now log an event */
if (nvl) {
log_event(EC_DEV_REMOVE, ev_subclass, nvl);
@@ -4610,8 +4758,9 @@
devfsadm_link_valid(char *link)
{
struct stat sb;
- char devlink[PATH_MAX + 1], *contents;
+ char devlink[PATH_MAX + 1], *contents = NULL;
int rv, type;
+ int instance = 0;
/* prepend link with dev_dir contents */
(void) strcpy(devlink, dev_dir);
@@ -4634,6 +4783,13 @@
* The link exists. Add it to the database
*/
(void) di_devlink_add_link(devlink_cache, link, contents, type);
+ if (system_labeled && (rv == DEVFSADM_TRUE) &&
+ strstr(devlink, DA_AUDIO_NAME) && contents) {
+ (void) sscanf(contents, "%*[a-z]%d", &instance);
+ (void) da_add_list(&devlist, devlink, instance,
+ DA_ADD|DA_AUDIO);
+ _update_devalloc_db(&devlist, 0, DA_ADD, NULL, root_dir);
+ }
free(contents);
return (rv);
diff --git a/usr/src/cmd/devfsadm/disk_link.c b/usr/src/cmd/devfsadm/disk_link.c
index 57805e6..f12f9cf 100644
--- a/usr/src/cmd/devfsadm/disk_link.c
+++ b/usr/src/cmd/devfsadm/disk_link.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -32,6 +31,7 @@
#include <stdlib.h>
#include <limits.h>
#include <sys/stat.h>
+#include <bsm/devalloc.h>
#define DISK_SUBPATH_MAX 100
#define RM_STALE 0x01
@@ -46,6 +46,8 @@
#define MN_EFI "wd"
#define ASCIIWWNSIZE 255
+extern int system_labeled;
+
static int disk_callback_chan(di_minor_t minor, di_node_t node);
static int disk_callback_nchan(di_minor_t minor, di_node_t node);
static int disk_callback_wwn(di_minor_t minor, di_node_t node);
@@ -209,6 +211,8 @@
char slice[4];
char *mn;
char *ctrl;
+ char *nt = NULL;
+ int nflags = 0;
if (strstr(mn = di_minor_name(minor), ",raw")) {
dir = "rdsk";
@@ -255,7 +259,17 @@
}
(void) strcat(l_path, slice);
- (void) devfsadm_mklink(l_path, node, minor, 0);
+ if (system_labeled) {
+ nt = di_minor_nodetype(minor);
+ if ((nt != NULL) &&
+ ((strcmp(nt, DDI_NT_CD) == 0) ||
+ (strcmp(nt, DDI_NT_CD_CHAN) == 0) ||
+ (strcmp(nt, DDI_NT_BLOCK_CHAN) == 0))) {
+ nflags = DA_ADD|DA_CD;
+ }
+ }
+
+ (void) devfsadm_mklink(l_path, node, minor, nflags);
if ((flags & RM_STALE) == RM_STALE) {
(void) strcpy(stale_re, "^");
diff --git a/usr/src/cmd/devfsadm/i386/misc_link_i386.c b/usr/src/cmd/devfsadm/i386/misc_link_i386.c
index 484214d..1e40053 100644
--- a/usr/src/cmd/devfsadm/i386/misc_link_i386.c
+++ b/usr/src/cmd/devfsadm/i386/misc_link_i386.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -34,6 +33,9 @@
#include <limits.h>
#include <ctype.h>
#include <sys/mc.h>
+#include <bsm/devalloc.h>
+
+extern int system_labeled;
static int lp(di_minor_t minor, di_node_t node);
static int serial_dialout(di_minor_t minor, di_node_t node);
@@ -151,16 +153,20 @@
static int
diskette(di_minor_t minor, di_node_t node)
{
+ int flags = 0;
char *a2;
char link[PATH_MAX];
char *addr = di_bus_addr(node);
char *mn = di_minor_name(minor);
+ if (system_labeled)
+ flags = DA_ADD|DA_FLOPPY;
+
if (strcmp(addr, "0,0") == 0) {
if (strcmp(mn, "c") == 0) {
- (void) devfsadm_mklink("diskette", node, minor, 0);
+ (void) devfsadm_mklink("diskette", node, minor, flags);
} else if (strcmp(mn, "c,raw") == 0) {
- (void) devfsadm_mklink("rdiskette", node, minor, 0);
+ (void) devfsadm_mklink("rdiskette", node, minor, flags);
}
}
@@ -171,11 +177,13 @@
if (strcmp(mn, "c") == 0) {
(void) strcpy(link, "diskette");
(void) strcat(link, a2);
- (void) devfsadm_mklink(link, node, minor, 0);
+ (void) devfsadm_mklink(link, node, minor,
+ flags);
} else if (strcmp(mn, "c,raw") == 0) {
(void) strcpy(link, "rdiskette");
(void) strcat(link, a2);
- (void) devfsadm_mklink(link, node, minor, 0);
+ (void) devfsadm_mklink(link, node, minor,
+ flags);
}
}
}
diff --git a/usr/src/cmd/devfsadm/sparc/misc_link_sparc.c b/usr/src/cmd/devfsadm/sparc/misc_link_sparc.c
index ee2c059..0d0aa69 100644
--- a/usr/src/cmd/devfsadm/sparc/misc_link_sparc.c
+++ b/usr/src/cmd/devfsadm/sparc/misc_link_sparc.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -33,6 +32,9 @@
#include <stdlib.h>
#include <limits.h>
#include <sys/mkdev.h>
+#include <bsm/devalloc.h>
+
+extern int system_labeled;
static int node_name(di_minor_t minor, di_node_t node);
@@ -123,14 +125,19 @@
static int
diskette(di_minor_t minor, di_node_t node)
{
- char *mn = di_minor_name(minor);
+ int flags = 0;
+ char *mn = di_minor_name(minor);
+
+ if (system_labeled)
+ flags = DA_ADD|DA_FLOPPY;
+
if (strcmp(mn, "c") == 0) {
- (void) devfsadm_mklink("diskette", node, minor, 0);
- (void) devfsadm_mklink("diskette0", node, minor, 0);
+ (void) devfsadm_mklink("diskette", node, minor, flags);
+ (void) devfsadm_mklink("diskette0", node, minor, flags);
} else if (strcmp(mn, "c,raw") == 0) {
- (void) devfsadm_mklink("rdiskette", node, minor, 0);
- (void) devfsadm_mklink("rdiskette0", node, minor, 0);
+ (void) devfsadm_mklink("rdiskette", node, minor, flags);
+ (void) devfsadm_mklink("rdiskette0", node, minor, flags);
}
return (DEVFSADM_CONTINUE);
diff --git a/usr/src/cmd/devfsadm/tape_link.c b/usr/src/cmd/devfsadm/tape_link.c
index 2aae4a4..cd532d2 100644
--- a/usr/src/cmd/devfsadm/tape_link.c
+++ b/usr/src/cmd/devfsadm/tape_link.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -30,7 +29,9 @@
#include <strings.h>
#include <stdlib.h>
#include <limits.h>
+#include <bsm/devalloc.h>
+extern int system_labeled;
static int tape_process(di_minor_t minor, di_node_t node);
@@ -60,6 +61,7 @@
static int
tape_process(di_minor_t minor, di_node_t node)
{
+ int flags = 0;
char l_path[PATH_MAX + 1];
char *buf;
char *mn;
@@ -98,7 +100,10 @@
(void) strcat(l_path, mn);
free(buf);
- (void) devfsadm_mklink(l_path, node, minor, 0);
+ if (system_labeled)
+ flags = DA_ADD|DA_TAPE;
+
+ (void) devfsadm_mklink(l_path, node, minor, flags);
return (DEVFSADM_CONTINUE);
}
diff --git a/usr/src/cmd/devfsadm/usb_link.c b/usr/src/cmd/devfsadm/usb_link.c
index 53f0380..5012d8a 100644
--- a/usr/src/cmd/devfsadm/usb_link.c
+++ b/usr/src/cmd/devfsadm/usb_link.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,7 +18,7 @@
*
* CDDL HEADER END
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -210,6 +209,7 @@
char *l_path, *p_path, *buf, *devfspath;
char *minor_nm, *drvr_nm, *name = (char *)NULL;
int i, index;
+ int flags = 0;
int create_secondary_link = 0;
minor_nm = di_minor_name(minor);
@@ -345,7 +345,7 @@
devfsadm_print(debug_mid, "mklink %s -> %s\n", l_path, p_path);
- (void) devfsadm_mklink(l_path, node, minor, 0);
+ (void) devfsadm_mklink(l_path, node, minor, flags);
if (create_secondary_link) {
/*
@@ -376,6 +376,7 @@
char ugen_RE[128];
devfsadm_enumerate_t ugen_rules[1];
char l_path[PATH_MAX];
+ int flags = 0;
devfsadm_print(debug_mid, "ugen_create_link: p_path=%s name=%s\n",
p_path, node_name);
@@ -418,7 +419,7 @@
devfsadm_print(debug_mid, "mklink %s -> %s\n", l_path, p_path);
- (void) devfsadm_mklink(l_path, node, minor, 0);
+ (void) devfsadm_mklink(l_path, node, minor, flags);
free(buf);
}
diff --git a/usr/src/cmd/fs.d/autofs/auto_subr.c b/usr/src/cmd/fs.d/autofs/auto_subr.c
index 28f8cf5..c92eef6 100644
--- a/usr/src/cmd/fs.d/autofs/auto_subr.c
+++ b/usr/src/cmd/fs.d/autofs/auto_subr.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1988-1999 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -54,6 +53,9 @@
#include <rpcsvc/nfs_prot.h>
#include <assert.h>
#include "automount.h"
+#include <zone.h>
+#include <priv.h>
+#include <fcntl.h>
static char *check_hier(char *);
static int natisa(char *, size_t);
@@ -62,9 +64,111 @@
static bool_t nodirect_map = FALSE;
+/*
+ * If the system is labeled then we need to
+ * have a uniquely-named auto_home map for each zone.
+ * The maps are made unique by appending the zonename.
+ * The home directory is made unique by prepending /zone/<zonename>
+ * for each zone that is dominated by the current zone.
+ * The current zone's home directory mount point is not changed.
+ *
+ * For each auto_home_<zonename> a default template map is created
+ * only if it doesn't exist yet. The default entry is used to declare
+ * local home directories created within each zone. For example:
+ *
+ * +auto_home_public
+ * * -fstype=lofs :/zone/public/export/home/&
+ */
+static void
+loadzone_maps(char *mntpnt, char *map, char *opts, char **stack, char ***stkptr)
+{
+ zoneid_t *zids = NULL;
+ zoneid_t my_zoneid;
+ uint_t nzents_saved;
+ uint_t nzents;
+ int i;
+
+ if (!priv_ineffect(PRIV_SYS_MOUNT))
+ return;
+
+ if (zone_list(NULL, &nzents) != 0) {
+ return;
+ }
+ my_zoneid = getzoneid();
+again:
+ if (nzents == 0)
+ return;
+
+ zids = malloc(nzents * sizeof (zoneid_t));
+ nzents_saved = nzents;
+
+ if (zone_list(zids, &nzents) != 0) {
+ free(zids);
+ return;
+ }
+ if (nzents != nzents_saved) {
+ /* list changed, try again */
+ free(zids);
+ goto again;
+ }
+
+ for (i = 0; i < nzents; i++) {
+ char zonename[ZONENAME_MAX];
+ char zoneroot[MAXPATHLEN];
+
+ if (getzonenamebyid(zids[i], zonename, ZONENAME_MAX) != -1) {
+ char appended_map[MAXPATHLEN];
+ char prepended_mntpnt[MAXPATHLEN];
+ char map_path[MAXPATHLEN];
+ int fd;
+
+ (void) snprintf(appended_map, sizeof (appended_map),
+ "%s_%s", map, zonename);
+
+ /* for current zone, leave mntpnt alone */
+ if (zids[i] != my_zoneid) {
+ (void) snprintf(prepended_mntpnt,
+ sizeof (prepended_mntpnt),
+ "/zone/%s%s", zonename, mntpnt);
+ if (zone_getattr(zids[i], ZONE_ATTR_ROOT,
+ zoneroot, sizeof (zoneroot)) == -1)
+ continue;
+ } else {
+ (void) strcpy(prepended_mntpnt, mntpnt);
+ zoneroot[0] = '\0';
+ }
+
+ dirinit(prepended_mntpnt, appended_map, opts, 0, stack,
+ stkptr);
+ /*
+ * Next create auto_home_<zone> maps for each zone
+ */
+
+ (void) snprintf(map_path, sizeof (map_path),
+ "/etc/%s", appended_map);
+ /*
+ * If the map file doesn't exist create a template
+ */
+ if ((fd = open(map_path, O_RDWR | O_CREAT | O_EXCL,
+ S_IRUSR | S_IWUSR | S_IRGRP| S_IROTH)) != -1) {
+ int len;
+ char map_rec[MAXPATHLEN];
+
+ len = snprintf(map_rec, sizeof (map_rec),
+ "+%s\n*\t-fstype=lofs\t:%s/export/home/&\n",
+ appended_map, zoneroot);
+ if (len <= sizeof (map_rec))
+ (void) write(fd, map_rec, len);
+ (void) close(fd);
+ }
+ }
+ }
+ free(zids);
+}
+
void
dirinit(char *mntpnt, char *map, char *opts, int direct, char **stack,
- char ***stkptr)
+ char ***stkptr)
{
struct autodir *dir;
char *p;
@@ -97,6 +201,16 @@
return;
}
+ /*
+ * Home directories are polyinstantiated on
+ * labeled systems.
+ */
+ if (is_system_labeled() &&
+ (strcmp(mntpnt, "/home") == 0) &&
+ (strcmp(map, "auto_home") == 0)) {
+ (void) loadzone_maps(mntpnt, map, opts, stack, stkptr);
+ return;
+ }
enter:
dir = (struct autodir *)malloc(sizeof (*dir));
if (dir == NULL)
diff --git a/usr/src/cmd/fs.d/autofs/autod_lookup.c b/usr/src/cmd/fs.d/autofs/autod_lookup.c
index a4abbbe..a70541b 100644
--- a/usr/src/cmd/fs.d/autofs/autod_lookup.c
+++ b/usr/src/cmd/fs.d/autofs/autod_lookup.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -22,7 +21,7 @@
/*
* autod_lookup.c
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -61,10 +60,6 @@
char *stack[STACKSIZ];
char **stkptr = stack;
-#ifdef lint
- path = path;
-#endif /* lint */
-
/*
* Default action is for no work to be done by kernel AUTOFS.
*/
diff --git a/usr/src/cmd/fs.d/autofs/autod_main.c b/usr/src/cmd/fs.d/autofs/autod_main.c
index 7bcf02d..ce57a1f 100644
--- a/usr/src/cmd/fs.d/autofs/autod_main.c
+++ b/usr/src/cmd/fs.d/autofs/autod_main.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -56,7 +55,8 @@
#include <rpcsvc/daemon_utils.h>
#include <deflt.h>
#include <strings.h>
-
+#include <priv.h>
+#include <tsol/label.h>
static void autofs_prog(struct svc_req *, SVCXPRT *);
static void autofs_mount_1_r(struct autofs_lookupargs *,
@@ -322,6 +322,14 @@
/* other initializations */
(void) rwlock_init(&portmap_cache_lock, USYNC_THREAD, NULL);
+ /* on a labeled system, the automounter implements read-down policy */
+ if (is_system_labeled()) {
+ if ((setpflags(NET_MAC_AWARE, 1) == -1) ||
+ (setpflags(NET_MAC_AWARE_INHERIT, 1) == -1))
+ syslog(LOG_ERR, "ignored failure to set MAC-aware "
+ "mode: %m");
+ }
+
if (!rpc_control(RPC_SVC_MTMODE_SET, &rpc_svc_mode)) {
syslog(LOG_ERR, "unable to set automatic MT mode");
exit(1);
diff --git a/usr/src/cmd/fs.d/autofs/autod_nfs.c b/usr/src/cmd/fs.d/autofs/autod_nfs.c
index dc5cf60..741eba3 100644
--- a/usr/src/cmd/fs.d/autofs/autod_nfs.c
+++ b/usr/src/cmd/fs.d/autofs/autod_nfs.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -81,6 +80,10 @@
#include <net/if.h>
#include <assert.h>
#include <rpcsvc/daemon_utils.h>
+#include <pwd.h>
+#include <strings.h>
+#include <tsol/label.h>
+#include <zone.h>
extern char *nfs_get_qop_name();
extern AUTH *nfs_create_ah();
@@ -145,6 +148,8 @@
struct netconfig **, char *, ushort_t, struct t_info *, caddr_t *,
bool_t, char *);
+static int create_homedir(const char *, const char *);
+
enum type_of_stuff {
SERVER_ADDR = 0,
SERVER_PING = 1,
@@ -416,7 +421,6 @@
struct mapfs **mfs_tail)
{
struct mapfs *tmp, *new;
- void bcopy();
for (tmp = *mfs_head; tmp; tmp = tmp->mfs_next)
if ((strcmp(tmp->mfs_host, mfs->mfs_host) == 0 &&
@@ -1990,7 +1994,19 @@
} /* syncaddr */
} /* AUTH_DH */
- nfs_sec.sc_uid = cred->aup_uid;
+ /*
+ * TSOL notes: automountd in tsol extension
+ * has "read down" capability, i.e. we allow
+ * a user to trigger an nfs mount into a lower
+ * labeled zone. We achieve this by always having
+ * root issue the mount request so that the
+ * lookup ops can go past /zone/<zone_name>
+ * on the server side.
+ */
+ if (is_system_labeled())
+ nfs_sec.sc_uid = (uid_t)0;
+ else
+ nfs_sec.sc_uid = cred->aup_uid;
/*
* If AUTH_DH is a chosen flavor now, its data will be stored
* in the sec_data structure via nfs_clnt_secdata().
@@ -2253,7 +2269,7 @@
else
sl = service_list;
- _check_services(sl);
+ (void) _check_services(sl);
}
/*
@@ -3598,6 +3614,13 @@
" loopbackmount: fsname=%s, dir=%s, flags=%d\n",
fsname, dir, flags);
+ if (is_system_labeled()) {
+ if (create_homedir((const char *)fsname,
+ (const char *)dir) == 0) {
+ return (NFSERR_NOENT);
+ }
+ }
+
if (mount(fsname, dir, flags | MS_DATA | MS_OPTIONSTR, fstype,
NULL, 0, optbuf, sizeof (optbuf)) < 0) {
syslog(LOG_ERR, "Mount of %s on %s: %m", fsname, dir);
@@ -4214,3 +4237,78 @@
return (FALSE);
}
+
+static int
+create_homedir(const char *src, const char *dst) {
+
+ struct stat stbuf;
+ char *dst_username;
+ struct passwd *pwd, pwds;
+ char buf_pwd[NSS_BUFLEN_PASSWD];
+ int homedir_len;
+ int dst_dir_len;
+ int src_dir_len;
+
+ if (trace > 1)
+ trace_prt(1, "entered create_homedir\n");
+
+ if (stat(src, &stbuf) == 0) {
+ if (trace > 1)
+ trace_prt(1, "src exists\n");
+ return (1);
+ }
+
+ dst_username = strrchr(dst, '/');
+ if (dst_username) {
+ dst_username++; /* Skip over slash */
+ pwd = getpwnam_r(dst_username, &pwds, buf_pwd,
+ sizeof (buf_pwd));
+ if (pwd == NULL) {
+ return (0);
+ }
+ } else {
+ return (0);
+ }
+
+ homedir_len = strlen(pwd->pw_dir);
+ dst_dir_len = strlen(dst) - homedir_len;
+ src_dir_len = strlen(src) - homedir_len;
+
+ /* Check that the paths are in the same zone */
+ if (src_dir_len < dst_dir_len ||
+ (strncmp(dst, src, dst_dir_len) != 0)) {
+ if (trace > 1)
+ trace_prt(1, " paths don't match\n");
+ return (0);
+ }
+ /* Check that mountpoint is an auto_home entry */
+ if (dst_dir_len < 0 ||
+ (strcmp(pwd->pw_dir, dst + dst_dir_len) != 0)) {
+ return (0);
+ }
+
+ /* Check that source is an home directory entry */
+ if (src_dir_len < 0 ||
+ (strcmp(pwd->pw_dir, src + src_dir_len) != 0)) {
+ if (trace > 1)
+ trace_prt(1, " homedir (2) doesn't match %s\n",
+ src+src_dir_len);
+ return (0);
+ }
+
+ if (mkdir(src,
+ S_IRUSR | S_IWUSR | S_IXUSR | S_IXGRP | S_IXOTH) == -1) {
+ if (trace > 1) {
+ trace_prt(1, " Couldn't mkdir %s\n", src);
+ }
+ return (0);
+ }
+
+ if (chown(src, pwd->pw_uid, pwd->pw_gid) == -1) {
+ unlink(src);
+ return (0);
+ }
+
+ /* Created new home directory for the user */
+ return (1);
+}
diff --git a/usr/src/cmd/fs.d/nfs/lib/nfs_tbind.c b/usr/src/cmd/fs.d/nfs/lib/nfs_tbind.c
index 358b4f5..b761e47 100644
--- a/usr/src/cmd/fs.d/nfs/lib/nfs_tbind.c
+++ b/usr/src/cmd/fs.d/nfs/lib/nfs_tbind.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -51,6 +50,9 @@
#include <nfs/nfs_acl.h>
#include <nfs/nfssys.h>
#include <nfs/nfs4.h>
+#include <zone.h>
+#include <sys/socket.h>
+#include <tsol/label.h>
/*
* Determine valid semantics for most applications.
@@ -93,6 +95,8 @@
*/
static int nofile_increase(int);
static int reuseaddr(int);
+static int recvucred(int);
+static int anonmlp(int);
static void add_to_poll_list(int, struct netconfig *);
static char *serv_name_to_port_name(char *);
static int bind_to_proto(char *, char *, struct netbuf **,
@@ -234,6 +238,7 @@
struct opthdr *opt;
char reqbuf[128];
bool_t use_any = FALSE;
+ bool_t gzone = TRUE;
if ((fd = nfslib_transport_open(nconf)) == -1) {
syslog(LOG_ERR, "cannot establish transport service over %s",
@@ -250,7 +255,7 @@
tb.addr.len = 0;
tb.addr.buf = 0;
use_any = TRUE;
-
+ gzone = (getzoneid() == GLOBAL_ZONEID);
} else if (netdir_getbyname(nconf, hs, &addrlist) != 0) {
syslog(LOG_ERR,
@@ -273,6 +278,31 @@
syslog(LOG_WARNING,
"couldn't set SO_REUSEADDR option on transport");
}
+ } else if (strcmp(nconf->nc_proto, "udp") == 0) {
+ /*
+ * In order to run MLP on UDP, we need to handle creds.
+ */
+ if (recvucred(fd) == -1) {
+ syslog(LOG_WARNING,
+ "couldn't set SO_RECVUCRED option on transport");
+ }
+ }
+
+ /*
+ * Make non global zone nfs4_callback port MLP
+ */
+ if (use_any && is_system_labeled() && !gzone) {
+ if (anonmlp(fd) == -1) {
+ /*
+ * failing to set this option means nfs4_callback
+ * could fail silently later. So fail it with
+ * with an error message now.
+ */
+ syslog(LOG_ERR,
+ "couldn't set SO_ANON_MLP option on transport");
+ (void) t_close(fd);
+ return (-1);
+ }
}
if (nconf->nc_semantics == NC_TPI_CLTS)
@@ -364,29 +394,26 @@
}
static int
-reuseaddr(int fd)
+setopt(int fd, int level, int name, int value)
{
struct t_optmgmt req, resp;
- struct opthdr *opt;
- char reqbuf[128];
- int *ip;
+ struct {
+ struct opthdr opt;
+ int value;
+ } reqbuf;
- /* LINTED pointer alignment */
- opt = (struct opthdr *)reqbuf;
- opt->level = SOL_SOCKET;
- opt->name = SO_REUSEADDR;
- opt->len = sizeof (int);
+ reqbuf.opt.level = level;
+ reqbuf.opt.name = name;
+ reqbuf.opt.len = sizeof (int);
- /* LINTED pointer alignment */
- ip = (int *)&reqbuf[sizeof (struct opthdr)];
- *ip = 1;
+ reqbuf.value = value;
req.flags = T_NEGOTIATE;
- req.opt.len = sizeof (struct opthdr) + opt->len;
- req.opt.buf = (char *)opt;
+ req.opt.len = sizeof (reqbuf);
+ req.opt.buf = (char *)&reqbuf;
resp.flags = 0;
- resp.opt.buf = reqbuf;
+ resp.opt.buf = (char *)&reqbuf;
resp.opt.maxlen = sizeof (reqbuf);
if (t_optmgmt(fd, &req, &resp) < 0 || resp.flags != T_SUCCESS) {
@@ -396,6 +423,24 @@
return (0);
}
+static int
+reuseaddr(int fd)
+{
+ return (setopt(fd, SOL_SOCKET, SO_REUSEADDR, 1));
+}
+
+static int
+recvucred(int fd)
+{
+ return (setopt(fd, SOL_SOCKET, SO_RECVUCRED, 1));
+}
+
+static int
+anonmlp(int fd)
+{
+ return (setopt(fd, SOL_SOCKET, SO_ANON_MLP, 1));
+}
+
void
nfslib_log_tli_error(char *tli_name, int fd, struct netconfig *nconf)
{
diff --git a/usr/src/cmd/fs.d/nfs/mountd/mountd.c b/usr/src/cmd/fs.d/nfs/mountd/mountd.c
index dda4b78..2ae1d1e 100644
--- a/usr/src/cmd/fs.d/nfs/mountd/mountd.c
+++ b/usr/src/cmd/fs.d/nfs/mountd/mountd.c
@@ -112,6 +112,7 @@
int maxthreads;
int maxrecsz = RPC_MAXDATASIZE;
bool_t exclbind = TRUE;
+ bool_t can_do_mlp;
/*
* Mountd requires uid 0 for:
@@ -123,10 +124,13 @@
* auditing
* nfs syscall
* file dac search (so it can stat all files)
+ * Optional privileges:
+ * MLP
*/
+ can_do_mlp = priv_ineffect(PRIV_NET_BINDMLP);
if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET, -1, -1,
- PRIV_SYS_NFS, PRIV_PROC_AUDIT, PRIV_FILE_DAC_SEARCH,
- (char *)NULL) == -1) {
+ PRIV_SYS_NFS, PRIV_PROC_AUDIT, PRIV_FILE_DAC_SEARCH,
+ can_do_mlp ? PRIV_NET_BINDMLP : NULL, NULL) == -1) {
(void) fprintf(stderr,
"%s must be run as with sufficient privileges\n",
argv[0]);
@@ -788,6 +792,19 @@
}
/*
+ * Trusted Extension doesn't support older versions of nfs(v2, v3).
+ * To prevent circumventing TX label policy via using an older
+ * version of nfs client, reject the mount request and log an
+ * error.
+ */
+ if (is_system_labeled()) {
+ syslog(LOG_ERR,
+ "mount rejected: Solaris TX only supports nfs4 clients");
+ error = EACCES;
+ goto reply;
+ }
+
+ /*
* Get the real path (no symbolic links in it)
*/
if (realpath(path, rpath) == NULL) {
diff --git a/usr/src/cmd/fs.d/nfs/nfsd/nfsd.c b/usr/src/cmd/fs.d/nfs/nfsd/nfsd.c
index 791fad6..818552f 100644
--- a/usr/src/cmd/fs.d/nfs/nfsd/nfsd.c
+++ b/usr/src/cmd/fs.d/nfs/nfsd/nfsd.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -137,6 +136,7 @@
NETSELDECL(df_proto) = NULL;
NETSELPDECL(providerp);
char *defval;
+ boolean_t can_do_mlp;
MyName = *av;
@@ -146,8 +146,10 @@
(void) _create_daemon_lock(NFSD, DAEMON_UID, DAEMON_GID);
svcsetprio();
+ can_do_mlp = priv_ineffect(PRIV_NET_BINDMLP);
if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET,
- DAEMON_UID, DAEMON_GID, PRIV_SYS_NFS, (char *)NULL) == -1) {
+ DAEMON_UID, DAEMON_GID, PRIV_SYS_NFS,
+ can_do_mlp ? PRIV_NET_BINDMLP : NULL, NULL) == -1) {
(void) fprintf(stderr, "%s should be run with"
" sufficient privileges\n", av[0]);
exit(1);
diff --git a/usr/src/cmd/fs.d/nfs/statd/sm_svc.c b/usr/src/cmd/fs.d/nfs/statd/sm_svc.c
index f90ec07..a3dca0c 100644
--- a/usr/src/cmd/fs.d/nfs/statd/sm_svc.c
+++ b/usr/src/cmd/fs.d/nfs/statd/sm_svc.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -671,9 +670,10 @@
*/
static void
-set_statmon_owner()
+set_statmon_owner(void)
{
int i;
+ boolean_t can_do_mlp;
/*
* Recursively chown/chgrp /var/statmon and the alternate paths,
@@ -687,8 +687,10 @@
one_statmon_owner(alt_path);
}
+ can_do_mlp = priv_ineffect(PRIV_NET_BINDMLP);
if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET,
- DAEMON_UID, DAEMON_GID, (char *)NULL) == -1) {
+ DAEMON_UID, DAEMON_GID, can_do_mlp ? PRIV_NET_BINDMLP : NULL,
+ NULL) == -1) {
syslog(LOG_ERR, "can't run unprivileged: %m");
exit(1);
}
diff --git a/usr/src/cmd/ldap/Makefile.com b/usr/src/cmd/ldap/Makefile.com
index 824788f..d65d341 100644
--- a/usr/src/cmd/ldap/Makefile.com
+++ b/usr/src/cmd/ldap/Makefile.com
@@ -1,4 +1,24 @@
#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -33,7 +53,7 @@
# ldapaddent command
LDAPADDENTPROG= ldapaddent
-LDAPADDENTSRCS= ldapaddent.c ldapaddrbac.c
+LDAPADDENTSRCS= ldapaddent.c ldapaddrbac.c ldapaddtsol.c
LDAPADDENTOBJS= $(LDAPADDENTSRCS:%.c=%.o)
# ldapclient command
@@ -74,7 +94,7 @@
lint:= TARGET= lint
# C Pre-Processor flags used by C, CC & lint
-CPPFLAGS += -DSUN -DSVR4 -D_SYS_STREAM_H -DSOLARIS_LDAP_CMD \
+CPPFLAGS += -DSUN -DSVR4 -DSOLARIS_LDAP_CMD \
-I ../../../lib/libldap5/include/ldap \
-I ../../../lib/libsldap/common \
-I ../../../lib/libnsl/include/rpcsvc \
@@ -87,7 +107,7 @@
ldapdelete := LDLIBS += -lldap
ldapmodify := LDLIBS += -lldap
ldaplist := LDLIBS += -lsldap
-ldapaddent := LDLIBS += -lsldap -lnsl
+ldapaddent := LDLIBS += -lsldap -lnsl -lsecdb
ldapclient := LDLIBS += -lsldap -lscf
lint := LDLIBS += -lldap
diff --git a/usr/src/cmd/ldap/ns_ldap/idsconfig.sh b/usr/src/cmd/ldap/ns_ldap/idsconfig.sh
index 645dfb7..485c5f9 100644
--- a/usr/src/cmd/ldap/ns_ldap/idsconfig.sh
+++ b/usr/src/cmd/ldap/ns_ldap/idsconfig.sh
@@ -1,11 +1,12 @@
#!/bin/sh
#
+# ident "%Z%%M% %I% %E% SMI"
+#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -21,11 +22,9 @@
# CDDL HEADER END
#
#
-# ident "%Z%%M% %I% %E% SMI"
-#
# idsconfig -- script to setup iDS 5.x for Native LDAP II.
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
@@ -3146,6 +3145,8 @@
attributetypes:( 1.3.6.1.4.1.42.2.27.5.1.63 NAME 'sun-printer-bsdaddr' DESC 'Sets the server, print queue destination name and whether the client generates protocol extensions. "Solaris" specifies a Solaris print server extension. The value is represented by the following value: server "," destination ", Solaris".' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )
attributetypes:( 1.3.6.1.4.1.42.2.27.5.1.64 NAME 'sun-printer-kvp' DESC 'This attribute contains a set of key value pairs which may have meaning to the print subsystem or may be user defined. Each value is represented by the following: key "=" value.' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )
attributetypes: ( 1.3.6.1.4.1.42.2.27.5.1.57 NAME 'nisplusTimeZone' DESC 'tzone column from NIS+ timezone table' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+attributetypes:( 1.3.6.1.4.1.42.2.27.5.1.67 NAME 'ipTnetTemplateName' DESC 'Trusted Solaris network template template_name' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+attributetypes:( 1.3.6.1.4.1.42.2.27.5.1.68 NAME 'ipTnetNumber' DESC 'Trusted Solaris network template ip_address' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
EOF
) > ${TMPDIR}/schema_attr
@@ -3291,6 +3292,16 @@
changetype: modify
add: objectclasses
objectclasses: ( 1.3.6.1.4.1.42.2.27.5.2.12 NAME 'nisplusTimeZoneData' DESC 'NIS+ timezone table data' SUP top STRUCTURAL MUST ( cn ) MAY ( nisplusTimeZone $ description ) )
+
+dn: cn=schema
+changetype: modify
+add: objectclasses
+objectclasses: ( 1.3.6.1.4.1.42.2.27.5.2.8 NAME 'ipTnetTemplate' DESC 'Object class for TSOL network templates' SUP 'top' MUST ( objectclass $ ipTnetTemplateName ) MAY ( SolarisAttrKeyValue ) )
+
+dn: cn=schema
+changetype: modify
+add: objectclasses
+objectclasses: ( 1.3.6.1.4.1.42.2.27.5.2.9 NAME 'ipTnetHost' DESC 'Associates an IP address or wildcard with a TSOL template_name' SUP 'top' AUXILIARY MUST ( objectclass $ ipTnetNumber ) )
EOF
) > ${TMPDIR}/schema_obj
@@ -3612,7 +3623,7 @@
for ou in people group rpc protocols networks netgroup \
aliases hosts services ethers profile printers \
- SolarisAuthAttr SolarisProfAttr Timezone ; do
+ SolarisAuthAttr SolarisProfAttr Timezone ipTnet ; do
# Check if nismaps already exist.
eval "${LDAPSEARCH} ${LDAP_ARGS} -b \"ou=${ou},${LDAP_BASEDN}\" -s base \"objectclass=*\" ${VERB}"
diff --git a/usr/src/cmd/ldap/ns_ldap/ldapaddent.c b/usr/src/cmd/ldap/ns_ldap/ldapaddent.c
index a5d420e..7b30890 100644
--- a/usr/src/cmd/ldap/ns_ldap/ldapaddent.c
+++ b/usr/src/cmd/ldap/ns_ldap/ldapaddent.c
@@ -3572,6 +3572,10 @@
filedbmline_comment, "SolarisAuthAttr" },
{ NS_LDAP_TYPE_AUUSER, genent_audit_user, dump_audit_user,
filedbmline_comment, "SolarisAuditUser" },
+ { NS_LDAP_TYPE_TNRHDB, genent_tnrhdb, dump_tnrhdb,
+ filedbmline_comment, "ipTnetHost" },
+ { NS_LDAP_TYPE_TNRHTP, genent_tnrhtp, dump_tnrhtp,
+ filedbmline_comment, "ipTnetTemplate" },
{ 0, 0, 0, 0, 0 }
};
@@ -3641,9 +3645,17 @@
(void) snprintf(filter, sizeof (filter),
"(&(objectclass=%s)(!(objectclass=SolarisExecAttr)))",
tt->objclass);
- } else
+ } else if (strcmp(tt->ttype, NS_LDAP_TYPE_TNRHDB) == 0) {
+ /*
+ * tnrhtp entries are ipTnet entries with SolarisAttrKeyValue
+ */
+ (void) snprintf(filter, sizeof (filter),
+ "(&(objectclass=%s)(SolarisAttrKeyValue=*)))",
+ tt->objclass);
+ } else {
(void) snprintf(filter, sizeof (filter),
"(objectclass=%s)", tt->objclass);
+ }
if (flags & F_VERBOSE)
(void) fprintf(stdout, gettext("FILTER = %s\n"), filter);
diff --git a/usr/src/cmd/ldap/ns_ldap/ldapaddent.h b/usr/src/cmd/ldap/ns_ldap/ldapaddent.h
index 6da82f1..42973d2 100644
--- a/usr/src/cmd/ldap/ns_ldap/ldapaddent.h
+++ b/usr/src/cmd/ldap/ns_ldap/ldapaddent.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -76,11 +75,16 @@
extern int genent_exec_attr(char *line, int (*cback)());
extern int genent_auth_attr(char *line, int (*cback)());
extern int genent_audit_user(char *line, int (*cback)());
+extern int genent_tnrhdb(char *line, int (*cback)());
+extern int genent_tnrhtp(char *line, int (*cback)());
+
extern void dump_user_attr(ns_ldap_result_t *res);
extern void dump_prof_attr(ns_ldap_result_t *res);
extern void dump_exec_attr(ns_ldap_result_t *res);
extern void dump_auth_attr(ns_ldap_result_t *res);
extern void dump_audit_user(ns_ldap_result_t *res);
+extern void dump_tnrhdb(ns_ldap_result_t *res);
+extern void dump_tnrhtp(ns_ldap_result_t *res);
#ifdef __cplusplus
}
diff --git a/usr/src/cmd/ldap/ns_ldap/ldapaddrbac.c b/usr/src/cmd/ldap/ns_ldap/ldapaddrbac.c
index 04da2f7..63c065e 100644
--- a/usr/src/cmd/ldap/ns_ldap/ldapaddrbac.c
+++ b/usr/src/cmd/ldap/ns_ldap/ldapaddrbac.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -66,7 +65,7 @@
* genent_attr:
* Generic function for generating entries for all of the *_attr databases.
*/
-static int
+int
genent_attr(
char *line, /* entry to parse */
int ncol, /* number of columns in the database */
diff --git a/usr/src/cmd/ldap/ns_ldap/ldapaddtsol.c b/usr/src/cmd/ldap/ns_ldap/ldapaddtsol.c
new file mode 100644
index 0000000..985a859
--- /dev/null
+++ b/usr/src/cmd/ldap/ns_ldap/ldapaddtsol.c
@@ -0,0 +1,142 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ldapaddtsol.c
+ *
+ * Routines to add tnrhdb and tnrhtp from /etc/security/tsol into LDAP.
+ * Can also be used to dump entries from a ldap container in /etc format.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <libintl.h>
+#include <string.h>
+#include <nss.h>
+#include <secdb.h>
+#include <sys/tsol/tndb.h>
+#include "ldapaddent.h"
+
+extern int genent_attr(char *, int, entry_col **);
+
+int
+genent_tnrhdb(char *line, int (*cback)())
+{
+ entry_col *ecol;
+ tsol_rhstr_t data;
+ int res, retval;
+
+ /*
+ * parse entry into columns
+ */
+ res = genent_attr(line, TNRHDB_NCOL, &ecol);
+ if (res != GENENT_OK)
+ return (res);
+
+ data.address = _do_unescape(ecol[0].ec_value.ec_value_val);
+ data.template = ecol[1].ec_value.ec_value_val;
+ if (strchr(data.address, ':') == NULL)
+ data.family = AF_INET;
+ else
+ data.family = AF_INET6;
+
+ if (flags & F_VERBOSE)
+ (void) printf(gettext("Adding entry : %s\n"), data.address);
+
+ retval = (*cback)(&data, 1);
+ if (retval)
+ res = GENENT_CBERR;
+
+ free(ecol);
+
+ return (res);
+}
+
+void
+dump_tnrhdb(ns_ldap_result_t *res)
+{
+ char **value = NULL;
+
+ value = __ns_ldap_getAttr(res->entry, "ipTnetNumber");
+ if (value && value[0])
+ (void) printf("%s", value[0]);
+ else
+ return;
+
+ (void) putchar(':');
+ value = __ns_ldap_getAttr(res->entry, "ipTnetTemplateName");
+ if (value && value[0])
+ (void) printf("%s", value[0]);
+ (void) putchar('\n');
+}
+
+int
+genent_tnrhtp(char *line, int (*cback)())
+{
+ entry_col *ecol;
+ tsol_tpstr_t data;
+ int res, retval;
+
+ /*
+ * parse entry into columns
+ */
+ res = genent_attr(line, TNRHTP_NCOL, &ecol);
+ if (res != GENENT_OK)
+ return (res);
+
+ data.template = ecol[0].ec_value.ec_value_val;
+ data.attrs = ecol[1].ec_value.ec_value_val;
+
+ if (flags & F_VERBOSE)
+ (void) printf(gettext("Adding entry : %s\n"), data.template);
+
+ retval = (*cback)(&data, 1);
+ if (retval)
+ res = GENENT_CBERR;
+
+ free(ecol);
+
+ return (res);
+}
+
+void
+dump_tnrhtp(ns_ldap_result_t *res)
+{
+ char **value = NULL;
+
+ value = __ns_ldap_getAttr(res->entry, "ipTnetTemplateName");
+ if (value && value[0])
+ (void) printf("%s", value[0]);
+ else
+ return;
+
+ (void) putchar(':');
+ value = __ns_ldap_getAttr(res->entry, "SolarisAttrKeyValue");
+ if (value && value[0])
+ (void) printf("%s", value[0]);
+ (void) putchar('\n');
+}
diff --git a/usr/src/cmd/ldap/ns_ldap/mapping.c b/usr/src/cmd/ldap/ns_ldap/mapping.c
index 57827c6..470ca20 100644
--- a/usr/src/cmd/ldap/ns_ldap/mapping.c
+++ b/usr/src/cmd/ldap/ns_ldap/mapping.c
@@ -18,6 +18,7 @@
*
* CDDL HEADER END
*/
+
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
@@ -29,6 +30,7 @@
#include <libintl.h>
#include <strings.h>
#include <stdio.h>
+#include <tsol/label.h>
#include "../../../lib/libsldap/common/ns_sldap.h"
@@ -67,6 +69,8 @@
{"exec_attr", "cn", "SolarisExecAttr", NULL},
{"user_attr", "uid", "SolarisUserAttr", NULL},
{"audit_user", "uid", "SolarisAuditUser", NULL},
+ {"tnrhtp", "ipTnetTemplateName", "ipTnetTemplate", NULL},
+ {"tnrhdb", "ipTnetNumber", "ipTnetHost", NULL},
{NULL, NULL, NULL, NULL}
};
@@ -112,10 +116,20 @@
"automountMapName",
"automountMap");
for (i = 0; maplist[i].database != NULL; i++) {
- /* skip printing shadow */
- if (strcasecmp(maplist[i].database, "shadow") != 0)
+ /* skip printing shadow */
+ if (strcasecmp(maplist[i].database, "shadow") == 0)
+ continue;
+ if (!is_system_labeled()) {
+ /*
+ * do not print tnrhdb and tnrhtp if system is
+ * not configured with Trusted Extensions
+ */
+ if ((strcasecmp(maplist[i].database, "tnrhdb") == 0) ||
+ (strcasecmp(maplist[i].database, "tnrhtp") == 0))
+ continue;
+ }
(void) fprintf(stdout, "%-15s%-20s%s\n", maplist[i].database,
- maplist[i].def_type, maplist[i].objectclass);
+ maplist[i].def_type, maplist[i].objectclass);
}
}
diff --git a/usr/src/cmd/lp/cmd/Makefile b/usr/src/cmd/lp/cmd/Makefile
index 9bffdde..2a50a58 100644
--- a/usr/src/cmd/lp/cmd/Makefile
+++ b/usr/src/cmd/lp/cmd/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -18,11 +17,13 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
+
+
#
#
# ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# cmd/lp/cmd/Makefile
@@ -69,12 +70,14 @@
cancel:= LDLIBS += $(LIBREQ) $(LIBMSG) $(LIBOAM) $(LIBLP)
lp:= LDLIBS += $(LIBPRT) $(LIBREQ) $(LIBMSG) $(LIBOAM) $(LIBLP)
lpfilter:= LDLIBS += $(LIBFLT) $(LIBMSG) $(LIBACC) $(LIBOAM) $(LIBLP) \
- -lgen
+ -lgen -z lazyload -lsecdb -z nolazyload
lpforms:= LDLIBS += $(LIBFRM) $(LIBMSG) $(LIBREQ) $(LIBOAM) \
- $(LIBACC) $(LIBLP)
+ $(LIBACC) $(LIBLP) \
+ -z lazyload -lsecdb -z nolazyload
lpmove:= LDLIBS += $(LIBMSG) $(LIBACC) $(LIBOAM) $(LIBLP)
lpshut:= LDLIBS += $(LIBMSG) $(LIBOAM) $(LIBLP)
-lpsystem:= LDLIBS += $(LIBSYS) $(LIBMSG) $(LIBOAM) $(LIBLP) -lnsl
+lpsystem:= LDLIBS += $(LIBSYS) $(LIBMSG) $(LIBACC) $(LIBOAM) $(LIBLP) \
+ -lnsl -z lazyload -lsecdb -z nolazyload
lpusers:= LDLIBS += $(LIBMSG) $(LIBACC) $(LIBOAM) $(LIBUSR) $(LIBLP)
.KEEP_STATE:
diff --git a/usr/src/cmd/lp/cmd/adaptor/Makefile b/usr/src/cmd/lp/cmd/adaptor/Makefile
index 5fc1aad..f7d7d75 100644
--- a/usr/src/cmd/lp/cmd/adaptor/Makefile
+++ b/usr/src/cmd/lp/cmd/adaptor/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -18,9 +17,11 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
+
+
#
#
-# Copyright 1996-2003 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -38,7 +39,7 @@
CPPFLAGS += -I$(LPINC)
CPPFLAGS += -I$(SRC)/lib
-LDLIBS += -lprint -lc
+LDLIBS += -lprint -z lazyload -ltsol -z nolazyload -lc
LDLIBS += -L$(SRC)/cmd/lp/lib/msgs -llpmsg
LDLIBS += -L$(SRC)/cmd/lp/lib/class -llpcls
LDLIBS += -L$(SRC)/cmd/lp/lib/lp -llp
diff --git a/usr/src/cmd/lp/cmd/adaptor/cancel_job.c b/usr/src/cmd/lp/cmd/adaptor/cancel_job.c
index 6ee2368..7ffa9af 100644
--- a/usr/src/cmd/lp/cmd/adaptor/cancel_job.c
+++ b/usr/src/cmd/lp/cmd/adaptor/cancel_job.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -83,7 +82,6 @@
return (buf);
}
-
/*
* lpsched_cancel_job() attempts to cancel an lpsched requests that match the
* passed in criteria. a message is written for each cancelation or
@@ -123,12 +121,12 @@
size_t size;
time_t date;
short outcome;
- char *dest, *form, *pwheel, *file, *owner, *reqid;
+ char *dest, *slabel, *form, *pwheel, *file, *owner, *reqid;
const char **list_ptr = list;
char buf[BUFSIZ];
- if (rcv_msg(R_INQUIRE_REQUEST, &status, &reqid, &owner, &size,
- &date, &outcome, &dest, &form, &pwheel,
+ if (rcv_msg(R_INQUIRE_REQUEST, &status, &reqid, &owner, &slabel,
+ &size, &date, &outcome, &dest, &form, &pwheel,
&file) < 0) {
fprintf(ofp,
gettext("Failure to communicate with lpsched\n"));
diff --git a/usr/src/cmd/lp/cmd/adaptor/misc.c b/usr/src/cmd/lp/cmd/adaptor/misc.c
index 75bec08..e4959df 100644
--- a/usr/src/cmd/lp/cmd/adaptor/misc.c
+++ b/usr/src/cmd/lp/cmd/adaptor/misc.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -39,6 +38,8 @@
#include <syslog.h>
+#include <tsol/label.h>
+
#include "misc.h"
/* lpsched include files */
@@ -48,7 +49,6 @@
static char Msg[MSGMAX];
-
/*
* Format and send message to lpsched
* (die if any errors occur)
@@ -216,15 +216,32 @@
* has access to communicate with the scheduler. In Solaris this currently
* has no meaning. The host is automatically allowed access.
*/
+char *slabel = NULL;
+
int
-lpsched_client_access(const char *printer, const char *host)
+lpsched_client_access(const char *printer, const char *host, int peerfd)
{
- syslog(LOG_DEBUG, "lpsched_client_access(%s, %s)",
- (printer ? printer : "NULL"), (host ? host : "NULL"));
+ syslog(LOG_DEBUG, "lpsched_client_access(%s, %s, %d)",
+ (printer ? printer : "NULL"), (host ? host : "NULL"),
+ peerfd);
if ((printer == NULL) || (host == NULL))
return (-1);
+ if (is_system_labeled) {
+ short status = MOK;
+ extern MESG *lp_Md; /* liblpmsg supplies this */
+
+ if ((snd_msg(S_PASS_PEER_CONNECTION) < 0) ||
+ (ioctl(lp_Md->writefd, I_SENDFD, peerfd) < 0) ||
+ (rcv_msg(R_PASS_PEER_CONNECTION, &status) < 0))
+ status = MTRANSMITERR;
+ if (status != MOK)
+ return (-1);
+
+ get_peer_label(peerfd, &slabel);
+ }
+
return (0);
}
diff --git a/usr/src/cmd/lp/cmd/adaptor/misc.h b/usr/src/cmd/lp/cmd/adaptor/misc.h
index 24b8d7f..f475468 100644
--- a/usr/src/cmd/lp/cmd/adaptor/misc.h
+++ b/usr/src/cmd/lp/cmd/adaptor/misc.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1996, by Sun Microsystems, Inc.
- * All Rights Reserved
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#ident "%Z%%M% %I% %E% SMI"
@@ -34,5 +33,6 @@
extern int id_no(const char *);
extern char *user_name(const char *);
extern char *user_host(const char *);
+extern char *slabel;
#endif /* _MISC_H */
diff --git a/usr/src/cmd/lp/cmd/adaptor/show_queue.c b/usr/src/cmd/lp/cmd/adaptor/show_queue.c
index 04867c6..4ed83ba 100644
--- a/usr/src/cmd/lp/cmd/adaptor/show_queue.c
+++ b/usr/src/cmd/lp/cmd/adaptor/show_queue.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 1995-2002 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -160,8 +159,8 @@
#define HEADER gettext("Rank\tOwner\tJob\tFile(s)\t\t\t\tTotal Size\n")
static int
-job_list(const char *printer, FILE *ofp, const int type, const char **list,
- const char *status_message, int *rank)
+job_list(const char *printer, FILE *ofp, const int type,
+ const char **list, const char *status_message, int *rank)
{
int count = 0;
short status, outcome;
@@ -173,10 +172,11 @@
size_t size;
time_t date;
int id;
- char *user, *reqid, *owner, *dest, *form, *pwheel, *file, *host;
+ char *user, *slabel, *reqid, *owner, *dest, *form, *pwheel,
+ *file, *host;
- if (rcv_msg(R_INQUIRE_REQUEST, &status, &reqid, &owner, &size,
- &date, &outcome, &dest, &form, &pwheel,
+ if (rcv_msg(R_INQUIRE_REQUEST, &status, &reqid, &owner, &slabel,
+ &size, &date, &outcome, &dest, &form, &pwheel,
&file) < 0)
return (count);
@@ -215,6 +215,7 @@
return (count);
}
+
/*
* lpsched_show_queue() attempts to display the queue of "pending" jobs. The
* "type" is used to determine if this should be a short or long format
diff --git a/usr/src/cmd/lp/cmd/adaptor/submit_job.c b/usr/src/cmd/lp/cmd/adaptor/submit_job.c
index d3bf04d..ac6ad66 100644
--- a/usr/src/cmd/lp/cmd/adaptor/submit_job.c
+++ b/usr/src/cmd/lp/cmd/adaptor/submit_job.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1995-1999,2001 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -31,15 +30,21 @@
#include <unistd.h>
#include <ctype.h>
#include <sys/types.h>
+#include <sys/zone.h>
#include <string.h>
#include <libintl.h>
#include <syslog.h>
#include <stdarg.h>
+#include <tsol/label.h>
+
#include "misc.h"
/* lpsched include files */
+#if defined PS_FAULTED
+#undef PS_FAULTED
+#endif /* PS_FAULTED */
#include "lp.h"
#include "msgs.h"
#include "printers.h"
@@ -85,11 +90,11 @@
}
}
-
/*
* mail() will send a mail message to the requesting user in the event of an
* error during job submission.
*/
+
static void
mail(REQUEST *request, char *req_file, char *fmt, ...)
{
@@ -97,6 +102,7 @@
char buf[BUFSIZ];
char *uname;
va_list ap;
+ char *mail_zonename = NULL;
/*
* Clean-up user name so we don't pass flags to /bin/mail, or
@@ -110,27 +116,59 @@
if (*uname == '\0')
return; /* No username found */
- snprintf(buf, sizeof (buf), "/bin/mail %s", uname);
+ /*
+ * If in the global zone and the system is labeled, mail is
+ * handled via a local labeled zone that is the same label as the
+ * request.
+ */
+ if ((getzoneid() == GLOBAL_ZONEID) && is_system_labeled() &&
+ slabel != NULL) {
+ if ((mail_zonename = get_labeled_zonename(slabel)) ==
+ (char *)-1) {
+ /* error during get_labeled_zonename, just return */
+ return;
+ }
+ }
+
+ /*
+ * If mail_zonename is not NULL, use zlogin to execute /bin/mail
+ * in the labeled zone 'mail_zonename'.
+ */
+
+ if (mail_zonename != NULL) {
+ syslog(LOG_DEBUG,
+ "lpsched: using '/usr/sbin/zlogin %s /bin/mail %s' to mail",
+ mail_zonename, uname);
+ snprintf(buf, sizeof (buf),
+ "/usr/sbin/zlogin %s /bin/mail %s",
+ mail_zonename, uname);
+ Free(mail_zonename);
+ } else {
+ syslog(LOG_DEBUG,
+ "lpsched: using '/bin/mail %s' to mail",
+ uname);
+ snprintf(buf, sizeof (buf), "/bin/mail %s", uname);
+ }
clean_string(buf);
if ((pp = popen(buf, "w+")) == NULL)
return;
fprintf(pp, gettext("Subject: print request for %s failed\n\n"),
- request->destination);
+ request->destination);
fprintf(pp, gettext("\n\tRequest File: %s"), req_file);
fprintf(pp, gettext("\n\tDocument Type: %s"),
- (request->input_type ? request->input_type :
- gettext("(unknown)")));
+ (request->input_type ? request->input_type :
+ gettext("(unknown)")));
fprintf(pp, gettext("\n\tTitle:\t%s"),
- (request->title ? request->title : gettext("(none)")));
+ (request->title ? request->title : gettext("(none)")));
fprintf(pp, gettext("\n\tCopies:\t%d"), request->copies);
fprintf(pp, gettext("\n\tPriority:\t%d"), request->priority);
fprintf(pp, gettext("\n\tForm:\t%s"),
- (request->form ? request->form : gettext("(none)")));
+ (request->form ? request->form : gettext("(none)")));
fprintf(pp, gettext("\n\tOptions:\t%s"),
- (request->options ? request->options : gettext("(none)")));
+ (request->options ? request->options : gettext("(none)")));
fprintf(pp, gettext("\n\tModes:\t%s"),
- (request->modes ? request->modes : gettext("(none)")));
+ (request->modes ? request->modes : gettext("(none)")));
fprintf(pp, gettext("\n\tReason for Failure:\n\n\t\t"));
va_start(ap, fmt);
@@ -505,7 +543,7 @@
char buf[MAXPATHLEN];
int file_no = 0;
int rc = -1;
- char *tmp_dir = (char *)lpsched_temp_dir(printer, host);
+ char *tmp_dir;
char *tmp;
short status;
long bits;
@@ -515,6 +553,8 @@
syslog(LOG_DEBUG, "lpsched_submit_job(%s, %s, 0x%x)",
(printer ? printer : "NULL"), (cf ? cf : "NULL"), df_list);
+ tmp_dir = (char *)lpsched_temp_dir(printer, host);
+
if ((printer == NULL) || (host == NULL) || (cf == NULL) ||
(df_list == NULL))
return (-1);
@@ -558,18 +598,21 @@
secure.req_id = strdup(buf);
secure.uid = LP_UID;
secure.gid = 0;
+ secure.slabel = NULL;
/* save the request file */
snprintf(buf, sizeof (buf), "%s/%d-0", host, request_id);
if (putrequest(buf, request) < 0) {
- mail(request, buf, gettext("Can't save print request"));
+ mail(request, buf,
+ gettext("Can't save print request"));
unlink_files(request->file_list);
return (-1);
}
/* save the secure file */
if (putsecure(buf, &secure) < 0) {
- mail(request, buf, gettext("Can't save print secure file"));
+ mail(request, buf,
+ gettext("Can't save print secure file"));
snprintf(buf, sizeof (buf), "%s/%s/%d-0", Lp_Tmp, host,
request_id);
unlink(buf);
@@ -624,7 +667,8 @@
gettext("failure to communicate with lpsched"));
break;
default:
- mail(request, buf, gettext("Unknown error: %d"),
+ mail(request, buf,
+ gettext("Unknown error: %d"),
status);
break;
}
diff --git a/usr/src/cmd/lp/cmd/lpadmin/Makefile b/usr/src/cmd/lp/cmd/lpadmin/Makefile
index c756879..bb3c282 100644
--- a/usr/src/cmd/lp/cmd/lpadmin/Makefile
+++ b/usr/src/cmd/lp/cmd/lpadmin/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -18,13 +17,15 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
+
+
#
#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
# ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
-#
# cmd/lp/cmd/lpadmin/Makefile
#
@@ -65,7 +66,8 @@
SYSLIBS= -lcurses
-LDLIBS += $(LPLIBS) $(SYSLIBS) $(I18N)
+LDLIBS += -z lazyload -lsecdb -z nolazyload $(LPLIBS) \
+ $(SYSLIBS) $(I18N)
PROG= lpadmin
diff --git a/usr/src/cmd/lp/cmd/lpadmin/do_printer.c b/usr/src/cmd/lp/cmd/lpadmin/do_printer.c
index f6a502f..66ab3f2 100644
--- a/usr/src/cmd/lp/cmd/lpadmin/do_printer.c
+++ b/usr/src/cmd/lp/cmd/lpadmin/do_printer.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -24,7 +23,7 @@
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,11 +34,16 @@
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
+#include <sys/zone.h>
#include <stdlib.h>
#include <libintl.h>
-
+#include <sys/tsol/label_macro.h>
+#include <bsm/devices.h>
#include "lp.h"
#include "class.h"
+#if defined PS_FAULTED
+#undef PS_FAULTED
+#endif
#include "printers.h"
#include "msgs.h"
@@ -59,9 +63,11 @@
#endif
extern char *label;
+
static void configure_printer();
static char *fullpath();
char *nameit();
+static void pack_white(char *ptr);
/**
** do_printer() - CREATE OR CHANGE PRINTER
@@ -630,6 +636,11 @@
);
done(1);
}
+
+ if ((getzoneid() == GLOBAL_ZONEID) && system_labeled &&
+ (prbufp->device != NULL))
+ update_dev_dbs(p, prbufp->device, "ADD");
+
END_CRITICAL
return;
@@ -683,3 +694,88 @@
(void) strcat (copy, nm);
return (copy);
}
+
+/*
+ * update_dev_dbs - ADD/REMOVE ENTRIES FOR THE PRINTER IN DEVICE
+ * ALLOCATION FILES
+ *
+ * We intentionally ignore errors, since we don't want the printer
+ * installation to be viewed as failing just because we didn't add
+ * the device_allocate entry.
+ *
+ * Input:
+ * prtname - printer name
+ * devname - device associated w/ this printer
+ * func - [ADD|REMOVE] entries in /etc/security/device_allocate
+ * and /etc/security/device_maps
+ *
+ * Return:
+ * Always 'quiet' return. Failures are ignored.
+ */
+void
+update_dev_dbs(char *prtname, char *devname, char *func)
+{
+ int fd, status;
+ pid_t pid;
+
+ pid = fork();
+ switch (pid) {
+ case -1:
+ /* fork failed, just return quietly */
+ return;
+ case 0:
+ /* child */
+ /* redirect to /dev/null */
+ (void) close(1);
+ (void) close(2);
+ fd = open("/dev/null", O_WRONLY);
+ fd = dup(fd);
+
+ if (strcmp(func, "ADD") == 0) {
+ execl("/usr/sbin/add_allocatable", "add_allocatable",
+ "-n", prtname, "-t", "lp", "-l", devname,
+ "-o", "minlabel=admin_low:maxlabel=admin_high",
+ "-a", "*", "-c", "/bin/true", NULL);
+ } else {
+ if (strcmp(func, "REMOVE") == 0) {
+ execl("/usr/sbin/remove_allocatable",
+ "remove_allocatable", "-n", prtname, NULL);
+ }
+ }
+ _exit(1);
+ /* NOT REACHED */
+ default:
+ waitpid(pid, &status, 0);
+ return;
+ }
+}
+
+/*
+ * pack_white(ptr) trims off multiple occurances of white space from a NULL
+ * terminated string pointed to by "ptr".
+ */
+static void
+pack_white(char *ptr)
+{
+ char *tptr;
+ char *mptr;
+ int cnt;
+
+ if (ptr == NULL)
+ return;
+ cnt = strlen(ptr);
+ if (cnt == 0)
+ return;
+ mptr = (char *)calloc((unsigned)cnt+1, sizeof (char));
+ if (mptr == NULL)
+ return;
+ tptr = strtok(ptr, " \t");
+ while (tptr != NULL) {
+ (void) strcat(mptr, tptr);
+ (void) strcat(mptr, " ");
+ tptr = strtok(NULL, " \t");
+ }
+ cnt = strlen(mptr);
+ (void) strcpy(ptr, mptr);
+ free(mptr);
+}
diff --git a/usr/src/cmd/lp/cmd/lpadmin/lpadmin.c b/usr/src/cmd/lp/cmd/lpadmin/lpadmin.c
index cfe77a7..83560a6 100644
--- a/usr/src/cmd/lp/cmd/lpadmin/lpadmin.c
+++ b/usr/src/cmd/lp/cmd/lpadmin/lpadmin.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -28,6 +27,11 @@
/* All Rights Reserved */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
#pragma ident "%Z%%M% %I% %E% SMI"
#include "stdio.h"
@@ -55,6 +59,8 @@
chkopts3(),
exit();
+int system_labeled = 0;
+
int scheduler_active = 0;
char *label = 0;
@@ -88,6 +94,8 @@
/*NOTREACHED*/
}
+ system_labeled = is_system_labeled();
+
uname(&un);
Local_System = strdup(un.nodename);
diff --git a/usr/src/cmd/lp/cmd/lpadmin/lpadmin.h b/usr/src/cmd/lp/cmd/lpadmin/lpadmin.h
index 7c22f4e..3e58a3b 100644
--- a/usr/src/cmd/lp/cmd/lpadmin/lpadmin.h
+++ b/usr/src/cmd/lp/cmd/lpadmin/lpadmin.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -24,7 +23,7 @@
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -126,6 +125,10 @@
startup(),
usage();
+/* Routines/variables needed for labeled systems */
+extern void update_dev_dbs(char *, char *, char *);
+extern int system_labeled;
+
#if defined(__STDC__)
void send_message( int , ... );
diff --git a/usr/src/cmd/lp/cmd/lpadmin/rmdest.c b/usr/src/cmd/lp/cmd/lpadmin/rmdest.c
index b13555e..35ff27d 100644
--- a/usr/src/cmd/lp/cmd/lpadmin/rmdest.c
+++ b/usr/src/cmd/lp/cmd/lpadmin/rmdest.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -23,7 +22,12 @@
/* All Rights Reserved */
-#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.1 */
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
#include "stdio.h"
#include "ctype.h"
@@ -103,6 +107,9 @@
if (STREQU(getdflt(), dest))
newdflt (NAME_NONE);
+ if (system_labeled) {
+ update_dev_dbs(dest, NULL, "REMOVE");
+ }
break;
case MBUSY:
diff --git a/usr/src/cmd/lp/cmd/lpc/process.c b/usr/src/cmd/lp/cmd/lpc/process.c
index f7abe95..ddeda2c 100644
--- a/usr/src/cmd/lp/cmd/lpc/process.c
+++ b/usr/src/cmd/lp/cmd/lpc/process.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -319,6 +318,7 @@
*reject_reason,
*request_id,
*form,
+ *slabel,
*file,
*char_set,
*disable_reason;
@@ -366,6 +366,7 @@
rcv_msg(R_INQUIRE_REQUEST_RANK, &status,
&request_id,
&user,
+ &slabel,
&size,
&date,
&state,
diff --git a/usr/src/cmd/lp/cmd/lpc/topq.c b/usr/src/cmd/lp/cmd/lpc/topq.c
index 23ce029..4a5b0fc 100644
--- a/usr/src/cmd/lp/cmd/lpc/topq.c
+++ b/usr/src/cmd/lp/cmd/lpc/topq.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -171,7 +170,7 @@
char *machine;
#endif
{
- char *request_id, *form, *character_set;
+ char *request_id, *form, *slabel, *character_set;
char buf[50];
char **rqlist = NULL, **pp;
short state, status;
@@ -188,6 +187,7 @@
rcv_msg(R_INQUIRE_REQUEST, &status,
&request_id,
&user,
+ &slabel,
&size,
&date,
&state,
diff --git a/usr/src/cmd/lp/cmd/lpsched/Makefile b/usr/src/cmd/lp/cmd/lpsched/Makefile
index 3012533..3d03c42 100644
--- a/usr/src/cmd/lp/cmd/lpsched/Makefile
+++ b/usr/src/cmd/lp/cmd/lpsched/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -18,11 +17,13 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
+
+
#
#
# ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# cmd/lp/cmd/lpsched/lpsched/Makefile
@@ -102,7 +103,8 @@
$(LIBLP) \
$(LIBSEC)
-SYSLIBS= -lcurses -lgen -lcurses -lnsl
+SYSLIBS= -lcurses -lgen -lcurses -lnsl -z lazyload \
+ -ltsol -lsecdb -lcmd -lbsm -z nolazyload
LDLIBS += $(LPLIBS) $(SYSLIBS)
diff --git a/usr/src/cmd/lp/cmd/lpsched/disp1.c b/usr/src/cmd/lp/cmd/lpsched/disp1.c
index 7473af6..a551b7e 100644
--- a/usr/src/cmd/lp/cmd/lpsched/disp1.c
+++ b/usr/src/cmd/lp/cmd/lpsched/disp1.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -145,6 +144,8 @@
rp->secure->req_id = Strdup(s->req_id);
rp->secure->user = Strdup(s->user);
rp->secure->system = Strdup(s->system);
+ if (md->slabel != NULL)
+ rp->secure->slabel = Strdup(md->slabel);
freesecure(s);
/*
** There are some anomallies associated w/
@@ -160,6 +161,8 @@
rp->request->outcome = 0;
rp->secure->uid = md->uid;
rp->secure->gid = md->gid;
+ if (md->slabel != NULL)
+ rp->secure->slabel = Strdup(md->slabel);
pw = getpwuid(md->uid);
endpwent();
@@ -365,6 +368,10 @@
if (!(rp = request_by_id(req_id)))
status = MUNKNOWN;
+ else if ((md->admin == 0) && (is_system_labeled()) &&
+ (md->slabel != NULL) && (rp->secure->slabel != NULL) &&
+ (!STREQU(md->slabel, rp->secure->slabel)))
+ status = MUNKNOWN;
else if (rp->request->outcome & RS_DONE)
status = M2LATE;
else if (!md->admin && md->uid != rp->secure->uid)
@@ -438,6 +445,10 @@
if (!(rp = request_by_id(req_id)))
status = MUNKNOWN;
+ else if ((md->admin == 0) && (is_system_labeled()) &&
+ (md->slabel != NULL) && (rp->secure->slabel != NULL) &&
+ (!STREQU(md->slabel, rp->secure->slabel)))
+ status = MUNKNOWN;
else if (!(rp->request->outcome & RS_CHANGING))
status = MNOSTART;
else {
@@ -618,6 +629,15 @@
return(Strdup(crp->secure->req_id));
}
+ /*
+ * For Trusted Extensions, we need to check the sensitivity label of the
+ * connection and job before we try to cancel it.
+ */
+ if ((md->admin == 0) && (is_system_labeled()) &&
+ (md->slabel != NULL) && (crp->secure->slabel != NULL) &&
+ (!STREQU(md->slabel, crp->secure->slabel)))
+ continue;
+
crp->reason = MOK;
creq_id = Strdup(crp->secure->req_id);
@@ -737,14 +757,23 @@
if (*pwheel && !SAME(pwheel, rp->pwheel_name))
continue;
+
+ /*
+ * For Trusted Extensions, we need to check the sensitivity label of the
+ * connection and job before we return it to the client.
+ */
+ if ((md->admin <= 0) && (is_system_labeled()) &&
+ (md->slabel != NULL) && (rp->secure->slabel != NULL) &&
+ (!STREQU(md->slabel, rp->secure->slabel)))
+ continue;
if (found) {
GetRequestFiles(found->request, files, sizeof(files));
mputm(md, R_INQUIRE_REQUEST,
MOKMORE,
found->secure->req_id,
- found->request->user,
- /* bgolden 091996, bug 1257405 */
+ found->request->user, /* bgolden 091996, bug 1257405 */
+ found->secure->slabel,
found->secure->size,
found->secure->date,
found->request->outcome,
@@ -763,6 +792,7 @@
MOK,
found->secure->req_id,
found->request->user, /* bgolden 091996, bug 1257405 */
+ found->secure->slabel,
found->secure->size,
found->secure->date,
found->request->outcome,
@@ -772,7 +802,7 @@
files
);
} else
- mputm(md, R_INQUIRE_REQUEST, MNOINFO, "", "", 0L, 0L, 0, "", "", "",
+ mputm(md, R_INQUIRE_REQUEST, MNOINFO, "", "", "", 0L, 0L, 0, "", "", "",
"");
return;
@@ -829,6 +859,15 @@
if (*pwheel && !SAME(pwheel, rp->pwheel_name))
continue;
+ /*
+ * For Trusted Extensions, we need to check the sensitivity
+ * label of the connection and job before we return it to the
+ * client.
+ */
+ if ((md->admin <= 0) && (is_system_labeled()) &&
+ (md->slabel != NULL) && (rp->secure->slabel != NULL) &&
+ (!STREQU(md->slabel, rp->secure->slabel)))
+ continue;
if (found) {
GetRequestFiles(found->request, files, sizeof(files));
@@ -837,6 +876,7 @@
found->secure->req_id,
found->request->user,
/* bgolden 091996, bug 1257405 */
+ found->secure->slabel,
found->secure->size,
found->secure->date,
found->request->outcome,
@@ -858,6 +898,7 @@
MOK,
found->secure->req_id,
found->request->user, /* bgolden 091996, bug 1257405 */
+ found->secure->slabel,
found->secure->size,
found->secure->date,
found->request->outcome,
@@ -868,8 +909,8 @@
files
);
} else
- mputm(md, R_INQUIRE_REQUEST_RANK, MNOINFO, "", "", 0L, 0L, 0,
- "", "", "", 0, "");
+ mputm(md, R_INQUIRE_REQUEST_RANK, MNOINFO, "", "", "", 0L, 0L,
+ 0, "", "", "", 0, "");
}
static int
@@ -1133,3 +1174,33 @@
return(path);
}
+
+/*
+ * The client is sending a peer connection to retreive label information
+ * from. This is used in the event that the client is an intermediary for
+ * the actual requestor in a Trusted environment.
+ */
+void s_pass_peer_connection(char *m, MESG *md)
+{
+ short status = MTRANSMITERR;
+ char *dest;
+ struct strrecvfd recv_fd;
+
+ (void) getmessage(m, S_PASS_PEER_CONNECTION);
+ syslog(LOG_DEBUG, "s_pass_peer_connection()");
+
+ memset(&recv_fd, NULL, sizeof (recv_fd));
+ if (ioctl(md->readfd, I_RECVFD, &recv_fd) == 0) {
+ int fd = recv_fd.fd;
+
+ if (get_peer_label(fd, &md->slabel) == 0) {
+ if (md->admin == 1)
+ md->admin = -1; /* turn off query privilege */
+ status = MOK;
+ }
+
+ close(fd);
+ }
+
+ mputm(md, R_PASS_PEER_CONNECTION, status);
+}
diff --git a/usr/src/cmd/lp/cmd/lpsched/dispatch.h b/usr/src/cmd/lp/cmd/lpsched/dispatch.h
index cd4c55d..d4d6e50 100644
--- a/usr/src/cmd/lp/cmd/lpsched/dispatch.h
+++ b/usr/src/cmd/lp/cmd/lpsched/dispatch.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -82,6 +81,7 @@
void s_unmount_tray ( char *, MESG *);
void s_paper_changed ( char *, MESG *);
void s_paper_allowed ( char *, MESG *);
+void s_pass_peer_connection ( char * , MESG * );
/**
** dispatch_table[]
diff --git a/usr/src/cmd/lp/cmd/lpsched/disptab.c b/usr/src/cmd/lp/cmd/lpsched/disptab.c
index a9452d5..46366a8 100644
--- a/usr/src/cmd/lp/cmd/lpsched/disptab.c
+++ b/usr/src/cmd/lp/cmd/lpsched/disptab.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 1996 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -139,6 +138,8 @@
/* R_PAPER_CHANGED */ 0, D_BADMSG,
/* S_PAPER_ALLOWED */ s_paper_allowed, 0,
/* R_PAPER_ALLOWED */ 0, D_BADMSG,
+/* S_PASS_PEER_CONNECTION */ s_pass_peer_connection, 0,
+/* R_PASS_PEER_CONNECTION */ 0, D_BADMSG,
};
static char * dispatch_names[] = {
@@ -244,6 +245,8 @@
"R_PAPER_CHANGED",
"S_PAPER_ALLOWED",
"R_PAPER_ALLOWED",
+"S_PASS_PEER_CONNECTION",
+"R_PASS_PEER_CONNECTION",
};
/* see include/msgs.h */
diff --git a/usr/src/cmd/lp/cmd/lpsched/exec.c b/usr/src/cmd/lp/cmd/lpsched/exec.c
index 579cada..4dd2b8a 100644
--- a/usr/src/cmd/lp/cmd/lpsched/exec.c
+++ b/usr/src/cmd/lp/cmd/lpsched/exec.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,6 +28,11 @@
#pragma ident "%Z%%M% %I% %E% SMI"
+#include <pwd.h>
+#include <zone.h>
+#if defined PS_FAULTED
+#undef PS_FAULTED
+#endif /* PS_FAULTED */
#include <dial.h>
#include <stdlib.h>
@@ -38,7 +42,7 @@
#include "dial.h"
#include "lpsched.h"
#include <syslog.h>
-#include <pwd.h>
+#include "tsol/label.h"
#define Done(EC,ERRNO) done(((EC) << 8),ERRNO)
@@ -256,6 +260,7 @@
}
static char time_buf[50];
+
/**
** exec() - FORK AND EXEC CHILD PROCESS
**/
@@ -304,6 +309,8 @@
char *av[ARG_MAX];
char **envp = NULL;
int ac = 0;
+ char *mail_zonename = NULL;
+ char *slabel = NULL;
syslog(LOG_DEBUG, "exec(%s)", _exec_name(type));
@@ -440,7 +447,6 @@
for (i = 0; i < OpenMax; i++)
if (i != ChildMd->writefd)
Close (i);
-
setpgrp();
/* Set a default path */
@@ -717,6 +723,14 @@
request->request->user);
}
/*
+ * Add the sensitivity label to the environment for
+ * banner page and header/footer processing
+ */
+
+ if (is_system_labeled() && request->secure->slabel != NULL)
+ addenv(&envp, "SLABEL", request->secure->slabel);
+
+ /*
* Add the system name to the user name (ala system!user)
* unless it is already there. RFS users may have trouble
* here, sorry!
@@ -1016,9 +1030,8 @@
request->request->alert);
} else {
char *user = strdup(request->secure->user);
- procuid = Lp_Uid;
- procgid = Lp_Gid;
clean_string(user);
+ slabel = request->secure->slabel;
if ((request->request->actions & ACT_WRITE) &&
(!request->secure->system ||
@@ -1032,9 +1045,41 @@
av[ac++] = arg_string(TRUSTED, "/bin/sh");
av[ac++] = arg_string(TRUSTED, "-c");
av[ac++] = arg_string(TRUSTED, "%s", argbuf);
- } else {
+ } else if ((getzoneid() == GLOBAL_ZONEID) &&
+ is_system_labeled() && (slabel != NULL)) {
+ /*
+ * If in the global zone and the system is
+ * labeled, mail is handled via a local
+ * labeled zone that is the same label as
+ * the request.
+ */
+ if ((mail_zonename =
+ get_labeled_zonename(slabel)) ==
+ (char *)-1) {
+ /*
+ * Cannot find labeled zone, just
+ * return 0.
+ */
+ return(0);
+ }
+ }
+ if (mail_zonename == NULL) {
+ procuid = Lp_Uid;
+ procgid = Lp_Gid;
av[ac++] = arg_string(TRUSTED, "%s", BINMAIL);
av[ac++] = arg_string(UNTRUSTED, "%s", user);
+ } else {
+ procuid = getuid();
+ procgid = getgid();
+ av[ac++] = arg_string(TRUSTED, "%s",
+ "/usr/sbin/zlogin");
+ av[ac++] = arg_string(TRUSTED, "%s",
+ mail_zonename);
+ av[ac++] = arg_string(TRUSTED, "%s",
+ BINMAIL);
+ av[ac++] = arg_string(UNTRUSTED, "%s",
+ user);
+ Free(mail_zonename);
}
free(user);
@@ -1070,7 +1115,7 @@
for (i = 0; av[i] != NULL; i++)
syslog(LOG_DEBUG, "exec: av[%d] = %s", i, av[i]);
- for (i = 0; av[i] != NULL; i++)
+ for (i = 0; envp[i] != NULL; i++)
syslog(LOG_DEBUG, "exec: envp[%d] = %s", i, envp[i]);
execvpe(av[0], av, envp);
diff --git a/usr/src/cmd/lp/cmd/lpsched/validate.c b/usr/src/cmd/lp/cmd/lpsched/validate.c
index 017dad7..2791428 100644
--- a/usr/src/cmd/lp/cmd/lpsched/validate.c
+++ b/usr/src/cmd/lp/cmd/lpsched/validate.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2001 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -28,15 +27,23 @@
/* All Rights Reserved */
-#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.11.1.10 */
+#pragma ident "%Z%%M% %I% %E% SMI"
+/* SVr4.0 1.11.1.10 */
/* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
#include "lpsched.h"
#include "validate.h"
+#include <syslog.h>
+#include <errno.h>
+#include <deflt.h>
+#include <tsol/label.h>
+#include <auth_list.h>
+
#define register auto
+
int pickfilter ( RSTATUS * , CANDIDATE * , FSTATUS * );
unsigned long chkprinter_result = 0;
@@ -46,10 +53,14 @@
char * o_length = 0;
static int wants_nobanner = 0;
+static int wants_nolabels = 0;
static int lp_or_root = 0;
static int _chkopts ( RSTATUS *, CANDIDATE * , FSTATUS * );
static void free_candidate ( CANDIDATE * );
+static int tsol_check_printer_label_range(char *, const char *);
+static int tsol_lpauth(char *, char *);
+static int secpolicy_chkpolicy(char *policyp);
/**
** _validate() - FIND A PRINTER TO HANDLE A REQUEST
@@ -79,6 +90,23 @@
wants_nobanner = 0;
memset (&single, 0, sizeof(single));
+ wants_nolabels = 0;
+ /*
+ * If the system is labeled, the printing of postscript files
+ * is restricted. All users can print postscript files if the
+ * file /etc/default/print contains "PRINT_POSTSCRIPT=1".
+ * (this is checked by secpolicy_chkpolicy). Otherwise the
+ * user must have PRINT_POSTSCRIPT_AUTH to print postscript files.
+ */
+ if ((is_system_labeled() &&
+ strcmp(prs->request->input_type, "postscript") == 0) &&
+ (secpolicy_chkpolicy("PRINT_POSTSCRIPT=") == 0)) {
+ if (tsol_lpauth(PRINT_POSTSCRIPT_AUTH, prs->secure->user)
+ == 0) {
+ ret = MDENYDEST;
+ goto Return;
+ }
+ }
lp_or_root = 0;
if (STREQU(prs->secure->system, Local_System))
@@ -166,6 +194,8 @@
o_length = Strdup(*pl + 7);
else if (STREQU(*pl, "nobanner"))
wants_nobanner = 1;
+ else if (STREQU(*pl, "nolabels"))
+ wants_nolabels = 1;
freelist (list);
}
}
@@ -296,6 +326,16 @@
goto Return;
}
+ /* Check printer label range */
+ if (is_system_labeled() && prs->secure->slabel != NULL) {
+ if (tsol_check_printer_label_range(
+ prs->secure->slabel,
+ pps->printer->name) == 0) {
+ ret = MDENYDEST;
+ goto Return;
+ }
+ }
+
/* Does the printer allow the form? */
if (pfs && !CHKF(pfs, pps)) {
ret = MNOMOUNT;
@@ -563,6 +603,30 @@
ret = MOK;
goto Return;
}
+ /*
+ * Clean out local printers
+ * where the request is outside the printer label range.
+ */
+ {
+ register CANDIDATE *pcend2;
+
+ if (is_system_labeled()) {
+ for (pcend2 = pc = arena; pc < pcend; pc++) {
+ if (tsol_check_printer_label_range(
+ prs->secure->slabel,
+ pps->printer->name) == 1)
+ *pcend2++ = *pc;
+ else
+ free_candidate(pc);
+ }
+ }
+
+ if (pcend2 == arena) {
+ ret = MDENYDEST;
+ goto Return;
+ }
+ pcend = pcend2;
+ }
#if defined(OTHER_FACTORS)
/*
@@ -790,6 +854,7 @@
char * paper = NULL;
char ** pt;
+ int nobanner_not_allowed = 0;
/*
@@ -844,11 +909,47 @@
if (!pc->printer_types)
ret |= chk;
- if (pc->pps->printer->banner == BAN_ALWAYS) {
- if ((wants_nobanner == 1) && (lp_or_root != 1)) {
- /* delete "nobanner" */
- char **list;
+ /*
+ * If the sytem is labeled, then user who wants 'nolabels' must
+ * have PRINT_UNLABELED_AUTH authorizations to allow it.
+ */
+ if (is_system_labeled() && (wants_nolabels == 1)) {
+ if (!tsol_lpauth(PRINT_UNLABELED_AUTH, prs->secure->user)) {
+ /* if not authorized, remove "nolabels" from options */
+ register char **list;
+ if (prs->request->options &&
+ (list = dashos(prs->request->options))) {
+ dellist(&list, "nolabels");
+ free(prs->request->options);
+ prs->request->options = sprintlist(list);
+ }
+ }
+ }
+
+ if (pc->pps->printer->banner == BAN_ALWAYS) {
+ /* delete "nobanner" */
+ char **list;
+
+ /*
+ * If the system is labeled, users must have
+ * PRINT_NOBANNER_AUTH authorization to print
+ * without a banner.
+ */
+ if (is_system_labeled()) {
+ if (wants_nobanner == 1) {
+ if (tsol_lpauth(PRINT_NOBANNER_AUTH,
+ prs->secure->user) == 0) {
+ nobanner_not_allowed = 1;
+ }
+ }
+
+ }
+ else if ((wants_nobanner == 1) && (lp_or_root != 1)) {
+ nobanner_not_allowed = 1;
+ }
+ if (nobanner_not_allowed == 1) {
+ /* Take out 'nobanner' from request options. */
if (prs->request->options &&
(list = dashos(prs->request->options))) {
dellist(&list, "nobanner");
@@ -897,3 +998,85 @@
unload_str (&(pc->output_type));
return;
}
+
+static int
+tsol_check_printer_label_range(char *slabel, const char *printer)
+{
+ int in_range = 0;
+ int err = 0;
+ m_range_t *range;
+ m_label_t *sl = NULL;
+
+ if (slabel == NULL)
+ return (0);
+
+ if ((err =
+ (str_to_label(slabel, &sl, USER_CLEAR, L_NO_CORRECTION, &in_range)))
+ == -1) {
+ /* stobsl error on printer max label */
+ return (0);
+ }
+ if ((range = getdevicerange(printer)) == NULL) {
+ m_label_free(sl);
+ return (0);
+ }
+
+ /* blinrange returns true (1) if in range, false (0) if not */
+ in_range = blinrange(sl, range);
+
+ m_label_free(sl);
+ m_label_free(range->lower_bound);
+ m_label_free(range->upper_bound);
+ free(range);
+
+ return (in_range);
+}
+
+/*
+ * Given a character string with a "username" or "system!username"
+ * this function returns a pointer to "username"
+ */
+static int
+tsol_lpauth(char *auth, char *in_name)
+{
+ char *cp;
+ int res;
+
+ if ((cp = strchr(in_name, '@')) != NULL) {
+ /* user@system */
+ *cp = '\0';
+ res = chkauthattr(auth, in_name);
+ *cp = '@';
+ } else if ((cp = strchr(in_name, '!')) != NULL)
+ /* system!user */
+ res = chkauthattr(auth, cp+1);
+ else
+ /* user */
+ res = chkauthattr(auth, in_name);
+
+ return (res);
+}
+
+#define POLICY_FILE "/etc/default/print"
+
+int
+secpolicy_chkpolicy(char *policyp)
+{
+ char *option;
+ int opt_val;
+
+ if (policyp == NULL)
+ return (0);
+ opt_val = 0;
+ if (defopen(POLICY_FILE) == 0) {
+
+ defcntl(DC_SETFLAGS, DC_STD & ~DC_CASE); /* ignore case */
+
+ if ((option = defread(policyp)) != NULL)
+ opt_val = atoi(option);
+ }
+ (void) defopen((char *)NULL);
+ syslog(LOG_DEBUG, "--- Policy %s, opt_val==%d",
+ policyp ? policyp : "NULL", opt_val);
+ return (opt_val);
+}
diff --git a/usr/src/cmd/lp/cmd/lpstat/Makefile b/usr/src/cmd/lp/cmd/lpstat/Makefile
index 2623a14..9e9b661 100644
--- a/usr/src/cmd/lp/cmd/lpstat/Makefile
+++ b/usr/src/cmd/lp/cmd/lpstat/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -18,11 +17,13 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
+
+
#
#
# ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 1989-2002 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# cmd/lp/cmd/lpstat/Makefile
@@ -61,7 +62,7 @@
SYSLIBS= -lcurses
-LDLIBS += $(LPLIBS) $(SYSLIBS) $(I18N)
+LDLIBS += $(LPLIBS) $(SYSLIBS) $(I18N) -z lazyload -lsecdb -z nolazyload
POFILE= lp_cmd_lpstat.po
diff --git a/usr/src/cmd/lp/cmd/lpstat/lpstat.h b/usr/src/cmd/lp/cmd/lpstat/lpstat.h
index a01ef97..b1d9a6d 100644
--- a/usr/src/cmd/lp/cmd/lpstat/lpstat.h
+++ b/usr/src/cmd/lp/cmd/lpstat/lpstat.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,9 +18,11 @@
*
* CDDL HEADER END
*/
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* Copyright (c) 2001 by Sun Microsystems, Inc. */
-/* All Rights Reserved */
#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.7 */
@@ -69,8 +70,8 @@
void do_user ( char ** );
void done ( int );
void parse ( int , char ** );
-void putoline(char *, char *, long, time_t, int, char *, char *,
- char *, int);
+void putoline(char *, char *, char *, long, time_t, int, char *,
+ char *, char *, int);
void putpline(char *, int, char *, time_t, char *, char *, char *);
void putqline(char *, int, time_t, char *);
void putppline ( char * , char *);
diff --git a/usr/src/cmd/lp/cmd/lpstat/output.c b/usr/src/cmd/lp/cmd/lpstat/output.c
index f03a7ec..1cf2051 100644
--- a/usr/src/cmd/lp/cmd/lpstat/output.c
+++ b/usr/src/cmd/lp/cmd/lpstat/output.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -56,6 +55,7 @@
char *class,
*user,
+ *slabel,
*reject_reason,
*request_id,
*printer,
@@ -131,6 +131,7 @@
&status,
&request_id,
&user,
+ &slabel,
&size,
&date,
&state,
@@ -147,8 +148,9 @@
case MOK:
case MOKMORE:
- putoline(request_id, user, size, date, state,
- printer, form, character_set, ++rank);
+ putoline(request_id, user, slabel, size, date,
+ state, printer, form, character_set,
+ ++rank);
break;
}
@@ -161,6 +163,7 @@
&status,
&request_id,
&user,
+ &slabel,
&size,
&date,
&state,
@@ -178,8 +181,9 @@
case MOK:
case MOKMORE:
- putoline(request_id, user, size, date, state,
- printer, form, character_set, rank);
+ putoline(request_id, user, slabel, size, date,
+ state, printer, form, character_set,
+ rank);
break;
}
diff --git a/usr/src/cmd/lp/cmd/lpstat/request.c b/usr/src/cmd/lp/cmd/lpstat/request.c
index 85bd2a6..6ced71d 100644
--- a/usr/src/cmd/lp/cmd/lpstat/request.c
+++ b/usr/src/cmd/lp/cmd/lpstat/request.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -22,9 +21,8 @@
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
-
/*
- * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,6 +34,7 @@
#include "sys/types.h"
#include "lp.h"
+#include "strings.h"
#include "msgs.h"
#include "requests.h"
@@ -178,17 +177,24 @@
user_name = NULL;
}
+
/*
* putoline()
*/
void
-putoline(char *request_id, char *user, long size, time_t clock, int state,
- char *printer, char *form, char *character_set, int rank)
+putoline(char *request_id, char *user, char *slabel, long size, time_t clock,
+ int state, char *printer, char *form, char *character_set, int rank)
{
int showRank;
+ char user_buf[LOGMAX];
char date[SZ_DATE_BUFF];
+ if ((slabel != NULL) && (slabel[0] != '\0'))
+ snprintf(user_buf, sizeof (user_buf), "%s:%s", user, slabel);
+ else
+ snprintf(user_buf, sizeof (user_buf), "%s", user);
+
/*
* This is the basic time format used in the output. It represents
* all times of the form "Dec 11 11:04" seen in the output.
@@ -215,13 +221,12 @@
((showRank) ? IDSIZE - 2 : IDSIZE),
request_id,
LOGMAX-1,
- user,
+ user_buf,
OSIZE,
size,
((showRank) ? "" : " "),
date);
-
if (!(verbosity & (V_LONG|V_BITS))) {
/*
diff --git a/usr/src/cmd/lp/cmd/lpsystem.c b/usr/src/cmd/lp/cmd/lpsystem.c
index b919330..6819f06 100644
--- a/usr/src/cmd/lp/cmd/lpsystem.c
+++ b/usr/src/cmd/lp/cmd/lpsystem.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,14 +19,17 @@
* CDDL HEADER END
*/
/*
- * Copyright 1997 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
-
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.8 */
@@ -45,6 +47,8 @@
#include "systems.h"
#include "msgs.h"
#include "boolean.h"
+#include "access.h"
+#include "tsol/label.h"
#define WHO_AM_I I_AM_LPSYSTEM
#include "oam.h"
@@ -283,11 +287,22 @@
SecurityCheck ()
#endif
{
- if (geteuid () != 0)
- {
- (void) fprintf (stderr,
- gettext("ERROR: You must be root.\n"));
- (void) exit (1);
+ /* On labeled systems check that user has print admin authorization */
+ if (is_system_labeled()) {
+ if (is_user_admin() == 0) {
+ (void) fprintf(stderr,
+ gettext(
+ "You are not authorized to administer printing.\n"\
+ ));
+ (void) exit (1);
+ }
+ } else {
+ if (geteuid () != 0)
+ {
+ (void) fprintf (stderr,
+ gettext("ERROR: You must be root.\n"));
+ (void) exit (1);
+ }
}
}
/*==================================================================*/
diff --git a/usr/src/cmd/lp/include/lp.h b/usr/src/cmd/lp/include/lp.h
index 4a7beb3..9cc5c01 100644
--- a/usr/src/cmd/lp/include/lp.h
+++ b/usr/src/cmd/lp/include/lp.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -599,6 +598,14 @@
char * next_x ( char * , long * , unsigned int );
+/*
+ * Stuff needed for Trusted Extensions
+ */
+
+extern char *get_labeled_zonename(char *);
+extern int get_peer_label(int fd, char **slabel);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/cmd/lp/include/msgs.h b/usr/src/cmd/lp/include/msgs.h
index f9aa711..7fa7046 100644
--- a/usr/src/cmd/lp/include/msgs.h
+++ b/usr/src/cmd/lp/include/msgs.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -152,10 +151,12 @@
# define R_PAPER_CHANGED 99
# define S_PAPER_ALLOWED 100
# define R_PAPER_ALLOWED 101
+# define S_PASS_PEER_CONNECTION 102
+# define R_PASS_PEER_CONNECTION 103
/*
** Last available message
*/
-# define LAST_MESSAGE 102
+# define LAST_MESSAGE 104
/*
** These are the possible status codes returned by the scheduler
@@ -322,6 +323,7 @@
MQUE * mque; /* backlogged message ptr */
uid_t uid; /* Clients UID */
gid_t gid; /* Clients GID */
+ char * slabel; /* Clients SLABEL */
void (**on_discon)(); /* Clean up functions */
} MESG;
diff --git a/usr/src/cmd/lp/include/secure.h b/usr/src/cmd/lp/include/secure.h
index b9b6323..ee95ff8 100644
--- a/usr/src/cmd/lp/include/secure.h
+++ b/usr/src/cmd/lp/include/secure.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -40,9 +39,9 @@
**/
/*
- * There are 7 fields in the secure request file.
+ * There are 8 fields in the secure request file.
*/
-#define SC_MAX 7
+#define SC_MAX 8
# define SC_REQID 0 /* Original request id */
# define SC_UID 1 /* Originator's user ID */
# define SC_USER 2 /* Originator's real login name */
@@ -50,6 +49,7 @@
# define SC_SIZE 4 /* Total size of the request data */
# define SC_DATE 5 /* Date submitted (in seconds) */
# define SC_SYSTEM 6 /* Originating system */
+# define SC_SLABEL 7 /* Sensitivity Label */
/**
** The internal copy of a request as seen by the rest of the world:
@@ -63,6 +63,7 @@
char *system;
char *user;
char *req_id;
+ char *slabel;
} SECURE;
/**
diff --git a/usr/src/cmd/lp/lib/access/allowed.c b/usr/src/cmd/lp/lib/access/allowed.c
index a0a5eb7..c8f6844 100644
--- a/usr/src/cmd/lp/lib/access/allowed.c
+++ b/usr/src/cmd/lp/lib/access/allowed.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -23,7 +22,13 @@
/* All Rights Reserved */
-#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.7 */
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
/* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
#include "string.h"
@@ -31,6 +36,10 @@
#include "lp.h"
#include "access.h"
+#include <pwd.h>
+#include <auth_attr.h>
+#include <auth_list.h>
+#include <tsol/label.h>
/**
** is_user_admin() - CHECK IF CURRENT USER IS AN ADMINISTRATOR
@@ -45,7 +54,15 @@
is_user_admin ()
#endif
{
- return (Access(Lp_A, W_OK) == -1? 0 : 1);
+ /* For a labeled system, tsol_check_admin_auth is called
+ * instead of using Access.
+ */
+ if (is_system_labeled()) {
+ /* Check that user has print admin authorization */
+ return (tsol_check_admin_auth(getuid()));
+ } else {
+ return (Access(Lp_A, W_OK) == -1? 0 : 1);
+ }
}
/**
@@ -181,3 +198,22 @@
return (0);
}
+
+/*
+ * Check to see if the specified user has the administer the printing
+ * system authorization.
+ */
+int
+tsol_check_admin_auth(uid_t uid)
+{
+ struct passwd *p;
+ char *name;
+
+ p = getpwuid(uid);
+ if (p != NULL && p->pw_name != NULL)
+ name = p->pw_name;
+ else
+ name = "";
+
+ return (chkauthattr(PRINT_ADMIN_AUTH, name));
+}
diff --git a/usr/src/cmd/lp/lib/lp/Makefile b/usr/src/cmd/lp/lib/lp/Makefile
index 440d800..3d14c21 100644
--- a/usr/src/cmd/lp/lib/lp/Makefile
+++ b/usr/src/cmd/lp/lib/lp/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -18,9 +17,11 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
+
+
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -69,6 +70,7 @@
syntax.o \
tidbit.o \
tinames.o \
+ tx.o \
wherelist.o \
which.o
diff --git a/usr/src/cmd/lp/lib/lp/tx.c b/usr/src/cmd/lp/lib/lp/tx.c
new file mode 100644
index 0000000..5ab2944
--- /dev/null
+++ b/usr/src/cmd/lp/lib/lp/tx.c
@@ -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 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/zone.h>
+#include <syslog.h>
+#include <strings.h>
+
+#include <ucred.h>
+#include "tsol/label.h"
+/* lpsched include files */
+#if defined PS_FAULTED
+#undef PS_FAULTED
+#endif /* PS_FAULTED */
+#include "lp.h"
+
+/*
+ * get_labeled_zonename - gets the the zonename with the same label.
+ *
+ * Input:
+ * slabel - USER_CLEAR label to match
+ *
+ * Output:
+ * -1 - zonename with that label could not be found
+ * or no memory for zonename
+ * 0 - label was GLOBAL_ZONENAME
+ * addr - zonename of zone matching USER_CLEAR label
+ * must be retuened by calling Free(addr)
+ *
+ */
+
+char *
+get_labeled_zonename(char *slabel)
+{
+ m_label_t *bsl = NULL;
+ int err = 0;
+ ssize_t zonename_size = -1;
+ zoneid_t zid = -1;
+ char *zname = NULL;
+
+ syslog(LOG_DEBUG, "lpsched: get_labeled_zonename %s", slabel);
+ /*
+ * convert the label to binary.
+ */
+ if (str_to_label(slabel, &bsl, USER_CLEAR,
+ L_NO_CORRECTION, &err) == -1) {
+ /* label could not be converted, error */
+ syslog(LOG_WARNING,
+ "lpsched: %s: label not recognized (error==%d)",
+ slabel, err);
+ return ((char *)-1);
+ }
+ if ((zid = getzoneidbylabel(bsl)) < 0) {
+ /* no zone with that label, cannot send mail */
+ syslog(LOG_WARNING,
+ "lpsched: cannot send mail, no zone with %s label",
+ slabel);
+ m_label_free(bsl);
+ return ((char *)-1);
+ }
+ zname = Malloc(ZONENAME_MAX + 1);
+ if ((zonename_size = getzonenamebyid(zid, zname, ZONENAME_MAX + 1))
+ == -1) {
+ /* cannot get zone name, cannot send mail */
+ syslog(LOG_WARNING,
+ "lpsched: cannot send mail, no zone name for %s",
+ slabel);
+ m_label_free(bsl);
+ Free(zname);
+ return ((char *)-1);
+ } else {
+ m_label_free(bsl);
+ if (strcmp(zname, GLOBAL_ZONENAME) == 0) {
+ Free(zname);
+ zname = NULL;
+ }
+ }
+ return (zname);
+}
+
+int
+get_peer_label(int fd, char **slabel)
+{
+ if (is_system_labeled()) {
+ ucred_t *uc = NULL;
+ m_label_t *sl;
+ char *pslabel = NULL; /* peer's slabel */
+
+ if ((fd < 0) || (slabel == NULL)) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if (getpeerucred(fd, &uc) == -1)
+ return (-1);
+
+ sl = ucred_getlabel(uc);
+ if (label_to_str(sl, &pslabel, M_INTERNAL, DEF_NAMES) != 0)
+ syslog(LOG_WARNING, "label_to_str(): %m");
+ ucred_free(uc);
+
+ if (pslabel != NULL) {
+ syslog(LOG_DEBUG, "get_peer_label(%d, %s): becomes %s",
+ fd, (*slabel ? *slabel : "NULL"), pslabel);
+ if (*slabel != NULL)
+ free(*slabel);
+ *slabel = strdup(pslabel);
+ }
+ }
+
+ return (0);
+}
diff --git a/usr/src/cmd/lp/lib/msgs/mlisten.c b/usr/src/cmd/lp/lib/msgs/mlisten.c
index f6f9c3d..b792801 100644
--- a/usr/src/cmd/lp/lib/msgs/mlisten.c
+++ b/usr/src/cmd/lp/lib/msgs/mlisten.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 1997 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,6 +36,9 @@
# include <fcntl.h>
# include <errno.h>
#include <syslog.h>
+#include <user_attr.h>
+#include <secdb.h>
+#include <pwd.h>
# include "lp.h"
# include "msgs.h"
@@ -328,7 +330,21 @@
md->type = MD_UNKNOWN;
md->uid = recbuf.uid;
+ /*
+ * Determine if a print administrator is contacting lpsched.
+ * currently, root, lp and users with the "solaris.print.admin"
+ * privilege are print administrators
+ */
md->admin = (md->uid == 0 || md->uid == Lp_Uid);
+ if (md->admin == 0) {
+ struct passwd *pw = NULL;
+
+ if ((pw = getpwuid(md->uid)) != NULL)
+ md->admin = chkauthattr("solaris.print.admin",
+ pw->pw_name);
+ }
+
+ get_peer_label(md->readfd, &md->slabel);
if (mlistenadd(md, POLLIN) != 0)
return(NULL);
diff --git a/usr/src/cmd/lp/lib/msgs/msgfmts.c b/usr/src/cmd/lp/lib/msgs/msgfmts.c
index 0596079..efe7bfc 100644
--- a/usr/src/cmd/lp/lib/msgs/msgfmts.c
+++ b/usr/src/cmd/lp/lib/msgs/msgfmts.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -47,7 +46,7 @@
"S", /* 11 - S_CANCEL_REQUEST */
"H", /* 12 - R_CANCEL_REQUEST */
"SSSSS", /* 13 - S_INQUIRE_REQUEST */
- "HSSLLHSSSS", /* 14 - R_INQUIRE_REQUEST */
+ "HSSSLLHSSSS", /* 14 - R_INQUIRE_REQUEST */
"S", /* 15 - S_LOAD_PRINTER */
"H", /* 16 - R_LOAD_PRINTER */
"S", /* 17 - S_UNLOAD_PRINTER */
@@ -108,7 +107,7 @@
"SSHH", /* 72 - S_GET_STATUS */
"HSHH", /* 73 - R_GET_STATUS */
"HSSSSS", /* 74 - S_INQUIRE_REQUEST_RANK */
- "HSSLLHSSSHS", /* 75 - R_INQUIRE_REQUEST_RANK */
+ "HSSSLLHSSSHS", /* 75 - R_INQUIRE_REQUEST_RANK */
"SSS", /* 76 - S_CANCEL */
"HLS", /* 77 - R_CANCEL */
"S", /* 78 - S_NEW_CHILD */
@@ -136,5 +135,7 @@
"H", /* 99 - R_PAPER_CHANGED */
"S", /* 100 - S_PAPER_ALLOWED */
"HSS", /* 101 - R_PAPER_ALLOWED */
+ "", /* 102 - S_PASS_PEER_CONNECTION */
+ "H", /* 103 - R_PASS_PEER_CONNECTION */
0,
};
diff --git a/usr/src/cmd/lp/lib/papi/Makefile b/usr/src/cmd/lp/lib/papi/Makefile
index b7afa69..72c7ff6 100644
--- a/usr/src/cmd/lp/lib/papi/Makefile
+++ b/usr/src/cmd/lp/lib/papi/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -18,9 +17,11 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
+
+
#
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -45,6 +46,8 @@
CPPFLAGS += -I$(LPINC)
CPPFLAGS += -I$(SRC)/lib
CPPFLAGS += -D_REENTRANT
+CPPFLAGS += $(ENVCPPFLAGS1)
+CPPFLAGS += $(ENVCPPFLAGS2)
LDLIBS += -lc
LDLIBS += -L$(SRC)/cmd/lp/lib/msgs -llpmsg
LDLIBS += -L$(SRC)/cmd/lp/lib/printers -llpprt
diff --git a/usr/src/cmd/lp/lib/papi/job.c b/usr/src/cmd/lp/lib/papi/job.c
index c2c8843..ff8aea7 100644
--- a/usr/src/cmd/lp/lib/papi/job.c
+++ b/usr/src/cmd/lp/lib/papi/job.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -783,6 +782,7 @@
*request_id = NULL,
*charset = NULL,
*user = NULL,
+ *slabel = NULL,
*file = NULL;
time_t date = 0;
size_t size = 0;
@@ -801,7 +801,7 @@
return (PAPI_SERVICE_UNAVAILABLE);
if (rcv_msg(svc, R_INQUIRE_REQUEST_RANK, &rc, &request_id,
- &user, &size, &date, &state, &dest, &form,
+ &user, &slabel, &size, &date, &state, &dest, &form,
&charset, &rank, &file) < 0) {
detailed_error(svc,
gettext("failed to read response from scheduler"));
@@ -814,7 +814,7 @@
if ((*job = j = calloc(1, sizeof (*j))) == NULL)
return (PAPI_TEMPORARY_ERROR);
- job_status_to_attributes(j, request_id, user, size, date, state,
+ job_status_to_attributes(j, request_id, user, slabel, size, date, state,
dest, form, charset, rank, file);
snprintf(req_id, sizeof (req_id), "%d-0", job_id);
diff --git a/usr/src/cmd/lp/lib/papi/lpsched-jobs.c b/usr/src/cmd/lp/lib/papi/lpsched-jobs.c
index 190aa9a..225cc08 100644
--- a/usr/src/cmd/lp/lib/papi/lpsched-jobs.c
+++ b/usr/src/cmd/lp/lib/papi/lpsched-jobs.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -470,9 +469,9 @@
* Convert R_REQUEST_* results to the equivalent PAPI attribute representation.
*/
void
-job_status_to_attributes(job_t *job, char *req_id, char *user, size_t size,
- time_t date, short state, char *destination, char *form,
- char *charset, short rank, char *file)
+job_status_to_attributes(job_t *job, char *req_id, char *user, char *slabel,
+ size_t size, time_t date, short state, char *destination,
+ char *form, char *charset, short rank, char *file)
{
char buf[BUFSIZ];
char *p;
@@ -517,6 +516,8 @@
"lpsched-file", file);
addLPString(&job->attributes, PAPI_ATTR_EXCL,
"job-name", file);
+ addLPString(&job->attributes, PAPI_ATTR_EXCL,
+ "tsol-sensitivity-label", slabel);
}
void
diff --git a/usr/src/cmd/lp/lib/papi/mapfile-vers b/usr/src/cmd/lp/lib/papi/mapfile-vers
index 0aaa691..2bddef2 100644
--- a/usr/src/cmd/lp/lib/papi/mapfile-vers
+++ b/usr/src/cmd/lp/lib/papi/mapfile-vers
@@ -1,13 +1,14 @@
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
+# ident "%Z%%M% %I% %E% SMI"
+#
# 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 +23,6 @@
#
# CDDL HEADER END
#
-# ident "%Z%%M% %I% %E% SMI"
#
# Generic interface definition for usr/src/cmd/lp/lib/papi
#
@@ -65,6 +65,7 @@
papiServiceCreate;
papiServiceDestroy;
+ papiServiceSetPeer; # used by to pass peer connection
papiServiceSetUserName;
papiServiceSetPassword;
papiServiceSetEncryption;
diff --git a/usr/src/cmd/lp/lib/papi/papi_impl.h b/usr/src/cmd/lp/lib/papi/papi_impl.h
index 8dfdb2a..d2359f4 100644
--- a/usr/src/cmd/lp/lib/papi/papi_impl.h
+++ b/usr/src/cmd/lp/lib/papi/papi_impl.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -82,9 +81,9 @@
extern void lpsched_request_to_job(REQUEST *r, job_t *j);
extern void job_status_to_attributes(job_t *job, char *req_id, char *user,
- size_t size, time_t date, short state,
- char *destination, char *form, char *charset,
- short rank, char *file);
+ char *slabel, size_t size, time_t date,
+ short state, char *destination, char *form,
+ char *charset, short rank, char *file);
extern papi_status_t addLPString(papi_attribute_t ***list,
int flags, char *name, char *value);
extern papi_status_t addLPStrings(papi_attribute_t ***list,
diff --git a/usr/src/cmd/lp/lib/papi/printer.c b/usr/src/cmd/lp/lib/papi/printer.c
index 8a3bd8c..2bfc1ea 100644
--- a/usr/src/cmd/lp/lib/papi/printer.c
+++ b/usr/src/cmd/lp/lib/papi/printer.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -328,14 +327,15 @@
*req_id = NULL,
*charset = NULL,
*owner = NULL,
+ *slabel = NULL,
*file = NULL;
time_t date = 0;
size_t size = 0;
short rank = 0, state = 0;
if (rcv_msg(svc, R_INQUIRE_REQUEST_RANK, &rc, &req_id,
- &owner, &size, &date, &state, &dest, &form,
- &charset, &rank, &file) < 0)
+ &owner, &slabel, &size, &date, &state, &dest,
+ &form, &charset, &rank, &file) < 0)
return (PAPI_SERVICE_UNAVAILABLE);
if ((rc != MOK) && (rc != MOKMORE))
@@ -352,8 +352,8 @@
if ((job = calloc(1, sizeof (*job))) == NULL)
continue;
- job_status_to_attributes(job, req_id, owner, size, date, state,
- dest, form, charset, rank, file);
+ job_status_to_attributes(job, req_id, owner, slabel, size,
+ date, state, dest, form, charset, rank, file);
if ((ptr = strrchr(file, '-')) != NULL) {
*++ptr = '0';
diff --git a/usr/src/cmd/lp/lib/papi/service.c b/usr/src/cmd/lp/lib/papi/service.c
index 6444bdf..d451263 100644
--- a/usr/src/cmd/lp/lib/papi/service.c
+++ b/usr/src/cmd/lp/lib/papi/service.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,6 +35,8 @@
#include <libintl.h>
#include <papi_impl.h>
+#include <tsol/label.h>
+
papi_status_t
papiServiceCreate(papi_service_t *handle, const char *service_name,
const char *user_name, const char *password,
@@ -91,6 +92,38 @@
}
}
+/*
+ * interface for passing a peer's connection to gather sensitivity labeling
+ * from for Trusted Solaris.
+ */
+papi_status_t
+papiServiceSetPeer(papi_service_t handle, int peerfd)
+{
+ papi_status_t result = PAPI_OK;
+ service_t *svc = handle;
+
+ if (svc == NULL)
+ return (PAPI_BAD_ARGUMENT);
+
+ if (is_system_labeled) {
+ short status;
+
+ if ((snd_msg(svc, S_PASS_PEER_CONNECTION) < 0) ||
+ (ioctl(svc->md->writefd, I_SENDFD, peerfd) < 0) ||
+ (rcv_msg(svc, R_PASS_PEER_CONNECTION, &status) < 0))
+ status = MTRANSMITERR;
+
+ if (status != MOK) {
+ detailed_error(svc,
+ gettext("failed to send peer connection: %s"),
+ lpsched_status_string(status));
+ result = lpsched_status_to_papi_status(status);
+ }
+ }
+
+ return (result);
+}
+
papi_status_t
papiServiceSetUserName(papi_service_t handle, const char *user_name)
{
diff --git a/usr/src/cmd/lp/lib/secure/secure.c b/usr/src/cmd/lp/lib/secure/secure.c
index 4bc257f..09796de 100644
--- a/usr/src/cmd/lp/lib/secure/secure.c
+++ b/usr/src/cmd/lp/lib/secure/secure.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 1997 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,6 +36,7 @@
#include "lp.h"
#include "secure.h"
+#include <tsol/label.h>
/**
** getsecure() - EXTRACT SECURE REQUEST STRUCTURE FROM DISK FILE
@@ -105,6 +105,10 @@
case SC_SYSTEM:
secbuf.system = Strdup(buf);
break;
+
+ case SC_SLABEL:
+ secbuf.slabel = Strdup(buf);
+ break;
}
}
if (errno != 0 || fld != SC_MAX) {
@@ -199,8 +203,31 @@
case SC_SYSTEM:
(void)fdprintf(fd, "%s\n", secbufp->system);
break;
- }
+ case SC_SLABEL:
+ if (secbufp->slabel == NULL) {
+ if (is_system_labeled()) {
+ m_label_t *sl;
+
+ sl = m_label_alloc(MAC_LABEL);
+ (void) getplabel(sl);
+ if (label_to_str(sl, &(secbufp->slabel),
+ M_INTERNAL, DEF_NAMES) != 0) {
+ perror("label_to_str");
+ secbufp->slabel =
+ strdup("bad_label");
+ }
+ m_label_free(sl);
+ (void) fdprintf(fd, "%s\n",
+ secbufp->slabel);
+ } else {
+ (void) fdprintf(fd, "none\n");
+ }
+ } else {
+ (void) fdprintf(fd, "%s\n", secbufp->slabel);
+ }
+ break;
+ }
close(fd);
return (0);
diff --git a/usr/src/cmd/mdb/common/modules/genunix/genunix.c b/usr/src/cmd/mdb/common/modules/genunix/genunix.c
index 4d72a12..ab0b15c 100644
--- a/usr/src/cmd/mdb/common/modules/genunix/genunix.c
+++ b/usr/src/cmd/mdb/common/modules/genunix/genunix.c
@@ -93,6 +93,7 @@
#include "sobj.h"
#include "sysevent.h"
#include "rctl.h"
+#include "tsol.h"
#include "typegraph.h"
#include "ldi.h"
#include "vfs.h"
@@ -3388,7 +3389,7 @@
/* from net.c */
{ "mi", ":[-p] [-d | -m]", "filter and display MI object or payload",
mi },
- { "netstat", "[-av] [-f inet | inet6 | unix] [-P tcp | udp]",
+ { "netstat", "[-arv] [-f inet | inet6 | unix] [-P tcp | udp]",
"show network statistics", netstat },
{ "sonode", "?[-f inet | inet6 | unix | #] "
"[-t stream | dgram | raw | #] [-p #]",
@@ -3763,6 +3764,12 @@
{ "tsd", "walk list of thread-specific data",
tsd_walk_init, tsd_walk_step, tsd_walk_fini },
+ /* from tsol.c */
+ { "tnrh", "walk remote host cache structures",
+ tnrh_walk_init, tnrh_walk_step, tnrh_walk_fini },
+ { "tnrhtp", "walk remote host template structures",
+ tnrhtp_walk_init, tnrhtp_walk_step, tnrhtp_walk_fini },
+
/*
* typegraph does not work under kmdb, as it requires too much memory
* for its internal data structures.
diff --git a/usr/src/cmd/mdb/common/modules/genunix/net.c b/usr/src/cmd/mdb/common/modules/genunix/net.c
index 209b207..0195489 100644
--- a/usr/src/cmd/mdb/common/modules/genunix/net.c
+++ b/usr/src/cmd/mdb/common/modules/genunix/net.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -57,8 +56,14 @@
#define ADDR_V6_WIDTH 23
#define ADDR_V4_WIDTH 15
-#define NETSTAT_ALL 0x1
-#define NETSTAT_VERBOSE 0x2
+#define NETSTAT_ALL 0x01
+#define NETSTAT_VERBOSE 0x02
+#define NETSTAT_ROUTE 0x04
+#define NETSTAT_V4 0x08
+#define NETSTAT_V6 0x10
+#define NETSTAT_UNIX 0x20
+
+#define NETSTAT_FIRST 0x80000000u
/*
* Print an IPv4 address and port number in a compact and easy to read format
@@ -790,6 +795,305 @@
"Swind", "Snext", "Suna", "Rwind", "Rack", "Rnext", "Rto", "Mss");
}
+static void
+get_ifname(const ire_t *ire, char *intf)
+{
+ ill_t ill;
+
+ *intf = '\0';
+ if (ire->ire_type == IRE_CACHE) {
+ queue_t stq;
+
+ if (mdb_vread(&stq, sizeof (stq), (uintptr_t)ire->ire_stq) ==
+ -1)
+ return;
+ if (mdb_vread(&ill, sizeof (ill), (uintptr_t)stq.q_ptr) == -1)
+ return;
+ (void) mdb_readstr(intf, MIN(LIFNAMSIZ, ill.ill_name_length),
+ (uintptr_t)ill.ill_name);
+ } else if (ire->ire_ipif != NULL) {
+ ipif_t ipif;
+ char *cp;
+
+ if (mdb_vread(&ipif, sizeof (ipif),
+ (uintptr_t)ire->ire_ipif) == -1)
+ return;
+ if (mdb_vread(&ill, sizeof (ill), (uintptr_t)ipif.ipif_ill) ==
+ -1)
+ return;
+ (void) mdb_readstr(intf, MIN(LIFNAMSIZ, ill.ill_name_length),
+ (uintptr_t)ill.ill_name);
+ if (ipif.ipif_id != 0) {
+ cp = intf + strlen(intf);
+ (void) mdb_snprintf(cp, LIFNAMSIZ + 1 - (cp - intf),
+ ":%u", ipif.ipif_id);
+ }
+ }
+}
+
+static void
+get_v4flags(const ire_t *ire, char *flags)
+{
+ (void) strcpy(flags, "U");
+ if (ire->ire_type == IRE_DEFAULT || ire->ire_type == IRE_PREFIX ||
+ ire->ire_type == IRE_HOST || ire->ire_type == IRE_HOST_REDIRECT)
+ (void) strcat(flags, "G");
+ if (ire->ire_mask == IP_HOST_MASK)
+ (void) strcat(flags, "H");
+ if (ire->ire_type == IRE_HOST_REDIRECT)
+ (void) strcat(flags, "D");
+ if (ire->ire_type == IRE_CACHE)
+ (void) strcat(flags, "A");
+ if (ire->ire_type == IRE_BROADCAST)
+ (void) strcat(flags, "B");
+ if (ire->ire_type == IRE_LOCAL)
+ (void) strcat(flags, "L");
+ if (ire->ire_flags & RTF_MULTIRT)
+ (void) strcat(flags, "M");
+ if (ire->ire_flags & RTF_SETSRC)
+ (void) strcat(flags, "S");
+}
+
+static int
+ip_mask_to_plen(ipaddr_t mask)
+{
+ int i;
+
+ if (mask == 0)
+ return (0);
+ for (i = 32; i > 0; i--, mask >>= 1)
+ if (mask & 1)
+ break;
+ return (i);
+}
+
+static int
+netstat_irev4_cb(uintptr_t kaddr, const void *walk_data, void *cb_data)
+{
+ const ire_t *ire = walk_data;
+ uint_t *opts = cb_data;
+ ipaddr_t gate;
+ char flags[10], intf[LIFNAMSIZ + 1];
+
+ if (ire->ire_ipversion != IPV4_VERSION || ire->ire_in_src_addr != 0 ||
+ ire->ire_in_ill != NULL)
+ return (WALK_NEXT);
+
+ if (!(*opts & NETSTAT_ALL) && (ire->ire_type == IRE_CACHE ||