diff options
Diffstat (limited to 'usr/src/lib')
127 files changed, 13970 insertions, 1114 deletions
diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile index 892a841235..c7d90d71de 100644 --- a/usr/src/lib/Makefile +++ b/usr/src/lib/Makefile @@ -184,6 +184,8 @@ SUBDIRS += \ libxnet \ libzonecfg \ libzoneinfo \ + libtsnet \ + libtsol \ gss_mechs/mech_spnego \ gss_mechs/mech_dummy \ gss_mechs/mech_dh \ @@ -268,6 +270,7 @@ MSGSUBDIRS= \ libsldap \ libslp \ libsmedia \ + libtsol \ libuutil \ libwanboot \ libwanbootutil \ @@ -327,6 +330,7 @@ HDRSUBDIRS= libaio \ libmail \ libmtmalloc \ libnvpair \ + libnsl \ libpam \ libpctx \ libpicl \ @@ -349,6 +353,8 @@ HDRSUBDIRS= libaio \ libtnf \ libtnfctl \ libtnfprobe \ + libtsnet \ + libtsol \ libvolmgt \ libumem \ libuutil \ @@ -425,6 +431,7 @@ auditd_plugins: libbsm libnsl libsecdb gss_mechs/mech_krb5: libgss libnsl libsocket libresolv pkcs11 libadt_jni: libbsm $(CLOSED_BUILD)libc: $(CLOSED)/lib/libc_i18n +libbsm: libtsol libcmdutils: libavl libcontract: libnvpair libdevid: libdevinfo @@ -450,9 +457,10 @@ sasl_plugins: pkcs11 libgss libsocket libsasl libsctp: libsocket libsocket: libnsl libldap5: libsasl libsocket libnsl libmd5 -libsldap: libldap5 +libsldap: libldap5 libtsol libpool: libnvpair libexacct libproject: libpool libproc libsecdb +libtsnet: libnsl libtsol libsecdb libwrap: libnsl libsocket libwanboot: libnvpair libresolv libnsl libsocket libdevinfo libinetutil \ libdhcputil openssl diff --git a/usr/src/lib/auditd_plugins/syslog/systoken.c b/usr/src/lib/auditd_plugins/syslog/systoken.c index 7ccc79d3c9..ae251a67bd 100644 --- a/usr/src/lib/auditd_plugins/syslog/systoken.c +++ b/usr/src/lib/auditd_plugins/syslog/systoken.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -46,6 +45,7 @@ #include <string.h> #include <sys/types.h> #include <bsm/libbsm.h> +#include <sys/tsol/label.h> #include "toktable.h" /* ../praudit */ #include "sysplugin.h" #include "systoken.h" @@ -1381,46 +1381,6 @@ xclient_token(parse_context_t *ctx) return (0); } -/* - * Format of clearance token: - * clearance adr_char*(sizeof (bclear_t)) - * - * ifdef TSOL because of bclear_t - */ -#ifndef TSOL -/* ARGSUSED */ -#endif /* !TSOL */ -int -clearance_token(parse_context_t *ctx) -{ -#ifdef TSOL - - ctx->adr.adr_now += sizeof (bclear_t); - - return (0); -#else /* !TSOL */ - return (-1); -#endif /* TSOL */ -} -/* - * Format of ilabel token: - * ilabel adr_char*(sizeof (bilabel_t)) - */ -#ifndef TSOL -/* ARGSUSED */ -#endif /* !TSOL */ -int -ilabel_token(parse_context_t *ctx) -{ -#ifdef TSOL - - ctx->adr.adr_now += sizeof (bilabel_t); - - return (0); -#else /* !TSOL */ - return (-1); -#endif /* TSOL */ -} /* * ----------------------------------------------------------------------- @@ -1445,22 +1405,23 @@ privilege_token(parse_context_t *ctx) /* * Format of slabel token: - * slabel adr_char*(sizeof (bslabel_t)) + * label ID 1 byte + * compartment length 1 byte + * classification 2 bytes + * compartment words <compartment length> * 4 bytes */ -#ifndef TSOL -/* ARGSUSED */ -#endif /* !TSOL */ int slabel_token(parse_context_t *ctx) { -#ifdef TSOL + char c; - ctx->adr.adr_now += sizeof (bslabel_t); + ctx->adr.adr_now += sizeof (char); /* label ID */ + adrm_char(&(ctx->adr), &c, 1); + + ctx->adr.adr_now += sizeof (ushort_t); /* classification */ + ctx->adr.adr_now += 4 * c; /* compartments */ return (0); -#else /* !TSOL */ - return (-1); -#endif /* TSOL */ } /* diff --git a/usr/src/lib/auditd_plugins/syslog/systoken.h b/usr/src/lib/auditd_plugins/syslog/systoken.h index db60ae43aa..af6517845a 100644 --- a/usr/src/lib/auditd_plugins/syslog/systoken.h +++ b/usr/src/lib/auditd_plugins/syslog/systoken.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -97,9 +96,7 @@ extern void acl_token(adr_t *, parse_context_t *); extern void attribute_token(adr_t *, parse_context_t *); extern void s5_IPC_perm_token(adr_t *, parse_context_t *); extern void group_token(); -extern void ilabel_token(adr_t *, parse_context_t *); extern void slabel_token(adr_t *, parse_context_t *); -extern void clearance_token(adr_t *, parse_context_t *); extern void privilege_token(adr_t *, parse_context_t *); extern void useofpriv_token(adr_t *, parse_context_t *); extern void zonename_token(adr_t *, parse_context_t *); diff --git a/usr/src/lib/common/inc/c_synonyms.h b/usr/src/lib/common/inc/c_synonyms.h index 06fa420471..2143bb8d06 100644 --- a/usr/src/lib/common/inc/c_synonyms.h +++ b/usr/src/lib/common/inc/c_synonyms.h @@ -414,6 +414,7 @@ extern "C" { #define isastream _isastream #define isatty _isatty #define issetugid _issetugid +#define is_system_labeled _is_system_labeled #define jrand48 _jrand48 #define kaio _kaio #define kill _kill diff --git a/usr/src/lib/libbsm/Makefile b/usr/src/lib/libbsm/Makefile index 55ccf943e2..4cc23687a8 100644 --- a/usr/src/lib/libbsm/Makefile +++ b/usr/src/lib/libbsm/Makefile @@ -18,6 +18,7 @@ # # CDDL HEADER END # + # # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. @@ -27,7 +28,6 @@ # lib/libbsm/Makefile # -include ../../Makefile.master include ../Makefile.lib SUBDIRS= spec .WAIT $(MACH) $(BUILD64) $(MACH64) @@ -46,54 +46,13 @@ package := TARGET= package all clean clobber delete install lint package: $(SUBDIRS) -OBJECTS= adr.o \ - adrf.o \ - adrm.o \ - adt.o \ - adt_token.o \ - adt_xlate.o \ - au_open.o \ - au_preselect.o \ - au_to.o \ - au_usermask.o \ - audit_allocate.o \ - audit_class.o \ - audit_cron.o \ - audit_crontab.o \ - audit_at.o \ - audit_event.o \ - audit_ftpd.o \ - audit_halt.o \ - audit_inetd.o \ - audit_kadmind.o \ - audit_krb5kdc.o \ - audit_mountd.o \ - audit_newgrp.o \ - audit_plugin.o \ - audit_reboot.o \ - audit_rexd.o \ - audit_rexecd.o \ - audit_rshd.o \ - audit_settid.o \ - audit_shutdown.o \ - audit_uadmin.o \ - audit_user.o \ - bsm.o \ - generic.o \ - getacinfo.o \ - getacval.o \ - getauditflags.o \ - getdaent.o \ - getdment.o \ - getfaudflgs.o - COMMONDIR = common # # Macros for libbsm header files. These define user-level only interfaces. # GENHDRS = audit_uevents.h -HDRS = libbsm.h devices.h adt.h adt_event.h audit_private.h +HDRS = libbsm.h devices.h devalloc.h adt.h adt_event.h audit_private.h COMMONHDRS = $(HDRS:%=$(COMMONDIR)/%) ROOTHDRDIR = $(ROOT)/usr/include/bsm ROOTCHDRS = $(HDRS:%=$(ROOTHDRDIR)/%) @@ -154,10 +113,8 @@ ARSYMLNK=$(RESAL)/files # # message catalogue file # -TEXT_DOMAIN= SUNW_OST_OSLIB -POFILE= libbsm.po -CATALOG=libbsm.po -POFILES= $(OBJECTS:%.o=%.po) +MSGFILES = `$(GREP) -l gettext $(COMMONDIR)/*.c` +POFILE = libbsm.po # # Definitions for XML (DTD AND XSL) @@ -241,24 +198,9 @@ $(ROOTETCSECURITY): $(ROOTETCSECURITY)/%: %.txt $(INS.rename) -%.po: $(COMMONDIR)/%.c - $(COMPILE.cpp) $< > $<.i - $(BUILD.po) - -_msg: $(MSGDOMAIN) $(POFILE) - $(RM) $(MSGDOMAIN)/$(CATALOG) - $(CP) $(POFILE) $(MSGDOMAIN) +$(POFILE): pofile_MSGFILES -catalog: _msg - -po_clean: - $(RM) $(POFILES) $(POFILE) - -clobber: po_clean - -$(POFILE): .WAIT $(POFILES) - $(RM) $@ - $(CAT) $(POFILES) > $@ +_msg: $(MSGDOMAINPOFILE) # has strings but doesn't use gettext adt_xlate.po: $(COMMONDIR)/adt_xlate.c @@ -267,11 +209,10 @@ adt_xlate.po: $(COMMONDIR)/adt_xlate.c $(SED) "/^domain/d" < messages.po > adt_xlate.po $(RM) messages.po -$(MSGDOMAIN): - $(INS.dir) - - spec $(MACH) $(MACH64) : FRC @cd $@; pwd; $(MAKE) $(TARGET) FRC: + +include ../Makefile.targ +include ../../Makefile.msg.targ diff --git a/usr/src/lib/libbsm/Makefile.com b/usr/src/lib/libbsm/Makefile.com index 3a7318aa72..52871561fc 100644 --- a/usr/src/lib/libbsm/Makefile.com +++ b/usr/src/lib/libbsm/Makefile.com @@ -24,7 +24,7 @@ # # ident "%Z%%M% %I% %E% SMI" # -# lib/libbsm/Makefile +# lib/libbsm/Makefile.com # LIBRARY = libbsm.a @@ -67,7 +67,10 @@ OBJECTS= adr.o \ getacval.o \ getauditflags.o \ getdaent.o \ + getdevicerange.o \ getdment.o \ + getdadefs.o \ + devalloc.o \ getfaudflgs.o # @@ -94,7 +97,10 @@ CLOBBERFILES += $(MAPFILE) CFLAGS += $(CCVERBOSE) DYNFLAGS += -M$(MAPFILE) -LDLIBS += -lsocket -lnsl -lmd5 -lc -lsecdb + +LAZYLIBS = $(ZLAZYLOAD) -ltsol $(ZNOLAZYLOAD) +LDLIBS += -lsocket -lnsl -lmd5 -lc -lsecdb $(LAZYLIBS) +lint := LAZYLIBS = -ltsol COMDIR= ../common diff --git a/usr/src/lib/libbsm/audit_class.txt b/usr/src/lib/libbsm/audit_class.txt index 5d0b8c7e03..69b06f2b80 100644 --- a/usr/src/lib/libbsm/audit_class.txt +++ b/usr/src/lib/libbsm/audit_class.txt @@ -1,13 +1,12 @@ # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -62,6 +61,29 @@ 0x00100000:ps:process start/stop 0x00200000:pm:process modify 0x00300000:pc:process (meta-class) +# +# The following four masks define X server related audit classes which +# are applicable to Trusted Extensions. X server audit events are mapped +# to these classes per the following criteria: +# +# xp : Protocols audited for use of privilege (successful or otherwise). +# E.g., ChangeWindowAttributes is audited when issued by a client to +# change attributes of another client's window. This class also includes +# any administrative protocols (e.g. SetAccessControl). +# xc : Server objects creation/destruction; e.g., CreateWindow. +# xs : Protocols that do not return X error messages to clients on failure for +# lack for security attributes. E.g., GetImage does not return BadWindow +# error if it cannot read from a window for lack of privilege. It just +# does not read from that window. +# These events should be selected for audit on success only. Selecting +# them for failure will cause a lot of noise in the audit trail. +# xx : All above X classes. +# +0x00400000:xp:X - privileged/administrative operations +0x00800000:xc:X - object create/destroy +0x01000000:xs:X - operations that always silently fail, if bad +0x01c00000:xx:X - all X events (meta-class) +# 0x20000000:io:ioctl 0x40000000:ex:exec 0x80000000:ot:other diff --git a/usr/src/lib/libbsm/audit_event.txt b/usr/src/lib/libbsm/audit_event.txt index 5bcc228838..7403d16365 100644 --- a/usr/src/lib/libbsm/audit_event.txt +++ b/usr/src/lib/libbsm/audit_event.txt @@ -1,13 +1,13 @@ # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -48,10 +48,25 @@ # 2048 - 32767 Reserved for the Solaris TCB programs. # 32768 - 65535 Available for third party TCB applications. # -# 6144 - 32767 SunOS 5.X user level audit events +# +# Allocation of reserved kernel events: +# (NOTE: the kernel event table, and possibly MAX_KEVENTS, must be updated +# in audit_kevents.h when changes are made to kernel events.) +# 1 - 511 allocated for Solaris +# 512 - 1023 allocated for Trusted Solaris/Trusted Extensions +# 1024 - 2047 (reserved but not allocated) +# +# Allocation of user level audit events: +# 2048 - 5999 (reserved but not allocated) +# 6000 - 7999 allocated for Solaris +# 8000 - 8999 (reserved but not allocated) +# 9000 - 9999 allocated for Trusted Solaris/Trusted Extensions +# 10000 - 32767 (reserved but not allocated) +# 32768 - 65535 (Available for third party TCB applications) # # # kernel audit events +# 1 - 511 allocated for Solaris # 0:AUE_NULL:indir system call:no 1:AUE_EXIT:exit(2):ps @@ -173,8 +188,6 @@ 113:AUE_SYSTEMBOOT:system booted:na 114:AUE_ASYNC_DAEMON_EXIT:async_daemon(2) exited:no 115:AUE_NFSSVC_EXIT:nfssvc(2) exited:no -128:AUE_WRITEL:writel(2):no -129:AUE_WRITEVL:writevl(2):no 130:AUE_GETAUID:getauid(2):aa 131:AUE_SETAUID:setauid(2):aa 132:AUE_GETAUDIT:getaudit(2):aa @@ -328,7 +341,12 @@ 292:AUE_CRYPTOADM:kernel cryptographic framework:as 293:AUE_CONFIGSSL:configure kernel SSL:as # +# Trusted Solaris/Trusted Extensions kernel audit events +# 512 - 1023 allocated for Trusted Solaris/Trusted Extensions +# +# # user level audit events +# 6000 - 7999 allocated for Solaris # # 2048 - 6143 Reserved # @@ -409,3 +427,113 @@ 6225:AUE_inetd_failrate:inetd failrate:na 6226:AUE_inetd_ratelimit:inetd ratelimit:na 6227:AUE_zlogin:login - zlogin:lo +# +# Trusted Solaris/Trusted Extensions user level audit events +# 9000 - 9999 allocated for Trusted Solaris/Trusted Extensions +# +9035:AUE_sl_change:Workspace label change:ap +9037:AUE_file_copy:file copy:fm +9038:AUE_file_move:file move:fm +9039:AUE_sel_mgr_xfer:selection manager transfer:fm +9101:AUE_ClientConnect:client connection to x server:lo +9102:AUE_ClientDisconnect:client disconn. from x server:lo +9120:AUE_ChangeProperty:XChangeProperty(3X11):xc +9121:AUE_DeleteProperty:XDeleteProperty(3X11):xc +9137:AUE_GrabServer:XGrabServer(3X11):ot +9138:AUE_UngrabServer:XUngrabServer(3X11):ot +9146:AUE_SetFontPath:XSetFontPath(3X11):ot +9173:AUE_InstallColormap:XInstallColormap(3X11):ot +9174:AUE_UninstallColormap:XUninstallColormap(3X11):xp +9193:AUE_SetScreenSaver:XSetScreenSaver(3X11):xp +9194:AUE_ChangeHosts:XChangeHosts(3X11):ot +9195:AUE_SetAccessControl:XSetAccessControl(3X11):xp +9196:AUE_SetCloseDownMode:XSetCloseDownMode(3X11):xs +9197:AUE_KillClient:XKillClient(3X11):xc +9202:AUE_XExtensions:X server extensions:xp +9103:AUE_CreateWindow:XCreateWindow(3X11):xc +9104:AUE_ChangeWindowAttributes:XChangeWindowAttributes(3X11):xp +9105:AUE_GetWindowAttributes:XGetWindowAttributes(3X11):xp +9106:AUE_DestroyWindow:XDestroyWindow(3X11):xc +9107:AUE_DestroySubwindows:XDestroySubwindows(3X11):xc +9108:AUE_ChangeSaveSet:XChangeSaveSet(3X11):xp +9109:AUE_ReparentWindow:XReparentWindow(3X11):xp +9110:AUE_MapWindow:XMapWindow(3X11):xp +9111:AUE_MapSubwindows:XMapSubwindows(3X11):xp +9112:AUE_UnmapWindow:XUnmapWindow(3X11):xp +9113:AUE_UnmapSubwindows:XUnmapSubwindows(3X11):xp +9114:AUE_ConfigureWindow:XConfigureWindow(3X11):xp +9115:AUE_CirculateWindow:XCirculateWindow(3X11):xp +9116:AUE_GetGeometry:XGetGeometry(3X11):xp +9117:AUE_QueryTree:XQueryTree(3X11):xp +9118:AUE_InternAtom:XInternAtom(3X11):xs +9119:AUE_GetAtomName:XGetAtomName(3X11):xs +9122:AUE_GetProperty:XGetProperty(3X11):xp +9123:AUE_ListProperties:XListProperties(3X11):xp +9124:AUE_SetSelectionOwner:XSetSelectionOwner(3X11):xp +9125:AUE_GetSelectionOwner:XGetSelectionOwner(3X11):xs +9126:AUE_ConvertSelection:XConvertSelection(3X11):xs +9127:AUE_SendEvent:XSendEvent(3X11):xs +9128:AUE_GrabPointer:XGrabPointer(3X11):xs +9129:AUE_UngrabPointer:XUngrabPointer(3X11):xs +9130:AUE_GrabButton:XGrabButton(3X11):xp +9131:AUE_UngrabButton:XUngrabButton(3X11):xs +9132:AUE_ChangeActivePointerGrab:XChangeActivePointerGrab(3X11):xs +9133:AUE_GrabKeyboard:XGrabKeyboard(3X11):xp +9134:AUE_UngrabKeyboard:XUngrabKeyboard(3X11):xs +9135:AUE_GrabKey:XGrabKey(3X11):xp +9136:AUE_UngrabKey:XUngrabKey(3X11):xp +9139:AUE_QueryPointer:XQueryPointer(3X11):xp +9140:AUE_GetMotionEvents:XGetMotionEvents(3X11):xp +9141:AUE_TranslateCoords:XTranslateCoords(3X11):xp +9142:AUE_WarpPointer:XWarpPointer(3X11):xs +9143:AUE_SetInputFocus:XSetInputFocus(3X11):xs +9144:AUE_GetInputFocus:XGetInputFocus(3X11):xs +9145:AUE_QueryKeymap:XQueryKeymap(3X11):xp +9147:AUE_FreePixmap:XFreePixmap(3X11):xc +9148:AUE_ChangeGC:XChangeGC(3X11):xp +9149:AUE_CopyGC:XCopyGC(3X11):xp +9150:AUE_SetDashes:XSetDashes(3X11):xp +9151:AUE_SetClipRectangles:XSetClipRectangles(3X11):xp +9152:AUE_FreeGC:XFreeGC(3X11):xc +9153:AUE_ClearArea:XClearArea(3X11):xp +9154:AUE_CopyArea:XCopyArea(3X11):xs +9155:AUE_CopyPlane:XCopyPlane(3X11):xs +9156:AUE_PolyPoint:XPolyPoint(3X11):xp +9157:AUE_PolyLine:XPolyLine(3X11):xp +9158:AUE_PolySegment:XPolySegment(3X11):xp +9159:AUE_PolyRectangle:XPolyRectangle(3X11):xs +9160:AUE_PolyArc:XPolyArc(3X11):xp +9161:AUE_FillPolygon:XFillPolygon(3X11):xp +9162:AUE_PolyFillRectangle:XPolyFillRectangle(3X11):xp +9163:AUE_PolyFillArc:XPolyFillArc(3X11):xp +9164:AUE_PutImage:XPutImage(3X11):xp +9165:AUE_GetImage:XGetImage(3X11):xs +9166:AUE_PolyText8:XPolyText8(3X11):xp +9167:AUE_PolyText16:XPolyText16(3X11):xp +9168:AUE_ImageText8:XImageText8(3X11):xp +9169:AUE_ImageText16:XImageText16(3X11):xp +9170:AUE_CreateColormap:XCreateColormap(3X11):xc +9171:AUE_FreeColormap:XFreeColormap(3X11):xc +9172:AUE_CopyColormapAndFree:XCopyColormapAndFree(3X11):xp +9175:AUE_ListInstalledColormaps:XListInstalledColormaps(3X11):xs +9176:AUE_AllocColor:XAllocColor(3X11):xc +9177:AUE_AllocNamedColor:XAllocNamedColor(3X11):xc +9178:AUE_AllocColorCells:XAllocColorCells(3X11):xc +9179:AUE_AllocColorPlanes:XAllocColorPlanes(3X11):xc +9180:AUE_FreeColors:XFreeColors(3X11):xc +9181:AUE_StoreColors:XStoreColors(3X11):xp +9182:AUE_StoreNamedColor:XStoreNamedColor(3X11):xp +9183:AUE_QueryColors:XQueryColors(3X11):xp +9184:AUE_LookupColor:XLookupColor(3X11):xp +9185:AUE_CreateCursor:XCreateCursor(3X11):xc +9186:AUE_CreateGlyphCursor:XCreateGlyphCursor(3X11):xc +9187:AUE_FreeCursor:XFreeCursor(3X11):xc +9188:AUE_RecolorCursor:XRecolorCursor(3X11):xp +9189:AUE_ChangeKeyboardMapping:XChangeKeyboardMapping(3X11):xs +9190:AUE_ChangeKeyboardControl:XChangeKeyboardControl(3X11):xs +9191:AUE_Bell:XBell(3X11):xs +9192:AUE_ChangePointerControl:XChangePointerControl(3X11):xs +9198:AUE_RotateProperties:XRotateProperties(3X11):xp +9199:AUE_ForceScreenSaver:XForceScreenSaver(3X11):xp +9200:AUE_SetPointerMapping:XSetPointerMapping(3X11):xs +9201:AUE_SetModifierMapping:XSetModifierMapping(3X11):xs diff --git a/usr/src/lib/libbsm/common/adt_token.c b/usr/src/lib/libbsm/common/adt_token.c index 49720539c7..1c6aec718b 100644 --- a/usr/src/lib/libbsm/common/adt_token.c +++ b/usr/src/lib/libbsm/common/adt_token.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -22,7 +21,7 @@ /* * adt_token.c * - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * This file does not provide any user callable functions. See adt.c @@ -41,6 +40,7 @@ #include <sys/priv_names.h> #include <sys/types.h> #include <sys/vnode.h> +#include <tsol/label.h> #include <time.h> #include <unistd.h> @@ -530,6 +530,9 @@ adt_to_subject(datadef *def, void *p_data, int required, au_to_newgroups(0, grouplist)); } } + + if (is_system_labeled()) + (void) au_write(event->ae_event_handle, au_to_mylabel()); } /* diff --git a/usr/src/lib/libbsm/common/au_to.c b/usr/src/lib/libbsm/common/au_to.c index 8c8fe49820..3747994d76 100644 --- a/usr/src/lib/libbsm/common/au_to.c +++ b/usr/src/lib/libbsm/common/au_to.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -42,6 +41,9 @@ #include <netinet/in.h> #include <netinet/in_pcb.h> #include <string.h> +#include <zone.h> +#include <sys/tsol/label.h> +#include <sys/tsol/label_macro.h> #define NGROUPS 16 /* XXX - temporary */ @@ -1242,6 +1244,50 @@ au_to_xselect(char *pstring, char *type, short dlen, char *data) } /* + * au_to_label + * return s: + * pointer to token chain containing a sensitivity label token. + */ +token_t * +au_to_label(bslabel_t *label) +{ + token_t *token; /* local token */ + adr_t adr; /* adr memory stream header */ + char data_header = AUT_LABEL; /* header for this token */ + short bs = sizeof (bslabel_t); + + token = get_token(sizeof (char) + bs); + if (token == NULL) + return (NULL); + adr_start(&adr, token->tt_data); + adr_char(&adr, &data_header, 1); + adr_char(&adr, (char *)label, bs); + + return (token); +} + +/* + * au_to_mylabel + * return s: + * pointer to a slabel token. + */ +token_t * +au_to_mylabel(void) +{ + bslabel_t slabel; + zoneid_t zid = getzoneid(); + + if (zid == GLOBAL_ZONEID) { + bsllow(&slabel); + } else { + if (zone_getattr(zid, ZONE_ATTR_SLBL, &slabel, + sizeof (bslabel_t)) < 0) + return (NULL); + } + return (au_to_label(&slabel)); +} + +/* * au_to_zonename * return s: * pointer to a zonename token. diff --git a/usr/src/lib/libbsm/common/audit_allocate.c b/usr/src/lib/libbsm/common/audit_allocate.c index e5d8e04d8a..35af6d9b53 100644 --- a/usr/src/lib/libbsm/common/audit_allocate.c +++ b/usr/src/lib/libbsm/common/audit_allocate.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,13 +19,14 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" #include <sys/types.h> +#include <tsol/label.h> #include <bsm/audit.h> #include <bsm/libbsm.h> #include <bsm/audit_private.h> @@ -136,6 +136,8 @@ audit_allocate_record(status) } (void) au_write(ad, au_to_newgroups(ng, grplst)); } + if (is_system_labeled()) + (void) au_write(ad, au_to_mylabel()); if (status) (void) au_write(ad, au_to_exit(status, -1)); diff --git a/usr/src/lib/libbsm/common/audit_ftpd.c b/usr/src/lib/libbsm/common/audit_ftpd.c index fb04a40579..023e78cb33 100644 --- a/usr/src/lib/libbsm/common/audit_ftpd.c +++ b/usr/src/lib/libbsm/common/audit_ftpd.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -37,6 +36,7 @@ #include <sys/socket.h> #include <sys/sockio.h> #include <netinet/in.h> +#include <tsol/label.h> #include <bsm/audit.h> #include <bsm/audit_record.h> @@ -187,6 +187,9 @@ generate_record( (void) au_write(rd, au_to_subject_ex(uid, uid, gid, ruid, rgid, pid, pid, &info.ai_termid)); + if (is_system_labeled()) + (void) au_write(rd, au_to_mylabel()); + /* add return token */ errno = 0; if (err) { @@ -291,6 +294,9 @@ audit_ftpd_logout(void) (void) au_write(rd, au_to_subject_ex(info.ai_auid, euid, egid, uid, gid, pid, pid, &info.ai_termid)); + if (is_system_labeled()) + (void) au_write(rd, au_to_mylabel()); + /* add return token */ errno = 0; #ifdef _LP64 diff --git a/usr/src/lib/libbsm/common/audit_rexd.c b/usr/src/lib/libbsm/common/audit_rexd.c index a868c17909..5c48b810b6 100644 --- a/usr/src/lib/libbsm/common/audit_rexd.c +++ b/usr/src/lib/libbsm/common/audit_rexd.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -39,6 +38,7 @@ #include <syslog.h> #include <pwd.h> #include <netinet/in.h> +#include <tsol/label.h> #include <locale.h> #include "generic.h" @@ -204,6 +204,8 @@ audit_rexd_fail(msg, hostname, user, uid, gid, shell, cmd) (void) au_write(rd, au_to_subject_ex(uid, uid, gid, uid, gid, pid, pid, &info.ai_termid)); + if (is_system_labeled()) + (void) au_write(rd, au_to_mylabel()); /* add reason for failure */ (void) au_write(rd, au_to_text(msg)); @@ -328,6 +330,8 @@ char **cmd; /* argv to be executed locally, may be NULL */ (void) au_write(rd, au_to_subject_ex(uid, uid, gid, uid, gid, pid, pid, &info.ai_termid)); + if (is_system_labeled()) + (void) au_write(rd, au_to_mylabel()); /* add hostname of machine requesting service */ diff --git a/usr/src/lib/libbsm/common/audit_rexecd.c b/usr/src/lib/libbsm/common/audit_rexecd.c index 79e33ce765..bb32ed9643 100644 --- a/usr/src/lib/libbsm/common/audit_rexecd.c +++ b/usr/src/lib/libbsm/common/audit_rexecd.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -39,6 +38,7 @@ #include <syslog.h> #include <pwd.h> #include <netinet/in.h> +#include <tsol/label.h> #include <locale.h> #include "generic.h" @@ -197,6 +197,8 @@ char *cmdbuf; /* command line to be executed locally */ /* add subject token */ (void) au_write(rd, au_to_subject_ex(uid, uid, gid, uid, gid, pid, pid, &tid)); + if (is_system_labeled()) + (void) au_write(rd, au_to_mylabel()); /* add reason for failure */ (void) au_write(rd, au_to_text(msg)); @@ -306,6 +308,8 @@ char *cmdbuf; /* command line to be executed locally */ /* add subject token */ (void) au_write(rd, au_to_subject_ex(uid, uid, gid, uid, gid, pid, pid, &tid)); + if (is_system_labeled()) + (void) au_write(rd, au_to_mylabel()); /* add hostname of machine requesting service */ (void) snprintf(buf, sizeof (buf), dgettext(bsm_dom, diff --git a/usr/src/lib/libbsm/common/audit_rshd.c b/usr/src/lib/libbsm/common/audit_rshd.c index f06ba169c7..7ff2523355 100644 --- a/usr/src/lib/libbsm/common/audit_rshd.c +++ b/usr/src/lib/libbsm/common/audit_rshd.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -37,6 +36,7 @@ #include <string.h> #include <syslog.h> #include <netinet/in.h> +#include <tsol/label.h> #include <locale.h> #include <unistd.h> #include <generic.h> @@ -134,6 +134,8 @@ generate_record(char *remuser, /* username at machine requesting service */ (void) au_write(rd, au_to_subject_ex(uid, uid, gid, uid, gid, pid, pid, &info.ai_termid)); + if (is_system_labeled()) + (void) au_write(rd, au_to_mylabel()); gtxt = dgettext(bsm_dom, "cmd %s"); tlen = strlen(gtxt) + strlen(cmdbuf) + 1; diff --git a/usr/src/lib/libbsm/common/devalloc.c b/usr/src/lib/libbsm/common/devalloc.c new file mode 100644 index 0000000000..4541191349 --- /dev/null +++ b/usr/src/lib/libbsm/common/devalloc.c @@ -0,0 +1,1723 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdlib.h> +#include <ctype.h> +#include <unistd.h> +#include <limits.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <utime.h> +#include <synch.h> +#include <strings.h> +#include <string.h> +#include <libintl.h> +#include <errno.h> +#include <auth_list.h> +#include <bsm/devices.h> +#include <bsm/devalloc.h> + +#define DA_DEFS "/etc/security/tsol/devalloc_defaults" + +extern int _readbufline(char *, int, char *, int, int *); +extern char *strtok_r(char *, const char *, char **); +extern char *_strtok_escape(char *, char *, char **); +extern int getdaon(void); +extern int da_matchname(devalloc_t *, char *); +extern int da_match(devalloc_t *, da_args *); +extern int dmap_matchname(devmap_t *, char *); +extern int dm_match(devmap_t *, da_args *); + +/* + * The following structure is for recording old entries to be retained. + * We read the entries from the database into a linked list in memory, + * then turn around and write them out again. + */ +typedef struct strentry { + struct strentry *se_next; + char se_str[4096 + 1]; +} strentry_t; + +/* + * da_check_longindevperm - + * reads /etc/logindevperm and checks if specified device is in the file. + * returns 1 if specified device found in /etc/logindevperm, else returns 0 + */ +int +da_check_logindevperm(char *devname) +{ + int ret = 0; + int fd = -1; + int nlen, plen, slen, lineno, fsize; + char line[MAX_CANON]; + char *field_delims = " \t\n"; + char *fbuf = NULL; + char *ptr, *device; + char *lasts = NULL; + FILE *fp; + struct stat f_stat; + + /* + * check if /etc/logindevperm exists and get its size + */ + if ((fd = open(LOGINDEVPERM, O_RDONLY)) == -1) + return (0); + if (fstat(fd, &f_stat) != 0) { + (void) close(fd); + return (0); + } + fsize = f_stat.st_size; + if ((fbuf = (char *)malloc(fsize)) == NULL) { + (void) close(fd); + return (0); + } + if ((fp = fdopen(fd, "r")) == NULL) { + free(fbuf); + (void) close(fd); + return (0); + } + + /* + * read and parse /etc/logindevperm + */ + plen = nlen = lineno = 0; + while (fgets(line, MAX_CANON, fp) != NULL) { + lineno++; + if ((ptr = strchr(line, '#')) != NULL) + *ptr = '\0'; /* handle comments */ + if (strtok_r(line, field_delims, &lasts) == NULL) + continue; /* ignore blank lines */ + if (strtok_r(NULL, field_delims, &lasts) == NULL) + /* invalid entry */ + continue; + if ((ptr = strtok_r(NULL, field_delims, &lasts)) == NULL) + /* empty device list */ + continue; + nlen = strlen(ptr) + 1; /* +1 terminator */ + nlen += (plen + 1); + if (plen == 0) + slen = snprintf(fbuf, nlen, "%s", ptr); + else + slen = snprintf(fbuf + plen, nlen - plen, ":%s", ptr); + if (slen >= fsize) { + fbuf[0] = '\0'; + (void) fclose(fp); + return (slen); + } + plen += slen; + } + (void) fclose(fp); + + /* + * check if devname exists in /etc/logindevperm + */ + device = strtok_r(fbuf, ":", &lasts); + while (device != NULL) { + /* + * device and devname may be one of these types - + * /dev/xx + * /dev/xx* + * /dev/dir/xx + * /dev/dir/xx* + * /dev/dir/"*" + */ + if (strcmp(device, devname) == 0) { + /* /dev/xx, /dev/dir/xx */ + free(fbuf); + return (1); + } + if ((ptr = strrchr(device, KV_WILDCHAR)) != NULL) { + /* all wildcard types */ + *ptr = '\0'; + if (strncmp(device, devname, strlen(device)) == 0) { + free(fbuf); + return (1); + } + } + device = strtok_r(NULL, ":", &lasts); + } + + return (ret); +} + +/* + * _da_read_file - + * establishes readers/writer lock on fname; reads in the file if its + * contents changed since the last time we read it. + * returns size of buffer read, or -1 on failure. + */ +int +_da_read_file(char *fname, char **fbuf, time_t *ftime, rwlock_t *flock, + int flag) +{ + int fd = -1; + int fsize = 0; + time_t newtime; + FILE *fp = NULL; + struct stat f_stat; + + if (flag & DA_FORCE) + *ftime = 0; + + /* check the size and the time stamp on the file */ + if (rw_rdlock(flock) != 0) + return (-1); + if (stat(fname, &f_stat) != 0) { + (void) rw_unlock(flock); + return (-1); + } + fsize = f_stat.st_size; + newtime = f_stat.st_mtime; + (void) rw_unlock(flock); + + while (newtime > *ftime) { + /* + * file has been modified since we last read it; or this + * is a forced read. + * read file into the buffer with rw lock. + */ + if (rw_wrlock(flock) != 0) + return (-1); + if ((fp = fopen(fname, "r")) == NULL) { + (void) rw_unlock(flock); + return (-1); + } + fd = fileno(fp); + if (*fbuf != NULL) { + free(*fbuf); + *fbuf = NULL; + } + if ((*fbuf = malloc(fsize)) == NULL) { + (void) rw_unlock(flock); + (void) close(fd); + return (-1); + } + if (read(fd, *fbuf, fsize) < fsize) { + free(*fbuf); + (void) rw_unlock(flock); + (void) close(fd); + return (-1); + } + (void) rw_unlock(flock); + /* + * verify that the file did not change just after we read it. + */ + if (rw_rdlock(flock) != 0) { + free(*fbuf); + (void) close(fd); + return (-1); + } + if (stat(fname, &f_stat) != 0) { + free(*fbuf); + (void) rw_unlock(flock); + (void) close(fd); + return (-1); + } + fsize = f_stat.st_size; + newtime = f_stat.st_mtime; + (void) rw_unlock(flock); + (void) close(fd); + *ftime = newtime; + } + + return (fsize); +} + +/* + * _update_zonename - + * add/remove current zone's name to the given devalloc_t. + */ +void +_update_zonename(da_args *dargs, devalloc_t *dap) +{ + int i, j; + int oldsize, newsize; + int has_zonename = 0; + char *zonename; + kva_t *newkva, *oldkva; + kv_t *newdata, *olddata; + devinfo_t *devinfo; + + devinfo = dargs->devinfo; + oldkva = dap->da_devopts; + if (oldkva == NULL) { + if (dargs->optflag & DA_REMOVE_ZONE) + return; + if (dargs->optflag & DA_ADD_ZONE) { + newkva = _str2kva(devinfo->devopts, KV_ASSIGN, + KV_TOKEN_DELIMIT); + if (newkva != NULL) + dap->da_devopts = newkva; + return; + } + } + newsize = oldsize = oldkva->length; + if (kva_match(oldkva, DAOPT_ZONE)) + has_zonename = 1; + if (dargs->optflag & DA_ADD_ZONE) { + if ((zonename = index(devinfo->devopts, '=')) == NULL) + return; + zonename++; + if (has_zonename) { + (void) _insert2kva(oldkva, DAOPT_ZONE, zonename); + return; + } + newsize += 1; + } else if (dargs->optflag & DA_REMOVE_ZONE) { + if (has_zonename) { + newsize -= 1; + if (newsize == 0) { + /* + * If zone name was the only key/value pair, + * put 'reserved' in the empty slot. + */ + _kva_free(oldkva); + dap->da_devopts = NULL; + return; + } + } else { + return; + } + } + newkva = _new_kva(newsize); + newkva->length = 0; + newdata = newkva->data; + olddata = oldkva->data; + for (i = 0, j = 0; i < oldsize; i++) { + if ((dargs->optflag & DA_REMOVE_ZONE) && + (strcmp(olddata[i].key, DAOPT_ZONE) == 0)) + continue; + newdata[j].key = strdup(olddata[i].key); + newdata[j].value = strdup(olddata[i].value); + newkva->length++; + j++; + } + if (dargs->optflag & DA_ADD_ZONE) { + newdata[j].key = strdup(DAOPT_ZONE); + newdata[j].value = strdup(zonename); + newkva->length++; + } + _kva_free(oldkva); + dap->da_devopts = newkva; +} + +/* + * _dmap2str - + * converts a device_map entry into a printable string + * returns 0 on success, -1 on error. + */ +/*ARGSUSED*/ +static int +_dmap2str(da_args *dargs, devmap_t *dmp, char *buf, int size, const char *sep) +{ + int length; + + length = snprintf(buf, size, "%s%s", dmp->dmap_devname, sep); + if (length >= size) + return (-1); + length += snprintf(buf + length, size - length, "%s%s", + dmp->dmap_devtype, sep); + if (length >= size) + return (-1); + length += snprintf(buf + length, size - length, "%s\n", + dmp->dmap_devlist); + if (length >= size) + return (-1); + return (0); +} + +/* + * _dmap2strentry - + * calls dmap2str to break given devmap_t into printable entry. + * returns pointer to decoded entry, NULL on error. + */ +static strentry_t * +_dmap2strentry(da_args *dargs, devmap_t *devmapp) +{ + strentry_t *sep; + + if ((sep = (strentry_t *)malloc(sizeof (strentry_t))) == NULL) + return (NULL); + if (_dmap2str(dargs, devmapp, sep->se_str, sizeof (sep->se_str), + KV_TOKEN_DELIMIT"\\\n\t") != 0) { + free(sep); + return (NULL); + } + return (sep); +} + +/* + * fix_optstr - + * removes trailing ':' from buf. + */ +void +fix_optstr(char *buf) +{ + char *p = NULL; + + if (p = rindex(buf, ':')) + *p = ';'; +} + +/* + * _da2str - + * converts a device_allocate entry into a printable string + * returns 0 on success, -1 on error. + */ +static int +_da2str(da_args *dargs, devalloc_t *dap, char *buf, int size, const char *sep, + const char *osep) +{ + int length; + int matching_entry = 0; + char **dnames; + + if (dargs->optflag & DA_UPDATE && + (dargs->optflag & DA_ADD_ZONE || + dargs->optflag & DA_REMOVE_ZONE) && + dargs->devnames) { + for (dnames = dargs->devnames; *dnames != NULL; dnames++) { + if (da_matchname(dap, *dnames)) { + matching_entry = 1; + break; + } + } + } + length = snprintf(buf, size, "%s%s", dap->da_devname, sep); + if (length >= size) + return (-1); + length += snprintf(buf + length, size - length, "%s%s", + dap->da_devtype, sep); + if (length >= size) + return (-1); + if (matching_entry) + _update_zonename(dargs, dap); + if ((dap->da_devopts == NULL) || ((dap->da_devopts->length == 1) && + (strcmp(dap->da_devopts->data->key, DA_RESERVED) == 0))) { + length += snprintf(buf + length, size - length, "%s%s", + DA_RESERVED, sep); + } else { + if (_kva2str(dap->da_devopts, buf + length, size - length, + KV_ASSIGN, (char *)osep) != 0) + return (-1); + length = strlen(buf); + } + if (dap->da_devopts) + fix_optstr(buf); + if (length >= size) + return (-1); + length += snprintf(buf + length, size - length, "%s%s", + DA_RESERVED, sep); + if (length >= size) + return (-1); + length += snprintf(buf + length, size - length, "%s%s", + dap->da_devauth ? dap->da_devauth : DA_ANYUSER, sep); + if (length >= size) + return (-1); + length += snprintf(buf + length, size - length, "%s\n", + dap->da_devexec ? dap->da_devexec : ""); + if (length >= size) + return (-1); + + return (0); +} + +/* + * _da2strentry - + * calls da2str to break given devalloc_t into printable entry. + * returns pointer to decoded entry, NULL on error. + */ +static strentry_t * +_da2strentry(da_args *dargs, devalloc_t *dap) +{ + strentry_t *sep; + + if ((sep = (strentry_t *)malloc(sizeof (strentry_t))) == NULL) + return (NULL); + if (_da2str(dargs, dap, sep->se_str, sizeof (sep->se_str), + KV_DELIMITER "\\\n\t", KV_TOKEN_DELIMIT "\\\n\t") != 0) { + free(sep); + return (NULL); + } + return (sep); +} + +/* + * _def2str + * converts da_defs_t into a printable string. + * returns 0 on success, -1 on error. + */ +static int +_def2str(da_defs_t *da_defs, char *buf, int size, const char *sep) +{ + int length; + + length = snprintf(buf, size, "%s%s", da_defs->devtype, sep); + if (length >= size) + return (-1); + if (da_defs->devopts) { + if (_kva2str(da_defs->devopts, buf + length, size - length, + KV_ASSIGN, KV_DELIMITER) != 0) + return (-1); + length = strlen(buf); + } + if (length >= size) + return (-1); + + return (0); +} + +/* + * _def2strentry + * calls _def2str to break given da_defs_t into printable entry. + * returns pointer decoded entry, NULL on error. + */ +static strentry_t * +_def2strentry(da_defs_t *da_defs) +{ + strentry_t *sep; + + if ((sep = (strentry_t *)malloc(sizeof (strentry_t))) == NULL) + return (NULL); + if (_def2str(da_defs, sep->se_str, sizeof (sep->se_str), + KV_TOKEN_DELIMIT) != 0) { + free(sep); + return (NULL); + } + + return (sep); +} + +/* + * _build_defattrs + * cycles through all defattr entries, stores them in memory. removes + * entries with the given search_key (device type). + * returns 0 if given entry not found, 1 if given entry removed, 2 on + * error. + */ +static int +_build_defattrs(da_args *dargs, strentry_t **head_defent) +{ + int rc = 0; + da_defs_t *da_defs; + strentry_t *tail_str, *tmp_str; + + setdadefent(); + while ((da_defs = getdadefent()) != NULL) { + rc = !(strcmp(da_defs->devtype, dargs->devinfo->devtype)); + if (rc && dargs->optflag & DA_ADD && + !(dargs->optflag & DA_FORCE)) { + /* + * During DA_ADD, we keep an existing entry unless + * we have DA_FORCE set to override that entry. + */ + dargs->optflag |= DA_NO_OVERRIDE; + rc = 0; + } + if (rc == 0) { + tmp_str = _def2strentry(da_defs); + if (tmp_str == NULL) { + freedadefent(da_defs); + enddadefent(); + return (2); + } + /* retaining defattr entry: tmp_str->se_str */ + tmp_str->se_next = NULL; + if (*head_defent == NULL) { + *head_defent = tail_str = tmp_str; + } else { + tail_str->se_next = tmp_str; + tail_str = tmp_str; + } + } + freedadefent(da_defs); + } + enddadefent(); + + return (rc); +} + +/* + * _build_lists - + * cycles through all the entries, stores them in memory. removes entries + * with the given search_key (device name or type). + * returns 0 if given entry not found, 1 if given entry removed, 2 on + * error. + */ +static int +_build_lists(da_args *dargs, strentry_t **head_devallocp, + strentry_t **head_devmapp) +{ + int rc = 0; + devalloc_t *devallocp; + devmap_t *devmapp; + strentry_t *tail_str; + strentry_t *tmp_str; + + if (dargs->optflag & DA_MAPS_ONLY) + goto dmap_only; + + /* build device_allocate */ + setdaent(); + while ((devallocp = getdaent()) != NULL) { + rc = da_match(devallocp, dargs); + if (rc && dargs->optflag & DA_ADD && + !(dargs->optflag & DA_FORCE)) { + /* + * During DA_ADD, we keep an existing entry unless + * we have DA_FORCE set to override that entry. + */ + dargs->optflag |= DA_NO_OVERRIDE; + rc = 0; + } + if (rc == 0) { + tmp_str = _da2strentry(dargs, devallocp); + if (tmp_str == NULL) { + freedaent(devallocp); + enddaent(); + return (2); + } + /* retaining devalloc entry: tmp_str->se_str */ + tmp_str->se_next = NULL; + if (*head_devallocp == NULL) { + *head_devallocp = tail_str = tmp_str; + } else { + tail_str->se_next = tmp_str; + tail_str = tmp_str; + } + } + freedaent(devallocp); + } + enddaent(); + +dmap_only: + if (dargs->optflag & DA_ALLOC_ONLY) + return (rc); + + /* build device_maps */ + rc = 0; + setdmapent(); + while ((devmapp = getdmapent()) != NULL) { + rc = dm_match(devmapp, dargs); + if (rc && dargs->optflag & DA_ADD && + !(dargs->optflag & DA_FORCE)) { + /* + * During DA_ADD, we keep an existing entry unless + * we have DA_FORCE set to override that entry. + */ + dargs->optflag |= DA_NO_OVERRIDE; + rc = 0; + } + if (rc == 0) { + tmp_str = _dmap2strentry(dargs, devmapp); + if (tmp_str == NULL) { + freedmapent(devmapp); + enddmapent(); + return (2); + } + /* retaining devmap entry: tmp_str->se_str */ + tmp_str->se_next = NULL; + if (*head_devmapp == NULL) { + *head_devmapp = tail_str = tmp_str; + } else { + tail_str->se_next = tmp_str; + tail_str = tmp_str; + } + } + freedmapent(devmapp); + } + enddmapent(); + + return (rc); +} + +/* + * _write_defattrs + * writes current entries to devalloc_defaults. + */ +static void +_write_defattrs(FILE *fp, strentry_t *head_defent) +{ + strentry_t *tmp_str; + + for (tmp_str = head_defent; tmp_str != NULL; + tmp_str = tmp_str->se_next) { + (void) fputs(tmp_str->se_str, fp); + (void) fputs("\n", fp); + } + +} + +/* + * _write_device_allocate - + * writes current entries in the list to device_allocate. + */ +static void +_write_device_allocate(char *odevalloc, FILE *dafp, strentry_t *head_devallocp) +{ + int is_on = -1; + strentry_t *tmp_str; + struct stat dastat; + + (void) fseek(dafp, (off_t)0, SEEK_SET); + + /* + * if the devalloc on/off string existed before, + * put it back before anything else. + * we need to check for the string only if the file + * exists. + */ + if (stat(odevalloc, &dastat) == 0) { + is_on = da_is_on(); + if (is_on == 0) + (void) fputs(DA_OFF_STR, dafp); + else if (is_on == 1) + (void) fputs(DA_ON_STR, dafp); + } + tmp_str = head_devallocp; + while (tmp_str) { + (void) fputs(tmp_str->se_str, dafp); + (void) fputs("\n", dafp); + tmp_str = tmp_str->se_next; + } +} + +/* + * _write_device_maps - + * writes current entries in the list to device_maps. + */ +static void +_write_device_maps(FILE *dmfp, strentry_t *head_devmapp) +{ + strentry_t *tmp_str; + + (void) fseek(dmfp, (off_t)0, SEEK_SET); + + tmp_str = head_devmapp; + while (tmp_str) { + (void) fputs(tmp_str->se_str, dmfp); + (void) fputs("\n", dmfp); + tmp_str = tmp_str->se_next; + } +} + +/* + * _write_new_defattrs + * writes the new entry to devalloc_defaults. + * returns 0 on success, -1 on error. + */ +static int +_write_new_defattrs(FILE *fp, da_args *dargs) +{ + int count; + char *tok = NULL, *tokp = NULL; + char *lasts; + devinfo_t *devinfo = dargs->devinfo; + + if (fseek(fp, (off_t)0, SEEK_END) == (off_t)-1) + return (-1); + if (!devinfo->devopts) + return (0); + (void) fprintf(fp, "%s%s", (devinfo->devtype ? devinfo->devtype : ""), + KV_TOKEN_DELIMIT); + if ((tokp = (char *)malloc(strlen(devinfo->devopts))) != NULL) { + (void) strcpy(tokp, devinfo->devopts); + if ((tok = strtok_r(tokp, KV_DELIMITER, &lasts)) != NULL) { + (void) fprintf(fp, "%s", tok); + count = 1; + } + while ((tok = strtok_r(NULL, KV_DELIMITER, &lasts)) != NULL) { + if (count) + (void) fprintf(fp, "%s", KV_DELIMITER); + (void) fprintf(fp, "%s", tok); + count++; + } + } else { + (void) fprintf(fp, "%s", devinfo->devopts); + } + + return (0); +} + +/* + * _write_new_entry - + * writes the new devalloc_t to device_allocate or the new devmap_t to + * device_maps. + * returns 0 on success, -1 on error. + */ +static int +_write_new_entry(FILE *fp, da_args *dargs, int flag) +{ + int count; + char *tok = NULL, *tokp = NULL; + char *lasts; + devinfo_t *devinfo = dargs->devinfo; + + if (flag & DA_MAPS_ONLY) + goto dmap_only; + + if (fseek(fp, (off_t)0, SEEK_END) == (off_t)-1) + return (-1); + + (void) fprintf(fp, "%s%s\\\n\t", + (devinfo->devname ? devinfo->devname : ""), KV_DELIMITER); + (void) fprintf(fp, "%s%s\\\n\t", + (devinfo->devtype ? devinfo->devtype : ""), KV_DELIMITER); + if (devinfo->devopts == NULL) { + (void) fprintf(fp, "%s%s\\\n\t", DA_RESERVED, + KV_DELIMITER); + } else { + if ((tokp = (char *)malloc(strlen(devinfo->devopts))) != NULL) { + (void) strcpy(tokp, devinfo->devopts); + if ((tok = strtok_r(tokp, KV_TOKEN_DELIMIT, &lasts)) != + NULL) { + (void) fprintf(fp, "%s", tok); + count = 1; + } + while ((tok = strtok_r(NULL, KV_TOKEN_DELIMIT, + &lasts)) != NULL) { + if (count) + (void) fprintf(fp, "%s", + KV_TOKEN_DELIMIT "\\\n\t"); + (void) fprintf(fp, "%s", tok); + count++; + } + if (count) + (void) fprintf(fp, "%s", + KV_DELIMITER "\\\n\t"); + } else { + (void) fprintf(fp, "%s%s", devinfo->devopts, + KV_DELIMITER "\\\n\t"); + } + } + (void) fprintf(fp, "%s%s\\\n\t", DA_RESERVED, KV_DELIMITER); + (void) fprintf(fp, "%s%s\\\n\t", + (devinfo->devauths ? devinfo->devauths : DA_ANYUSER), + KV_DELIMITER); + (void) fprintf(fp, "%s\n", + (devinfo->devexec ? devinfo->devexec : KV_DELIMITER)); + +dmap_only: + if (flag & DA_ALLOC_ONLY) + return (0); + + if (fseek(fp, (off_t)0, SEEK_END) == (off_t)-1) + return (-1); + + (void) fprintf(fp, "%s%s\\\n", + (devinfo->devname ? devinfo->devname : ""), KV_TOKEN_DELIMIT); + (void) fprintf(fp, "\t%s%s\\\n", + (devinfo->devtype ? devinfo->devtype : ""), KV_TOKEN_DELIMIT); + (void) fprintf(fp, "\t%s\n", + (devinfo->devlist ? devinfo->devlist : KV_TOKEN_DELIMIT)); + + return (0); +} + +/* + * _da_lock_devdb - + * locks the database files; lock can be either broken explicitly by + * closing the fd of the lock file, or it expires automatically at process + * termination. + * returns fd of the lock file or -1 on error. + */ +int +_da_lock_devdb(char *rootdir) +{ + int lockfd = -1; + char *lockfile; + char path[MAXPATHLEN]; + int size = sizeof (path); + + if (rootdir == NULL) { + lockfile = DA_DB_LOCK; + } else { + path[0] = '\0'; + if (snprintf(path, size, "%s%s", rootdir, DA_DB_LOCK) >= size) + return (-1); + lockfile = path; + } + + if ((lockfd = open(lockfile, O_RDWR | O_CREAT, 0600)) == -1) + /* cannot open lock file */ + return (-1); + + (void) fchown(lockfd, DA_UID, DA_GID); + + if (lseek(lockfd, (off_t)0, SEEK_SET) == -1) { + /* cannot position lock file */ + (void) close(lockfd); + return (-1); + } + if (lockf(lockfd, F_TLOCK, 0) == -1) { + /* cannot set lock */ + (void) close(lockfd); + return (-1); + } + (void) utime(lockfile, NULL); + + return (lockfd); +} + +/* + * da_open_devdb - + * opens one or both database files - device_allocate, device_maps - in + * the specified mode. + * locks the database files; lock is either broken explicitly by the + * caller by closing the lock file fd, or it expires automatically at + * process termination. + * writes the file pointer of opened file in the input args - dafp, dmfp. + * returns fd of the lock file on success, -2 if database file does not + * exist, -1 on other errors. + */ +int +da_open_devdb(char *rootdir, FILE **dafp, FILE **dmfp, int flag) +{ + int oflag = 0; + int fda = -1; + int fdm = -1; + int lockfd = -1; + char *fname; + char *fmode; + char path[MAXPATHLEN]; + FILE *devfile; + + if ((dafp == NULL) && (dmfp == NULL)) + return (-1); + + if (flag & DA_RDWR) { + oflag = DA_RDWR; + fmode = "r+"; + } else if (flag & DA_RDONLY) { + oflag = DA_RDONLY; + fmode = "r"; + } + + if ((lockfd = _da_lock_devdb(rootdir)) == -1) + return (-1); + + if ((dafp == NULL) || (flag & DA_MAPS_ONLY)) + goto dmap_only; + + path[0] = '\0'; + + /* + * open the device allocation file + */ + if (rootdir == NULL) { + fname = DEVALLOC; + } else { + if (snprintf(path, sizeof (path), "%s%s", rootdir, + DEVALLOC) >= sizeof (path)) { + if (lockfd != -1) + (void) close(lockfd); + return (-1); + } + fname = path; + } + if ((fda = open(fname, oflag, DA_DBMODE)) == -1) { + if (lockfd != -1) + (void) close(lockfd); + return ((errno == ENOENT) ? -2 : -1); + } + if ((devfile = fdopen(fda, fmode)) == NULL) { + (void) close(fda); + if (lockfd != -1) + (void) close(lockfd); + return (-1); + } + *dafp = devfile; + (void) fchmod(fda, DA_DBMODE); + + if ((flag & DA_ALLOC_ONLY)) + goto out; + +dmap_only: + path[0] = '\0'; + /* + * open the device map file + */ + if (rootdir == NULL) { + fname = DEVMAP; + } else { + if (snprintf(path, sizeof (path), "%s%s", rootdir, + DEVMAP) >= sizeof (path)) { + (void) close(fda); + if (lockfd != -1) + (void) close(lockfd); + return (-1); + } + fname = path; + } + + if ((fdm = open(fname, oflag, DA_DBMODE)) == -1) { + if (lockfd != -1) + (void) close(lockfd); + return ((errno == ENOENT) ? -2 : -1); + } + + if ((devfile = fdopen(fdm, fmode)) == NULL) { + (void) close(fdm); + (void) close(fda); + if (lockfd != -1) + (void) close(lockfd); + return (-1); + } + *dmfp = devfile; + (void) fchmod(fdm, DA_DBMODE); + +out: + return (lockfd); +} + +/* + * _record_on_off - + * adds either DA_ON_STR or DA_OFF_STR to device_allocate + * returns 0 on success, -1 on error. + */ +static int +_record_on_off(da_args *dargs, FILE *tafp, FILE *dafp) +{ + int dafd; + int nsize; + int nitems = 1; + int actionlen; + int str_found = 0; + int len = 0, nlen = 0, plen = 0; + char *ptr = NULL; + char *actionstr; + char *nbuf = NULL; + char line[MAX_CANON]; + struct stat dastat; + + if (dargs->optflag & DA_ON) + actionstr = DA_ON_STR; + else + actionstr = DA_OFF_STR; + actionlen = strlen(actionstr); + dafd = fileno(dafp); + if (fstat(dafd, &dastat) == -1) + return (-1); + + /* check the old device_allocate for on/off string */ + ptr = fgets(line, MAX_CANON, dafp); + if (ptr != NULL) { + if ((strcmp(line, DA_ON_STR) == 0) || + (strcmp(line, DA_OFF_STR) == 0)) { + str_found = 1; + nsize = dastat.st_size; + } + } + if (!ptr || !str_found) { + /* + * the file never had either the on or the off string; + * make room for it. + */ + str_found = 0; + nsize = dastat.st_size + actionlen + 1; + } + if ((nbuf = (char *)malloc(nsize)) == NULL) + return (-1); + nbuf[0] = '\0'; + /* put the on/off string */ + (void) strcpy(nbuf, actionstr); + nlen = strlen(nbuf); + plen = nlen; + if (ptr && !str_found) { + /* now put the first line that we read in fgets */ + nlen = plen + strlen(line) + 1; + len = snprintf(nbuf + plen, nlen - plen, "%s", line); + if (len >= nsize) { + free(nbuf); + return (-1); + } + plen += len; + } + + /* now get the rest of the old file */ + while (fgets(line, MAX_CANON, dafp) != NULL) { + nlen = plen + strlen(line) + 1; + len = snprintf(nbuf + plen, nlen - plen, "%s", line); + if (len >= nsize) { + free(nbuf); + return (-1); + } + plen += len; + } + len = strlen(nbuf) + 1; + if (len < nsize) + nbuf[len] = '\n'; + + /* write the on/off str + the old device_allocate to the temp file */ + if (fwrite(nbuf, nsize, nitems, tafp) < nitems) { + free(nbuf); + return (-1); + } + + free(nbuf); + + return (0); +} + +/* + * da_update_defattrs - + * writes default attributes to devalloc_defaults + * returns 0 on success, -1 on error. + */ +int +da_update_defattrs(da_args *dargs) +{ + int rc = 0, lockfd = 0, tmpfd = 0; + char *defpath = DEFATTRS; + char *tmpdefpath = TMPATTRS; + FILE *tmpfp = NULL; + struct stat dstat; + strentry_t *head_defent = NULL; + + if (dargs == NULL) + return (0); + if ((lockfd = _da_lock_devdb(NULL)) == -1) + return (-1); + if ((tmpfd = open(tmpdefpath, O_RDWR|O_CREAT, DA_DBMODE)) == -1) { + (void) close(lockfd); + return (-1); + } + (void) fchown(tmpfd, DA_UID, DA_GID); + if ((tmpfp = fdopen(tmpfd, "r+")) == NULL) { + (void) close(tmpfd); + (void) unlink(tmpdefpath); + (void) close(lockfd); + return (-1); + } + /* + * examine all entries, remove an old one if required, check + * if a new one needs to be added. + */ + if (stat(defpath, &dstat) == 0) { + if ((rc = _build_defattrs(dargs, &head_defent)) != 0) { + if (rc == 1) { + (void) close(tmpfd); + (void) unlink(tmpdefpath); + (void) close(lockfd); + return (rc); + } + } + } + /* + * write back any existing entries. + */ + _write_defattrs(tmpfp, head_defent); + + if (dargs->optflag & DA_ADD && !(dargs->optflag & DA_NO_OVERRIDE)) { + /* add new entries */ + rc = _write_new_defattrs(tmpfp, dargs); + (void) fclose(tmpfp); + } else { + (void) fclose(tmpfp); + } + if (rename(tmpdefpath, defpath) != 0) { + rc = -1; + (void) unlink(tmpdefpath); + } + (void) close(lockfd); + + return (rc); +} + +/* + * da_update_device - + * writes devices entries to device_allocate and device_maps. + * returns 0 on success, -1 on error. + */ +int +da_update_device(da_args *dargs) +{ + int rc; + int tafd = -1, tmfd = -1; + int lockfd = -1; + char *rootdir = NULL; + char *apathp = NULL, *mpathp = NULL, *dapathp = NULL, + *dmpathp = NULL; + char apath[MAXPATHLEN], mpath[MAXPATHLEN], + dapath[MAXPATHLEN], dmpath[MAXPATHLEN]; + FILE *tafp = NULL, *tmfp = NULL, *dafp = NULL; + struct stat dastat; + devinfo_t *devinfo; + strentry_t *head_devmapp = NULL; + strentry_t *head_devallocp = NULL; + + if (dargs == NULL) + return (0); + + rootdir = dargs->rootdir; + devinfo = dargs->devinfo; + + /* + * adding/removing entries should be done in both + * device_allocate and device_maps. updates can be + * done in both or either of the files. + */ + if (dargs->optflag & DA_ADD || dargs->optflag & DA_REMOVE) { + if (dargs->optflag & DA_ALLOC_ONLY || + dargs->optflag & DA_MAPS_ONLY) + return (0); + } + + /* + * name, type and list are required fields for adding a new + * device. + */ + if ((dargs->optflag & DA_ADD) && + ((devinfo->devname == NULL) || + (devinfo->devtype == NULL) || + (devinfo->devlist == NULL))) { + return (-1); + } + + if (rootdir != NULL) { + if (snprintf(apath, sizeof (apath), "%s%s", rootdir, + TMPALLOC) >= sizeof (apath)) + return (-1); + apathp = apath; + if (snprintf(dapath, sizeof (dapath), "%s%s", rootdir, + DEVALLOC) >= sizeof (dapath)) + return (-1); + dapathp = dapath; + if (!(dargs->optflag & DA_ALLOC_ONLY)) { + if (snprintf(mpath, sizeof (mpath), "%s%s", rootdir, + TMPMAP) >= sizeof (mpath)) + return (-1); + mpathp = mpath; + if (snprintf(dmpath, sizeof (dmpath), "%s%s", rootdir, + DEVMAP) >= sizeof (dmpath)) + return (-1); + dmpathp = dmpath; + } + } else { + apathp = TMPALLOC; + dapathp = DEVALLOC; + mpathp = TMPMAP; + dmpathp = DEVMAP; + } + + if (dargs->optflag & DA_MAPS_ONLY) + goto dmap_only; + + /* + * Check if we are here just to record on/off status of + * device_allocation. + */ + if (dargs->optflag & DA_ON || dargs->optflag & DA_OFF) + lockfd = da_open_devdb(dargs->rootdir, &dafp, NULL, + DA_RDONLY|DA_ALLOC_ONLY); + else + lockfd = _da_lock_devdb(rootdir); + if (lockfd == -1) + return (-1); + + if ((tafd = open(apathp, O_RDWR|O_CREAT, DA_DBMODE)) == -1) { + (void) close(lockfd); + (void) fclose(dafp); + return (-1); + } + (void) fchown(tafd, DA_UID, DA_GID); + if ((tafp = fdopen(tafd, "r+")) == NULL) { + (void) close(tafd); + (void) unlink(apathp); + (void) fclose(dafp); + (void) close(lockfd); + return (-1); + } + + /* + * We don't need to parse the file if we are here just to record + * on/off status of device_allocation. + */ + if (dargs->optflag & DA_ON || dargs->optflag & DA_OFF) { + if (_record_on_off(dargs, tafp, dafp) == -1) { + (void) close(tafd); + (void) unlink(apathp); + (void) fclose(dafp); + (void) close(lockfd); + return (-1); + } + (void) fclose(dafp); + goto out; + } + + /* + * examine all the entries, remove an old one if forced to, + * and check that they are suitable for updating. + * we need to do this only if the file exists already. + */ + if (stat(dapathp, &dastat) == 0) { + if ((rc = _build_lists(dargs, &head_devallocp, + &head_devmapp)) != 0) { + if (rc != 1) { + (void) close(tafd); + (void) unlink(apathp); + (void) close(lockfd); + return (rc); + } + } + } + + /* + * write back any existing devalloc entries, along with + * the devalloc on/off string. + */ + _write_device_allocate(dapathp, tafp, head_devallocp); + + if (dargs->optflag & DA_ALLOC_ONLY) + goto out; + +dmap_only: + if ((tmfd = open(mpathp, O_RDWR|O_CREAT, DA_DBMODE)) == -1) { + (void) close(tafd); + (void) unlink(apathp); + (void) close(lockfd); + return (-1); + } + (void) fchown(tmfd, DA_UID, DA_GID); + if ((tmfp = fdopen(tmfd, "r+")) == NULL) { + (void) close(tafd); + (void) unlink(apathp); + (void) close(tmfd); + (void) unlink(mpathp); + (void) close(lockfd); + return (-1); + } + + /* write back any existing devmap entries */ + if (head_devmapp != NULL) + _write_device_maps(tmfp, head_devmapp); + +out: + if (dargs->optflag & DA_ADD && !(dargs->optflag & DA_NO_OVERRIDE)) { + /* add any new entries */ + rc = _write_new_entry(tafp, dargs, DA_ALLOC_ONLY); + (void) fclose(tafp); + + if (rc == 0) + rc = _write_new_entry(tmfp, dargs, DA_MAPS_ONLY); + (void) fclose(tmfp); + } else { + if (tafp) + (void) fclose(tafp); + if (tmfp) + (void) fclose(tmfp); + } + + rc = 0; + if (!(dargs->optflag & DA_MAPS_ONLY)) { + if (rename(apathp, dapathp) != 0) { + rc = -1; + (void) unlink(apathp); + } + } + if (!(dargs->optflag & DA_ALLOC_ONLY)) { + if (rename(mpathp, dmpathp) != 0) { + rc = -1; + (void) unlink(mpathp); + } + } + + (void) close(lockfd); + + return (rc); +} + +/* + * da_add_list - + * adds new /dev link name to the linked list of devices. + * returns 0 if link added successfully, -1 on error. + */ +int +da_add_list(devlist_t *dlist, char *link, int new_instance, int flag) +{ + int instance; + int nlen, plen; + int new_entry = 0; + char *dtype, *dexec, *tname, *kval; + char *minstr = NULL, *maxstr = NULL; + char dname[DA_MAXNAME]; + kva_t *kva; + deventry_t *dentry = NULL, *nentry = NULL, *pentry = NULL; + da_defs_t *da_defs; + + if (dlist == NULL || link == NULL) + return (-1); + + dname[0] = '\0'; + if (flag & DA_AUDIO) { + dentry = dlist->audio; + tname = DA_AUDIO_NAME; + dtype = DA_AUDIO_TYPE; + dexec = DA_DEFAULT_AUDIO_CLEAN; + } else if (flag & DA_CD) { + dentry = dlist->cd; + tname = DA_CD_NAME; + dtype = DA_CD_TYPE; + dexec = DA_DEFAULT_DISK_CLEAN; + } else if (flag & DA_FLOPPY) { + dentry = dlist->floppy; + tname = DA_FLOPPY_NAME; + dtype = DA_FLOPPY_TYPE; + dexec = DA_DEFAULT_DISK_CLEAN; + } else if (flag & DA_TAPE) { + dentry = dlist->tape; + tname = DA_TAPE_NAME; + dtype = DA_TAPE_TYPE; + dexec = DA_DEFAULT_TAPE_CLEAN; + } else if (flag & DA_RMDISK) { + dentry = dlist->rmdisk; + tname = DA_RMDISK_NAME; + dtype = DA_RMDISK_TYPE; + dexec = DA_DEFAULT_DISK_CLEAN; + } else { + return (-1); + } + + for (nentry = dentry; nentry != NULL; nentry = nentry->next) { + pentry = nentry; + (void) sscanf(nentry->devinfo.devname, "%*[a-z]%d", &instance); + if (nentry->devinfo.instance == new_instance) + /* + * Add the new link name to the list of links + * that the device 'dname' has. + */ + break; + } + + if (nentry == NULL) { + /* + * Either this is the first entry ever, or no matching entry + * was found. Create a new one and add to the list. + */ + if (dentry == NULL) /* first entry ever */ + instance = 0; + else /* no matching entry */ + instance++; + (void) snprintf(dname, sizeof (dname), "%s%d", tname, instance); + if ((nentry = (deventry_t *)malloc(sizeof (deventry_t))) == + NULL) + return (-1); + if (pentry != NULL) + pentry->next = nentry; + new_entry = 1; + nentry->devinfo.devname = strdup(dname); + nentry->devinfo.devtype = dtype; + nentry->devinfo.devauths = DEFAULT_DEV_ALLOC_AUTH; + nentry->devinfo.devexec = dexec; + nentry->devinfo.instance = new_instance; + /* + * Look for default label range, authorizations and cleaning + * program in devalloc_defaults. If label range is not + * specified in devalloc_defaults, assume it to be admin_low + * to admin_high. + */ + minstr = DA_DEFAULT_MIN; + maxstr = DA_DEFAULT_MAX; + setdadefent(); + if (da_defs = getdadeftype(nentry->devinfo.devtype)) { + kva = da_defs->devopts; + if ((kval = kva_match(kva, DAOPT_MINLABEL)) != NULL) + minstr = strdup(kval); + if ((kval = kva_match(kva, DAOPT_MAXLABEL)) != NULL) + maxstr = strdup(kval); + if ((kval = kva_match(kva, DAOPT_AUTHS)) != NULL) + nentry->devinfo.devauths = strdup(kval); + if ((kval = kva_match(kva, DAOPT_CSCRIPT)) != NULL) + nentry->devinfo.devexec = strdup(kval); + freedadefent(da_defs); + } + enddadefent(); + kval = NULL; + nlen = strlen(DAOPT_MINLABEL) + strlen(KV_ASSIGN) + + strlen(minstr) + strlen(KV_TOKEN_DELIMIT) + + strlen(DAOPT_MAXLABEL) + strlen(KV_ASSIGN) + strlen(maxstr) + + 1; /* +1 for terminator */ + if (kval = (char *)malloc(nlen)) + (void) snprintf(kval, nlen, "%s%s%s%s%s%s%s", + DAOPT_MINLABEL, KV_ASSIGN, minstr, KV_TOKEN_DELIMIT, + DAOPT_MAXLABEL, KV_ASSIGN, maxstr); + nentry->devinfo.devopts = kval; + + nentry->devinfo.devlist = NULL; + nentry->next = NULL; + } + + nlen = strlen(link) + 1; /* +1 terminator */ + if (nentry->devinfo.devlist) { + plen = strlen(nentry->devinfo.devlist); + nlen = nlen + plen + 1; /* +1 for blank to separate entries */ + } else { + plen = 0; + } + + if ((nentry->devinfo.devlist = + (char *)realloc(nentry->devinfo.devlist, nlen)) == NULL) { + if (new_entry) { + nentry->devinfo.devname = NULL; + free(nentry->devinfo.devname); + nentry = NULL; + free(nentry); + if (pentry != NULL) + pentry->next = NULL; + } + return (-1); + } + + if (plen == 0) + (void) snprintf(nentry->devinfo.devlist, nlen, "%s", link); + else + (void) snprintf(nentry->devinfo.devlist + plen, nlen - plen, + " %s", link); + + if (pentry == NULL) { + /* + * This is the first entry of this device type. + */ + if (flag & DA_AUDIO) + dlist->audio = nentry; + else if (flag & DA_CD) + dlist->cd = nentry; + else if (flag & DA_FLOPPY) + dlist->floppy = nentry; + else if (flag & DA_TAPE) + dlist->tape = nentry; + else if (flag & DA_RMDISK) + dlist->rmdisk = nentry; + } + + return (0); +} + +/* + * da_remove_list - + * removes a /dev link name from the linked list of devices. + * returns type of device if link for that device removed + * successfully, else returns -1 on error. + * if all links for a device are removed, stores that device + * name in devname. + */ +int +da_remove_list(devlist_t *dlist, char *link, int type, char *devname, int size) +{ + int flag; + int remove_dev = 0; + int nlen, plen, slen; + char *lasts, *lname, *oldlist; + struct stat rmstat; + deventry_t *dentry, *current, *prev; + + if (type != NULL) + flag = type; + else if (link == NULL) + return (-1); + else if (strstr(link, DA_AUDIO_NAME) || strstr(link, DA_SOUND_NAME)) + flag = DA_AUDIO; + else if (strstr(link, "dsk") || strstr(link, "rdsk") || + strstr(link, "sr") || strstr(link, "rsr")) + flag = DA_CD; + else if (strstr(link, "fd") || strstr(link, "rfd") || + strstr(link, "diskette") || strstr(link, "rdiskette")) + flag = DA_FLOPPY; + else if (strstr(link, DA_TAPE_NAME)) + flag = DA_TAPE; + else + flag = DA_RMDISK; + + switch (type) { + case DA_AUDIO: + dentry = dlist->audio; + break; + case DA_CD: + dentry = dlist->cd; + break; + case DA_FLOPPY: + dentry = dlist->floppy; + break; + case DA_TAPE: + dentry = dlist->tape; + break; + case DA_RMDISK: + dentry = dlist->rmdisk; + break; + default: + return (-1); + } + + if ((type != NULL) && (link == NULL)) { + for (current = dentry, prev = dentry; current != NULL; + current = current->next) { + oldlist = strdup(current->devinfo.devlist); + for (lname = strtok_r(oldlist, " ", &lasts); + lname != NULL; + lname = strtok_r(NULL, " ", &lasts)) { + if (stat(lname, &rmstat) != 0) { + remove_dev = 1; + goto remove_dev; + } + } + prev = current; + } + return (-1); + } + + for (current = dentry, prev = dentry; current != NULL; + current = current->next) { + plen = strlen(current->devinfo.devlist); + nlen = strlen(link); + if (plen == nlen) { + if (strcmp(current->devinfo.devlist, link) == 0) { + /* last name in the list */ + remove_dev = 1; + break; + } + } + if (strstr(current->devinfo.devlist, link)) { + nlen = plen - nlen + 1; + oldlist = strdup(current->devinfo.devlist); + if ((current->devinfo.devlist = + (char *)realloc(current->devinfo.devlist, + nlen)) == NULL) { + free(oldlist); + return (-1); + } + current->devinfo.devlist[0] = '\0'; + nlen = plen = slen = 0; + for (lname = strtok_r(oldlist, " ", &lasts); + lname != NULL; + lname = strtok_r(NULL, " ", &lasts)) { + if (strcmp(lname, link) == 0) + continue; + nlen = strlen(lname) + plen + 1; + if (plen == 0) { + slen = + snprintf(current->devinfo.devlist, + nlen, "%s", lname); + } else { + slen = + snprintf(current->devinfo.devlist + + plen, nlen - plen, " %s", + lname); + } + plen = plen + slen + 1; + } + free(oldlist); + break; + } + prev = current; + } + +remove_dev: + if (remove_dev == 1) { + (void) strlcpy(devname, current->devinfo.devname, size); + free(current->devinfo.devname); + free(current->devinfo.devlist); + current->devinfo.devname = current->devinfo.devlist = NULL; + prev->next = current->next; + free(current); + current = NULL; + } + if ((remove_dev == 1) && (prev->devinfo.devname == NULL)) { + if (prev->next) { + /* + * what we removed above was the first entry + * in the list. make the next entry to be the + * first. + */ + current = prev->next; + } else { + /* + * the matching entry was the only entry in the list + * for this type. + */ + current = NULL; + } + if (flag & DA_AUDIO) + dlist->audio = current; + else if (flag & DA_CD) + dlist->cd = current; + else if (flag & DA_FLOPPY) + dlist->floppy = current; + else if (flag & DA_TAPE) + dlist->tape = current; + else if (flag & DA_RMDISK) + dlist->rmdisk = current; + } + + return (flag); +} + +/* + * da_is_on - + * checks if device allocation feature is turned on. + * returns 1 if on, 0 if off, -1 if status string not + * found in device_allocate. + */ +int +da_is_on() +{ + return (getdaon()); +} + +/* + * da_print_device - + * debug routine to print device entries. + */ +void +da_print_device(int flag, devlist_t *devlist) +{ + deventry_t *entry, *dentry; + devinfo_t *devinfo; + + if (flag & DA_AUDIO) + dentry = devlist->audio; + else if (flag & DA_CD) + dentry = devlist->cd; + else if (flag & DA_FLOPPY) + dentry = devlist->floppy; + else if (flag & DA_TAPE) + dentry = devlist->tape; + else if (flag & DA_RMDISK) + dentry = devlist->rmdisk; + else + return; + + for (entry = dentry; entry != NULL; entry = entry->next) { + devinfo = &(entry->devinfo); + (void) fprintf(stdout, "name: %s\n", devinfo->devname); + (void) fprintf(stdout, "type: %s\n", devinfo->devtype); + (void) fprintf(stdout, "auth: %s\n", devinfo->devauths); + (void) fprintf(stdout, "exec: %s\n", devinfo->devexec); + (void) fprintf(stdout, "list: %s\n\n", devinfo->devlist); + } +} diff --git a/usr/src/lib/libbsm/common/devalloc.h b/usr/src/lib/libbsm/common/devalloc.h new file mode 100644 index 0000000000..7952a302f5 --- /dev/null +++ b/usr/src/lib/libbsm/common/devalloc.h @@ -0,0 +1,185 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _DEVALLOC_H +#define _DEVALLOC_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <fcntl.h> +#include <sys/param.h> +#include <secdb.h> + +/* + * These are unsupported, SUNWprivate interfaces. + */ + +#define DA_UID (uid_t)0 /* root */ +#define DA_GID (gid_t)3 /* sys */ +#define LOGINDEVPERM "/etc/logindevperm" +#define DA_DB_LOCK "/etc/security/.da_db_lock" +#define DA_DEV_LOCK "/etc/security/.da_dev_lock" +#define DEVALLOC "/etc/security/device_allocate" +#define DEVMAP "/etc/security/device_maps" +#define DEFATTRS "/etc/security/tsol/devalloc_defaults" +#define TMPALLOC "/etc/security/.device_allocate" +#define TMPMAP "/etc/security/.device_maps" +#define TMPATTRS "/etc/security/tsol/.devalloc_defaults" + +#define DA_DEFAULT_MIN "admin_low" +#define DA_DEFAULT_MAX "admin_high" +#define DA_DEFAULT_CLEAN "/bin/true" +#define DA_DEFAULT_AUDIO_CLEAN "/etc/security/lib/audio_clean_wrapper" +#define DA_DEFAULT_DISK_CLEAN "/etc/security/lib/disk_clean" +#define DA_DEFAULT_TAPE_CLEAN "/etc/security/lib/st_clean" + +#define DA_ON_STR "DEVICE_ALLOCATION=ON\n" +#define DA_OFF_STR "DEVICE_ALLOCATION=OFF\n" +#define DA_IS_LABELED "system_labeled" +#define DA_LABEL_CHECK "/usr/bin/plabel" +#define DA_DBMODE 0644 +#define DA_COUNT 5 /* allocatable devices suppported */ + /* audio, cd, floppy, rmdisk, tape */ +#define DA_AUTHLEN MAX_CANON /* approx. sum of strlen of all */ + /* device auths in auth_list.h */ +#define DA_MAXNAME 80 +#define DA_BUFSIZE 4096 + +#define DA_RDWR O_RDWR|O_CREAT|O_NONBLOCK +#define DA_RDONLY O_RDONLY|O_NONBLOCK + +#define DA_ANYUSER "*" +#define DA_NOUSER "@" + +#define ALLOC_UID (uid_t)0 /* root */ +#define ALLOC_GID (gid_t)3 /* sys */ +#define ALLOC_ERRID (uid_t)2 /* bin */ +#define ALLOC_MODE 0600 +#define DEALLOC_MODE 0000 + +#define DA_SILENT 0x00000001 +#define DA_VERBOSE 0x00000002 +#define DA_ADD 0x00000004 +#define DA_REMOVE 0x00000008 +#define DA_UPDATE 0x00000010 +#define DA_ADD_ZONE 0x00000020 +#define DA_REMOVE_ZONE 0x00000040 +#define DA_FORCE 0x00000080 +#define DA_ALLOC_ONLY 0x00000100 +#define DA_MAPS_ONLY 0x00000200 +#define DA_ON 0x00000400 +#define DA_OFF 0x00000800 +#define DA_NO_OVERRIDE 0x00001000 +#define DA_DEFATTRS 0x00002000 + +#define DA_AUDIO 0x00001000 +#define DA_CD 0x00002000 +#define DA_FLOPPY 0x00004000 +#define DA_TAPE 0x00008000 +#define DA_RMDISK 0x00010000 + +#define DA_AUDIO_NAME "audio" +#define DA_SOUND_NAME "sound" +#define DA_AUDIO_TYPE DA_AUDIO_NAME +#define DA_AUDIO_DIR "/dev/sound/" + +#define DA_CD_NAME "cdrom" +#define DA_CD_TYPE "sr" + +#define DA_DISK_DIR "/dev/dsk/" +#define DA_DISK_DIRR "/dev/rdsk/" +#define DA_DISKR_DIR "/dev/(r)dsk" + +#define DA_FLOPPY_NAME "floppy" +#define DA_FLOPPY_TYPE "fd" + +#define DA_RMDISK_NAME "rmdisk" +#define DA_RMDISK_TYPE DA_RMDISK_NAME + +#define DA_TAPE_NAME "tape" +#define DA_TAPE_DIR "/dev/rmt/" +#define DA_TAPE_TYPE "st" + +typedef struct _devinfo_t { + char *devname; + char *devtype; + char *devauths; + char *devexec; + char *devopts; + char *devlist; + int instance; +} devinfo_t; + +typedef struct _deventry_t { + devinfo_t devinfo; + struct _deventry_t *next; +} deventry_t; + +typedef struct _devlist_t { + deventry_t *audio; + deventry_t *cd; + deventry_t *floppy; + deventry_t *tape; + deventry_t *rmdisk; +} devlist_t; + +typedef struct _da_optargs { + int optflag; + char *rootdir; + char **devnames; + devinfo_t *devinfo; +} da_args; + +typedef struct _da_defs { + char *devtype; + kva_t *devopts; +} da_defs_t; + +da_defs_t *getdadefent(void); +da_defs_t *getdadeftype(char *); +void freedadefent(da_defs_t *); +void setdadefent(void); +void enddadefent(void); +int da_is_on(void); +int da_check_logindevperm(char *); +int da_open_devdb(char *, FILE **, FILE **, int); +int da_update_device(da_args *); +int da_update_defattrs(da_args *); +int da_add_list(devlist_t *, char *, int, int); +int da_remove_list(devlist_t *, char *, int, char *, int); +void da_print_device(int, devlist_t *); + + +#ifdef __cplusplus +} +#endif + +#endif /* _DEVALLOC_H */ diff --git a/usr/src/lib/libbsm/common/devices.h b/usr/src/lib/libbsm/common/devices.h index 609a0aeb1a..04a3edceea 100644 --- a/usr/src/lib/libbsm/common/devices.h +++ b/usr/src/lib/libbsm/common/devices.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -33,36 +32,55 @@ extern "C" { #endif -typedef struct { /* see getdmapent(3) */ - char *dmap_devname; - char *dmap_devtype; - char *dmap_devlist; -} devmap_t; +#include <stdio.h> +#include <secdb.h> + +/* + * These are unsupported, SUN-private interfaces. + */ -devmap_t *getdmapent(void); -devmap_t *getdmaptype(char *); -devmap_t *getdmapnam(char *); -devmap_t *getdmapdev(char *); -void setdmapent(void); -void enddmapent(void); -void setdmapfile(char *); +#define DAOPT_AUTHS "auths" +#define DAOPT_CSCRIPT "cleanscript" +#define DAOPT_MINLABEL "minlabel" +#define DAOPT_MAXLABEL "maxlabel" +#define DAOPT_ZONE "zone" +#define DA_RESERVED "reserved" -typedef struct { /* see getdaent(3) */ - char *da_devname; - char *da_devtype; - char *da_devmin; - char *da_devmax; - char *da_devauth; - char *da_devexec; +typedef struct { + char *da_devname; + char *da_devtype; + char *da_devauth; + char *da_devexec; + kva_t *da_devopts; } devalloc_t; -devalloc_t *getdaent(void); -devalloc_t *getdatype(char *); -devalloc_t *getdanam(char *); -devalloc_t *getdadev(char *); -void setdaent(void); -void enddaent(void); -void setdafile(char *); +typedef struct { + char *dmap_devname; + char *dmap_devtype; + char *dmap_devlist; + char **dmap_devarray; +} devmap_t; + +int getdadmline(char *, int, FILE *); + +devalloc_t *getdaent(void); +devalloc_t *getdatype(char *); +devalloc_t *getdanam(char *); +void setdaent(void); +void enddaent(void); +void freedaent(devalloc_t *); +void setdafile(char *); + +devmap_t *getdmapent(void); +devmap_t *getdmaptype(char *); +devmap_t *getdmapnam(char *); +devmap_t *getdmapdev(char *); +void setdmapent(void); +void enddmapent(void); +void freedmapent(devmap_t *); +void setdmapfile(char *); +char *getdmapfield(char *); +char *getdmapdfield(char *); #ifdef __cplusplus } diff --git a/usr/src/lib/libbsm/common/generic.c b/usr/src/lib/libbsm/common/generic.c index 457b2e8c37..d5953826b9 100644 --- a/usr/src/lib/libbsm/common/generic.c +++ b/usr/src/lib/libbsm/common/generic.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -37,6 +36,7 @@ #include <string.h> #include <unistd.h> #include <stdlib.h> +#include <tsol/label.h> #include <bsm/audit.h> #include <bsm/libbsm.h> #include <bsm/audit_uevents.h> @@ -426,6 +426,9 @@ aug_audit(void) (void) au_write(ad, au_to_newgroups(ng, grplst)); } } + if (is_system_labeled()) + (void) au_write(ad, au_to_mylabel()); + if (aug_text != NULL) { (void) au_write(ad, au_to_text(aug_text)); } diff --git a/usr/src/lib/libbsm/common/getdadefs.c b/usr/src/lib/libbsm/common/getdadefs.c new file mode 100644 index 0000000000..3f62566293 --- /dev/null +++ b/usr/src/lib/libbsm/common/getdadefs.c @@ -0,0 +1,234 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <string.h> +#include <stdlib.h> +#include <bsm/devices.h> +#include <bsm/devalloc.h> + +char *strtok_r(char *, const char *, char **); + +/* externs from getdaent.c */ +extern char *trim_white(char *); +extern int pack_white(char *); +extern char *getdadmfield(char *, char *); +extern int getdadmline(char *, int, FILE *); + +extern char *_strdup_null(char *); + +static struct _dadefbuff { + FILE *_dadeff; + /* pointer into /etc/security/tsol/devalloc_defaults */ + da_defs_t _interpdadefs; + char _interpdadefline[DA_BUFSIZE + 1]; + char *_DADEFS; +} *__dadefbuff; + +#define dadeff (_df->_dadeff) +#define interpdadefs (_df->_interpdadefs) +#define interpdadefline (_df->_interpdadefline) +#define DADEFS_FILE (_df->_DADEFS) + +static da_defs_t *dadef_interpret(char *); +int dadef_matchtype(da_defs_t *, char *); + +/* + * _dadefalloc - + * allocates common buffers and structures. + * returns pointer to the new structure, else returns NULL on error. + */ +static struct _dadefbuff * +_dadefalloc(void) +{ + struct _dadefbuff *_df = __dadefbuff; + + if (_df == NULL) { + _df = (struct _dadefbuff *)calloc((unsigned)1, + (unsigned)sizeof (*__dadefbuff)); + if (_df == NULL) + return (NULL); + DADEFS_FILE = "/etc/security/tsol/devalloc_defaults"; + __dadefbuff = _df; + } + + return (__dadefbuff); +} + +/* + * setdadefent - + * rewinds devalloc_defaults file to the begining. + */ + +void +setdadefent(void) +{ + struct _dadefbuff *_df = _dadefalloc(); + + if (_df == NULL) + return; + if (dadeff == NULL) + dadeff = fopen(DADEFS_FILE, "r"); + else + rewind(dadeff); +} + +/* + * enddadefent - + * closes devalloc_defaults file. + */ + +void +enddadefent(void) +{ + struct _dadefbuff *_df = _dadefalloc(); + + if (_df == NULL) + return; + if (dadeff != NULL) { + (void) fclose(dadeff); + dadeff = NULL; + } +} + +void +freedadefent(da_defs_t *da_def) +{ + if (da_def == NULL) + return; + _kva_free(da_def->devopts); + da_def->devopts = NULL; +} + +/* + * getdadefent - + * When first called, returns a pointer to the first da_defs_t + * structure in devalloc_defaults; thereafter, it returns a pointer to the + * next da_defs_t structure in the file. Thus, successive calls can be + * used to search the entire file. + * call to getdadefent should be bracketed by setdadefent and enddadefent. + * returns NULL on error. + */ +da_defs_t * +getdadefent(void) +{ + char line1[DA_BUFSIZE + 1]; + da_defs_t *da_def; + struct _dadefbuff *_df = _dadefalloc(); + + if ((_df == 0) || (dadeff == NULL)) + return (NULL); + + while (getdadmline(line1, (int)sizeof (line1), dadeff) != 0) { + if ((da_def = dadef_interpret(line1)) == NULL) + continue; + return (da_def); + } + + return (NULL); +} + +/* + * getdadeftype - + * searches from the beginning of devalloc_defaults for the device + * specified by its type. + * call to getdadeftype should be bracketed by setdadefent and enddadefent. + * returns pointer to da_defs_t for the device if it is found, else + * returns NULL if device not found or in case of error. + */ +da_defs_t * +getdadeftype(char *type) +{ + char line1[DA_BUFSIZE + 1]; + da_defs_t *da_def; + struct _dadefbuff *_df = _dadefalloc(); + + if ((type == NULL) || (_df == NULL) || (dadeff == NULL)) + return (NULL); + + while (getdadmline(line1, (int)sizeof (line1), dadeff) != 0) { + if (strstr(line1, type) == NULL) + continue; + if ((da_def = dadef_interpret(line1)) == NULL) + continue; + if (dadef_matchtype(da_def, type)) + return (da_def); + freedadefent(da_def); + } + + return (NULL); +} + +/* + * dadef_matchtype - + * checks if the specified da_defs_t is for the device type specified. + * returns 1 if match found, else, returns 0. + */ +int +dadef_matchtype(da_defs_t *da_def, char *type) +{ + if (da_def->devtype == NULL) + return (0); + + return ((strcmp(da_def->devtype, type) == 0)); +} + +/* + * dadef_interpret - + * parses val and initializes pointers in da_defs_t. + * returns pointer to parsed da_defs_t entry, else returns NULL on error. + */ +static da_defs_t * +dadef_interpret(char *val) +{ + struct _dadefbuff *_df = _dadefalloc(); + int i; + char *opts; + kva_t *kvap; + kv_t *kvp; + + if (_df == NULL) + return (NULL); + + (void) strcpy(interpdadefline, val); + interpdadefs.devtype = getdadmfield(interpdadefline, KV_TOKEN_DELIMIT); + opts = getdadmfield(NULL, KV_TOKEN_DELIMIT); + interpdadefs.devopts = NULL; + if (interpdadefs.devtype == NULL) + return (NULL); + if (opts != NULL) + interpdadefs.devopts = + _str2kva(opts, KV_ASSIGN, KV_DELIMITER); + /* remove any extraneous whitespace in the options */ + if ((kvap = interpdadefs.devopts) != NULL) { + for (i = 0, kvp = kvap->data; i < kvap->length; i++, kvp++) { + (void) pack_white(kvp->key); + (void) pack_white(kvp->value); + } + } + + return (&interpdadefs); +} diff --git a/usr/src/lib/libbsm/common/getdaent.c b/usr/src/lib/libbsm/common/getdaent.c index f461015dbc..2deb5a65d6 100644 --- a/usr/src/lib/libbsm/common/getdaent.c +++ b/usr/src/lib/libbsm/common/getdaent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,320 +18,242 @@ * * CDDL HEADER END */ - /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" -#include <stdio.h> +#ifndef lint +static char sccsid[] = "%Z%%M% %I% %E% SMI"; +#endif + +#include <ctype.h> #include <string.h> -#include <malloc.h> +#include <stdlib.h> +#include <tsol/label.h> #include <bsm/devices.h> +#include <bsm/devalloc.h> -#define MAXINT 0x7fffffff; -#ifdef SunOS_CMW -extern char *calloc(); -#endif +extern char *_strdup_null(char *); static struct _dabuff { - devalloc_t _NULLDA; - FILE *_daf; /* pointer into /etc/security/device_allocate */ - devalloc_t _interpdevalloc; - char _interpline[BUFSIZ + 1]; - char *_DEVALLOC; + FILE *_daf; /* pointer into /etc/security/device_allocate */ + devalloc_t _interpdevalloc; + char _interpdaline[DA_BUFSIZE + 1]; + char *_DEVALLOC; } *__dabuff; -#define NULLDA (_da->_NULLDA) -#define daf (_da->_daf) -#define interpdevalloc (_da->_interpdevalloc) -#define interpline (_da->_interpline) -#define DEVALLOC (_da->_DEVALLOC) -static devalloc_t *interpret(); -static int matchname(); +#define daf (_da->_daf) +#define interpdevalloc (_da->_interpdevalloc) +#define interpdaline (_da->_interpdaline) +#define DEVALLOC_FILE (_da->_DEVALLOC) +static devalloc_t *da_interpret(char *); + +int da_matchname(devalloc_t *, char *); +int da_matchtype(devalloc_t *, char *); + +static int system_labeled = 0; /* - * trim_white(ptr) trims off leading and trailing white space from a NULL - * terminated string pointed to by "ptr". The leading white space is skipped - * by moving the pointer forward. The trailing white space is removed by - * nulling the white space characters. The pointer is returned to the white - * string. If the resulting string is null in length then a NULL pointer is - * returned. If "ptr" is NULL then a NULL pointer is returned. + * trim_white - + * trims off leading and trailing white space from input string. + * The leading white space is skipped by moving the pointer forward. + * The trailing white space is removed by nulling the white space + * characters. + * returns pointer to non-white string, else returns NULL if input string + * is null or if the resulting string has zero length. */ -static char * -trim_white(ptr) -char *ptr; +char * +trim_white(char *ptr) { - register char *tptr; - register int cnt; + char *tptr; + if (ptr == NULL) return (NULL); - while ((*ptr == ' ') || (*ptr == '\t')) { + while (isspace(*ptr)) ptr++; - } - cnt = strlen(ptr); - if (cnt != 0) { - tptr = ptr + cnt - 1; - while ((*tptr == ' ') || (*tptr == '\t')) { - *tptr = '\0'; - tptr--; - } - } - if (*ptr == NULL) + tptr = ptr + strlen(ptr); + while (tptr != ptr && isspace(tptr[-1])) + --tptr; + *tptr = '\0'; + if (*ptr == '\0') return (NULL); + return (ptr); } - /* - * scan string pointed to by pointer "p" - * find next colin or end of line. Null it and - * return pointer to next char. + * pack_white - + * trims off multiple occurrences of white space from input string. + * returns the number of spaces retained */ -static char * -daskip(p) -register char *p; +int +pack_white(char *ptr) { - while (*p && *p != ';' && *p != '\n') - ++p; - if (*p == '\n') - *p = '\0'; - else if (*p != '\0') - *p++ = '\0'; - return (p); -} + int cnt = 0; + char *tptr, ch; + if (ptr == NULL) + return (0); + tptr = ptr; + while (isspace(*tptr)) + tptr++; + for (;;) { + while ((ch = *tptr) != '\0' && !isspace(ch)) { + *ptr++ = ch; + tptr++; + } + while (isspace(*tptr)) + tptr++; + if (*tptr == '\0') + break; + *ptr++ = ' '; + cnt++; + } + *ptr = '\0'; -/* - * scan string pointed to by pointer "p" - * find next colin or end of line. Null it and - * return pointer to next char. - */ -static char * -dadskip(p) -register char *p; -{ - while (*p && *p != ' ' && *p != '\n') - ++p; - if (*p != '\0') - *p++ = '\0'; - return (p); + return (cnt); } - /* - * _daalloc() allocates common buffers and structures used by the device - * allocate library routines. Then returns a pointer to a structure. The - * returned pointer will be null if there is an error condition. + * getdadmline - + * reads one device_alloc/device_maps line from stream into buff of len + * bytes. Continued lines from stream are concatenated into one line in + * buff. Comments are removed from buff. + * returns the number of characters in buff, else returns 0 if no + * characters are read or an error occurred. */ -static struct _dabuff * -_daalloc() +int +getdadmline(char *buff, int len, FILE *stream) { - register struct _dabuff *_da = __dabuff; - - if (_da == 0) { - _da = (struct _dabuff *) - calloc((size_t)1, sizeof (*__dabuff)); - if (_da == 0) - return (0); - DEVALLOC = "/etc/security/device_allocate"; - __dabuff = _da; - } - return (__dabuff); -} + int tmpcnt; + int charcnt = 0; + int fileerr = 0; + int contline = 0; + char *cp; + char *ccp; - -/* - * getdaline(buff,len,stream) reads one device allocate line from "stream" into - * "buff" on "len" bytes. Continued lines from "stream" are concatinated - * into one line in "buff". Comments are removed from "buff". The number of - * characters in "buff" is returned. If no characters are read or an err or - * occured then "0" is returned - */ -static int -getdaline(buff, len, stream) - char *buff; - int len; - FILE *stream; -{ - register struct _dabuff *_da = _daalloc(); - char *cp; - char *ccp; - int tmpcnt; - int charcnt = 0; - int fileerr = 0; - int contline; - if (_da == 0) - return (0); do { cp = buff; *cp = NULL; do { + contline = 0; if (fgets(cp, len - charcnt, stream) == NULL) { fileerr = 1; break; } - ccp = strpbrk(cp, "\\\n"); + ccp = strchr(cp, '\n'); if (ccp != NULL) { - if (*ccp == '\\') + if (ccp != cp && ccp[-1] == '\\') { + ccp--; contline = 1; - else + } + else contline = 0; *ccp = NULL; } tmpcnt = strlen(cp); - if (tmpcnt != 0) { - cp += tmpcnt; - charcnt += tmpcnt; - } + cp += tmpcnt; + charcnt += tmpcnt; } while ((contline) || (charcnt == 0)); ccp = strpbrk(buff, "#"); if (ccp != NULL) *ccp = NULL; charcnt = strlen(buff); } while ((fileerr == 0) && (charcnt == 0)); - if (fileerr) + + if (fileerr && !charcnt) return (0); - else + else return (charcnt); } -char * -getdafield(ptr) -char *ptr; -{ - static char *tptr; - if (ptr == NULL) - ptr = tptr; - if (ptr == NULL) - return (NULL); - tptr = daskip(ptr); - ptr = trim_white(ptr); - if (ptr == NULL) - return (NULL); - if (*ptr == NULL) - return (NULL); - return (ptr); -} - -char * -getdadfield(ptr) -char *ptr; -{ - static char *tptr; - if (ptr != NULL) { - ptr = trim_white(ptr); - } else { - ptr = tptr; - } - if (ptr == NULL) - return (NULL); - tptr = dadskip(ptr); - if (ptr == NULL) - return (NULL); - if (*ptr == NULL) - return (NULL); - return (ptr); -} - /* - * getdadev(dev) searches from the beginning of the file until a logical - * device matching "dev" is found and returns a pointer to the particular - * structure in which it was found. If an EOF or an error is encountered on - * reading, these functions return a NULL pointer. + * _daalloc - + * allocates common buffers and structures. + * returns pointer to the new structure, else returns NULL on error. */ -#ifdef NOTDEF -devalloc_t * -getdadev(name) - register char *name; +static struct _dabuff * +_daalloc(void) { - register struct _dabuff *_da = _daalloc(); - devalloc_t *da; - char line[BUFSIZ + 1]; + struct _dabuff *_da = __dabuff; - if (_da == 0) - return (0); - setdaent(); - if (!daf) - return ((devalloc_t *)NULL); - while (getdaline(line, sizeof (line), daf) != 0) { - if ((da = interpret(line)) == NULL) - continue; - if (matchdev(&da, name)) { - enddaent(); - return (da); - } + if (_da == NULL) { + _da = (struct _dabuff *)calloc((unsigned)1, + (unsigned)sizeof (*__dabuff)); + if (_da == NULL) + return (NULL); + DEVALLOC_FILE = "/etc/security/device_allocate"; + daf = NULL; + __dabuff = _da; + system_labeled = is_system_labeled(); } - enddaent(); - return ((devalloc_t *)NULL); -} - -#endif /* NOTDEF */ + return (__dabuff); +} /* - * getdanam(name) searches from the beginning of the file until a audit-name - * matching "name" is found and returns a pointer to the particular structure - * in which it was found. If an EOF or an error is encountered on reading, - * these functions return a NULL pointer. + * getdadmfield - + * gets individual fields separated by skip in ptr. */ -devalloc_t * -getdanam(name) - register char *name; +char * +getdadmfield(char *ptr, char *skip) { - register struct _dabuff *_da = _daalloc(); - devalloc_t *da; - char line[BUFSIZ + 1]; + static char *tptr = NULL; + char *pend; - if (_da == 0) - return (0); - setdaent(); - if (!daf) - return ((devalloc_t *)NULL); - while (getdaline(line, (int)sizeof (line), daf) != 0) { - if ((da = interpret(line)) == NULL) - continue; - if (matchname(&da, name)) { - enddaent(); - return (da); - } - } - enddaent(); - return ((devalloc_t *)NULL); -} + /* check for a continuing search */ + if (ptr == NULL) + ptr = tptr; + /* check for source end */ + if (ptr == NULL || *ptr == '\0') + return (NULL); + /* find terminator */ + pend = strpbrk(ptr, skip); + /* terminate and set continuation pointer */ + if (pend != NULL) { + *pend++ = '\0'; + tptr = pend; + } else + tptr = NULL; + /* + * trim off any surrounding white space, return what's left + */ + return (trim_white(ptr)); +} /* - * setdaent() essentially rewinds the device_allocate file to the begining. + * setdaent - + * rewinds the device_allocate file to the begining. */ void -setdaent() +setdaent(void) { - register struct _dabuff *_da = _daalloc(); + struct _dabuff *_da = _daalloc(); - if (_da == 0) + if (_da == NULL) return; - if (daf == NULL) { - daf = fopen(DEVALLOC, "r"); - } else + if (daf == NULL) + daf = fopen(DEVALLOC_FILE, "r"); + else rewind(daf); } - /* - * enddaent() may be called to close the device_allocate file when processing - * is complete. + * enddaent - + * closes device_allocate file. */ void -enddaent() +enddaent(void) { - register struct _dabuff *_da = _daalloc(); + struct _dabuff *_da = _daalloc(); - if (_da == 0) + if (_da == NULL) return; if (daf != NULL) { (void) fclose(daf); @@ -340,173 +261,294 @@ enddaent() } } - /* - * setdafile(name) changes the default device_allocate file to "name" thus - * allowing alternate device_allocate files to be used. Note: it does not - * close the previous file . If this is desired, enddaent should be called - * prior to it. + * setdafile - + * changes the default device_allocate file to the one specified. + * It does not close the previous file. If this is desired, enddaent + * should be called prior to setdafile. */ void -setdafile(file) -char *file; +setdafile(char *file) { - register struct _dabuff *_da = _daalloc(); + struct _dabuff *_da = _daalloc(); - if (_da == 0) + if (_da == NULL) return; if (daf != NULL) { (void) fclose(daf); daf = NULL; } - DEVALLOC = file; + DEVALLOC_FILE = file; } +void +freedaent(devalloc_t *dap) +{ + if (dap == NULL) + return; + _kva_free(dap->da_devopts); + dap->da_devopts = NULL; +} /* - * getdatype(tp) When first called, returns a pointer to the - * first devalloc_t structure in the file with device-type matching - * "tp"; thereafter, it returns a pointer to the next devalloc_t - * structure in the file with device-type matching "tp". - * Thus successive calls can be used to search the - * entire file for entries having device-type matching "tp". - * A null pointer is returned on error. + * getdaon - + * checks if device_allocate has string DEVICE_ALLOCATION=ON or + * DEVICE_ALLOCATION=OFF string in it. + * returns 1 if the string is DEVICE_ALLOCATION=ON, 0 if it is + * DEVICE_ALLOCATION=OFF, -1 if neither string present. + */ +int +getdaon() +{ + int is_on = -1; + char line1[DA_BUFSIZE + 1]; + struct _dabuff *_da = _daalloc(); + + setdaent(); + if ((_da == NULL) || (daf == NULL)) { + enddaent(); + return (is_on); + } + while (getdadmline(line1, (int)sizeof (line1), daf) != 0) { + if (strncmp(line1, DA_ON_STR, (strlen(DA_ON_STR) - 1)) == 0) { + is_on = 1; + break; + } else if (strncmp(line1, DA_OFF_STR, + (strlen(DA_OFF_STR) - 1)) == 0) { + is_on = 0; + break; + } + } + enddaent(); + + return (is_on); +} + +/* + * getdaent - + * When first called, returns a pointer to the first devalloc_t + * structure in device_allocate; thereafter, it returns a pointer to the + * next devalloc_t structure in the file. Thus, successive calls can be + * used to search the entire file. + * call to getdaent should be bracketed by setdaent and enddaent. + * returns NULL on error. */ devalloc_t * -getdatype(tp) - char *tp; +getdaent(void) { - register struct _dabuff *_da = _daalloc(); - char line1[BUFSIZ + 1]; - devalloc_t *da; + char line1[DA_BUFSIZE + 1]; + devalloc_t *da; + struct _dabuff *_da = _daalloc(); - if (_da == 0) - return (0); - if (daf == NULL && (daf = fopen(DEVALLOC, "r")) == NULL) { + if ((_da == 0) || (daf == NULL)) return (NULL); + + while (getdadmline(line1, (int)sizeof (line1), daf) != 0) { + if ((strncmp(line1, DA_ON_STR, (strlen(DA_ON_STR) - 1)) == 0) || + (strncmp(line1, DA_OFF_STR, (strlen(DA_OFF_STR) - 1)) == 0)) + continue; + if ((da = da_interpret(line1)) == NULL) + continue; + return (da); } - do { - if (getdaline(line1, (int)sizeof (line1), daf) == 0) - return (NULL); - if ((da = interpret(line1)) == NULL) - return (NULL); - } while (strcmp(tp, da->da_devtype) != 0); - return (da); + return (NULL); } - /* - * getdaent() When first called, returns a pointer to the first devalloc_t - * structure in the file; thereafter, it returns a pointer to the next - * devalloc_t structure in the file. Thus successive calls can be used to - * search the entire file. A null pointer is returned on error. + * getdanam + * searches from the beginning of device_allocate for the device specified + * by its name. + * call to getdanam should be bracketed by setdaent and enddaent. + * returns pointer to devalloc_t for the device if it is found, else + * returns NULL if device not found or in case of error. */ devalloc_t * -getdaent() +getdanam(char *name) { - register struct _dabuff *_da = _daalloc(); - char line1[BUFSIZ + 1]; - devalloc_t *da; + char line[DA_BUFSIZE + 1]; + devalloc_t *da; + struct _dabuff *_da = _daalloc(); - if (_da == 0) - return (0); - if (daf == NULL && (daf = fopen(DEVALLOC, "r")) == NULL) { + if ((name == NULL) || (_da == 0) || (daf == NULL)) return (NULL); + + while (getdadmline(line, (int)sizeof (line), daf) != 0) { + if (strstr(line, name) == NULL) + continue; + if ((da = da_interpret(line)) == NULL) + continue; + if (da_matchname(da, name)) { + enddaent(); + return (da); + } + freedaent(da); } - if (getdaline(line1, (int)sizeof (line1), daf) == 0) - return (NULL); - if ((da = interpret(line1)) == NULL) - return (NULL); - return (da); + return (NULL); } - /* - * matchdev(dap,dev) The dev_list in the structure pointed to by "dap" is - * searched for string "dev". If a match occures then a "1" is returned - * otherwise a "0" is returned. + * getdatype - + * searches from the beginning of device_allocate for the device specified + * by its type. + * call to getdatype should be bracketed by setdaent and enddaent. + * returns pointer to devalloc_t for the device if it is found, else + * returns NULL if device not found or in case of error. */ -#ifdef NOTDEF -static -matchdev(dap, dev) - devalloc_t **dap; - char *dev; +devalloc_t * +getdatype(char *type) { - register struct _dabuff *_da = _daalloc(); - devalloc_t *da = *dap; - char tmpdev[BUFSIZ + 1]; - int charcnt; - int tmpcnt; - char *cp; - char *tcp; - char *last; - - charcnt = strlen(dev); - if (_da == 0) - return (0); - if (da->da_devlist == NULL) - return (0); - (void) strcpy(tmpdev, da->da_devlist); - tcp = tmpdev; - while ((cp = strtok_r(tcp, " ", &last)) != NULL) { - tcp = NULL; - tmpcnt = strlen(cp); - if (tmpcnt != charcnt) + char line1[DA_BUFSIZE + 1]; + devalloc_t *da; + struct _dabuff *_da = _daalloc(); + + if ((type == NULL) || (_da == NULL) || (daf == NULL)) + return (NULL); + + while (getdadmline(line1, (int)sizeof (line1), daf) != 0) { + if (strstr(line1, type) == NULL) + continue; + if ((da = da_interpret(line1)) == NULL) continue; - if (strcmp(cp, dev) == 0) - return (1); + if (da_matchtype(da, type)) + return (da); + freedaent(da); } - return (0); + + return (NULL); } -#endif /* NOTDEF */ /* - * matchname(dap,name) The audit-name in the structure pointed to by "dap" is - * searched for string "name". If a match occures then a "1" is returned - * otherwise a "0" is returned. + * da_matchname - + * checks if the specified devalloc_t is for the device specified. + * returns 1 if it is, else returns 0. */ -static int -matchname(dap, name) - devalloc_t **dap; - char *name; +int +da_matchname(devalloc_t *dap, char *name) { - register struct _dabuff *_da = _daalloc(); - devalloc_t *da = *dap; - - if (_da == 0) - return (0); - if (da->da_devname == NULL) + if (dap->da_devname == NULL) return (0); - if (strlen(da->da_devname) != strlen(name)) + + return ((strcmp(dap->da_devname, name) == 0)); +} + +/* + * da_matchtype - + * checks if the specified devalloc_t is for the device type specified. + * returns 1 if match found, else, returns 0. + */ +int +da_matchtype(devalloc_t *da, char *type) +{ + if (da->da_devtype == NULL) return (0); - if (strcmp(da->da_devname, name) == 0) - return (1); - return (0); + + return ((strcmp(da->da_devtype, type) == 0)); } +/* + * da_match - + * calls da_matchname or da_matchdev as appropriate. + */ +int +da_match(devalloc_t *dap, da_args *dargs) +{ + if (dargs->devinfo->devname) + return (da_matchname(dap, dargs->devinfo->devname)); + else if (dargs->devinfo->devtype) + return (da_matchtype(dap, dargs->devinfo->devtype)); + + return (0); +} /* - * interpret(val) string "val" is parsed and the pointers in a devalloc_t - * structure are initialized to point to fields in "val". A pointer to this - * structure is returned. + * da_interpret - + * parses val and initializes pointers in devalloc_t. + * returns pointer to parsed devalloc_t entry, else returns NULL on error. */ static devalloc_t * -interpret(val) -char *val; +da_interpret(char *val) { - register struct _dabuff *_da = _daalloc(); + struct _dabuff *_da = _daalloc(); + char *opts; + int i; + kva_t *kvap; + kv_t *kvp; - if (_da == 0) - return (0); - (void) strcpy(interpline, val); - interpdevalloc.da_devname = getdafield(interpline); - interpdevalloc.da_devtype = getdafield((char *)NULL); - interpdevalloc.da_devmin = getdafield((char *)NULL); - interpdevalloc.da_devmax = getdafield((char *)NULL); - interpdevalloc.da_devauth = getdafield((char *)NULL); - interpdevalloc.da_devexec = getdafield((char *)NULL); + if (_da == NULL) + return (NULL); + + (void) strcpy(interpdaline, val); + interpdevalloc.da_devname = getdadmfield(interpdaline, KV_DELIMITER); + interpdevalloc.da_devtype = getdadmfield(NULL, KV_DELIMITER); + opts = getdadmfield(NULL, KV_DELIMITER); + (void) getdadmfield(NULL, KV_DELIMITER); /* reserved field */ + interpdevalloc.da_devauth = getdadmfield(NULL, KV_DELIMITER); + interpdevalloc.da_devexec = getdadmfield(NULL, KV_DELIMITER); + interpdevalloc.da_devopts = NULL; + if (interpdevalloc.da_devname == NULL || + interpdevalloc.da_devtype == NULL) + return (NULL); + if ((opts != NULL) && + (strncmp(opts, DA_RESERVED, strlen(DA_RESERVED)) != 0)) { + interpdevalloc.da_devopts = + _str2kva(opts, KV_ASSIGN, KV_TOKEN_DELIMIT); + } + /* remove any extraneous whitespace in the options */ + if ((kvap = interpdevalloc.da_devopts) != NULL) { + for (i = 0, kvp = kvap->data; i < kvap->length; i++, kvp++) { + (void) pack_white(kvp->key); + (void) pack_white(kvp->value); + } + } + + if (system_labeled) { + /* if label range is not defined, use the default range. */ + int i = 0, nlen = 0; + char *minstr = NULL, *maxstr = NULL; + kva_t *nkvap = NULL; + kv_t *ndata = NULL, *odata = NULL; + + if (kvap == NULL) { + nlen = 2; /* minlabel, maxlabel */ + } else { + nlen += kvap->length; + if ((minstr = kva_match(kvap, DAOPT_MINLABEL)) == NULL) + nlen++; + if ((maxstr = kva_match(kvap, DAOPT_MAXLABEL)) == NULL) + nlen++; + } + if ((minstr != NULL) && (maxstr != NULL)) + /* + * label range provided; we don't need to construct + * default range. + */ + goto out; + nkvap = _new_kva(nlen); + ndata = nkvap->data; + if (kvap != NULL) { + for (i = 0; i < kvap->length; i++) { + odata = kvap->data; + ndata[i].key = _strdup_null(odata[i].key); + ndata[i].value = _strdup_null(odata[i].value); + nkvap->length++; + } + } + if (minstr == NULL) { + ndata[i].key = strdup(DAOPT_MINLABEL); + ndata[i].value = strdup(DA_DEFAULT_MIN); + nkvap->length++; + i++; + } + if (maxstr == NULL) { + ndata[i].key = strdup(DAOPT_MAXLABEL); + ndata[i].value = strdup(DA_DEFAULT_MAX); + nkvap->length++; + } + interpdevalloc.da_devopts = nkvap; + } +out: return (&interpdevalloc); } diff --git a/usr/src/lib/libbsm/common/getdevicerange.c b/usr/src/lib/libbsm/common/getdevicerange.c new file mode 100644 index 0000000000..6b993de18f --- /dev/null +++ b/usr/src/lib/libbsm/common/getdevicerange.c @@ -0,0 +1,109 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdlib.h> +#include <errno.h> +#include <tsol/label.h> +#include <bsm/devices.h> + + +/* + * getdevicerange + * Gets the minimum and maximum labels within which the device can + * be used. If label range is not specified for the device in + * device_allocate, defaults to admin_low and admin_high. + * Returns malloc'ed blrange pointer, or NULL on any error. + */ +blrange_t * +getdevicerange(const char *dev) +{ + int err; + char *lstr; + devalloc_t *da; + devmap_t *dm; + blrange_t *range; + + errno = 0; + if ((range = malloc(sizeof (blrange_t))) == NULL) + return (NULL); + if ((range->lower_bound = blabel_alloc()) == NULL) { + free(range); + return (NULL); + } + if ((range->upper_bound = blabel_alloc()) == NULL) { + blabel_free(range->lower_bound); + free(range); + return (NULL); + } + + /* + * If an entry is found for the named device, + * return its label range. + */ + setdaent(); + if ((da = getdanam((char *)dev)) == NULL) { + setdmapent(); + /* check for an actual device file */ + if ((dm = getdmapdev((char *)dev)) != NULL) { + da = getdanam(dm->dmap_devname); + freedmapent(dm); + } + enddmapent(); + } + enddaent(); + if (da == NULL) { + bsllow(range->lower_bound); + bslhigh(range->upper_bound); + } else { + lstr = kva_match(da->da_devopts, DAOPT_MINLABEL); + if (lstr == NULL) { + bsllow(range->lower_bound); + } else if (stobsl(lstr, range->lower_bound, NO_CORRECTION, + &err) == 0) { + blabel_free(range->lower_bound); + blabel_free(range->upper_bound); + free(range); + errno = ENOTSUP; + return (NULL); + } + lstr = kva_match(da->da_devopts, DAOPT_MAXLABEL); + if (lstr == NULL) { + bslhigh(range->upper_bound); + } else if (stobsl(lstr, range->upper_bound, NO_CORRECTION, + &err) == 0) { + blabel_free(range->lower_bound); + blabel_free(range->upper_bound); + free(range); + errno = ENOTSUP; + return (NULL); + } + freedaent(da); + } + + return (range); +} diff --git a/usr/src/lib/libbsm/common/getdment.c b/usr/src/lib/libbsm/common/getdment.c index 9e4556c9c7..2b13f5bc6e 100644 --- a/usr/src/lib/libbsm/common/getdment.c +++ b/usr/src/lib/libbsm/common/getdment.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,446 +19,486 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" -#include <stdio.h> #include <string.h> -#include <malloc.h> +#include <stdlib.h> #include <bsm/devices.h> -#include <sys/errno.h> +#include <bsm/devalloc.h> -#define MAXINT 0x7fffffff; +char *strtok_r(char *, const char *, char **); + +/* externs from getdaent.c */ +extern char *trim_white(char *); +extern int pack_white(char *); +extern char *getdadmfield(char *, char *); +extern int getdadmline(char *, int, FILE *); static struct _dmapbuff { - devmap_t _NULLDM; - FILE *_dmapf; /* pointer into /etc/security/device_maps */ - devmap_t _interpdevmap; - char _interpline[BUFSIZ + 1]; - char *_DEVMAP; + FILE *_dmapf; /* for /etc/security/device_maps */ + devmap_t _interpdevmap; + char _interpdmline[DA_BUFSIZE + 1]; + char *_DEVMAP; } *__dmapbuff; -#define NULLDM (_dmap->_NULLDM) -#define dmapf (_dmap->_dmapf) -#define interpdevmap (_dmap->_interpdevmap) -#define interpline (_dmap->_interpline) -#define DEVMAP (_dmap->_DEVMAP) -static devmap_t *interpret(); -static int matchdev(); -static int matchname(); +#define dmapf (_dmap->_dmapf) +#define interpdevmap (_dmap->_interpdevmap) +#define interpdmline (_dmap->_interpdmline) +#define DEVMAPS_FILE (_dmap->_DEVMAP) + +devmap_t *dmap_interpret(char *, devmap_t *); +static devmap_t *dmap_interpretf(char *, devmap_t *); +static devmap_t *dmap_dlexpand(devmap_t *); + +int dmap_matchdev(devmap_t *, char *); +int dmap_matchname(devmap_t *, char *); + + /* - * trim_white(ptr) trims off leading and trailing white space from a NULL - * terminated string pointed to by "ptr". The leading white space is skipped - * by moving the pointer forward. The trailing white space is removed by - * nulling the white space characters. The pointer is returned to the white - * string. If the resulting string is null in length then a NULL pointer is - * returned. If "ptr" is NULL then a NULL pointer is returned. + * _dmapalloc - + * allocates common buffers and structures. + * returns pointer to the new structure, else returns NULL on error. */ -static char * -trim_white(char *ptr) +static struct _dmapbuff * +_dmapalloc(void) { - register char *tptr; - register int cnt; - if (ptr == NULL) - return (NULL); - while ((*ptr == ' ') || (*ptr == '\t')) { - ptr++; - } - cnt = strlen(ptr); - if (cnt != 0) { - tptr = ptr + cnt - 1; - while ((*tptr == ' ') || (*tptr == '\t')) { - *tptr = '\0'; - tptr--; - } + struct _dmapbuff *_dmap = __dmapbuff; + + if (_dmap == NULL) { + _dmap = (struct _dmapbuff *)calloc((unsigned)1, + (unsigned)sizeof (*__dmapbuff)); + if (_dmap == NULL) + return (NULL); + DEVMAPS_FILE = "/etc/security/device_maps"; + dmapf = NULL; + __dmapbuff = _dmap; } - if (*ptr == NULL) - return (NULL); - return (ptr); + + return (_dmap); } + /* - * scan string pointed to by pointer "p" - * find next colin or end of line. Null it and - * return pointer to next char. + * setdmapent - + * rewinds the device_maps file to the beginning. */ -static char * -dmapskip(register char *p) +void +setdmapent(void) { - while (*p && *p != ':' && *p != '\n') - ++p; - if (*p == '\n') - *p = '\0'; - else if (*p != '\0') - *p++ = '\0'; - return (p); + struct _dmapbuff *_dmap = _dmapalloc(); + + if (_dmap == NULL) + return; + if (dmapf == NULL) + dmapf = fopen(DEVMAPS_FILE, "r"); + else + rewind(dmapf); } + /* - * scan string pointed to by pointer "p" - * find next colin or end of line. Null it and - * return pointer to next char. + * enddmapent - + * closes device_maps file. */ -static char * -dmapdskip(register char *p) +void +enddmapent(void) { - while (*p && *p != ' ' && *p != '\n') - ++p; - if (*p != '\0') - *p++ = '\0'; - return (p); + struct _dmapbuff *_dmap = _dmapalloc(); + + if (_dmap == NULL) + return; + if (dmapf != NULL) { + (void) fclose(dmapf); + dmapf = NULL; + } } -/* - * _dmapalloc() allocates common buffers and structures used by the device - * maps library routines. Then returns a pointer to a structure. The - * returned pointer will be null if there is an error condition. - */ -static struct _dmapbuff * -_dmapalloc(void) +void +freedmapent(devmap_t *dmap) { - register struct _dmapbuff *_dmap = __dmapbuff; - - if (_dmap == 0) { - _dmap = (struct _dmapbuff *) - calloc((unsigned)1, (unsigned)sizeof (*__dmapbuff)); - if (_dmap == 0) - return (0); - DEVMAP = "/etc/security/device_maps"; - __dmapbuff = _dmap; + char **darp; + + if ((darp = dmap->dmap_devarray) != NULL) { + while (*darp != NULL) + free(*darp++); + free(dmap->dmap_devarray); + dmap->dmap_devarray = NULL; } - return (__dmapbuff); } + /* - * getdmapline(buff,len,stream) reads one device maps line from "stream" into - * "buff" on "len" bytes. Continued lines from "stream" are concatinated - * into one line in "buff". Comments are removed from "buff". The number of - * characters in "buff" is returned. If no characters are read or an error - * occured then "0" is returned + * setdmapfile - + * changes the default device_maps file to the one specified. + * It does not close the previous file. If this is desired, enddmapent + * should be called prior to setdampfile. */ -static int -getdmapline(char *buff, int len, FILE *stream) +void +setdmapfile(char *file) { - register struct _dmapbuff *_dmap = _dmapalloc(); - char *cp; - char *ccp; - size_t tmpcnt; - int charcnt = 0; - int fileerr = 0; - int contline; - if (_dmap == 0) - return (0); - do { - cp = buff; - *cp = NULL; - do { - if ((len - charcnt <= 1) || - (fgets(cp, len - charcnt, stream) == NULL)) { - fileerr = 1; - break; - } - ccp = strpbrk(cp, "\\\n"); - if (ccp != NULL) { - if (*ccp == '\\') - contline = 1; - else - contline = 0; - *ccp = NULL; - } - tmpcnt = strlen(cp); - if (tmpcnt != 0) { - cp += tmpcnt; - charcnt += tmpcnt; - } - } while ((contline) || (charcnt == 0)); - ccp = strpbrk(buff, "#"); - if (ccp != NULL) - *ccp = NULL; - charcnt = strlen(buff); - } while ((fileerr == 0) && (charcnt == 0)); - if (fileerr && !charcnt) - return (0); - else - return (charcnt); + struct _dmapbuff *_dmap = _dmapalloc(); + + if (_dmap == NULL) + return; + if (dmapf != NULL) { + (void) fclose(dmapf); + dmapf = NULL; + } + DEVMAPS_FILE = file; } -char -*getdmapfield(char *ptr) + +/* + * getdmapent - + * When first called, returns a pointer to the first devmap_t structure + * in device_maps; thereafter, it returns a pointer to the next devmap_t + * structure in the file. Thus successive calls can be used to read the + * entire file. + * call to getdmapent should be bracketed by setdmapent and enddmapent. + * returns pointer to devmap_t found, else returns NULL if no entry found + * or on error. + */ +devmap_t * +getdmapent(void) { - static char *tptr; - if (ptr == NULL) - ptr = tptr; - if (ptr == NULL) - return (NULL); - tptr = dmapskip(ptr); - ptr = trim_white(ptr); - if (ptr == NULL) - return (NULL); - if (*ptr == NULL) + devmap_t *dmap; + struct _dmapbuff *_dmap = _dmapalloc(); + + if ((_dmap == 0) || (dmapf == NULL)) return (NULL); - return (ptr); -} -char -*getdmapdfield(char *ptr) -{ - static char *tptr; - if (ptr != NULL) { - ptr = trim_white(ptr); - } else { - ptr = tptr; + + while (getdadmline(interpdmline, (int)sizeof (interpdmline), + dmapf) != 0) { + if ((dmap = dmap_interpret(interpdmline, + &interpdevmap)) == NULL) + continue; + return (dmap); } - if (ptr == NULL) - return (NULL); - tptr = dmapdskip(ptr); - if (ptr == NULL) - return (NULL); - if (*ptr == NULL) - return (NULL); - return (ptr); + + return (NULL); } + /* - * getdmapdev(dev) searches from the beginning of the file until a logical - * device matching "dev" is found and returns a pointer to the particular - * structure in which it was found. If an EOF or an error is encountered on - * reading, these functions return a NULL pointer. + * getdmapnam - + * searches from the beginning of device_maps for the device specified by + * its name. + * call to getdmapnam should be bracketed by setdmapent and enddmapent. + * returns pointer to devmapt_t for the device if it is found, else + * returns NULL if device not found or in case of error. */ devmap_t * -getdmapdev(register char *name) +getdmapnam(char *name) { - register struct _dmapbuff *_dmap = _dmapalloc(); - devmap_t *dmap; - char line[BUFSIZ + 1]; + devmap_t *dmap; + struct _dmapbuff *_dmap = _dmapalloc(); - if (_dmap == 0) - return (0); - setdmapent(); - if (!dmapf) + if ((name == NULL) || (_dmap == 0) || (dmapf == NULL)) return (NULL); - while (getdmapline(line, (int)sizeof (line), dmapf) != 0) { - if ((dmap = interpret(line)) == NULL) + + while (getdadmline(interpdmline, (int)sizeof (interpdmline), + dmapf) != 0) { + if (strstr(interpdmline, name) == NULL) continue; - if (matchdev(&dmap, name)) { + if ((dmap = dmap_interpretf(interpdmline, + &interpdevmap)) == NULL) + continue; + if (dmap_matchname(dmap, name)) { + if ((dmap = dmap_dlexpand(dmap)) == NULL) + continue; enddmapent(); return (dmap); } + freedmapent(dmap); } - enddmapent(); + return (NULL); } + /* - * getdmapnam(name) searches from the beginning of the file until a audit-name - * matching "name" is found and returns a pointer to the particular structure - * in which it was found. If an EOF or an error is encountered on reading, - * these functions return a NULL pointer. + * getdmapdev - + * searches from the beginning of device_maps for the device specified by + * its logical name. + * call to getdmapdev should be bracketed by setdmapent and enddmapent. + * returns pointer to the devmap_t for the device if device is found, + * else returns NULL if device not found or on error. */ devmap_t * -getdmapnam(register char *name) +getdmapdev(char *dev) { - register struct _dmapbuff *_dmap = _dmapalloc(); - devmap_t *dmap; - char line[BUFSIZ + 1]; + devmap_t *dmap; + struct _dmapbuff *_dmap = _dmapalloc(); - if (_dmap == 0) - return (0); - setdmapent(); - if (!dmapf) + if ((dev == NULL) || (_dmap == 0) || (dmapf == NULL)) return (NULL); - while (getdmapline(line, (int)sizeof (line), dmapf) != 0) { - if ((dmap = interpret(line)) == NULL) + + while (getdadmline(interpdmline, (int)sizeof (interpdmline), + dmapf) != 0) { + if ((dmap = dmap_interpret(interpdmline, + &interpdevmap)) == NULL) continue; - if (matchname(&dmap, name)) { + if (dmap_matchdev(dmap, dev)) { enddmapent(); return (dmap); } + freedmapent(dmap); } - enddmapent(); + return (NULL); } /* - * setdmapent() essentially rewinds the device_maps file to the begining. + * getdmaptype - + * searches from the beginning of device_maps for the device specified by + * its type. + * call to getdmaptype should be bracketed by setdmapent and enddmapent. + * returns pointer to devmap_t found, else returns NULL if no entry found + * or on error. */ - -void -setdmapent(void) +devmap_t * +getdmaptype(char *type) { - register struct _dmapbuff *_dmap = _dmapalloc(); + devmap_t *dmap; + struct _dmapbuff *_dmap = _dmapalloc(); + if ((type == NULL) || (_dmap == 0) || (dmapf == NULL)) + return (NULL); - if (_dmap == 0) - return; + while (getdadmline(interpdmline, (int)sizeof (interpdmline), + dmapf) != 0) { + if ((dmap = dmap_interpretf(interpdmline, + &interpdevmap)) == NULL) + continue; + if (dmap->dmap_devtype != NULL && + strcmp(type, dmap->dmap_devtype) == 0) { + if ((dmap = dmap_dlexpand(dmap)) == NULL) + continue; + return (dmap); + } + freedmapent(dmap); + } - if (dmapf == NULL) { - dmapf = fopen(DEVMAP, "r"); - } else - rewind(dmapf); + return (NULL); } - /* - * enddmapent() may be called to close the device_maps file when processing - * is complete. + * dmap_matchdev - + * checks if the specified devmap_t is for the device specified. + * returns 1 if it is, else returns 0. */ - -void -enddmapent(void) +int +dmap_matchdev(devmap_t *dmap, char *dev) { - register struct _dmapbuff *_dmap = _dmapalloc(); + char **dva; + char *dv; - if (_dmap == 0) - return; - if (dmapf != NULL) { - (void) fclose(dmapf); - dmapf = NULL; + if (dmap->dmap_devarray == NULL) + return (0); + for (dva = dmap->dmap_devarray; (dv = *dva) != NULL; dva ++) { + if (strcmp(dv, dev) == 0) + return (1); } -} + return (0); +} /* - * setdmapfile(name) changes the default device_maps file to "name" thus - * allowing alternate device_maps files to be used. Note: it does not - * close the previous file . If this is desired, enddmapent should be called - * prior to it. + * dmap_matchtype - + * checks if the specified devmap_t is for the device specified. + * returns 1 if it is, else returns 0. */ -void -setdmapfile(char *file) +int +dmap_matchtype(devmap_t *dmap, char *type) { - register struct _dmapbuff *_dmap = _dmapalloc(); + if ((dmap->dmap_devtype == NULL) || (type == NULL)) + return (0); - if (_dmap == 0) - return; - if (dmapf != NULL) { - (void) fclose(dmapf); - dmapf = NULL; - } - DEVMAP = file; + return ((strcmp(dmap->dmap_devtype, type) == 0)); } + /* - * getdmaptype(tp) When first called, returns a pointer to the - * first devmap_t structure in the file with device-type matching - * "tp"; thereafter, it returns a pointer to the next devmap_t - * structure in the file with device-type matching "tp". - * Thus successive calls can be used to search the - * entire file for entries having device-type matching "tp". - * A null pointer is returned on error. + * dmap_matchname - + * checks if the specified devmap_t is for the device specified. + * returns 1 if it is, else returns 0. */ -devmap_t * -getdmaptype(char *tp) +int +dmap_matchname(devmap_t *dmap, char *name) { - register struct _dmapbuff *_dmap = _dmapalloc(); - char line1[BUFSIZ + 1]; - devmap_t *dmap; - - if (_dmap == 0) + if (dmap->dmap_devname == NULL) return (0); - if (dmapf == NULL && (dmapf = fopen(DEVMAP, "r")) == NULL) { - return (NULL); - } - do { - if (getdmapline(line1, (int)sizeof (line1), dmapf) == 0) - return (NULL); - if ((dmap = interpret(line1)) == NULL) - return (NULL); - } while (strcmp(tp, dmap->dmap_devtype) != 0); - return (dmap); + return ((strcmp(dmap->dmap_devname, name) == 0)); } /* - * getdmapent() When first called, returns a pointer to the first devmap_t - * structure in the file; thereafter, it returns a pointer to the next devmap_t - * structure in the file. Thus successive calls can be used to search the - * entire file. A null pointer is returned on error. + * dm_match - + * calls dmap_matchname or dmap_matchtype as appropriate. */ -devmap_t * -getdmapent(void) +int +dm_match(devmap_t *dmap, da_args *dargs) { - register struct _dmapbuff *_dmap = _dmapalloc(); - char line1[BUFSIZ + 1]; - devmap_t *dmap; + if (dargs->devinfo->devname) + return (dmap_matchname(dmap, dargs->devinfo->devname)); + else if (dargs->devinfo->devtype) + return (dmap_matchtype(dmap, dargs->devinfo->devtype)); - if (_dmap == 0) - return (0); - if (dmapf == NULL && (dmapf = fopen(DEVMAP, "r")) == NULL) { - return (NULL); - } - if (getdmapline(line1, (int)sizeof (line1), dmapf) == 0) + return (0); +} + +/* + * dmap_interpret - + * calls dmap_interpretf and dmap_dlexpand to parse devmap_t line. + * returns pointer to parsed devmapt_t entry, else returns NULL on error. + */ +devmap_t * +dmap_interpret(char *val, devmap_t *dm) +{ + if (dmap_interpretf(val, dm) == NULL) return (NULL); - if ((dmap = interpret(line1)) == NULL) + return (dmap_dlexpand(dm)); +} + +/* + * dmap_interpretf - + * parses string "val" and initializes pointers in the given devmap_t to + * fields in "val". + * returns pointer to updated devmap_t. + */ +static devmap_t * +dmap_interpretf(char *val, devmap_t *dm) +{ + dm->dmap_devname = getdadmfield(val, KV_TOKEN_DELIMIT); + dm->dmap_devtype = getdadmfield(NULL, KV_TOKEN_DELIMIT); + dm->dmap_devlist = getdadmfield(NULL, KV_TOKEN_DELIMIT); + dm->dmap_devarray = NULL; + if (dm->dmap_devname == NULL || + dm->dmap_devtype == NULL || + dm->dmap_devlist == NULL) return (NULL); - return (dmap); + + return (dm); } + /* - * matchdev(dmapp,dev) The dev_list in the structure pointed to by "dmapp" is - * searched for string "dev". If a match occures then a "1" is returned - * otherwise a "0" is returned. + * dmap_dlexpand - + * expands dmap_devlist of the form `devlist_generate` + * returns unexpanded form if there is no '\`' or in case of error. */ -static int -matchdev(devmap_t **dmapp, char *dev) +static devmap_t * +dmap_dlexpand(devmap_t *dmp) { - register struct _dmapbuff *_dmap = _dmapalloc(); - devmap_t *dmap = *dmapp; - char tmpdev[BUFSIZ + 1]; - int charcnt; - int tmpcnt; - char *cp; - char *tcp; - char *last; - charcnt = strlen(dev); - if (_dmap == 0) - return (0); - if (dmap->dmap_devlist == NULL) - return (0); - (void) strcpy(tmpdev, dmap->dmap_devlist); - tcp = tmpdev; - while ((cp = strtok_r(tcp, " ", &last)) != NULL) { - tcp = NULL; - tmpcnt = strlen(cp); - if (tmpcnt != charcnt) - continue; - if (strcmp(cp, dev) == 0) - return (1); + char tmplist[DA_BUFSIZE + 1]; + char *cp, *cpl, **darp; + int count; + FILE *expansion; + + dmp->dmap_devarray = NULL; + if (dmp->dmap_devlist == NULL) + return (NULL); + if (*(dmp->dmap_devlist) != '`') { + (void) strcpy(tmplist, dmp->dmap_devlist); + } else { + (void) strcpy(tmplist, dmp->dmap_devlist + 1); + if ((cp = strchr(tmplist, '`')) != NULL) + *cp = '\0'; + if ((expansion = popen(tmplist, "r")) == NULL) + return (NULL); + count = fread(tmplist, 1, sizeof (tmplist) - 1, expansion); + (void) pclose(expansion); + tmplist[count] = '\0'; } - return (0); + + /* cleanup the list */ + count = pack_white(tmplist); + dmp->dmap_devarray = darp = + (char **)malloc((count + 2) * sizeof (char *)); + if (darp == NULL) + return (NULL); + cp = tmplist; + while ((cp = strtok_r(cp, " ", &cpl)) != NULL) { + *darp = strdup(cp); + if (*darp == NULL) { + freedmapent(dmp); + return (NULL); + } + darp++; + cp = NULL; + } + *darp = NULL; + + return (dmp); } + /* - * matchname(dmapp,name) The audit-name in the structure pointed to by "dmapp" - * is searched for string "name". If a match occures then a "1" is returned - * otherwise a "0" is returned. + * dmapskip - + * scans input string to find next colon or end of line. + * returns pointer to next char. */ -static int -matchname(devmap_t **dmapp, char *name) +static char * +dmapskip(char *p) { - register struct _dmapbuff *_dmap = _dmapalloc(); - devmap_t *dmap = *dmapp; + while (*p && *p != ':' && *p != '\n') + ++p; + if (*p == '\n') + *p = '\0'; + else if (*p != '\0') + *p++ = '\0'; - if (_dmap == 0) - return (0); - if (dmap->dmap_devname == NULL) - return (0); - if (strlen(dmap->dmap_devname) != strlen(name)) - return (0); - if (strcmp(dmap->dmap_devname, name) == 0) - return (1); - return (0); + return (p); } + /* - * interpret(val) string "val" is parsed and the pointers in a devmap_t - * structure are initialized to point to fields in "val". A pointer to this - * structure is returned. + * dmapdskip - + * scans input string to find next space or end of line. + * returns pointer to next char. */ -static devmap_t * -interpret(char *val) +static char * +dmapdskip(p) + register char *p; { - register struct _dmapbuff *_dmap = _dmapalloc(); + while (*p && *p != ' ' && *p != '\n') + ++p; + if (*p != '\0') + *p++ = '\0'; - if (_dmap == 0) - return (0); - (void) strcpy(interpline, val); - interpdevmap.dmap_devname = getdmapfield(interpline); - interpdevmap.dmap_devtype = getdmapfield((char *)NULL); - interpdevmap.dmap_devlist = getdmapfield((char *)NULL); + return (p); +} + +char * +getdmapfield(char *ptr) +{ + static char *tptr; - return (&interpdevmap); + if (ptr == NULL) + ptr = tptr; + if (ptr == NULL) + return (NULL); + tptr = dmapskip(ptr); + ptr = trim_white(ptr); + if (ptr == NULL) + return (NULL); + if (*ptr == NULL) + return (NULL); + + return (ptr); +} + +char * +getdmapdfield(char *ptr) +{ + static char *tptr; + if (ptr != NULL) { + ptr = trim_white(ptr); + } else { + ptr = tptr; + } + if (ptr == NULL) + return (NULL); + tptr = dmapdskip(ptr); + if (ptr == NULL) + return (NULL); + if (*ptr == NULL) + return (NULL); + + return (ptr); } diff --git a/usr/src/lib/libbsm/common/llib-lbsm b/usr/src/lib/libbsm/common/llib-lbsm index b95cf4f0d3..a00c330276 100644 --- a/usr/src/lib/libbsm/common/llib-lbsm +++ b/usr/src/lib/libbsm/common/llib-lbsm @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -23,12 +22,13 @@ /* PROTOLIB1 */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" #include <bsm/devices.h> +#include <bsm/devalloc.h> #include <bsm/audit.h> #include <bsm/libbsm.h> #include <bsm/audit_record.h> diff --git a/usr/src/lib/libbsm/mkhdr.sh b/usr/src/lib/libbsm/mkhdr.sh index ca1be7eaec..3de666cb2f 100644 --- a/usr/src/lib/libbsm/mkhdr.sh +++ b/usr/src/lib/libbsm/mkhdr.sh @@ -3,9 +3,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -21,8 +20,12 @@ # CDDL HEADER END # # +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# # ident "%Z%%M% %I% %E% SMI" # + # Automagically generate the audit_uevents.h header file. # DATABASE=audit_event.txt @@ -30,8 +33,8 @@ HEADER_FILE=audit_uevents.h cat <<EOF > $HEADER_FILE /* - * Copyright (c) 1993-2001, Sun Microsystems, Inc. - * All Rights Reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #ifndef _BSM_AUDIT_UEVENTS_H @@ -57,12 +60,31 @@ EOF nawk -F: '{if ((NF == 4) && substr($1,0,1) != "#") if ($1 >= 2048) { - printf("#define %s ",$2) - if (length($2) < 8) - printf(" ") - if (length($2) < 16) - printf(" ") - printf("%s /* =%s %s */\n",$1,$4,$3) + # compute total output line length first + tlen = length($2); + llen = 8 + tlen; + llen += 8 - (llen % 8); + if (llen < 32) + llen = 32; + llen += length($1); + llen += 8 - (llen % 8); + llen += 5 + length($4) + length($3) + 3; + + # if line is too long, then print the comment first + if (llen > 80) + printf("/* =%s %s */\n", $4, $3); + + printf("#define\t%s\t", $2) + if (tlen < 8) + printf("\t"); + if (tlen < 16) + printf("\t") + printf("%s", $1); + + if (llen > 80) + printf("\n"); + else + printf("\t/* =%s %s */\n", $4, $3); } }' \ < $DATABASE >> $HEADER_FILE diff --git a/usr/src/lib/libbsm/spec/Makefile.targ b/usr/src/lib/libbsm/spec/Makefile.targ index a4a58c29f8..1784ff6015 100644 --- a/usr/src/lib/libbsm/spec/Makefile.targ +++ b/usr/src/lib/libbsm/spec/Makefile.targ @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -18,11 +17,13 @@ # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END + + # #ident "%Z%%M% %I% %E% SMI" # -# Copyright (c) 1998-1999 by Sun Microsystems, Inc. -# All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # # lib/libbsm/spec/Makefile.targ @@ -36,6 +37,7 @@ OBJECTS = au_open.o \ audit.o \ auditon.o \ auditsvc.o \ + devalloc.o \ exceptions.o \ getacinfo.o \ getauclassent.o \ diff --git a/usr/src/lib/libbsm/spec/devalloc.spec b/usr/src/lib/libbsm/spec/devalloc.spec new file mode 100644 index 0000000000..3861d93b6c --- /dev/null +++ b/usr/src/lib/libbsm/spec/devalloc.spec @@ -0,0 +1,220 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" +# +# lib/libbsm/spec/devalloc.spec + +function getdadmline +include <bsm/devices.h> +declaration int getdadmline(char *, int, FILE *) +version SUNWprivate_1.1 +end + +function getdmapdfield +include <bsm/devices.h> +declaration char *getdmapdfield(char *) +version SUNWprivate_1.1 +end + +function setdaent +include <bsm/devices.h> +declaration void setdaent(void) +version SUNWprivate_1.1 +end + +function enddaent +include <bsm/devices.h> +declaration void enddaent(void) +version SUNWprivate_1.1 +end + +function setdafile +include <bsm/devices.h> +declaration void setdafile(char *) +version SUNWprivate_1.1 +end + +function freedaent +include <bsm/devices.h> +declaration void freedaent(devalloc_t *) +version SUNWprivate_1.1 +end + +function getdaent +include <bsm/devices.h> +declaration devalloc_t *getdaent(void) +version SUNWprivate_1.1 +end + +function getdanam +include <bsm/devices.h> +declaration devalloc_t *getdanam(char *) +version SUNWprivate_1.1 +end + +function getdatype +include <bsm/devices.h> +declaration devalloc_t *getdatype(char *) +version SUNWprivate_1.1 +end + +function setdmapent +include <bsm/devices.h> +declaration void setdmapent(void) +version SUNWprivate_1.1 +end + +function enddmapent +include <bsm/devices.h> +declaration void enddmapent(void) +version SUNWprivate_1.1 +end + +function setdmapfile +include <bsm/devices.h> +declaration void setdmapfile(char *) +version SUNWprivate_1.1 +end + +function freedmapent +include <bsm/devices.h> +declaration void freedmapent(devmap_t *) +version SUNWprivate_1.1 +end + +function getdmapent +include <bsm/devices.h> +declaration devmap_t *getdmapent(void) +version SUNWprivate_1.1 +end + +function getdmapnam +include <bsm/devices.h> +declaration devmap_t *getdmapnam(char *) +version SUNWprivate_1.1 +end + +function getdmapdev +include <bsm/devices.h> +declaration devmap_t *getdmapdev(char *) +version SUNWprivate_1.1 +end + +function getdmaptype +include <bsm/devices.h> +declaration devmap_t *getdmaptype(char *) +version SUNWprivate_1.1 +end + +function getdmapfield +include <bsm/devices.h> +declaration char *getdmapfield(char *) +version SUNWprivate_1.1 +end + +function setdadefent +include <bsm/devalloc.h> +declaration void setdadefent(void) +version SUNWprivate_1.1 +end + +function enddadefent +include <bsm/devalloc.h> +declaration void enddadefent(void) +version SUNWprivate_1.1 +end + +function freedadefent +include <bsm/devalloc.h> +declaration void freedadefent(da_defs_t *) +version SUNWprivate_1.1 +end + +function getdadefent +include <bsm/devalloc.h> +declaration da_defs_t *getdadefent(void) +version SUNWprivate_1.1 +end + +function getdadeftype +include <bsm/devalloc.h> +declaration da_defs_t *getdadeftype(char *) +version SUNWprivate_1.1 +end + +function da_is_on +include <bsm/devalloc.h> +declaration int da_is_on(void) +version SUNWprivate_1.1 +end + +function da_check_logindevperm +include <bsm/devalloc.h> +declaration int da_check_logindevperm(char *) +version SUNWprivate_1.1 +end + +function da_open_devdb +include <bsm/devalloc.h> +declaration int da_open_devdb(char *, FILE **, FILE **, int) +version SUNWprivate_1.1 +end + +function da_update_device +include <bsm/devalloc.h> +declaration int da_update_device(da_args *) +version SUNWprivate_1.1 +end + +function da_update_defattrs +include <bsm/devalloc.h> +declaration int da_update_defattrs(da_args *) +version SUNWprivate_1.1 +end + +function da_add_list +include <bsm/devalloc.h> +declaration int da_add_list(devlist_t *, char *, int, int) +version SUNWprivate_1.1 +end + +function da_remove_list +include <bsm/devalloc.h> +declaration int da_remove_list(devlist_t *, char *, int, char *, int) +version SUNWprivate_1.1 +end + +function da_print_device +include <bsm/devalloc.h> +declaration void da_print_device(int, devlist_t *) +version SUNWprivate_1.1 +end + +function getdevicerange +include <sys/tsol/label.h> <bsm/devices.h> +declaration int getdevicerange(const char *, brange_t *); +version SUNWprivate_1.1 +end diff --git a/usr/src/lib/libbsm/spec/private.spec b/usr/src/lib/libbsm/spec/private.spec index 1435ae29e9..95cc9e1795 100644 --- a/usr/src/lib/libbsm/spec/private.spec +++ b/usr/src/lib/libbsm/spec/private.spec @@ -242,6 +242,18 @@ declaration token_t *au_to_xselect(char *pstring, char *type, \ version SUNWprivate_1.1 end +function au_to_mylabel +include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> +declaration token_t *au_to_mylabel(void) +version SUNWprivate_1.1 +end + +function au_to_label +include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> +declaration token_t *au_to_label(bslabel_t *label) +version SUNWprivate_1.1 +end + function audit_allocate_argv include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> declaration int audit_allocate_argv(int flg, int argc, char *argv[]) @@ -644,18 +656,6 @@ declaration int cannot_audit(int force) version SUNWprivate_1.1 end -function enddaent -include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> -declaration void enddaent(void) -version SUNWprivate_1.1 -end - -function enddmapent -include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> -declaration void enddmapent(void) -version SUNWprivate_1.1 -end - function _openac include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h> declaration au_acinfo_t *_openac(char *) @@ -704,96 +704,6 @@ declaration int _getacflg(au_acinfo_t *, char *, int) version SUNWprivate_1.1 end -function getdadfield -include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> -declaration char *getdadfield(char *ptr) -version SUNWprivate_1.1 -end - -function getdaent -include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> -declaration devalloc_t *getdaent(void) -version SUNWprivate_1.1 -end - -function getdafield -include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> -declaration char *getdafield(char *ptr) -version SUNWprivate_1.1 -end - -function getdanam -include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> -declaration devalloc_t *getdanam(char *name) -version SUNWprivate_1.1 -end - -function getdatype -include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> -declaration devalloc_t *getdatype(char *tp) -version SUNWprivate_1.1 -end - -function getdmapdev -include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> -declaration devmap_t *getdmapdev(char *name) -version SUNWprivate_1.1 -end - -function getdmapdfield -include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> -declaration char *getdmapdfield(char *ptr) -version SUNWprivate_1.1 -end - -function getdmapent -include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> -declaration devmap_t *getdmapent(void) -version SUNWprivate_1.1 -end - -function getdmapfield -include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> -declaration char *getdmapfield(char *ptr) -version SUNWprivate_1.1 -end - -function getdmapnam -include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> -declaration devmap_t *getdmapnam(char *name) -version SUNWprivate_1.1 -end - -function getdmaptype -include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> -declaration devmap_t *getdmaptype(char *tp) -version SUNWprivate_1.1 -end - -function setdaent -include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> -declaration void setdaent(void) -version SUNWprivate_1.1 -end - -function setdafile -include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> -declaration void setdafile(char *file) -version SUNWprivate_1.1 -end - -function setdmapent -include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> -declaration void setdmapent(void) -version SUNWprivate_1.1 -end - -function setdmapfile -include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> -declaration void setdmapfile(char *file) -version SUNWprivate_1.1 -end - function audit_at_create include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> version SUNWprivate_1.1 @@ -1124,3 +1034,15 @@ errno EAGAIN EBADF EBUSY EFBIG EINTR EINVAL EIO \ ENXIO EPERM EWOULDBLOCK exception $return == -1 end + +function au_to_privset +include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> +declaration token_t *au_to_privset(const char *priv_type, const priv_set_t *privilege) +version SUNWprivate_1.1 +end + +function au_to_uauth +include <sys/types.h>, <bsm/audit.h>, <bsm/libbsm.h>, <bsm/audit_record.h>, <bsm/devices.h>, <pwd.h> +declaration token_t *au_to_uauth(char *text) +version SUNWprivate_1.1 +end diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile index f5f2219db9..646428e3e4 100644 --- a/usr/src/lib/libc/amd64/Makefile +++ b/usr/src/lib/libc/amd64/Makefile @@ -772,6 +772,7 @@ PORTSYS= \ getpeerucred.o \ inst_sync.o \ issetugid.o \ + label.o \ libc_link.o \ libc_open.o \ lockf.o \ diff --git a/usr/src/lib/libc/i386/Makefile.com b/usr/src/lib/libc/i386/Makefile.com index 4e9df745fc..e4156e0ae6 100644 --- a/usr/src/lib/libc/i386/Makefile.com +++ b/usr/src/lib/libc/i386/Makefile.com @@ -811,6 +811,7 @@ PORTSYS= \ getpeerucred.o \ inst_sync.o \ issetugid.o \ + label.o \ libc_link.o \ libc_open.o \ lockf.o \ diff --git a/usr/src/lib/libc/inc/synonyms.h b/usr/src/lib/libc/inc/synonyms.h index b392b4140a..179f25f627 100644 --- a/usr/src/lib/libc/inc/synonyms.h +++ b/usr/src/lib/libc/inc/synonyms.h @@ -481,6 +481,7 @@ extern "C" { #define isphonogram _isphonogram #define issetugid _issetugid #define isspecial _isspecial +#define is_system_labeled _is_system_labeled #define iswalnum _iswalnum #define iswalpha _iswalpha #define iswcntrl _iswcntrl @@ -1039,6 +1040,7 @@ extern "C" { #define ucred_getegid _ucred_getegid #define ucred_geteuid _ucred_geteuid #define ucred_getgroups _ucred_getgroups +#define ucred_getlabel _ucred_getlabel #define ucred_getpflags _ucred_getpflags #define ucred_getpid _ucred_getpid #define ucred_getprivset _ucred_getprivset diff --git a/usr/src/lib/libc/port/gen/ucred.c b/usr/src/lib/libc/port/gen/ucred.c index 8367c0f90c..b500617d48 100644 --- a/usr/src/lib/libc/port/gen/ucred.c +++ b/usr/src/lib/libc/port/gen/ucred.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -43,6 +42,7 @@ #pragma weak ucred_getauid = _ucred_getauid #pragma weak ucred_getasid = _ucred_getasid #pragma weak ucred_getatid = _ucred_getatid +#pragma weak ucred_getlabel = _ucred_getlabel #pragma weak ucred_getamask = _ucred_getamask #pragma weak ucred_size = _ucred_size @@ -66,6 +66,7 @@ #include <sys/procfs.h> #include <sys/sysmacros.h> #include <sys/zone.h> +#include <tsol/label.h> ucred_t * _ucred_alloc(void) @@ -260,6 +261,20 @@ ucred_getzoneid(const ucred_t *uc) return (uc->uc_zoneid); } +bslabel_t * +ucred_getlabel(const ucred_t *uc) +{ + /* LINTED: alignment */ + bslabel_t *slabel = UCLABEL(uc); + + if (!is_system_labeled() || slabel == NULL) { + errno = EINVAL; + return (NULL); + } + + return (slabel); +} + /* * For now, assume single bit flags. */ diff --git a/usr/src/lib/libc/port/llib-lc b/usr/src/lib/libc/port/llib-lc index 31c57bd49b..9930b72c9c 100644 --- a/usr/src/lib/libc/port/llib-lc +++ b/usr/src/lib/libc/port/llib-lc @@ -1740,3 +1740,6 @@ volatile sc_shared_t *volatile *_thr_schedctl(void); /* private interface to unmount all autofs mounts */ int _autofssys(enum autofssys_op, void *); + +/* label.c */ +extern int is_system_labeled(void); diff --git a/usr/src/lib/libc/port/sys/label.c b/usr/src/lib/libc/port/sys/label.c new file mode 100644 index 0000000000..15c476ba8d --- /dev/null +++ b/usr/src/lib/libc/port/sys/label.c @@ -0,0 +1,54 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#pragma weak is_system_labeled = _is_system_labeled + +#include "synonyms.h" +#include <sys/types.h> +#include <sys/syscall.h> +#include <sys/tsol/tsyscall.h> +#include <unistd.h> +#include <limits.h> +#include <stdlib.h> +#include <errno.h> +#include "libc.h" + +static int _is_labeled = -1; + +/* + * is_system_labeled : + * Return the status of MAC labeling on this system. + * Returns 0 if labeling is not installed or not active, + */ +int +is_system_labeled(void) +{ + if (_is_labeled >= 0) + return (_is_labeled); /* fast path if cached */ + + return (_is_labeled = syscall(SYS_labelsys, TSOL_SYSLABELING)); +} diff --git a/usr/src/lib/libc/port/sys/zone.c b/usr/src/lib/libc/port/sys/zone.c index fc852c4dd5..12e34c0de6 100644 --- a/usr/src/lib/libc/port/sys/zone.c +++ b/usr/src/lib/libc/port/sys/zone.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -37,14 +36,15 @@ #include <sys/priv.h> #include <priv_private.h> #include <zone.h> +#include <sys/tsol/label.h> #include <dlfcn.h> #include <stdlib.h> #include <errno.h> -extern zoneid_t +zoneid_t zone_create(const char *name, const char *root, const struct priv_set *privs, const char *rctls, size_t rctlsz, const char *zfs, size_t zfssz, - int *extended_error) + int *extended_error, int match, int doi, const bslabel_t *label) { zone_def zd; priv_data_t *d; @@ -60,6 +60,9 @@ zone_create(const char *name, const char *root, const struct priv_set *privs, zd.zfsbuf = zfs; zd.zfsbufsz = zfssz; zd.extended_error = extended_error; + zd.match = match; + zd.doi = doi; + zd.label = label; return ((zoneid_t)syscall(SYS_zone, ZONE_CREATE, &zd)); } diff --git a/usr/src/lib/libc/sparc/Makefile b/usr/src/lib/libc/sparc/Makefile index 587a8d0306..7b5a74a3a3 100644 --- a/usr/src/lib/libc/sparc/Makefile +++ b/usr/src/lib/libc/sparc/Makefile @@ -836,6 +836,7 @@ PORTSYS= \ getpeerucred.o \ inst_sync.o \ issetugid.o \ + label.o \ libc_link.o \ libc_open.o \ lockf.o \ diff --git a/usr/src/lib/libc/sparcv9/Makefile b/usr/src/lib/libc/sparcv9/Makefile index d2c0bd1f8c..55d2c9d7be 100644 --- a/usr/src/lib/libc/sparcv9/Makefile +++ b/usr/src/lib/libc/sparcv9/Makefile @@ -781,6 +781,7 @@ PORTSYS= \ getpeerucred.o \ inst_sync.o \ issetugid.o \ + label.o \ libc_link.o \ libc_open.o \ lockf.o \ diff --git a/usr/src/lib/libc/spec/gen.spec b/usr/src/lib/libc/spec/gen.spec index cf7993a61c..55d40dd946 100644 --- a/usr/src/lib/libc/spec/gen.spec +++ b/usr/src/lib/libc/spec/gen.spec @@ -4698,6 +4698,17 @@ weak ucred_getzoneid version SUNW_1.22 end +function ucred_getlabel +include <ucred.h> +declaration bslabel_t *ucred_getlabel(const ucred_t *) +version SUNW_1.22.2 +end + +function _ucred_getlabel +weak ucred_getlabel +version SUNW_1.22.2 +end + function ucred_getpflags include <ucred.h> declaration uint_t ucred_getpflags(const ucred_t *, uint_t) diff --git a/usr/src/lib/libc/spec/sys.spec b/usr/src/lib/libc/spec/sys.spec index 7b181ab7d5..1e928c42b8 100644 --- a/usr/src/lib/libc/spec/sys.spec +++ b/usr/src/lib/libc/spec/sys.spec @@ -1,13 +1,12 @@ # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -3432,9 +3431,11 @@ end function zone_create include <zone.h> -declaration zoneid_t zone_create(const char *zone_name, \ - const char *zone_root, const priv_set_t *zone_privs, \ - const char *rctlbuf, size_t rctlbufsz, int *) +declaration zoneid_t zone_create(const char *name, const char *root, \ + const struct priv_set *privs, const char *rctls, \ + size_t rctlsz, const char *zfs, size_t zfssz, \ + int *extended_error, int match, \ + int doi, const bslabel_t *label) version SUNWprivate_1.1 exception $return == -1 end @@ -3519,3 +3520,13 @@ function _getzonenamebyid weak getzonenamebyid version SUNWprivate_1.1 end + +function is_system_labeled +declaration int is_system_labeled(void) +version SUNW_1.22.2 +end + +function _is_system_labeled +weak is_system_labeled +version SUNWprivate_1.1 +end diff --git a/usr/src/lib/libc/spec/versions b/usr/src/lib/libc/spec/versions index 210eb67629..cbfc8b9c6b 100644 --- a/usr/src/lib/libc/spec/versions +++ b/usr/src/lib/libc/spec/versions @@ -1,13 +1,12 @@ # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -26,6 +25,7 @@ # i386 { + SUNW_1.22.2: {SUNW_1.22.1}; SUNW_1.22.1: {SUNW_1.22}; SUNW_1.22: {SUNW_1.21.3}; SUNW_1.21.3: {SUNW_1.21.2}; @@ -62,6 +62,7 @@ i386 { SUNWprivate_1.1; } amd64 { + SUNW_1.22.2: {SUNW_1.22.1}; SUNW_1.22.1: {SUNW_1.22}; SUNW_1.22: {SUNW_1.21.3}; SUNW_1.21.3: {SUNW_1.21.2}; @@ -98,6 +99,7 @@ amd64 { SUNWprivate_1.1; } sparc { + SUNW_1.22.2: {SUNW_1.22.1}; SUNW_1.22.1: {SUNW_1.22}; SUNW_1.22: {SUNW_1.21.3}; SUNW_1.21.3: {SUNW_1.21.2}; @@ -135,6 +137,7 @@ sparc { SUNWprivate_1.1; } sparcv9 { + SUNW_1.22.2: {SUNW_1.22.1}; SUNW_1.22.1: {SUNW_1.22}; SUNW_1.22: {SUNW_1.21.3}; SUNW_1.21.3: {SUNW_1.21.2}; diff --git a/usr/src/lib/libipsecutil/common/ipsec_util.h b/usr/src/lib/libipsecutil/common/ipsec_util.h index 70bedb66bd..3e8876db93 100644 --- a/usr/src/lib/libipsecutil/common/ipsec_util.h +++ b/usr/src/lib/libipsecutil/common/ipsec_util.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -45,9 +44,11 @@ extern "C" { #include <err.h> #include <net/pfpolicy.h> +#ifndef A_CNT /* macros for array manipulation */ #define A_CNT(arr) (sizeof (arr)/sizeof (arr[0])) #define A_END(arr) (&arr[A_CNT(arr)]) +#endif /* used for file parsing */ #define NBUF_SIZE 16 diff --git a/usr/src/lib/libldap5/Makefile.com b/usr/src/lib/libldap5/Makefile.com index b641d18cd3..a90c72761d 100644 --- a/usr/src/lib/libldap5/Makefile.com +++ b/usr/src/lib/libldap5/Makefile.com @@ -1,5 +1,25 @@ # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -68,7 +88,7 @@ SRCS= $(BEROBJS:%.o=../sources/ldap/ber/%.c) \ LIBS = $(DYNLIB) $(LINTLIB) DYNFLAGS += $(ZNODELETE) -CPPFLAGS += -I$(COM_INC) +CPPFLAGS= $(COM_INC) $(CPPFLAGS.master) # definitions for lint diff --git a/usr/src/lib/libnsl/Makefile b/usr/src/lib/libnsl/Makefile index 756e9d14d1..04728bf54a 100644 --- a/usr/src/lib/libnsl/Makefile +++ b/usr/src/lib/libnsl/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -18,6 +17,8 @@ # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END + + # # # Copyright 2006 Sun Microsystems, Inc. All rights reserved. @@ -27,7 +28,7 @@ # # lib/libnsl/Makefile # -PROTOCOL_DIR= $(ROOT)/usr/include/rpcsvc +PROTOCOL_DIR= $(ROOTHDRDIR)/rpcsvc PROTOCOL_SRCDIR= $(SRC)/head/rpcsvc PROTOCOL_UTS_SRCDIR= $(SRC)/uts/common/rpc @@ -71,9 +72,9 @@ CLEANFILES += $(DERIVED_FILES) # include library definitions include ../Makefile.lib -SED= sed -CP= cp -GREP= grep +# header file delivered to /usr/include; internal to ON build process +HDRS = nss.h +HDRDIR = nss LIBRARY= libnsl.a TEXT_DOMAIN= SUNW_OST_NETRPC @@ -99,6 +100,11 @@ headers: $(PROTOCOL_DIR) .WAIT $(PROTOCOL_FILES) $(PROTOCOL_FILES_UTS) \ install: all $(SUBDIRS) +install_h: $(ROOTHDRS) + +# nss.h isn't delivered; no reason to check +check: + clean clobber delete lint package: $(SUBDIRS) $(PROTOCOL_DIR): diff --git a/usr/src/lib/libnsl/Makefile.com b/usr/src/lib/libnsl/Makefile.com index 7945cdb4c2..0159a59cba 100644 --- a/usr/src/lib/libnsl/Makefile.com +++ b/usr/src/lib/libnsl/Makefile.com @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -18,6 +17,8 @@ # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END + + # # # Copyright 2006 Sun Microsystems, Inc. All rights reserved. @@ -190,7 +191,8 @@ MAPOPTS= $(MAPFILES:%=-M%) # then use the environment variable LD_OPTIONS=-Dgot,detail to have the # linker print out the list of GOT hogs.. -GOTHOGS = dial.o print_obj.o clnt_perror.o +GOTHOGS = dial.o print_obj.o clnt_perror.o nsl_stdio_prv.o netdir.o \ + algs.o netselect.o BIGPICS = $(GOTHOGS:%=pics/%) $(BIGPICS) := sparc_C_PICFLAGS = $(C_BIGPICFLAGS) $(BIGPICS) := i386_C_PICFLAGS = $(C_BIGPICFLAGS) diff --git a/usr/src/lib/libnsl/nss/nss.h b/usr/src/lib/libnsl/nss/nss.h index 7efd4e83ee..e3f1463dcd 100644 --- a/usr/src/lib/libnsl/nss/nss.h +++ b/usr/src/lib/libnsl/nss/nss.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -64,6 +63,14 @@ extern void _nss_initf_ipnodes(nss_db_params_t *); extern void order_haddrlist_af(sa_family_t, char **); extern int nss_ioctl(int, int, void *); +/* parse.c */ +extern char *_strtok_escape(char *, char *, char **); +extern char *_strpbrk_escape(char *, char *); +extern char *_escape(char *, char *); +extern char *_unescape(char *, char *); +extern char *_strdup_null(char *); +extern int _readbufline(char *, int, char *, int, int *); + #ifdef __cplusplus } #endif diff --git a/usr/src/lib/libnsl/rpc/clnt_bcast.c b/usr/src/lib/libnsl/rpc/clnt_bcast.c index fc18ed6236..ab16e8a595 100644 --- a/usr/src/lib/libnsl/rpc/clnt_bcast.c +++ b/usr/src/lib/libnsl/rpc/clnt_bcast.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -43,6 +42,7 @@ */ #include "mt.h" +#include "rpc_mt.h" #include <string.h> #include <strings.h> #include <rpc/rpc.h> @@ -51,8 +51,6 @@ #include <netdir.h> #ifdef PORTMAP #include <rpc/pmap_prot.h> -#include <rpc/pmap_clnt.h> -#include <rpc/pmap_rmt.h> #endif #ifdef RPC_DEBUG #include <stdio.h> @@ -187,11 +185,13 @@ rpc_broadcast_exp(const rpcprog_t prog, const rpcvers_t vers, stat = RPC_CANTSEND; continue; } + __rpc_set_mac_options(fd, nconf, prog); if (t_bind(fd, NULL, NULL) == -1) { (void) t_close(fd); stat = RPC_CANTSEND; continue; } + /* Do protocol specific negotiating for broadcast */ if (netdir_options(nconf, ND_SET_BROADCAST, fd, NULL)) { (void) t_close(fd); diff --git a/usr/src/lib/libnsl/rpc/clnt_generic.c b/usr/src/lib/libnsl/rpc/clnt_generic.c index add0dfe880..f3507134ce 100644 --- a/usr/src/lib/libnsl/rpc/clnt_generic.c +++ b/usr/src/lib/libnsl/rpc/clnt_generic.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -403,6 +402,8 @@ clnt_create_service_timed(const char *host, const char *service, if (fd < __rpc_minfd) fd = __rpc_raise_fd(fd); + __rpc_set_mac_options(fd, nconf, prog); + /* LINTED pointer cast */ if ((tbind = (struct t_bind *)t_alloc(fd, T_BIND, T_ADDR)) == NULL) { @@ -622,6 +623,7 @@ _clnt_tli_create_timed(int fd, const struct netconfig *nconf, if (fd < __rpc_minfd) fd = __rpc_raise_fd(fd); madefd = TRUE; + __rpc_set_mac_options(fd, nconf, prog); if (t_bind(fd, NULL, NULL) == -1) goto err; switch (nconf->nc_semantics) { diff --git a/usr/src/lib/libnsl/rpc/rpc_mt.h b/usr/src/lib/libnsl/rpc/rpc_mt.h index 52b49c3a82..75e93f390f 100644 --- a/usr/src/lib/libnsl/rpc/rpc_mt.h +++ b/usr/src/lib/libnsl/rpc/rpc_mt.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -36,6 +35,7 @@ #include <sys/types.h> #include <rpc/rpc.h> +#include <netconfig.h> #ifdef __cplusplus extern "C" { @@ -94,6 +94,8 @@ extern int __getpublickey_cached(char *, char *, int *); extern void __getpublickey_flush(const char *); extern int __can_use_af(sa_family_t); extern int __rpc_raise_fd(int); +extern void __rpc_set_mac_options(int, const struct netconfig *, + rpcprog_t); extern void __tli_sys_strerror(char *, size_t, int, int); #ifdef __cplusplus diff --git a/usr/src/lib/libnsl/rpc/svc_dg.c b/usr/src/lib/libnsl/rpc/svc_dg.c index 8a73cb8faa..b66ba988f0 100644 --- a/usr/src/lib/libnsl/rpc/svc_dg.c +++ b/usr/src/lib/libnsl/rpc/svc_dg.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -21,7 +20,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ @@ -44,6 +43,7 @@ #include "rpc_mt.h" #include <stdio.h> #include <sys/types.h> +#include <sys/sysmacros.h> #include <rpc/rpc.h> #include <errno.h> #include <syslog.h> @@ -284,6 +284,37 @@ svc_dg_stat(SVCXPRT *xprt) return (XPRT_IDLE); } +/* + * Find the SCM_UCRED in src and place a pointer to that option alone in dest. + * Note that these two 'netbuf' structures might be the same one, so the code + * has to be careful about referring to src after changing dest. + */ +static void +extract_cred(const struct netbuf *src, struct netbuf *dest) +{ + char *cp = src->buf; + unsigned int len = src->len; + const struct T_opthdr *opt; + unsigned int olen; + + while (len >= sizeof (*opt)) { + /* LINTED: pointer alignment */ + opt = (const struct T_opthdr *)cp; + olen = opt->len; + if (olen > len || olen < sizeof (*opt) || + !IS_P2ALIGNED(olen, sizeof (t_uscalar_t))) + break; + if (opt->level == SOL_SOCKET && opt->name == SCM_UCRED) { + dest->buf = cp; + dest->len = olen; + return; + } + cp += olen; + len -= olen; + } + dest->len = 0; +} + static bool_t svc_dg_recv(SVCXPRT *xprt, struct rpc_msg *msg) { @@ -354,9 +385,10 @@ again: /* tu_data.addr is already set */ tu_data->udata.buf = reply; tu_data->udata.len = (uint_t)replylen; - tu_data->opt.len = 0; + extract_cred(&tu_data->opt, &tu_data->opt); (void) t_sndudata(xprt->xp_fd, tu_data); tu_data->udata.buf = (char *)rpc_buffer(xprt); + tu_data->opt.buf = (char *)su->opts; return (FALSE); } } @@ -425,7 +457,7 @@ svc_dg_reply(SVCXPRT *xprt, struct rpc_msg *msg) slen = (int)XDR_GETPOS(xdrs); tu_data->udata.len = slen; - tu_data->opt.len = 0; + extract_cred(&su->optbuf, &tu_data->opt); try_again: if (t_sndudata(xprt->xp_fd, tu_data) == 0) { stat = TRUE; @@ -440,6 +472,7 @@ try_again: "svc_dg_reply: t_sndudata error t_errno=%d errno=%d\n", t_errno, errno); } + tu_data->opt.buf = (char *)su->opts; } return (stat); } diff --git a/usr/src/lib/libnsl/rpc/svc_generic.c b/usr/src/lib/libnsl/rpc/svc_generic.c index 10f6ce1508..a0673e43c8 100644 --- a/usr/src/lib/libnsl/rpc/svc_generic.c +++ b/usr/src/lib/libnsl/rpc/svc_generic.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -21,7 +20,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -52,7 +51,14 @@ #include <malloc.h> #include <string.h> #include <stropts.h> - +#include <tsol/label.h> +#include <nfs/nfs.h> +#include <nfs/nfs_acl.h> +#include <rpcsvc/mount.h> +#include <rpcsvc/nsm_addr.h> +#include <rpcsvc/rquota.h> +#include <rpcsvc/sm_inter.h> +#include <rpcsvc/nlm_prot.h> extern int __svc_vc_setflag(SVCXPRT *, int); @@ -80,6 +86,22 @@ extern bool_t __rpc_try_doors(const char *, bool_t *); SVCXPRT_LIST *_svc_xprtlist = NULL; extern mutex_t xprtlist_lock; +static SVCXPRT * svc_tli_create_common(int, const struct netconfig *, + const struct t_bind *, uint_t, uint_t, boolean_t); + +boolean_t +is_multilevel(rpcprog_t prognum) +{ + /* This is a list of identified multilevel service provider */ + if ((prognum == MOUNTPROG) || (prognum == NFS_PROGRAM) || + (prognum == NFS_ACL_PROGRAM) || (prognum == NLM_PROG) || + (prognum == NSM_ADDR_PROGRAM) || (prognum == RQUOTAPROG) || + (prognum == SM_PROG)) + return (B_TRUE); + + return (B_FALSE); +} + void __svc_free_xprtlist(void) { @@ -162,6 +184,7 @@ svc_tp_create(void (*dispatch)(), const rpcprog_t prognum, const rpcvers_t versnum, const struct netconfig *nconf) { SVCXPRT *xprt; + boolean_t anon_mlp = B_FALSE; if (nconf == NULL) { (void) syslog(LOG_ERR, @@ -169,7 +192,11 @@ svc_tp_create(void (*dispatch)(), const rpcprog_t prognum, prognum, versnum); return (NULL); } - xprt = svc_tli_create(RPC_ANYFD, nconf, NULL, 0, 0); + + /* Some programs need to allocate MLP for multilevel services */ + if (is_system_labeled() && is_multilevel(prognum)) + anon_mlp = B_TRUE; + xprt = svc_tli_create_common(RPC_ANYFD, nconf, NULL, 0, 0, anon_mlp); if (xprt == NULL) return (NULL); (void) rpcb_unset(prognum, versnum, (struct netconfig *)nconf); @@ -183,6 +210,13 @@ svc_tp_create(void (*dispatch)(), const rpcprog_t prognum, return (xprt); } +SVCXPRT * +svc_tli_create(const int fd, const struct netconfig *nconf, + const struct t_bind *bindaddr, const uint_t sendsz, const uint_t recvsz) +{ + return (svc_tli_create_common(fd, nconf, bindaddr, sendsz, recvsz, 0)); +} + /* * If fd is RPC_ANYFD, then it opens a fd for the given transport * provider (nconf cannot be NULL then). If the t_state is T_UNBND and @@ -193,8 +227,9 @@ svc_tp_create(void (*dispatch)(), const rpcprog_t prognum, * If sendsz or recvsz are zero, their default values are chosen. */ SVCXPRT * -svc_tli_create(const int ofd, const struct netconfig *nconf, - const struct t_bind *bindaddr, const uint_t sendsz, const uint_t recvsz) +svc_tli_create_common(const int ofd, const struct netconfig *nconf, + const struct t_bind *bindaddr, const uint_t sendsz, + const uint_t recvsz, boolean_t mlp_flag) { SVCXPRT *xprt = NULL; /* service handle */ struct t_info tinfo; /* transport info */ @@ -293,6 +328,17 @@ svc_tli_create(const int ofd, const struct netconfig *nconf, switch (state) { bool_t tcp, exclbind; case T_UNBND: + /* If this is a labeled system, then ask for an MLP */ + if (is_system_labeled() && + (strcmp(nconf->nc_protofmly, NC_INET) == 0 || + strcmp(nconf->nc_protofmly, NC_INET6) == 0)) { + (void) __rpc_tli_set_options(fd, SOL_SOCKET, + SO_RECVUCRED, 1); + if (mlp_flag) + (void) __rpc_tli_set_options(fd, SOL_SOCKET, + SO_ANON_MLP, 1); + } + /* * {TCP,UDP}_EXCLBIND has the following properties * - an fd bound to port P via IPv4 will prevent an IPv6 diff --git a/usr/src/lib/libnsl/rpc/ti_opts.c b/usr/src/lib/libnsl/rpc/ti_opts.c index 1b5e910261..ae32fa9788 100644 --- a/usr/src/lib/libnsl/rpc/ti_opts.c +++ b/usr/src/lib/libnsl/rpc/ti_opts.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -59,11 +58,10 @@ #include <alloca.h> #include <stdlib.h> #include <zone.h> +#include <tsol/label.h> -extern const char *inet_ntop(int, const void *, char *, socklen_t); extern bool_t __svc_get_door_ucred(const SVCXPRT *, ucred_t *); - /* * This routine is typically called on the server side if the server * wants to know the caller ucred. Called typically by rpcbind. It @@ -494,6 +492,8 @@ __rpc_tli_set_options(int fd, int optlevel, int optname, int optval) case SO_REUSEADDR: case SO_DGRAM_ERRIND: case SO_RECVUCRED: + case SO_ANON_MLP: + case SO_MAC_EXEMPT: case TCP_EXCLBIND: case UDP_EXCLBIND: /* LINTED */ @@ -548,3 +548,34 @@ __tli_sys_strerror(char *buf, size_t buflen, int tli_err, int sys_err) (void) strlcpy(buf, errorstr, buflen); } } + +/* + * Depending on the specified RPC number, attempt to set mac_exempt + * option on the opened socket; these requests need to be able to do MAC + * MAC read-down operations. Privilege is needed to set this option. + */ + +void +__rpc_set_mac_options(int fd, const struct netconfig *nconf, rpcprog_t prognum) +{ + int ret = 0; + + if (!is_system_labeled()) + return; + + if (strcmp(nconf->nc_protofmly, NC_INET) != 0 && + strcmp(nconf->nc_protofmly, NC_INET6) != 0) + return; + + if (is_multilevel(prognum)) { + ret = __rpc_tli_set_options(fd, SOL_SOCKET, SO_MAC_EXEMPT, 1); + if (ret < 0) { + char errorstr[100]; + + __tli_sys_strerror(errorstr, sizeof (errorstr), + t_errno, errno); + (void) syslog(LOG_ERR, "rpc_set_mac_options: %s", + errorstr); + } + } +} diff --git a/usr/src/lib/libsldap/common/ns_common.c b/usr/src/lib/libsldap/common/ns_common.c index b3a812e92f..05323c204b 100644 --- a/usr/src/lib/libsldap/common/ns_common.c +++ b/usr/src/lib/libsldap/common/ns_common.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -82,6 +81,8 @@ static ns_service_map ns_def_map[] = { { "profile", "ou=profile,", NULL }, { "printers", "ou=printers,", NULL }, { "automount", "", NULL }, + { "tnrhtp", "ou=ipTnet,", NULL }, + { "tnrhdb", "ou=ipTnet,", "tnrhtp" }, { NULL, NULL, NULL } }; diff --git a/usr/src/lib/libsldap/common/ns_sldap.h b/usr/src/lib/libsldap/common/ns_sldap.h index 8e8c59113c..0138c1e3d5 100644 --- a/usr/src/lib/libsldap/common/ns_sldap.h +++ b/usr/src/lib/libsldap/common/ns_sldap.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -450,6 +449,8 @@ typedef struct _ns_automount { #define NS_LDAP_TYPE_AUUSER "audit_user" #define NS_LDAP_TYPE_BOOTPARAMS "bootparams" #define NS_LDAP_TYPE_AUTOMOUNT "auto_" +#define NS_LDAP_TYPE_TNRHDB "tnrhdb" +#define NS_LDAP_TYPE_TNRHTP "tnrhtp" /* * service descriptor/attribute mapping structure diff --git a/usr/src/lib/libsldap/common/ns_writes.c b/usr/src/lib/libsldap/common/ns_writes.c index 146752c88a..217586e340 100644 --- a/usr/src/lib/libsldap/common/ns_writes.c +++ b/usr/src/lib/libsldap/common/ns_writes.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -56,6 +55,8 @@ #include <prof_attr.h> #include <user_attr.h> #include <bsm/libbsm.h> +#include <sys/tsol/tndb.h> +#include <tsol/label.h> /* @@ -3246,7 +3247,128 @@ __s_cvt_audituser(const void *data, char **rdn, return (NS_LDAP_SUCCESS); } +/* + * Conversion: tnrhtp + * Input format: tsol_tpstr_t + * Exported objectclass: ipTnetTemplate + */ +static int +__s_cvt_tnrhtp(const void *data, char **rdn, + ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) +{ + ns_ldap_entry_t *e; + int rc; + char trdn[RDNSIZE]; + /* routine specific */ + int max_attr = 2; + tsol_tpstr_t *ptr; + static char *oclist[] = { + "ipTnetTemplate", + "top", + NULL + }; + + if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) + return (NS_LDAP_OP_FAILED); + + *entry = e = __s_mk_entry(oclist, max_attr); + if (e == NULL) + return (NS_LDAP_MEMORY); + + /* Convert the structure */ + ptr = (tsol_tpstr_t *)data; + + if ((ptr->template == NULL) || (strlen(ptr->template) <= 1)) { + __ns_ldap_freeEntry(e); + *entry = NULL; + return (NS_LDAP_INVALID_PARAM); + } + + /* Create an appropriate rdn */ + (void) snprintf(trdn, RDNSIZE, "ipTnetTemplateName=%s", ptr->template); + *rdn = strdup(trdn); + if (*rdn == NULL) { + __ns_ldap_freeEntry(e); + *entry = NULL; + return (NS_LDAP_MEMORY); + } + + rc = __s_add_attr(e, "ipTnetTemplateName", ptr->template); + if (rc != NS_LDAP_SUCCESS) { + __s_cvt_freeEntryRdn(entry, rdn); + return (rc); + } + + rc = __s_add_attr(e, "SolarisAttrKeyValue", ptr->attrs); + if (rc != NS_LDAP_SUCCESS) { + __s_cvt_freeEntryRdn(entry, rdn); + return (rc); + } + return (NS_LDAP_SUCCESS); +} +/* + * Conversion: tnrhdb + * Input format: tsol_rhstr_t + * Exported objectclass: ipTnetHost + */ +static int +__s_cvt_tnrhdb(const void *data, char **rdn, + ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) +{ + ns_ldap_entry_t *e; + int rc; + char trdn[RDNSIZE]; + /* routine specific */ + tsol_rhstr_t *ptr; + int max_attr = 2; + static char *oclist[] = { + "ipTnetHost", + "ipTnetTemplate", + "top", + NULL + }; + + if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) + return (NS_LDAP_OP_FAILED); + + *entry = e = __s_mk_entry(oclist, max_attr); + if (e == NULL) + return (NS_LDAP_MEMORY); + + /* Convert the structure */ + ptr = (tsol_rhstr_t *)data; + + if ((ptr->address == NULL) || (strlen(ptr->address) <= 1) || + (ptr->template == NULL) || (strlen(ptr->template) <= 1)) { + __ns_ldap_freeEntry(e); + *entry = NULL; + return (NS_LDAP_INVALID_PARAM); + } + + /* Create an appropriate rdn */ + (void) snprintf(trdn, RDNSIZE, "ipTnetNumber=%s", ptr->address); + *rdn = strdup(trdn); + if (*rdn == NULL) { + __ns_ldap_freeEntry(e); + *entry = NULL; + return (NS_LDAP_MEMORY); + } + + rc = __s_add_attr(e, "ipTnetNumber", ptr->address); + if (rc != NS_LDAP_SUCCESS) { + __s_cvt_freeEntryRdn(entry, rdn); + return (rc); + } + + rc = __s_add_attr(e, "ipTnetTemplateName", ptr->template); + if (rc != NS_LDAP_SUCCESS) { + __s_cvt_freeEntryRdn(entry, rdn); + return (rc); + } + + return (NS_LDAP_SUCCESS); +} /* * Add Typed Entry Conversion data structures */ @@ -3283,6 +3405,8 @@ static __ns_cvt_type_t __s_cvtlist[] = { { NS_LDAP_TYPE_AUTOMOUNT, 0, __s_cvt_auto_mount }, { NS_LDAP_TYPE_PUBLICKEY, AE, __s_cvt_publickey }, { NS_LDAP_TYPE_AUUSER, AE, __s_cvt_audituser }, + { NS_LDAP_TYPE_TNRHTP, 0, __s_cvt_tnrhtp }, + { NS_LDAP_TYPE_TNRHDB, 0, __s_cvt_tnrhdb }, { NULL, 0, NULL }, }; diff --git a/usr/src/lib/libtsnet/Makefile b/usr/src/lib/libtsnet/Makefile new file mode 100644 index 0000000000..aa06ccdef0 --- /dev/null +++ b/usr/src/lib/libtsnet/Makefile @@ -0,0 +1,67 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.lib + +HDRS = libtsnet.h +HDRDIR = common +SUBDIRS = $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET= all +clean := TARGET= clean +clobber := TARGET= clobber +install := TARGET= install +lint := TARGET= lint + +POFILE = libtsnet.po +MSGFILES = common/misc.i + +.KEEP_STATE: + +all install: spec .WAIT $(SUBDIRS) + +clean clobber: spec $(SUBDIRS) + +lint: $(SUBDIRS) + +install_h: $(ROOTHDRS) + +check: $(CHECKHDRS) + +_msg: $(MSGDOMAINPOFILE) + +$(POFILE): $(MSGFILES) + $(BUILDPO.msgfiles) + +spec $(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include $(SRC)/Makefile.msg.targ +include ../Makefile.targ diff --git a/usr/src/lib/libtsnet/Makefile.com b/usr/src/lib/libtsnet/Makefile.com new file mode 100644 index 0000000000..c77b2403ad --- /dev/null +++ b/usr/src/lib/libtsnet/Makefile.com @@ -0,0 +1,63 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +LIBRARY = libtsnet.a +VERS = .1 + +OBJECTS = \ + misc.o \ + tnrh.o tnrhtp.o tnmlp.o \ + tsol_getrhent.o tsol_gettpent.o \ + tsol_sgetrhent.o tsol_sgettpent.o tsol_sgetzcent.o + +include ../../Makefile.lib + +# install this library in the root filesystem +include ../../Makefile.rootfs + +LIBS = $(DYNLIB) $(LINTLIB) +$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) + +LAZYLIBS = $(ZLAZYLOAD) -ltsol $(ZNOLAZYLOAD) +LDLIBS += -lsocket -lnsl -lc -lsecdb $(LAZYLIBS) +lint := LAZYLIBS = -ltsol + +SRCDIR = ../common +MAPDIR = ../spec/$(TRANSMACH) +SPECMAPFILE = $(MAPDIR)/mapfile + +LIBTSOLINC = $(SRC)/lib/libtsol/common + +CPPFLAGS += -D_REENTRANT -I$(LIBTSOLINC) + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +include ../../Makefile.targ diff --git a/usr/src/lib/libtsnet/amd64/Makefile b/usr/src/lib/libtsnet/amd64/Makefile new file mode 100644 index 0000000000..69cf39010b --- /dev/null +++ b/usr/src/lib/libtsnet/amd64/Makefile @@ -0,0 +1,31 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +#ident "%Z%%M% %I% %E% SMI" + +include ../Makefile.com +include ../../Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64) diff --git a/usr/src/lib/libtsnet/common/libtsnet.h b/usr/src/lib/libtsnet/common/libtsnet.h new file mode 100644 index 0000000000..2aa6d5fc56 --- /dev/null +++ b/usr/src/lib/libtsnet/common/libtsnet.h @@ -0,0 +1,148 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * All symbols and functions in this header file and library are private to Sun + * Microsystems. The only guarantee that is made is that if your application + * uses them, it will break on upgrade. + */ + +#ifndef _LIBTSNET_H +#define _LIBTSNET_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <sys/tsol/tndb.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define TNRHTP_PATH "/etc/security/tsol/tnrhtp" +#define TNRHDB_PATH "/etc/security/tsol/tnrhdb" +#define TNZONECFG_PATH "/etc/security/tsol/tnzonecfg" + +#define TNDB_COMMA ", \t" + +/* + * String parsing routines + * + * These functions are in four logical groups: one for template (tnrhtp) + * entries, one for remote host (tnrhdb) entries, one for zone configuration + * (tnzonecfg) entries, and a fourth for routing attributes. + * + * In each group, there are functions that parse from a string or database, and + * a function to free returned entries. The parsing functions all take a + * pointer to an integer and a pointer to a character pointer for returning + * errors. On error, the returned entry pointer is NULL, the integer is set to + * one of the LTSNET_* errors below, and the character pointer points to the + * location of the error. (For the functions that iterate on a database, this + * points into static storage in the library. This storage is associated with + * the iterator.) + * + * The functions that do look-ups based on a value (name or address) do not + * return errors other than "not found," which is signaled by a return value of + * NULL. + */ + +/* Template entry parsing */ +extern tsol_tpent_t *tsol_gettpbyname(const char *); +extern tsol_tpent_t *tsol_gettpent(void); +extern tsol_tpent_t *tsol_fgettpent(FILE *); +extern void tsol_freetpent(tsol_tpent_t *); +extern void tsol_settpent(int); +extern void tsol_endtpent(void); +extern int str_to_tpstr(const char *, int, void *, char *, int); +extern tsol_tpent_t *tpstr_to_ent(tsol_tpstr_t *, int *, char **); + +/* Remote host entry parsing */ +extern tsol_rhent_t *tsol_getrhbyaddr(const void *, size_t, int); +extern tsol_rhent_t *tsol_getrhent(void); +extern tsol_rhent_t *tsol_fgetrhent(FILE *); +extern void tsol_freerhent(tsol_rhent_t *); +extern void tsol_setrhent(int); +extern void tsol_endrhent(void); +extern int str_to_rhstr(const char *, int, void *, char *, int); +extern tsol_rhent_t *rhstr_to_ent(tsol_rhstr_t *, int *, char **); +extern tsol_host_type_t tsol_getrhtype(char *); + + +/* Zone configuration parsing */ +extern tsol_zcent_t *tsol_sgetzcent(const char *, int *, char **); +extern void tsol_freezcent(tsol_zcent_t *); + +/* Routing attribute parsing */ +extern const char *sl_to_str(const bslabel_t *); +struct rtsa_s; +extern const char *rtsa_to_str(const struct rtsa_s *, char *, size_t); +extern boolean_t rtsa_keyword(const char *, struct rtsa_s *, int *, char **); +extern const char *parse_entry(char *, size_t, const char *, const char *); + +/* Convert LTSNET_* to a printable string */ +extern const char *tsol_strerror(int, int); + +/* System calls; these return -1 on error and set errno */ +extern int tnrhtp(int, tsol_tpent_t *); +extern int tnrh(int, tsol_rhent_t *); +extern int tnmlp(int, tsol_mlpent_t *); + +/* + * Errors that can occur in the parsing routines. Note that not all errors are + * possible with every routine. Must be kept in sync with list in misc.c. + */ +#define LTSNET_NONE 0 /* No error */ +#define LTSNET_SYSERR 1 /* System error; see errno */ +#define LTSNET_EMPTY 2 /* Empty string or end of list */ +#define LTSNET_ILL_ENTRY 3 /* Entry is malformed */ +#define LTSNET_NO_NAME 4 /* Missing name */ +#define LTSNET_NO_ATTRS 5 /* Missing template attributes */ +#define LTSNET_ILL_NAME 6 /* Illegal name */ +#define LTSNET_ILL_KEYDELIM 7 /* Illegal keyword delimiter */ +#define LTSNET_ILL_KEY 8 /* Unknown keyword */ +#define LTSNET_DUP_KEY 9 /* Duplicate keyword */ +#define LTSNET_ILL_VALDELIM 10 /* Illegal value delimiter */ +#define LTSNET_NO_HOSTTYPE 11 /* Missing host type */ +#define LTSNET_ILL_HOSTTYPE 12 /* Illegal host type */ +#define LTSNET_NO_LABEL 13 /* Missing label */ +#define LTSNET_ILL_LABEL 14 /* Illegal label */ +#define LTSNET_NO_RANGE 15 /* Missing label range */ +#define LTSNET_ILL_RANGE 16 /* Illegal label range */ +#define LTSNET_NO_LOWERBOUND 17 /* No lower bound in range */ +#define LTSNET_ILL_LOWERBOUND 18 /* Illegal lower bound in range */ +#define LTSNET_NO_UPPERBOUND 19 /* No upper bound in range */ +#define LTSNET_ILL_UPPERBOUND 20 /* Illegal upper bound in range */ +#define LTSNET_NO_DOI 21 /* Missing DOI */ +#define LTSNET_ILL_DOI 22 /* Illegal DOI */ +#define LTSNET_SET_TOO_BIG 23 /* Too many entries in set */ +#define LTSNET_NO_ADDR 24 /* Missing address/network */ +#define LTSNET_ILL_ADDR 25 /* Illegal address/network */ +#define LTSNET_ILL_FLAG 26 /* Illegal flag */ +#define LTSNET_ILL_MLP 27 /* Illegal MLP specification */ +#define LTSNET_BAD_TYPE 28 /* Unacceptable keyword for type */ + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBTSNET_H */ diff --git a/usr/src/lib/libtsnet/common/llib-ltsnet b/usr/src/lib/libtsnet/common/llib-ltsnet new file mode 100644 index 0000000000..4dbadf3b68 --- /dev/null +++ b/usr/src/lib/libtsnet/common/llib-ltsnet @@ -0,0 +1,32 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* LINTLIBRARY */ +/* PROTOLIB1 */ + +#include <libtsnet.h> diff --git a/usr/src/lib/libtsnet/common/misc.c b/usr/src/lib/libtsnet/common/misc.c new file mode 100644 index 0000000000..9e8c20cdc8 --- /dev/null +++ b/usr/src/lib/libtsnet/common/misc.c @@ -0,0 +1,359 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * From "misc.c 5.15 00/05/31 SMI; TSOL 2.x" + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Miscellaneous user interfaces to trusted label functions. + */ + + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <errno.h> +#include <libintl.h> +#include <libtsnet.h> +#include <tsol/label.h> + +#include <net/route.h> + +#define MAX_STRING_SIZE 256 +#define MAX_ATTR_LEN 1024 + +/* + * Parse off an entry from a line. Entry is stored in 'outbuf'. Returned + * value is a pointer to the first unprocessed input character from 'instr'. + */ +const char * +parse_entry(char *outbuf, size_t outlen, const char *instr, + const char *delimit) +{ + boolean_t escape_state = B_FALSE; + boolean_t any_white; + char chr; + + any_white = strchr(delimit, '\n') != NULL; + + /* + * User may specify outlen as 0 to skip over a field without storing + * it anywhere. Otherwise, we need at least one byte for the + * terminating NUL plus one byte to store another byte from instr. + */ + while (outlen != 1 && (chr = *instr++) != '\0') { + if (!escape_state) { + if (chr == '\\') { + escape_state = B_TRUE; + continue; + } + if (strchr(delimit, chr) != NULL) + break; + if (any_white && isspace(chr)) + break; + } + escape_state = B_FALSE; + if (outlen > 0) { + *outbuf++ = chr; + outlen--; + } + } + if (outlen != 1) + instr--; + if (escape_state) + instr--; + if (outlen > 0) + *outbuf = '\0'; + return (instr); +} + +const char * +sl_to_str(const bslabel_t *sl) +{ + const char *sl_str; + static const char unknown_str[] = "UNKNOWN"; + + if (sl == NULL) + return (unknown_str); + + if ((sl_str = sbsltos(sl, MAX_STRING_SIZE)) == NULL && + (sl_str = bsltoh(sl)) == NULL) + sl_str = unknown_str; + return (sl_str); +} + +static const char *rtsa_keywords[] = { +#define SAK_MINSL 0 + "min_sl", +#define SAK_MAXSL 1 + "max_sl", +#define SAK_DOI 2 + "doi", +#define SAK_CIPSO 3 + "cipso", +#define SAK_INVAL 4 + NULL +}; + +const char * +rtsa_to_str(const struct rtsa_s *rtsa, char *line, size_t len) +{ + size_t slen; + uint32_t mask, i; + + slen = 0; + *line = '\0'; + mask = rtsa->rtsa_mask; + + for (i = 1; mask != 0 && i != 0 && slen < len - 1; i <<= 1) { + if (!(i & (RTSA_MINSL|RTSA_MAXSL|RTSA_DOI|RTSA_CIPSO))) + continue; + if (!(i & mask)) + continue; + if (slen != 0) + line[slen++] = ','; + switch (i & mask) { + case RTSA_MINSL: + slen += snprintf(line + slen, len - slen, "min_sl=%s", + sl_to_str(&rtsa->rtsa_slrange.lower_bound)); + break; + case RTSA_MAXSL: + slen += snprintf(line + slen, len - slen, "max_sl=%s", + sl_to_str(&rtsa->rtsa_slrange.upper_bound)); + break; + case RTSA_DOI: + slen += snprintf(line + slen, len - slen, "doi=%d", + rtsa->rtsa_doi); + break; + case RTSA_CIPSO: + slen += snprintf(line + slen, len - slen, "cipso"); + break; + } + } + + return (line); +} + +boolean_t +rtsa_keyword(const char *options, struct rtsa_s *sp, int *errp, char **errstrp) +{ + const char *valptr, *nxtopt; + uint32_t mask = 0, doi; + int key; + bslabel_t min_sl, max_sl; + char attrbuf[MAX_ATTR_LEN]; + const char **keyword; + int err; + char *errstr, *cp; + + if (errp == NULL) + errp = &err; + if (errstrp == NULL) + errstrp = &errstr; + + *errstrp = (char *)options; + + while (*options != '\0') { + valptr = parse_entry(attrbuf, sizeof (attrbuf), options, ",="); + + if (attrbuf[0] == '\0') { + *errstrp = (char *)options; + *errp = LTSNET_ILL_ENTRY; + return (B_FALSE); + } + for (keyword = rtsa_keywords; *keyword != NULL; keyword++) + if (strcmp(*keyword, attrbuf) == 0) + break; + if ((key = keyword - rtsa_keywords) == SAK_INVAL) { + *errstrp = (char *)options; + *errp = LTSNET_ILL_KEY; + return (B_FALSE); + } + if ((key == SAK_CIPSO && *valptr == '=') || + (key != SAK_CIPSO && *valptr != '=')) { + *errstrp = (char *)valptr; + *errp = LTSNET_ILL_VALDELIM; + return (B_FALSE); + } + + nxtopt = valptr; + if (*valptr == '=') { + valptr++; + nxtopt = parse_entry(attrbuf, sizeof (attrbuf), + valptr, ",="); + if (*nxtopt == '=') { + *errstrp = (char *)nxtopt; + *errp = LTSNET_ILL_KEYDELIM; + return (B_FALSE); + } + } + if (*nxtopt == ',') + nxtopt++; + + switch (key) { + case SAK_MINSL: + if (mask & RTSA_MINSL) { + *errstrp = (char *)options; + *errp = LTSNET_DUP_KEY; + return (B_FALSE); + } + if (stobsl(attrbuf, &min_sl, NO_CORRECTION, + &err) != 1) { + *errstrp = (char *)valptr; + *errp = LTSNET_ILL_LOWERBOUND; + return (B_FALSE); + } + mask |= RTSA_MINSL; + break; + + case SAK_MAXSL: + if (mask & RTSA_MAXSL) { + *errstrp = (char *)options; + *errp = LTSNET_DUP_KEY; + return (B_FALSE); + } + if (stobsl(attrbuf, &max_sl, NO_CORRECTION, + &err) != 1) { + *errstrp = (char *)valptr; + *errp = LTSNET_ILL_UPPERBOUND; + return (B_FALSE); + } + mask |= RTSA_MAXSL; + break; + + case SAK_DOI: + if (mask & RTSA_DOI) { + *errstrp = (char *)options; + *errp = LTSNET_DUP_KEY; + return (B_FALSE); + } + errno = 0; + doi = strtoul(attrbuf, &cp, 0); + if (doi == 0 || errno != 0 || *cp != '\0') { + *errstrp = (char *)valptr; + *errp = LTSNET_ILL_DOI; + return (B_FALSE); + } + mask |= RTSA_DOI; + break; + + case SAK_CIPSO: + if (mask & RTSA_CIPSO) { + *errstrp = (char *)options; + *errp = LTSNET_DUP_KEY; + return (B_FALSE); + } + mask |= RTSA_CIPSO; + break; + } + + options = nxtopt; + } + + /* Defaults to CIPSO if not specified */ + mask |= RTSA_CIPSO; + + /* If RTSA_CIPSO is specified, RTSA_DOI must be specified */ + if (!(mask & RTSA_DOI)) { + *errp = LTSNET_NO_DOI; + return (B_FALSE); + } + + /* SL range must be specified */ + if (!(mask & (RTSA_MINSL|RTSA_MAXSL))) { + *errp = LTSNET_NO_RANGE; + return (B_FALSE); + } + if (!(mask & RTSA_MINSL)) { + *errp = LTSNET_NO_LOWERBOUND; + return (B_FALSE); + } + if (!(mask & RTSA_MAXSL)) { + *errp = LTSNET_NO_UPPERBOUND; + return (B_FALSE); + } + + /* SL range must have upper bound dominating lower bound */ + if (!bldominates(&max_sl, &min_sl)) { + *errp = LTSNET_ILL_RANGE; + return (B_FALSE); + } + + if (mask & RTSA_MINSL) + sp->rtsa_slrange.lower_bound = min_sl; + if (mask & RTSA_MAXSL) + sp->rtsa_slrange.upper_bound = max_sl; + if (mask & RTSA_DOI) + sp->rtsa_doi = doi; + sp->rtsa_mask = mask; + + return (B_TRUE); +} + +/* Keep in sync with libtsnet.h */ +static const char *tsol_errlist[] = { + "No error", + "System error", + "Empty string or end of list", + "Entry is malformed", + "Missing name", + "Missing attributes", + "Illegal name", + "Illegal keyword delimiter", + "Unknown keyword", + "Duplicate keyword", + "Illegal value delimiter", + "Missing host type", + "Illegal host type", + "Missing label", + "Illegal label", + "Missing label range", + "Illegal label range", + "No lower bound in range", + "Illegal lower bound in range", + "No upper bound in range", + "Illegal upper bound in range", + "Missing DOI", + "Illegal DOI", + "Too many entries in set", + "Missing address/network", + "Illegal address/network", + "Illegal flag", + "Illegal MLP specification", + "Unacceptable keyword for type" +}; +static const int tsol_nerr = sizeof (tsol_errlist) / sizeof (*tsol_errlist); + +const char * +tsol_strerror(int libtserr, int errnoval) +{ + if (libtserr == LTSNET_SYSERR) + return (strerror(errnoval)); + if (libtserr >= 0 && libtserr < tsol_nerr) + return (gettext(tsol_errlist[libtserr])); + return (gettext("Unknown error")); +} diff --git a/usr/src/lib/libtsnet/common/synonyms.h b/usr/src/lib/libtsnet/common/synonyms.h new file mode 100644 index 0000000000..ed28e16910 --- /dev/null +++ b/usr/src/lib/libtsnet/common/synonyms.h @@ -0,0 +1,52 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * From "synonyms.h 7.2 99/06/21 SMI; TSOL 2.x" + */ + +#ifndef _SYNONYMS_H +#define _SYNONYMS_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__STDC__) + +/* external data */ + +/* functions */ +#define tnrh _tnrh +#define tnrhtp _tnrhtp +#define tnmlp _tnmlp + +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SYNONYMS_H */ diff --git a/usr/src/lib/libtsnet/common/tnmlp.c b/usr/src/lib/libtsnet/common/tnmlp.c new file mode 100644 index 0000000000..ea4e1c2fc9 --- /dev/null +++ b/usr/src/lib/libtsnet/common/tnmlp.c @@ -0,0 +1,49 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include "synonyms.h" +#include <sys/types.h> +#include <sys/syscall.h> +#include <libtsnet.h> +#include <sys/tsol/tsyscall.h> + +/* + * tnmlp(2TSOL) - manipulate kernel trusted network multilevel port + * entries + * + * This is the library interface to the system call. + */ + +#ifdef __STDC__ +#pragma weak tnmlp = _tnmlp +#endif + +int +tnmlp(int cmd, tsol_mlpent_t *buf) +{ + return (syscall(SYS_labelsys, TSOL_TNMLP, cmd, buf)); +} diff --git a/usr/src/lib/libtsnet/common/tnrh.c b/usr/src/lib/libtsnet/common/tnrh.c new file mode 100644 index 0000000000..3213005cc9 --- /dev/null +++ b/usr/src/lib/libtsnet/common/tnrh.c @@ -0,0 +1,48 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include "synonyms.h" +#include <sys/types.h> +#include <sys/syscall.h> +#include <libtsnet.h> +#include <sys/tsol/tsyscall.h> + +/* + * tnrh(2TSOL) - manipulate kernel trusted network remote hosts cache + * + * This is the library interface to the system call. + */ + +#ifdef __STDC__ +#pragma weak tnrh = _tnrh +#endif + +int +tnrh(int cmd, tsol_rhent_t *buf) +{ + return (syscall(SYS_labelsys, TSOL_TNRH, cmd, buf)); +} diff --git a/usr/src/lib/libtsnet/common/tnrhtp.c b/usr/src/lib/libtsnet/common/tnrhtp.c new file mode 100644 index 0000000000..9591b6ad60 --- /dev/null +++ b/usr/src/lib/libtsnet/common/tnrhtp.c @@ -0,0 +1,49 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include "synonyms.h" +#include <sys/types.h> +#include <sys/syscall.h> +#include <libtsnet.h> +#include <sys/tsol/tsyscall.h> + +/* + * tnrhtp(2TSOL) - manipulate kernel trusted network remote host + * templates cache + * + * This is the library interface to the system call. + */ + +#ifdef __STDC__ +#pragma weak tnrhtp = _tnrhtp +#endif + +int +tnrhtp(int cmd, tsol_tpent_t *buf) +{ + return (syscall(SYS_labelsys, TSOL_TNRHTP, cmd, buf)); +} diff --git a/usr/src/lib/libtsnet/common/tsol_getrhent.c b/usr/src/lib/libtsnet/common/tsol_getrhent.c new file mode 100644 index 0000000000..24455f0960 --- /dev/null +++ b/usr/src/lib/libtsnet/common/tsol_getrhent.c @@ -0,0 +1,257 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * From "tsol_getrhent.c 7.6 00/09/22 SMI; TSOL 2.x" + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <nss_dbdefs.h> +#include <libtsnet.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <string.h> +#include <secdb.h> +#include <nss.h> +#include <libtsnet.h> +#include <libintl.h> + +extern void _nss_XbyY_fgets(FILE *, nss_XbyY_args_t *); /* from lib.c */ + +static int tsol_rh_stayopen; /* Unsynchronized, but it affects only */ + /* efficiency, not correctness */ +static DEFINE_NSS_DB_ROOT(db_root); +static DEFINE_NSS_GETENT(context); + +static void +_nss_initf_tsol_rh(nss_db_params_t *p) +{ + p->name = NSS_DBNAM_TSOL_RH; + p->default_config = NSS_DEFCONF_TSOL_RH; +} + +tsol_rhent_t * +tsol_getrhbyaddr(const void *addrp, size_t len, int af) +{ + int err = 0; + char *errstr = NULL; + char buf[NSS_BUFLEN_TSOL_RH]; + tsol_rhstr_t result; + tsol_rhstr_t *rhstrp = NULL; + nss_XbyY_args_t arg; + + NSS_XbyY_INIT(&arg, &result, buf, sizeof (buf), str_to_rhstr); + + arg.key.hostaddr.addr = (const char *)addrp; + arg.key.hostaddr.len = len; + arg.key.hostaddr.type = af; + arg.stayopen = tsol_rh_stayopen; + arg.h_errno = TSOL_NOT_FOUND; + arg.status = nss_search(&db_root, _nss_initf_tsol_rh, + NSS_DBOP_TSOL_RH_BYADDR, &arg); + rhstrp = (tsol_rhstr_t *)NSS_XbyY_FINI(&arg); + +#ifdef DEBUG + (void) fprintf(stdout, "tsol_getrhbyaddr %s: %s\n", + (char *)addrp, rhstrp ? rhstrp->template : "NULL"); +#endif /* DEBUG */ + + if (rhstrp == NULL) + return (NULL); + + return (rhstr_to_ent(rhstrp, &err, &errstr)); +} + +void +tsol_setrhent(int stay) +{ + tsol_rh_stayopen |= stay; + nss_setent(&db_root, _nss_initf_tsol_rh, &context); +} + +void +tsol_endrhent(void) +{ + tsol_rh_stayopen = 0; + nss_endent(&db_root, _nss_initf_tsol_rh, &context); + nss_delete(&db_root); +} + +tsol_rhent_t * +tsol_getrhent(void) +{ + int err = 0; + char *errstr = NULL; + char buf[NSS_BUFLEN_TSOL_RH]; + tsol_rhstr_t result; + tsol_rhstr_t *rhstrp = NULL; + nss_XbyY_args_t arg; + + NSS_XbyY_INIT(&arg, &result, buf, sizeof (buf), str_to_rhstr); + /* No key, no stayopen */ + arg.status = nss_getent(&db_root, _nss_initf_tsol_rh, &context, &arg); + rhstrp = (tsol_rhstr_t *)NSS_XbyY_FINI(&arg); + +#ifdef DEBUG + (void) fprintf(stdout, "tsol_getrhent: %s\n", + rhstrp ? rhstrp->template : "NULL"); +#endif /* DEBUG */ + + if (rhstrp == NULL) + return (NULL); + + return (rhstr_to_ent(rhstrp, &err, &errstr)); +} + +tsol_rhent_t * +tsol_fgetrhent(FILE *f) +{ + int err = 0; + char *errstr = NULL; + char buf[NSS_BUFLEN_TSOL_RH]; + tsol_rhstr_t result; + tsol_rhstr_t *rhstrp = NULL; + tsol_rhent_t *rhentp = NULL; + nss_XbyY_args_t arg; + + NSS_XbyY_INIT(&arg, &result, buf, sizeof (buf), str_to_rhstr); + _nss_XbyY_fgets(f, &arg); + rhstrp = (tsol_rhstr_t *)NSS_XbyY_FINI(&arg); + if (rhstrp == NULL) + return (NULL); + rhentp = rhstr_to_ent(rhstrp, &err, &errstr); + while (rhentp == NULL) { + /* + * Loop until we find a non-blank, non-comment line, or + * until EOF. No need to log blank lines, comments. + */ + if (err != LTSNET_EMPTY) + (void) fprintf(stderr, "%s: %.32s%s: %s\n", + gettext("Error parsing tnrhdb file"), errstr, + (strlen(errstr) > 32)? "...": "", + (char *)tsol_strerror(err, errno)); + _nss_XbyY_fgets(f, &arg); + rhstrp = (tsol_rhstr_t *)NSS_XbyY_FINI(&arg); + if (rhstrp == NULL) /* EOF */ + return (NULL); + rhentp = rhstr_to_ent(rhstrp, &err, &errstr); + } + return (rhentp); +} + +/* + * This is the callback routine for nss. + */ +int +str_to_rhstr(const char *instr, int lenstr, void *entp, char *buffer, + int buflen) +{ + int len; + char *str = NULL; + char *last = NULL; + char *sep = KV_TOKEN_DELIMIT; + tsol_rhstr_t *rhstrp = (tsol_rhstr_t *)entp; + + if ((instr >= buffer && (buffer + buflen) > instr) || + (buffer >= instr && (instr + lenstr) > buffer)) + return (NSS_STR_PARSE_PARSE); + if (lenstr >= buflen) + return (NSS_STR_PARSE_ERANGE); + (void) strncpy(buffer, instr, buflen); + str = _strtok_escape(buffer, sep, &last); + rhstrp->address = _do_unescape(str); + /* + * _do_unesape uses isspace() which removes "\n". + * we keep "\n" as we use it in checking for + * blank lines. + */ + if (strcmp(instr, "\n") == 0) + rhstrp->address = "\n"; + rhstrp->template = _strtok_escape(NULL, sep, &last); + if (rhstrp->template != NULL) { + len = strlen(rhstrp->template); + if (rhstrp->template[len - 1] == '\n') + rhstrp->template[len - 1] = '\0'; + } + if (rhstrp->address == NULL) + rhstrp->family = 0; + else if (strchr(rhstrp->address, ':') == NULL) + rhstrp->family = AF_INET; + else + rhstrp->family = AF_INET6; + +#ifdef DEBUG + (void) fprintf(stdout, + "str_to_rhstr:str - %s\taddress - %s\n\ttemplate - %s\n", + instr, rhstrp->address ? rhstrp->address : "NULL", + rhstrp->template ? rhstrp->template : "NULL"); +#endif /* DEBUG */ + + return (NSS_STR_PARSE_SUCCESS); +} + +tsol_host_type_t +tsol_getrhtype(char *rhost) { + int herr; + struct hostent *hp; + in6_addr_t in6; + char abuf[INET6_ADDRSTRLEN]; + tsol_rhent_t rhent; + tsol_tpent_t tp; + + if ((hp = getipnodebyname(rhost, AF_INET6, + AI_ALL | AI_ADDRCONFIG | AI_V4MAPPED, &herr)) == NULL) { + return (UNLABELED); + } + + (void) memset(&rhent, 0, sizeof (rhent)); + (void) memcpy(&in6, hp->h_addr, hp->h_length); + + if (IN6_IS_ADDR_V4MAPPED(&in6)) { + rhent.rh_address.ta_family = AF_INET; + IN6_V4MAPPED_TO_INADDR(&in6, &rhent.rh_address.ta_addr_v4); + (void) inet_ntop(AF_INET, &rhent.rh_address.ta_addr_v4, abuf, + sizeof (abuf)); + } else { + rhent.rh_address.ta_family = AF_INET6; + rhent.rh_address.ta_addr_v6 = in6; + (void) inet_ntop(AF_INET6, &in6, abuf, sizeof (abuf)); + } + + if (tnrh(TNDB_GET, &rhent) != 0) + return (UNLABELED); + + if (rhent.rh_template[0] == '\0') + return (UNLABELED); + + (void) strlcpy(tp.name, rhent.rh_template, sizeof (tp.name)); + + if (tnrhtp(TNDB_GET, &tp) != 0) + return (UNLABELED); + + return (tp.host_type); +} diff --git a/usr/src/lib/libtsnet/common/tsol_gettpent.c b/usr/src/lib/libtsnet/common/tsol_gettpent.c new file mode 100644 index 0000000000..ab20c85620 --- /dev/null +++ b/usr/src/lib/libtsnet/common/tsol_gettpent.c @@ -0,0 +1,195 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * From "tsol_gettpent.c 7.13 00/10/13 SMI; TSOL 2.x" + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <string.h> +#include <nss_dbdefs.h> +#include <libtsnet.h> +#include <secdb.h> +#include <nss.h> +#include <libintl.h> + +extern void _nss_XbyY_fgets(FILE *, nss_XbyY_args_t *); /* from lib.c */ + +static int tsol_tp_stayopen; /* Unsynchronized, but it affects only */ + /* efficiency, not correctness */ +static DEFINE_NSS_DB_ROOT(db_root); +static DEFINE_NSS_GETENT(context); + + +static void +_nss_initf_tsol_tp(nss_db_params_t *p) +{ + p->name = NSS_DBNAM_TSOL_TP; + p->default_config = NSS_DEFCONF_TSOL_TP; +} + +tsol_tpent_t * +tsol_gettpbyname(const char *name) +{ + int err = 0; + char *errstr = NULL; + char buf[NSS_BUFLEN_TSOL_TP]; + tsol_tpstr_t result; + tsol_tpstr_t *tpstrp = NULL; + nss_XbyY_args_t arg; + + NSS_XbyY_INIT(&arg, &result, buf, sizeof (buf), str_to_tpstr); + + arg.key.name = name; + arg.stayopen = tsol_tp_stayopen; + arg.h_errno = TSOL_NOT_FOUND; + arg.status = nss_search(&db_root, _nss_initf_tsol_tp, + NSS_DBOP_TSOL_TP_BYNAME, &arg); + tpstrp = (tsol_tpstr_t *)NSS_XbyY_FINI(&arg); + +#ifdef DEBUG + (void) fprintf(stdout, "tsol_gettpbyname %s: %s\n", + name, tpstrp ? tpstrp->template : "NULL"); +#endif /* DEBUG */ + + if (tpstrp == NULL) + return (NULL); + + return (tpstr_to_ent(tpstrp, &err, &errstr)); +} + +void +tsol_settpent(int stay) +{ + tsol_tp_stayopen |= stay; + nss_setent(&db_root, _nss_initf_tsol_tp, &context); +} + +void +tsol_endtpent(void) +{ + tsol_tp_stayopen = 0; + nss_endent(&db_root, _nss_initf_tsol_tp, &context); + nss_delete(&db_root); +} + +tsol_tpent_t * +tsol_gettpent(void) +{ + int err = 0; + char *errstr = NULL; + char buf[NSS_BUFLEN_TSOL_TP]; + tsol_tpstr_t result; + tsol_tpstr_t *tpstrp = NULL; + nss_XbyY_args_t arg; + + NSS_XbyY_INIT(&arg, &result, buf, sizeof (buf), str_to_tpstr); + /* No key, no stayopen */ + arg.status = nss_getent(&db_root, _nss_initf_tsol_tp, &context, &arg); + tpstrp = (tsol_tpstr_t *)NSS_XbyY_FINI(&arg); + +#ifdef DEBUG + (void) fprintf(stdout, "tsol_gettpent: %s\n", + tpstrp ? tpstrp->template : "NULL"); +#endif /* DEBUG */ + + if (tpstrp == NULL) + return (NULL); + + return (tpstr_to_ent(tpstrp, &err, &errstr)); +} + +tsol_tpent_t * +tsol_fgettpent(FILE *f) +{ + int err = 0; + char *errstr = NULL; + char buf[NSS_BUFLEN_TSOL_TP]; + tsol_tpstr_t result; + tsol_tpstr_t *tpstrp = NULL; + tsol_tpent_t *tpentp = NULL; + nss_XbyY_args_t arg; + + NSS_XbyY_INIT(&arg, &result, buf, sizeof (buf), str_to_tpstr); + _nss_XbyY_fgets(f, &arg); + tpstrp = (tsol_tpstr_t *)NSS_XbyY_FINI(&arg); + if (tpstrp == NULL) + return (NULL); + tpentp = tpstr_to_ent(tpstrp, &err, &errstr); + while (tpentp == NULL) { + /* + * Loop until we find a non-blank, non-comment line, or + * until EOF. No need to log blank lines, comments. + */ + if (err != LTSNET_EMPTY) + (void) fprintf(stderr, "%s: %.32s%s: %s\n", + gettext("Error parsing tnrhtp file"), errstr, + (strlen(errstr) > 32)? "...": "", + (char *)tsol_strerror(err, errno)); + _nss_XbyY_fgets(f, &arg); + tpstrp = (tsol_tpstr_t *)NSS_XbyY_FINI(&arg); + if (tpstrp == NULL) /* EOF */ + return (NULL); + tpentp = tpstr_to_ent(tpstrp, &err, &errstr); + } + return (tpentp); +} + +/* + * This is the callback routine for nss. It just wraps the tsol_sgettpent + * parser. + */ +int +str_to_tpstr(const char *instr, int lenstr, void *entp, char *buffer, + int buflen) +{ + int len; + char *last = NULL; + char *sep = KV_TOKEN_DELIMIT; + tsol_tpstr_t *tpstrp = (tsol_tpstr_t *)entp; + + if ((instr >= buffer && (buffer + buflen) > instr) || + (buffer >= instr && (instr + lenstr) > buffer)) + return (NSS_STR_PARSE_PARSE); + if (lenstr >= buflen) + return (NSS_STR_PARSE_ERANGE); + (void) strncpy(buffer, instr, buflen); + tpstrp->template = _strtok_escape(buffer, sep, &last); + tpstrp->attrs = _strtok_escape(NULL, sep, &last); + if (tpstrp->attrs != NULL) { + len = strlen(tpstrp->attrs); + if (tpstrp->attrs[len - 1] == '\n') + tpstrp->attrs[len - 1] = '\0'; + } + +#ifdef DEBUG + (void) fprintf(stdout, + "str_to_tpstr:\nstr - %s\n\ttemplate - %s\n\tattrs - %s\n", + instr, tpstrp->template ? tpstrp->template : "NULL", + tpstrp->attrs ? tpstrp->attrs : "NULL"); +#endif /* DEBUG */ + + return (NSS_STR_PARSE_SUCCESS); +} diff --git a/usr/src/lib/libtsnet/common/tsol_getzcent.c b/usr/src/lib/libtsnet/common/tsol_getzcent.c new file mode 100644 index 0000000000..4faf1cf5be --- /dev/null +++ b/usr/src/lib/libtsnet/common/tsol_getzcent.c @@ -0,0 +1,141 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <ctype.h> +#include <nss_dbdefs.h> +#include <libtsnet.h> + +static int tsol_zc_stayopen; /* Unsynchronized, but it affects only */ + /* efficiency, not correctness */ +static DEFINE_NSS_DB_ROOT(db_root); +static DEFINE_NSS_GETENT(context); + +struct zc_args { + tsol_zcent_t *zc; + int err; + char *errstr; + int errno_val; +}; + +static int str2tsol_zcent(const char *, int, void *, char *, int); + +static void +_nss_initf_tsol_zc(nss_db_params_t *p) +{ + p->name = NSS_DBNAM_TSOL_ZC; + p->default_config = NSS_DEFCONF_TSOL_ZC; +} + +/* + * This is just a placeholder. The system doesn't currently lookup tnzonecfg + * entries via name services. + */ +/* ARGSUSED */ +static void +switch_callback(void *res, const char *zonename, const char *label, + const char *flags, const char *privmlp, const char *globalmlp) +{ +} + +tsol_zcent_t * +tsol_getzcbyname(const char *name) +{ + nss_XbyY_args_t arg; + struct zc_args zcargs; + + zcargs.zc = NULL; + NSS_XbyY_INIT(&arg, &zcargs, (char *)switch_callback, 1, + str2tsol_zcent); + arg.key.name = name; + arg.stayopen = tsol_zc_stayopen; + arg.h_errno = TSOL_NOT_FOUND; + arg.status = nss_search(&db_root, _nss_initf_tsol_zc, + NSS_DBOP_TSOL_ZC_BYNAME, &arg); + (void) NSS_XbyY_FINI(&arg); + if (arg.status != 0) { + tsol_freezcent(zcargs.zc); + zcargs.zc = NULL; + } + return (zcargs.zc); +} + +void +tsol_setzcent(int stay) +{ + tsol_zc_stayopen |= stay; + nss_setent(&db_root, _nss_initf_tsol_zc, &context); +} + +void +tsol_endzcent(void) +{ + tsol_zc_stayopen = 0; + nss_endent(&db_root, _nss_initf_tsol_zc, &context); + nss_delete(&db_root); +} + +struct tsol_zcent * +tsol_getzcent(void) +{ + nss_XbyY_args_t arg; + struct zc_args zcargs; + + zcargs.zc = NULL; + zcargs.errno_val = errno; + NSS_XbyY_INIT(&arg, &zcargs, (char *)switch_callback, 1, + str2tsol_zcent); + /* No key, no stayopen */ + arg.status = nss_getent(&db_root, _nss_initf_tsol_zc, &context, &arg); + (void) NSS_XbyY_FINI(&arg); + if (arg.status != 0) { + tsol_freezcent(zcargs.zc); + zcargs.zc = NULL; + } + if (zcargs.zc == NULL && zcargs.err == LTSNET_SYSERR) + errno = zcargs.errno_val; + return (zcargs.zc); +} + +/* + * This is the callback routine for nss. It just wraps the tsol_sgetzcent + * parser. + */ +/* ARGSUSED */ +static int +str2tsol_zcent(const char *instr, int lenstr, void *entp, char *buffer, + int buflen) +{ + struct zc_args *zcargs = entp; + + if (zcargs->zc != NULL) + tsol_freezcent(zcargs->zc); + zcargs->zc = tsol_sgetzcent(instr, &zcargs->err, &zcargs->errstr); + zcargs->errno_val = errno; + + return (zcargs->zc == NULL ? NSS_STR_PARSE_PARSE : + NSS_STR_PARSE_SUCCESS); +} diff --git a/usr/src/lib/libtsnet/common/tsol_sgetrhent.c b/usr/src/lib/libtsnet/common/tsol_sgetrhent.c new file mode 100644 index 0000000000..5037b6b37a --- /dev/null +++ b/usr/src/lib/libtsnet/common/tsol_sgetrhent.c @@ -0,0 +1,272 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * From "tsol_tndb_parser.c 7.24 01/09/05 SMI; TSOL 2.x" + * + * These functions parse entries in the "thrhdb" (remote host database) file. + * Each entry in the file has two fields, separated by a colon. The first + * field is the IP host or network address. The second is the name of the + * template to use (from tnrhtp). + * + * In order to help preserve sanity, we do not allow more than one unescaped + * colon in a line. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> +#include <stddef.h> +#include <string.h> +#include <strings.h> +#include <libtsnet.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <inet/ip.h> +#include <arpa/inet.h> +#include <nss.h> +#include <errno.h> + +/* + * This routine deals with old pre-CIDR subnet address specifications. In the + * bad old days, a subnet was represented as: + * + * Expression Implied Prefix + * 10.1.1.0 /24 + * 10.1.0.0 /16 + * 10.0.0.0 /8 + * 0.0.0.0 /0 + */ +static int +get_classful_prefix(in_addr_t addr) +{ + int bits; + + if (addr == 0) + return (0); + addr = ntohl(addr); + for (bits = IP_ABITS; bits > 0 && (addr & 0xFF) == 0; bits -= 8) + addr >>= 8; + + return (bits); +} + +/* + * This routine deals with old pre-CIDR network address specifications. In the + * bad old days, a network was represented as: + * + * Expression Implied Prefix + * 10.1.1 /24 + * 10.1 /16 + * 10 /8 + * + * This routine must compute the mask and left-align the address. + */ +static int +get_network_prefix(in_addr_t *addrp) +{ + int bits; + in_addr_t addr; + + addr = ntohl(*addrp); + for (bits = IP_ABITS; bits > 0 && addr < 0x01000000; bits -= 8) + addr <<= 8; + *addrp = htonl(addr); + + return (bits); +} + +static boolean_t +parse_address(tsol_rhent_t *rh, const char *addrbuf) +{ + int upper_lim; + int len; + const uchar_t *aptr; + + if (strchr(addrbuf, ':') == NULL) { + /* IPv4 address */ + rh->rh_address.ta_family = AF_INET; + if (inet_pton(AF_INET, addrbuf, + &rh->rh_address.ta_addr_v4) > 0) { + if (rh->rh_prefix == -1) + rh->rh_prefix = get_classful_prefix(rh-> + rh_address.ta_addr_v4.s_addr); + } else if ((rh->rh_address.ta_addr_v4.s_addr = + inet_network(addrbuf)) != (in_addr_t)-1) { + len = get_network_prefix(&rh->rh_address.ta_addr_v4. + s_addr); + if (rh->rh_prefix == -1) + rh->rh_prefix = len; + } else { + return (B_FALSE); + } + upper_lim = IP_ABITS; + aptr = (const uchar_t *)&rh->rh_address.ta_addr_v4; + } else { + /* IPv6 address */ + rh->rh_address.ta_family = AF_INET6; + if (inet_pton(AF_INET6, addrbuf, + &rh->rh_address.ta_addr_v6) <= 0) + return (B_FALSE); + if (rh->rh_prefix == -1) + rh->rh_prefix = IPV6_ABITS; + upper_lim = IPV6_ABITS; + aptr = (const uchar_t *)&rh->rh_address.ta_addr_v6; + } + + if (rh->rh_prefix < 0 || rh->rh_prefix > upper_lim) + return (B_FALSE); + + /* + * Verify that there are no bits set in the "host" portion of the + * IP address. + */ + len = rh->rh_prefix; + aptr += len / 8; + if ((len & 7) != 0) { + if ((*aptr++ & (0xff >> (len & 7))) != 0) + return (B_FALSE); + len = (len + 7) & ~7; + } + while (len < upper_lim) { + if (*aptr++ != 0) + return (B_FALSE); + len += 8; + } + + return (B_TRUE); +} + +tsol_rhent_t * +rhstr_to_ent(tsol_rhstr_t *rhstrp, int *errp, char **errstrp) +{ + int len; + int err = 0; + char *cp, *cp2, *errstr; + char *address = rhstrp->address; + char *template = rhstrp->template; + char addrbuf[1024]; + tsol_rhent_t *rhentp = NULL; + + /* + * The user can specify NULL pointers for these. Make sure that we + * don't have to deal with checking for NULL everywhere by just + * pointing to our own variables if the user gives NULL. + */ + if (errp == NULL) + errp = &err; + if (errstrp == NULL) + errstrp = &errstr; + /* The default, unless we find a more specific error locus. */ + *errstrp = address; + + if (address == NULL || *address == '#' || *address == '\n') { + *errp = LTSNET_EMPTY; + if (template && *template != '\0' && *template != '#' && + *template != '\n') + *errstrp = template; + else if (address == NULL) + *errstrp = " "; + goto err_ret; + } + if (*address == '\0') { + *errp = LTSNET_NO_ADDR; + if (template && *template != '\0' && *template != '#' && + *template != '\n') + *errstrp = template; + goto err_ret; + } + if (template == NULL || *template == '#' || *template == '\n' || + *template == '\0') { + *errp = LTSNET_NO_HOSTTYPE; + goto err_ret; + } + if ((rhentp = calloc(1, sizeof (*rhentp))) == NULL) { + *errp = LTSNET_SYSERR; + return (NULL); + } + if ((cp = strrchr(address, '/')) != NULL) { + len = cp - address; + if (len >= sizeof (addrbuf)) { + *errp = LTSNET_ILL_ADDR; + goto err_ret; + } + (void) memset(addrbuf, '\0', sizeof (addrbuf)); + (void) memcpy(addrbuf, address, len); + cp++; + errno = 0; + rhentp->rh_prefix = strtol(cp, &cp2, 0); + if (errno != 0) { + *errp = LTSNET_SYSERR; + *errstrp = cp2; + goto err_ret; + } + if ((isdigit(*cp) == 0)) { + *errp = LTSNET_ILL_ADDR; + *errstrp = address; + goto err_ret; + } + } else { + rhentp->rh_prefix = -1; + (void) strlcpy(addrbuf, address, sizeof (addrbuf)); + } + if (strlcpy(rhentp->rh_template, template, + sizeof (rhentp->rh_template)) >= sizeof (rhentp->rh_template)) { + *errstrp = template; + *errp = LTSNET_ILL_NAME; + goto err_ret; + } + if (!parse_address(rhentp, addrbuf)) { + *errp = LTSNET_ILL_ADDR; + *errstrp = address; + goto err_ret; + } + +#ifdef DEBUG + (void) fprintf(stdout, "rhstr_to_ent: %s:%s\n", + address, rhentp->rh_template); +#endif /* DEBUG */ + + return (rhentp); + +err_ret: + err = errno; + tsol_freerhent(rhentp); + errno = err; +#ifdef DEBUG + (void) fprintf(stderr, "\nrhstr_to_ent: %s: %s\n", + *errstrp, (char *)tsol_strerror(*errp, errno)); +#endif /* DEBUG */ + + return (NULL); +} + +void +tsol_freerhent(tsol_rhent_t *rh) +{ + if (rh != NULL) + free(rh); +} diff --git a/usr/src/lib/libtsnet/common/tsol_sgettpent.c b/usr/src/lib/libtsnet/common/tsol_sgettpent.c new file mode 100644 index 0000000000..37fd75b234 --- /dev/null +++ b/usr/src/lib/libtsnet/common/tsol_sgettpent.c @@ -0,0 +1,301 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * From "tsol_tndb_parser.c 7.24 01/09/05 SMI; TSOL 2.x" + * + * These functions parse entries in the "tnrhtp" (remote host template) file. + * Each entry in this file has two fields, separated by a colon. The first + * field is the template name. The second is a list of "key=value" attributes, + * separated by semicolons. + * + * In order to help preserve sanity, we do not allow more than one unescaped + * colon in a line, nor any unescaped '=' or ';' characters in the template + * name. Such things are indicative of typing errors, not intentional + * configuration. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> +#include <stddef.h> +#include <string.h> +#include <strings.h> +#include <libtsnet.h> +#include <tsol/label.h> +#include <sys/types.h> +#include <nss.h> +#include <secdb.h> +#include <errno.h> + +static int +get_tn_doi(tsol_tpent_t *tpentp, kva_t *kv) +{ + char *cp; + char *val = NULL; + + val = kva_match(kv, TP_DOI); + if (val == NULL) + return (LTSNET_NO_DOI); + + errno = 0; + tpentp->tp_doi = strtol(val, &cp, 0); + if (errno != 0) + return (LTSNET_SYSERR); + if (*cp != '\0') + return (LTSNET_ILL_DOI); + + return (0); +} + +static int +get_tn_sl_range(brange_t *range, char *min, char *max) +{ + int err = 0; + + if (min == NULL && max == NULL) + return (LTSNET_NO_RANGE); + if (min == NULL) + return (LTSNET_NO_LOWERBOUND); + if (max == NULL) + return (LTSNET_NO_UPPERBOUND); + + if (stobsl(min, &range->lower_bound, NO_CORRECTION, &err) == 0) + return (LTSNET_ILL_LOWERBOUND); + if (stobsl(max, &range->upper_bound, NO_CORRECTION, &err) == 0) + return (LTSNET_ILL_UPPERBOUND); + if (!bldominates(&range->upper_bound, &range->lower_bound)) + return (LTSNET_ILL_RANGE); + + return (0); +} + +static int +get_tn_sl_set(blset_t *labelset, char *setstr) +{ + int sc, err; + char *tokp, *finally; + bslabel_t *labels; + + (void) memset(labelset, 0, sizeof (blset_t)); + labels = (bslabel_t *)labelset; + tokp = strtok_r(setstr, TNDB_COMMA, &finally); + for (sc = 0; tokp != NULL && sc < NSLS_MAX; sc++) { + if (stobsl(tokp, &labels[sc], NO_CORRECTION, &err) == 0) + return (LTSNET_ILL_LABEL); + tokp = strtok_r(NULL, TNDB_COMMA, &finally); + } + if (tokp != NULL && sc >= NSLS_MAX) + return (LTSNET_SET_TOO_BIG); + + return (0); +} + +static int +parse_remainder(tsol_tpent_t *tpentp, kva_t *kv) +{ + int err = 0; + char *val = NULL; + char *val2 = NULL; + + val = kva_match(kv, TP_HOSTTYPE); + + if (val == NULL) + return (LTSNET_NO_HOSTTYPE); + if (strcasecmp(val, TP_UNLABELED) == 0) + tpentp->host_type = UNLABELED; + else if (strcasecmp(val, TP_CIPSO) == 0) + tpentp->host_type = SUN_CIPSO; + else + return (LTSNET_ILL_HOSTTYPE); + + /* + * parse fields by host type - + * add on to the following if statement for each new host type. + */ + if (tpentp->host_type == UNLABELED) { + tpentp->tp_mask_unl = 0; + /* + * doi + */ + if ((err = get_tn_doi(tpentp, kv)) != 0) + return (err); + tpentp->tp_mask_unl |= TSOL_MSK_CIPSO_DOI; + /* + * default label + */ + val = kva_match(kv, TP_DEFLABEL); + if (val == NULL) + return (LTSNET_NO_LABEL); + if (stobsl(val, &tpentp->tp_def_label, NO_CORRECTION, + &err) == 0) + return (LTSNET_ILL_LABEL); + tpentp->tp_mask_unl |= TSOL_MSK_DEF_LABEL; + /* + * check label range + */ + val = kva_match(kv, TP_MINLABEL); + val2 = kva_match(kv, TP_MAXLABEL); + if (val == NULL && val2 == NULL) { + /* + * This is the old format. Use ADMIN_LOW to SL of the + * default label as the gw_sl_range. + */ + bsllow(&tpentp->tp_gw_sl_range.lower_bound); + tpentp->tp_gw_sl_range.upper_bound = + tpentp->tp_def_label; + } else { + err = get_tn_sl_range(&tpentp->tp_gw_sl_range, val, + val2); + if (err != 0) + return (err); + } + tpentp->tp_mask_unl |= TSOL_MSK_SL_RANGE_TSOL; + + /* + * also label set, if present. (optional) + */ + val = kva_match(kv, TP_SET); + if (val != NULL) { + err = get_tn_sl_set(&tpentp->tp_gw_sl_set, val); + if (err != 0) + return (err); + tpentp->tp_mask_cipso |= TSOL_MSK_SL_RANGE_TSOL; + } + } else { + tpentp->tp_mask_cipso = 0; + /* + * doi + */ + if ((err = get_tn_doi(tpentp, kv)) != 0) + return (err); + tpentp->tp_mask_cipso |= TSOL_MSK_CIPSO_DOI; + /* + * label range + */ + val = kva_match(kv, TP_MINLABEL); + val2 = kva_match(kv, TP_MAXLABEL); + err = get_tn_sl_range(&tpentp->tp_sl_range_cipso, val, val2); + if (err != 0) + return (err); + tpentp->tp_mask_cipso |= TSOL_MSK_SL_RANGE_TSOL; + /* + * also label set, if present. (optional) + */ + val = kva_match(kv, TP_SET); + if (val != NULL) { + err = get_tn_sl_set(&tpentp->tp_sl_set_cipso, val); + if (err != 0) + return (err); + tpentp->tp_mask_cipso |= TSOL_MSK_SL_RANGE_TSOL; + } + + /* CIPSO entries don't support default labels */ + val = kva_match(kv, TP_DEFLABEL); + if (val != NULL) + return (LTSNET_BAD_TYPE); + } + + return (0); +} + +tsol_tpent_t * +tpstr_to_ent(tsol_tpstr_t *tpstrp, int *errp, char **errstrp) +{ + int err = 0; + char *errstr; + char *template = tpstrp->template; + char *attrs = tpstrp->attrs; + kva_t *kv; + tsol_tpent_t *tpentp = NULL; + + /* + * The user can specify NULL pointers for these. Make sure that we + * don't have to deal with checking for NULL everywhere by just + * pointing to our own variables if the user gives NULL. + */ + if (errp == NULL) + errp = &err; + if (errstrp == NULL) + errstrp = &errstr; + /* The default, unless we find a more specific error locus. */ + *errstrp = template; + + if (template == NULL || *template == '#' || *template == '\n') { + *errp = LTSNET_EMPTY; + if (attrs && *attrs != '\0' && *attrs != '#' && *attrs != '\n') + *errstrp = attrs; + else if (template == NULL) + *errstrp = " "; + goto err_ret; + } + if (*template == '\0') { + *errp = LTSNET_NO_NAME; + if (attrs && *attrs != '\0' && *attrs != '#' && *attrs != '\n') + *errstrp = attrs; + goto err_ret; + } + if (attrs == NULL || *attrs == '\0' || *attrs == '#' || + *attrs == '\n') { + *errp = LTSNET_NO_ATTRS; + goto err_ret; + } + if ((tpentp = calloc(1, sizeof (*tpentp))) == NULL) { + *errp = LTSNET_SYSERR; + return (NULL); + } + if (strlcpy(tpentp->name, template, sizeof (tpentp->name)) >= + sizeof (tpentp->name)) + goto err_ret; + kv = _str2kva(attrs, KV_ASSIGN, KV_DELIMITER); + *errp = parse_remainder(tpentp, kv); + _kva_free(kv); + if (*errp == 0) { +#ifdef DEBUG + (void) fprintf(stdout, "tpstr_to_ent: %s:%s\n", tpentp->name, + attrs); +#endif /* DEBUG */ + + return (tpentp); + } + +err_ret: + err = errno; + tsol_freetpent(tpentp); + errno = err; +#ifdef DEBUG + (void) fprintf(stderr, "\ntpstr_to_ent: %s:%s\n", + *errstrp, (char *)tsol_strerror(*errp, errno)); +#endif /* DEBUG */ + + return (NULL); +} + +void +tsol_freetpent(tsol_tpent_t *tp) +{ + if (tp != NULL) + free(tp); +} diff --git a/usr/src/lib/libtsnet/common/tsol_sgetzcent.c b/usr/src/lib/libtsnet/common/tsol_sgetzcent.c new file mode 100644 index 0000000000..657c3be47c --- /dev/null +++ b/usr/src/lib/libtsnet/common/tsol_sgetzcent.c @@ -0,0 +1,285 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * From "tsol_tndb_parser.c 7.24 01/09/05 SMI; TSOL 2.x" + * + * These functions parse entries in the "tnzonecfg" (zone configuration) file. + * Each entry in this file has five fields, separated by a colon. These fields + * are: + * + * zone name : label : flags : zone-specific MLPs : global MLPs + * + * The fourth and fifth fields contain subfields consisting of MLP entries + * separated by semicolons. The MLP entries are of the form: + * + * port[-port]/protocol + * + * In order to help preserve sanity, we do not allow more than four unescaped + * colons in a line, nor any unescaped ';' characters in the non-MLP fields. + * Such things are indicative of typing errors, not intentional configuration. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <ctype.h> +#include <stdlib.h> +#include <stddef.h> +#include <string.h> +#include <strings.h> +#include <libtsnet.h> +#include <tsol/label.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <nss.h> +#include <errno.h> +#include <secdb.h> + +/* + * Parse an MLP specification in port1-port2/proto or port/proto form. + */ +static int +str_to_mlp(char *mlp_str, tsol_mlp_t *zone_mlp) +{ + char *fieldp; + char *lasts, *cp; + int i; + ulong_t ulv; + struct protoent proto; + char gbuf[1024]; + + (void) memset(zone_mlp, 0, sizeof (tsol_mlp_t)); + + fieldp = strtok_r(mlp_str, KV_DELIMITER, &lasts); + if (fieldp == NULL) + return (-1); + + errno = 0; + for (i = 0; fieldp != NULL && i < NMLP_MAX; i++) { + ulv = strtoul(fieldp, &cp, 0); + zone_mlp[i].mlp_port = (uint16_t)ulv; + zone_mlp[i].mlp_port_upper = 0; + if (errno != 0 || ulv > 65535) + return (-1); + if (*cp == '-') { + ulv = strtol(cp + 1, &cp, 0); + zone_mlp[i].mlp_port_upper = (uint16_t)ulv; + if (errno != 0 || ulv > 65535) + return (-1); + } + if (*cp != '/') + return (-1); + fieldp = cp + 1; + ulv = strtol(fieldp, &cp, 0); + if (errno == 0 && ulv <= 255 && *cp == '\0') + zone_mlp->mlp_ipp = (uint8_t)ulv; + else if (getprotobyname_r(fieldp, &proto, gbuf, + sizeof (gbuf)) != NULL) + zone_mlp->mlp_ipp = proto.p_proto; + else + return (-1); + fieldp = strtok_r(NULL, KV_DELIMITER, &lasts); + } + return (0); +} + +static boolean_t +parse_mlp_list(tsol_mlp_t **list, char *str, int *errp, char **errstrp) +{ + int mmax; + tsol_mlp_t *mlp; + char *tokp, *finally; + int mc; + + mmax = 0; + if ((mlp = *list) != NULL) { + while (!TSOL_MLP_END(mlp)) { + mmax++; + mlp++; + } + mmax++; + } + mlp = *list; + tokp = strtok_r(str, KV_DELIMITER, &finally); + for (mc = 0; tokp != NULL; mc++) { + if (mc >= mmax) { + mmax += 8; + mlp = realloc(mlp, mmax * sizeof (*mlp)); + if (mlp == NULL) { + *errp = LTSNET_SYSERR; + *errstrp = tokp; + return (B_FALSE); + } + *list = mlp; + } + if (str_to_mlp(tokp, mlp + mc) == -1) { + *errp = LTSNET_ILL_MLP; + *errstrp = tokp; + return (B_FALSE); + } + tokp = strtok_r(NULL, KV_DELIMITER, &finally); + } + if (mc >= mmax) { + mlp = realloc(mlp, (mmax + 1) * sizeof (*mlp)); + if (mlp == NULL) { + *errp = LTSNET_SYSERR; + *errstrp = finally; + return (B_FALSE); + } + *list = mlp; + } + (void) memset(mlp + mc, 0, sizeof (*mlp)); + return (B_TRUE); +} + +tsol_zcent_t * +tsol_sgetzcent(const char *instr, int *errp, char **errstrp) +{ + int err; + char *errstr; + tsol_zcent_t *zc; + const char *nextf; + char *cp; + char fieldbuf[1024]; + + /* + * The user can specify NULL pointers for these. Make sure that we + * don't have to deal with checking for NULL everywhere by just + * pointing to our own variables if the user gives NULL. + */ + if (errp == NULL) + errp = &err; + if (errstrp == NULL) + errstrp = &errstr; + + /* The default, unless we find a more specific error locus. */ + *errstrp = (char *)instr; + + if ((zc = calloc(1, sizeof (*zc))) == NULL) { + *errp = LTSNET_SYSERR; + return (NULL); + } + + /* First, parse off the zone name. */ + instr = parse_entry(zc->zc_name, sizeof (zc->zc_name), instr, "#;:\n"); + if (zc->zc_name[0] == '\0') { + *errstrp = (char *)instr; + if (*instr == '\0' || *instr == '#' || *instr == '\n') + *errp = LTSNET_EMPTY; + else if (*instr == ':') + *errp = LTSNET_NO_NAME; + else + *errp = LTSNET_ILL_NAME; + goto err_ret; + } + if (*instr != ':') { + *errstrp = (char *)instr; + if (*instr == '=' || *instr == ';') + *errp = LTSNET_ILL_NAME; + else + *errp = LTSNET_ILL_ENTRY; + goto err_ret; + } + instr++; + + /* Field two: parse off the label. */ + nextf = parse_entry(fieldbuf, sizeof (fieldbuf), instr, "#;:\n"); + if (*nextf != ':') { + *errstrp = (char *)nextf; + *errp = LTSNET_ILL_ENTRY; + goto err_ret; + } + if (fieldbuf[0] == '\0') { + *errstrp = (char *)instr; + *errp = LTSNET_NO_LABEL; + goto err_ret; + } + if (stobsl(fieldbuf, &zc->zc_label, NO_CORRECTION, &err) == 0) { + *errstrp = (char *)instr; + *errp = LTSNET_ILL_LABEL; + goto err_ret; + } + instr = nextf + 1; + + /* Not in the entry, but should be */ + zc->zc_doi = 1; + + /* Field three: get match flag */ + errno = 0; + zc->zc_match = (uchar_t)strtol(instr, &cp, 0); + if (errno != 0 || (*cp != ':' && *cp != '\0')) { + *errp = LTSNET_ILL_FLAG; + *errstrp = (char *)instr; + goto err_ret; + } + if (*cp != ':') { + *errp = LTSNET_ILL_VALDELIM; + *errstrp = cp; + goto err_ret; + } + instr = cp + 1; + + /* Field four: get zone-specific MLP list. */ + nextf = parse_entry(fieldbuf, sizeof (fieldbuf), instr, "#:\n"); + if (*nextf != ':') { + *errstrp = (char *)nextf; + *errp = LTSNET_ILL_ENTRY; + goto err_ret; + } + if (!parse_mlp_list(&zc->zc_private_mlp, fieldbuf, errp, errstrp)) { + *errstrp = (char *)instr + (*errstrp - fieldbuf); + goto err_ret; + } + instr = nextf + 1; + + /* Field five: get global MLP list. */ + nextf = parse_entry(fieldbuf, sizeof (fieldbuf), instr, "#:\n"); + if (*nextf != '\0' && *nextf != '#' && !isspace(*nextf)) { + *errstrp = (char *)nextf; + *errp = LTSNET_ILL_ENTRY; + goto err_ret; + } + if (!parse_mlp_list(&zc->zc_shared_mlp, fieldbuf, errp, errstrp)) { + *errstrp = (char *)instr + (*errstrp - fieldbuf); + goto err_ret; + } + + return (zc); + +err_ret: + err = errno; + tsol_freezcent(zc); + errno = err; + return (NULL); +} + +void +tsol_freezcent(tsol_zcent_t *zc) +{ + if (zc != NULL) { + free(zc->zc_private_mlp); + free(zc->zc_shared_mlp); + free(zc); + } +} diff --git a/usr/src/lib/libtsnet/i386/Makefile b/usr/src/lib/libtsnet/i386/Makefile new file mode 100644 index 0000000000..ee3ea88a08 --- /dev/null +++ b/usr/src/lib/libtsnet/i386/Makefile @@ -0,0 +1,35 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +MAPDIR= ../spec/i386 +include ../Makefile.com + +.KEEP_STATE: + +all: $(LIBS) + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff --git a/usr/src/lib/libtsnet/sparc/Makefile b/usr/src/lib/libtsnet/sparc/Makefile new file mode 100644 index 0000000000..73ba2bbce8 --- /dev/null +++ b/usr/src/lib/libtsnet/sparc/Makefile @@ -0,0 +1,32 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +all: $(LIBS) + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff --git a/usr/src/lib/libtsnet/sparcv9/Makefile b/usr/src/lib/libtsnet/sparcv9/Makefile new file mode 100644 index 0000000000..69cf39010b --- /dev/null +++ b/usr/src/lib/libtsnet/sparcv9/Makefile @@ -0,0 +1,31 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +#ident "%Z%%M% %I% %E% SMI" + +include ../Makefile.com +include ../../Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64) diff --git a/usr/src/lib/libtsnet/spec/Makefile b/usr/src/lib/libtsnet/spec/Makefile new file mode 100644 index 0000000000..66c61a6d05 --- /dev/null +++ b/usr/src/lib/libtsnet/spec/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# +# lib/libtsnet/spec/Makefile +# + +include $(SRC)/lib/Makefile.spec.arch diff --git a/usr/src/lib/libtsnet/spec/Makefile.targ b/usr/src/lib/libtsnet/spec/Makefile.targ new file mode 100644 index 0000000000..aeafa46121 --- /dev/null +++ b/usr/src/lib/libtsnet/spec/Makefile.targ @@ -0,0 +1,35 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# +# lib/libtsnet/spec/Makefile.targ +# + +LIBRARY= libtsnet.a +VERS= .1 + +OBJECTS= tsnet.o + +SPECCPP += -I../../ diff --git a/usr/src/lib/libtsnet/spec/amd64/Makefile b/usr/src/lib/libtsnet/spec/amd64/Makefile new file mode 100644 index 0000000000..03d9b122a2 --- /dev/null +++ b/usr/src/lib/libtsnet/spec/amd64/Makefile @@ -0,0 +1,33 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +.KEEP_STATE: + +include ../Makefile.targ +include $(SRC)/lib/Makefile.lib +include $(SRC)/lib/Makefile.lib.64 +include $(SRC)/lib/Makefile.spec diff --git a/usr/src/lib/libtsnet/spec/i386/Makefile b/usr/src/lib/libtsnet/spec/i386/Makefile new file mode 100644 index 0000000000..b378e293ca --- /dev/null +++ b/usr/src/lib/libtsnet/spec/i386/Makefile @@ -0,0 +1,34 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# +# lib/libtsnet/spec/i386/Makefile +# + +.KEEP_STATE: + +include ../Makefile.targ +include $(SRC)/lib/Makefile.lib +include $(SRC)/lib/Makefile.spec diff --git a/usr/src/lib/libtsnet/spec/sparc/Makefile b/usr/src/lib/libtsnet/spec/sparc/Makefile new file mode 100644 index 0000000000..013c8f71b0 --- /dev/null +++ b/usr/src/lib/libtsnet/spec/sparc/Makefile @@ -0,0 +1,34 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# +# lib/libtsnet/spec/sparc/Makefile +# + +.KEEP_STATE: + +include ../Makefile.targ +include $(SRC)/lib/Makefile.lib +include $(SRC)/lib/Makefile.spec diff --git a/usr/src/lib/libtsnet/spec/sparcv9/Makefile b/usr/src/lib/libtsnet/spec/sparcv9/Makefile new file mode 100644 index 0000000000..03d9b122a2 --- /dev/null +++ b/usr/src/lib/libtsnet/spec/sparcv9/Makefile @@ -0,0 +1,33 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +.KEEP_STATE: + +include ../Makefile.targ +include $(SRC)/lib/Makefile.lib +include $(SRC)/lib/Makefile.lib.64 +include $(SRC)/lib/Makefile.spec diff --git a/usr/src/lib/libtsnet/spec/tsnet.spec b/usr/src/lib/libtsnet/spec/tsnet.spec new file mode 100644 index 0000000000..78e222075d --- /dev/null +++ b/usr/src/lib/libtsnet/spec/tsnet.spec @@ -0,0 +1,206 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# +# lib/libtsnet/spec/tsnet.spec +# + +function tsol_gettpbyname +include <libtsnet.h> +declaration tsol_tpent_t *tsol_gettpbyname(const char *name); +version SUNWprivate_1.1 +exception $return == 0 +end + +function tsol_gettpent +include <libtsnet.h> +declaration tsol_tpent_t *tsol_gettpent(void); +version SUNWprivate_1.1 +exception $return == 0 +end + +function tsol_fgettpent +include <libtsnet.h> +declaration tsol_tpent_t *tsol_gettpent(FILE *); +version SUNWprivate_1.1 +exception $return == 0 +end + +function tsol_freetpent +include <libtsnet.h> +declaration void tsol_freetpent(tsol_tpent_t *); +version SUNWprivate_1.1 +exception $return == 0 +end + +function tsol_settpent +include <libtsnet.h> +declaration void tsol_settpent(int stay); +version SUNWprivate_1.1 +end + +function tsol_endtpent +include <libtsnet.h> +declaration void tsol_endtpent(void); +version SUNWprivate_1.1 +end + +function str_to_tpstr +include <libtsnet.h> +declaration int str_to_tpstr(const char *, int, void *, char *, int); +version SUNWprivate_1.1 +end + +function tpstr_to_ent +include <libtsnet.h> +declaration tsol_tpent_t *tpstr_to_ent(tsol_tpstr_t *, int *, char **); +version SUNWprivate_1.1 +end + +function tsol_getrhbyaddr +include <libtsnet.h> +declaration tsol_rhent_t *tsol_getrhbyaddr(const void *addr, size_t len, \ + int type); +version SUNWprivate_1.1 +exception $return == 0 +end + +function tsol_getrhent +include <libtsnet.h> +declaration tsol_rhent_t *tsol_getrhent(void); +version SUNWprivate_1.1 +exception $return == 0 +end + +function tsol_fgetrhent +include <libtsnet.h> +declaration tsol_rhent_t *tsol_getrhent(FILE *); +version SUNWprivate_1.1 +exception $return == 0 +end + +function tsol_freerhent +include <libtsnet.h> +declaration void tsol_freerhent(tsol_rhent_t *); +version SUNWprivate_1.1 +exception $return == 0 +end + +function tsol_setrhent +include <libtsnet.h> +declaration void tsol_setrhent(int stay); +version SUNWprivate_1.1 +end + +function tsol_endrhent +include <libtsnet.h> +declaration void tsol_endrhent(void); +version SUNWprivate_1.1 +end + +function str_to_rhstr +include <libtsnet.h> +declaration int str_to_rhstr(const char *, int, void *, char *, int); +version SUNWprivate_1.1 +end + +function rhstr_to_ent +include <libtsnet.h> +declaration tsol_rhent_t *rhstr_to_ent(tsol_rhstr_t *, int *, char **); +version SUNWprivate_1.1 +end + +function tsol_getrhtype +include <libtsnet.h> +declaration tsol_host_type_t tsol_getrhtype(char *); +version SUNWprivate_1.1 +end + +function tsol_sgetzcent +include <libtsnet.h> +declaration tsol_zcent_t *tsol_sgetzcent(const char *instr, int *errp, \ + char **errstrp); +version SUNWprivate_1.1 +exception $return == 0 +end + +function tsol_freezcent +include <libtsnet.h> +declaration void tsol_freezcent(tsol_zcent_t *); +version SUNWprivate_1.1 +exception $return == 0 +end + +function sl_to_str +include <libtsnet.h> +declaration const char *sl_to_str(const bslabel_t *sl); +version SUNWprivate_1.1 +end + +function rtsa_to_str +include <libtsnet.h> +declaration const char *rtsa_to_str(const struct rtsa_s *rtsa, \ + char *line, size_t len); +version SUNWprivate_1.1 +exception $return == 0 +end + +function rtsa_keyword +include <libtsnet.h> +declaration boolean_t rtsa_keyword(const char *opt, struct rtsa_s *rtsa, \ + int *errp, char **errstr); +version SUNWprivate_1.1 +exception $return == 0 +end + +function tsol_strerror +include <libtsnet.h> +declaration const char *tsol_strerror(int libtserr, int errnoval); +version SUNWprivate_1.1 +end + +function tnrhtp +include <libtsnet.h> +declaration int tnrhtp(int cmd, tsol_tpent_t *buf); +version SUNWprivate_1.1 +errno ENOSYS EFAULT EINVAL ENOENT EOPNOTSUPP EPERM +exception $return == -1 +end + +function tnrh +include <libtsnet.h> +declaration int tnrh(int cmd, tsol_rhent_t *buf); +version SUNWprivate_1.1 +errno ENOSYS EFAULT EINVAL ENOENT EOPNOTSUPP EPERM ENOMEM +exception $return == -1 +end + +function tnmlp +include <libtsnet.h> +declaration int tnmlp(int cmd, tsol_mlpent_t *buf); +version SUNWprivate_1.1 +errno ENOSYS EFAULT EINVAL ENOENT EEXIST EOPNOTSUPP EPERM +exception $return == -1 +end diff --git a/usr/src/lib/libtsnet/spec/versions b/usr/src/lib/libtsnet/spec/versions new file mode 100644 index 0000000000..43c70977f7 --- /dev/null +++ b/usr/src/lib/libtsnet/spec/versions @@ -0,0 +1,35 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# +# lib/libtsnet/spec/versions +# + +sparc { + SUNWprivate_1.1; +} +i386 { + SUNWprivate_1.1; +} diff --git a/usr/src/lib/libtsol/Makefile b/usr/src/lib/libtsol/Makefile new file mode 100644 index 0000000000..2bb6a81725 --- /dev/null +++ b/usr/src/lib/libtsol/Makefile @@ -0,0 +1,73 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +#ident "%Z%%M% %I% %E% SMI" + +# +# lib/libtsol/Makefile +# + +include ../Makefile.lib + +HDRS = label.h +HDRDIR = common +SUBDIRS = $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) + +POFILE = libtsol.po +MSGFILES = common/btos.c common/private.c common/stob.c +XGETFLAGS = -a + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +# Override so that label.h gets installed where expected. +ROOTHDRDIR= $(ROOT)/usr/include/tsol + +all clean clobber install: spec .WAIT $(SUBDIRS) + +lint: $(SUBDIRS) + +install_h: $(ROOTHDRS) + +check: $(CHECKHDRS) + +$(POFILE): $(MSGFILES) + $(BUILDPO.msgfiles) + +_msg: $(MSGDOMAINPOFILE) + +$(SUBDIRS) spec: FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include $(SRC)/Makefile.msg.targ +include $(SRC)/lib/Makefile.targ diff --git a/usr/src/lib/libtsol/Makefile.com b/usr/src/lib/libtsol/Makefile.com new file mode 100644 index 0000000000..46959e7662 --- /dev/null +++ b/usr/src/lib/libtsol/Makefile.com @@ -0,0 +1,74 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +#ident "%Z%%M% %I% %E% SMI" + +# +# lib/libtsol/Makefile.com +# + +LIBRARY = libtsol.a +VERS = .2 + +OBJECTS = \ + blabel.o btohex.o btos.o call_labeld.o \ + getlabel.o getplabel.o hextob.o \ + ltos.o misc.o getpathbylabel.o private.o privlib.o \ + setflabel.o stob.o stol.o zone.o + +include ../../Makefile.lib + +# install this library in the root filesystem +include ../../Makefile.rootfs + +LIBS = $(DYNLIB) $(LINTLIB) +$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) +LDLIBS += -lsecdb -lc + +NONCOMMON = $(OBJECTS:blabel.o=) +lint:= SRCS = $(NONCOMMON:%.o=$(SRCDIR)/%.c) $(COMMONDIR)/blabel.c + +SRCDIR = ../common +MAPDIR = ../spec/$(TRANSMACH) +SPECMAPFILE = $(MAPDIR)/mapfile + +COMMONDIR= $(SRC)/common/tsol + +CFLAGS += $(CCVERBOSE) +CPPFLAGS += -D_REENTRANT -I$(SRCDIR) -I$(COMMONDIR) + +LINTFLAGS64 += -Xarch=v9 + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +objs/%.o pic_profs/%.o pics/%.o: $(COMMONDIR)/%.c + $(COMPILE.c) -o $@ $< + $(POST_PROCESS_O) + +include ../../Makefile.targ diff --git a/usr/src/lib/libtsol/amd64/Makefile b/usr/src/lib/libtsol/amd64/Makefile new file mode 100644 index 0000000000..69cf39010b --- /dev/null +++ b/usr/src/lib/libtsol/amd64/Makefile @@ -0,0 +1,31 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +#ident "%Z%%M% %I% %E% SMI" + +include ../Makefile.com +include ../../Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64) diff --git a/usr/src/lib/libtsol/common/btohex.c b/usr/src/lib/libtsol/common/btohex.c new file mode 100644 index 0000000000..19122382c7 --- /dev/null +++ b/usr/src/lib/libtsol/common/btohex.c @@ -0,0 +1,200 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * btohex.c - Binary to Hexadecimal string conversion. + * + * These routines convert binary labels into canonical + * hexadecimal representations of the binary form. + */ + +#include <stdlib.h> +#include <strings.h> +#include <tsol/label.h> +#include <sys/tsol/label_macro.h> + +/* 0x + Classification + '-' + ll + '-' + Compartments + end of string */ +#define _HEX_SIZE 2+(sizeof (Classification_t)*2)+4+\ + (sizeof (Compartments_t)*2)+1 + +static char hex_buf[_HEX_SIZE]; + +/* + * h_alloc - Allocate data storage for a Hexadecimal label string. + * + * Entry id = Type of label to allocate storage for. + * SUN_SL_ID - Sensitivity Label. + * SUN_CLR_ID - Clearance. + * + * Returns NULL, If unable to allocate storage. + * Address of buffer. + * + * Calls malloc; + */ + +char * +h_alloc(unsigned char id) +{ + size_t size; + + switch (id) { + + case SUN_SL_ID: + size = _HEX_SIZE; + break; + + case SUN_CLR_ID: + size = _HEX_SIZE; + break; + + default: + return (NULL); + } + + return ((char *)malloc(size)); +} + + +/* + * h_free - Free a Hexadecimal label string. + * + * Entry hex = Hexadecimal label string. + * + * Returns none. + * + * Calls free. + */ + +void +h_free(char *hex) +{ + + if (hex == NULL) + return; + + free(hex); +} + + +/* + * bsltoh_r - Convert a Sensitivity Label into a Hexadecimal label string. + * + * Entry label = Sensitivity Label to be translated. + * hex = Buffer to place converted label. + * len = Length of buffer. + * + * Returns NULL, If invalid label type. + * Address of buffer. + * + * Calls label_to_str, strncpy. + */ + +char * +bsltoh_r(const m_label_t *label, char *hex) +{ + char *h; + + if (label_to_str(label, &h, M_INTERNAL, DEF_NAMES) != 0) { + free(h); + return (NULL); + } + + (void) strncpy(hex, (const char *)h, _HEX_SIZE); + free(h); + return (hex); +} + + +/* + * bsltoh - Convert a Sensitivity Label into a Hexadecimal label string. + * + * Entry label = Sensitivity Label to be translated. + * + * Returns NULL, If invalid label type. + * Address of statically allocated hex label string. + * + * Calls bsltoh_r. + * + * Uses hex_buf. + */ + +char * +bsltoh(const m_label_t *label) +{ + + return (bsltoh_r(label, hex_buf)); +} + + +/* + * bcleartoh_r - Convert a Clearance into a Hexadecimal label string. + * + * Entry clearance = Clearance to be translated. + * hex = Buffer to place converted label. + * len = Length of buffer. + * + * Returns NULL, If invalid label type. + * Address of buffer. + * + * Calls label_to_str, strncpy. + */ + +char * +bcleartoh_r(const m_label_t *clearance, char *hex) +{ + char *h; + + if (label_to_str(clearance, &h, M_INTERNAL, DEF_NAMES) != 0) { + free(h); + return (NULL); + } + + (void) strncpy(hex, (const char *)h, _HEX_SIZE); + free(h); + return (hex); +} + + +/* + * bcleartoh - Convert a Clearance into a Hexadecimal label string. + * + * Entry clearance = Clearance to be translated. + * + * Returns NULL, If invalid label type. + * Address of statically allocated hex label string. + * + * Calls bcleartoh_r. + * + * Uses hex_buf. + */ + +char * +bcleartoh(const m_label_t *clearance) +{ + + return (bcleartoh_r(clearance, hex_buf)); +} diff --git a/usr/src/lib/libtsol/common/btos.c b/usr/src/lib/libtsol/common/btos.c new file mode 100644 index 0000000000..7ed4a6cdee --- /dev/null +++ b/usr/src/lib/libtsol/common/btos.c @@ -0,0 +1,485 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Binary label to label string translations. + */ + +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <wchar.h> + +#include <sys/mman.h> + +#include <tsol/label.h> + +#include "clnt.h" +#include "labeld.h" +#include <sys/tsol/label_macro.h> + +#if !defined(TEXT_DOMAIN) /* should be defined by Makefiles */ +#define TEXT_DOMAIN "SYS_TEST" +#endif /* TEXT_DOMAIN */ + +static bslabel_t slow; /* static admin_low high sensitivity label */ +static bslabel_t shigh; /* static admin_high sensitivity label */ +static bclear_t clrlow, clrhigh; /* static admin_low and admin_high Clearance */ + +static char *sstring; /* return string for sb*tos */ +static size_t ssize; /* current size of return string */ + +static int +return_string(char **string, int str_len, char *val) +{ + char *cpyptr; + size_t val_len = strlen(val) + 1; + + if (*string == NULL) { + if ((*string = malloc(val_len)) == NULL) + return (0); + } else if (val_len > str_len) { + **string = '\0'; + return (0); + } + + cpyptr = *string; + bcopy(val, cpyptr, val_len); + + return (val_len); +} + +void +set_label_view(uint_t *callflags, uint_t flags) +{ + if (flags&VIEW_INTERNAL) { + *callflags |= LABELS_VIEW_INTERNAL; + } else if (flags&VIEW_EXTERNAL) { + *callflags |= LABELS_VIEW_EXTERNAL; + } +} + +int +alloc_string(char **string, size_t size, char val) +{ + if (*string == NULL) { + if ((*string = malloc(ALLOC_CHUNK)) == NULL) + return (0); + } else { + if ((*string = realloc(*string, size + ALLOC_CHUNK)) == NULL) { + **string = val; + return (0); + } + } + **string = val; + return (ALLOC_CHUNK); +} + +#define slcall callp->param.acall.cargs.bsltos_arg +#define slret callp->param.aret.rvals.bsltos_ret +/* + * bsltos - Convert Binary Sensitivity Label to Sensitivity Label string. + * + * Entry label = Binary Sensitivity Label to be converted. + * string = NULL ((char *) 0), if memory to be allocated, + * otherwise, pointer to preallocated memory. + * str_len = Length of preallocated memory, else ignored. + * flags = Logical sum of: + * LONG_CLASSIFICATION or SHORT_CLASSIFICATION, + * LONG_WORDS or SHORT_WORDS, + * VIEW_INTERNAL or VIEW_EXTERNAL, and + * NO_CLASSIFICATION. + * LONG_CLASSIFICATION, use long classification names. + * SHORT_CLASSIFICATION, use short classification + * names (default). + * NO_CLASSIFICATION, don't translate classification. + * LONG_WORDS, use the long form of words (default). + * SHORTWORDS, use the short form of words where available. + * VIEW_INTERNAL, don't promote/demote admin low/high. + * VIEW_EXTERNAL, promote/demote admin low/high. + * + * Exit string = Sensitivity Label string, or empty string if + * not enough preallocated memory. + * + * Returns -1, If unable to access label encodings database. + * 0, If unable to allocate string, + * or allocated string to short + * (and **string = '\0'). + * length (including null) of Sensitivity Label string, + * If successful. + * + * Calls RPC - LABELS_BSLTOS, BCLHIGH, BCLLOW, BCLTOSL, BLEQUAL, + * BLTYPE, SETBSLABEL, UCLNT, memcpy, clnt_call, + * clnt_perror, malloc, strcat, strlen. + * + * Uses ADMIN_HIGH, ADMIN_LOW, shigh, slow. + */ + +ssize_t +bsltos(const bslabel_t *label, char **string, size_t str_len, + int flags) +{ + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize = CALL_SIZE(bsltos_call_t, 0); + int rval; + + if (!BLTYPE(label, SUN_SL_ID)) { + return (-1); + } + + call.callop = BSLTOS; + slcall.label = *label; + slcall.flags = (flags&NO_CLASSIFICATION) ? LABELS_NO_CLASS : 0; + slcall.flags |= (flags&SHORT_CLASSIFICATION || + !(flags&LONG_CLASSIFICATION)) ? LABELS_SHORT_CLASS : 0; + slcall.flags |= (flags&SHORT_WORDS && !(flags&LONG_WORDS)) ? + LABELS_SHORT_WORDS : 0; + set_label_view(&slcall.flags, flags); + + if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) { + + if (callp->reterr != 0) + return (-1); + + /* unpack Sensitivity Label */ + + rval = return_string(string, str_len, slret.slabel); + + if (callp != &call) + (void) munmap((void *)callp, bufsize); + return (rval); + } else if (rval == NOSERVER) { + /* server not present */ + /* special case admin_high and admin_low */ + + if (!BLTYPE(&slow, SUN_SL_ID)) { + /* initialize static labels */ + + BSLLOW(&slow); + BSLHIGH(&shigh); + } + + if (BLEQUAL(label, &slow)) { + return (return_string(string, str_len, ADMIN_LOW)); + } else if (BLEQUAL(label, &shigh)) { + return (return_string(string, str_len, ADMIN_HIGH)); + } + } + return (-1); +} /* bsltos */ +#undef slcall +#undef slret + +#define clrcall callp->param.acall.cargs.bcleartos_arg +#define clrret callp->param.aret.rvals.bcleartos_ret +/* + * bcleartos - Convert Binary Clearance to Clearance string. + * + * Entry clearance = Binary Clearance to be converted. + * string = NULL ((char *) 0), if memory to be allocated, + * otherwise, pointer to preallocated memory. + * str_len = Length of preallocated memory, else ignored. + * flags = Logical sum of: + * LONG_CLASSIFICATION or SHORT_CLASSIFICATION, + * LONG_WORDS or SHORT_WORDS, + * VIEW_INTERNAL or VIEW_EXTERNAL. + * LONG_CLASSIFICATION, use long classification names. + * SHORT_CLASSIFICATION, use short classification + * names (default). + * LONG_WORDS, use the long form of words (default). + * SHORTWORDS, use the short form of words where available. + * VIEW_INTERNAL, don't promote/demote admin low/high. + * VIEW_EXTERNAL, promote/demote admin low/high. + * + * Exit string = Clearance string, or empty string if not + * enough preallocated memory. + * + * Returns -1, If unable to access label encodings database. + * 0, If unable to allocate string, + * or allocated string to short + * (and **string = '\0'). + * length (including null) of Clearance string, + * If successful. + * + * Calls RPC - LABELS_BSLTOS, BCLHIGH, BCLLOW, BCLTOSL, BLEQUAL, + * BLTYPE, SETBSLABEL, UCLNT, memcpy, clnt_call, + * clnt_perror, malloc, strcat, strlen. + * + * Uses ADMIN_HIGH, ADMIN_LOW, clrhigh, clrlow. + */ + +ssize_t +bcleartos(const bclear_t *clearance, char **string, size_t str_len, + int flags) +{ + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize = CALL_SIZE(bcleartos_call_t, 0); + int rval; + + if (!BLTYPE(clearance, SUN_CLR_ID)) { + return (-1); + } + + call.callop = BCLEARTOS; + clrcall.clear = *clearance; + clrcall.flags = (flags&SHORT_CLASSIFICATION || + !(flags&LONG_CLASSIFICATION)) ? LABELS_SHORT_CLASS : 0; + clrcall.flags |= (flags&SHORT_WORDS && !(flags&LONG_WORDS)) ? + LABELS_SHORT_WORDS : 0; + set_label_view(&clrcall.flags, flags); + + if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) { + + if (callp->reterr != 0) + return (-1); + + /* unpack Clearance */ + + rval = return_string(string, str_len, clrret.cslabel); + + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (rval); + } else if (rval == NOSERVER) { + /* server not present */ + /* special case admin_high and admin_low */ + + if (!BLTYPE(&clrlow, SUN_CLR_ID)) { + /* initialize static labels */ + + BCLEARLOW(&clrlow); + BCLEARHIGH(&clrhigh); + } + if (BLEQUAL(clearance, &clrlow)) { + return (return_string(string, str_len, ADMIN_LOW)); + } else if (BLEQUAL(clearance, &clrhigh)) { + return (return_string(string, str_len, ADMIN_HIGH)); + } + } + return (-1); +} /* bcleartos */ +#undef clrcall +#undef clrret + +/* + * sbsltos - Convert Sensitivity Label to canonical clipped form. + * + * Entry label = Sensitivity Label to be converted. + * len = Maximum length of translated string, excluding NULL. + * 0, full string. + * sstring = address of string to translate into. + * ssize = size of memory currently allocated to sstring. + * + * Exit sstring = Newly translated string. + * ssize = Updated if more memory pre-allocated. + * + * Returns NULL, If error, len too small, unable to translate, or get + * memory for string. + * Address of string containing converted value. + * + * Calls alloc_string, bsltos, strcpy. + * + * Uses ssize, sstring. + */ + +char * +sbsltos(const bslabel_t *label, size_t len) +{ + ssize_t slen; /* length including NULL */ + wchar_t *wstring; + int wccount; + + if (ssize == 0) { + /* Allocate string memory. */ + if ((ssize = alloc_string(&sstring, ssize, 's')) == 0) + /* can't get initial memory for string */ + return (NULL); + } + +again: + if ((slen = bsltos(label, &sstring, ssize, + (SHORT_CLASSIFICATION | LONG_WORDS))) <= 0) { + /* error in translation */ + if (slen == 0) { + if (*sstring == '\0') { + int newsize; + /* sstring not long enough */ + if ((newsize = alloc_string(&sstring, ssize, + 's')) == 0) { + /* Can't get more memory */ + return (NULL); + } + ssize += newsize; + goto again; + } + } + return (NULL); + } + if (len == 0) { + return (sstring); + } else if (len < MIN_SL_LEN) { + return (NULL); + } + if ((wstring = malloc(slen * sizeof (wchar_t))) == NULL) + return (NULL); + if ((wccount = mbstowcs(wstring, sstring, slen - 1)) == -1) { + free(wstring); + return (NULL); + } + if (wccount > len) { + wchar_t *clipp = wstring + (len - 2); + + /* Adjust string size to desired length */ + + clipp[0] = L'<'; + clipp[1] = L'-'; + clipp[2] = L'\0'; + + while (wcstombs(NULL, wstring, 0) >= ssize) { + int newsize; + + /* sstring not long enough */ + if ((newsize = alloc_string(&sstring, ssize, 's')) == + 0) { + /* Can't get more memory */ + return (NULL); + } + ssize += newsize; + } + + if ((wccount = wcstombs(sstring, wstring, ssize)) == -1) { + free(wstring); + return (NULL); + } + } + free(wstring); + + return (sstring); +} /* sbsltos */ + +/* + * sbcleartos - Convert Clearance to canonical clipped form. + * + * Entry clearance = Clearance to be converted. + * len = Maximum length of translated string, excluding NULL. + * 0, full string. + * sstring = address of string to translate into. + * ssize = size of memory currently allocated to sstring. + * + * Exit sstring = Newly translated string. + * ssize = Updated if more memory pre-allocated. + * + * Returns NULL, If error, len too small, unable to translate, or get + * memory for string. + * Address of string containing converted value. + * + * Calls alloc_string, bcleartos, strcpy. + * + * Uses ssize, sstring. + */ + +char * +sbcleartos(const bclear_t *clearance, size_t len) +{ + ssize_t slen; /* length including NULL */ + wchar_t *wstring; + int wccount; + + if (ssize == 0) { + /* Allocate string memory. */ + if ((ssize = alloc_string(&sstring, ssize, 'c')) == 0) + /* can't get initial memory for string */ + return (NULL); + } + +again: + if ((slen = bcleartos(clearance, &sstring, ssize, + (SHORT_CLASSIFICATION | LONG_WORDS))) <= 0) { + /* error in translation */ + if (slen == 0) { + if (*sstring == '\0') { + int newsize; + /* sstring not long enough */ + if ((newsize = alloc_string(&sstring, ssize, + 'c')) == 0) { + /* Can't get more memory */ + return (NULL); + } + ssize += newsize; + goto again; + } + } + return (NULL); + } + if (len == 0) { + return (sstring); + } else if (len < MIN_CLR_LEN) { + return (NULL); + } + if ((wstring = malloc(slen * sizeof (wchar_t))) == NULL) + return (NULL); + if ((wccount = mbstowcs(wstring, sstring, slen - 1)) == -1) { + free(wstring); + return (NULL); + } + if (wccount > len) { + wchar_t *clipp = wstring + (len - 2); + + /* Adjust string size to desired length */ + + clipp[0] = L'<'; + clipp[1] = L'-'; + clipp[2] = L'\0'; + + while (wcstombs(NULL, wstring, 0) >= ssize) { + int newsize; + + /* sstring not long enough */ + if ((newsize = alloc_string(&sstring, ssize, 'c')) == + 0) { + /* Can't get more memory */ + free(wstring); + return (NULL); + } + ssize += newsize; + } + if ((wccount = wcstombs(sstring, wstring, ssize)) == -1) { + free(wstring); + return (NULL); + } + } + free(wstring); + + return (sstring); +} /* sbcleartos */ diff --git a/usr/src/lib/libtsol/common/call_labeld.c b/usr/src/lib/libtsol/common/call_labeld.c new file mode 100644 index 0000000000..35d94450f5 --- /dev/null +++ b/usr/src/lib/libtsol/common/call_labeld.c @@ -0,0 +1,308 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <door.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <synch.h> +#include <time.h> +#include <unistd.h> + +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include "labeld.h" + +#ifndef DEBUG +#define perror(e) +#endif /* !DEBUG */ + +/* + * Library prototypes to get away from lots of static build problems. + */ + +extern int __nanosleep(const struct timespec *, struct timespec *); + +/* + * This is cloned from _nsc_trydoorcall used by the nscd client. + * + * Routine that actually performs the door call. + * Note that we cache a file descriptor. We do + * the following to prevent disasters: + * + * 1) Never use 0, 1 or 2; if we get this from the open + * we dup it upwards. + * + * 2) Set the close on exec flags so descriptor remains available + * to child processes. + * + * 3) Verify that the door is still the same one we had before + * by using door_info on the client side. + * + * Note that we never close the file descriptor if it isn't one + * we allocated; we check this with door info. The rather tricky + * logic is designed to be fast in the normal case (fd is already + * allocated and is ok) while handling the case where the application + * closed it underneath us or where the nscd dies or re-execs itself + * and we're a multi-threaded application. Note that we cannot protect + * the application if it closes the fd and it is multi-threaded. + * + * int __call_labeld(label_door_op **dptr, int *ndata, int *adata); + * + * *dptr IN: points to arg buffer OUT: points to results buffer + * *ndata IN: overall size of buffer OUT: overall size of buffer + * *adata IN: size of call data OUT: size of return data + * + * Note that *dptr may change if provided space as defined by *bufsize is + * inadequate. In this case the door call mmaps more space and places + * the answer there and sets dptr to contain a pointer to the space, which + * should be freed with munmap. + * + * Returns 0 if the door call reached the server, -1 if contact was not made. + * + */ + + +static mutex_t _door_lock = DEFAULTMUTEX; + +int +__call_labeld(labeld_data_t **dptr, size_t *ndata, size_t *adata) +{ + static int doorfd = -1; + static door_info_t real_door; + struct stat st; + door_info_t my_door; + door_arg_t param; + char door_name[MAXPATHLEN]; + struct timespec ts; + int busy = 0; /* number of busy loops */ + +#ifdef DEBUG + labeld_data_t *callptr = *dptr; + int buf_size = *ndata; + int return_size = *adata; +#endif /* DEBUG */ + + /* + * the first time in we try and open and validate the door. + * the validations are that the door must have been + * created with the label service door cookie and + * that it has the same door ID. If any of these + * validations fail we refuse to use the door. + */ + ts.tv_sec = 0; /* initialize nanosecond retry timer */ + ts.tv_nsec = 100; + (void) mutex_lock(&_door_lock); + +try_again: + if (doorfd == -1) { + int tbc[3]; + int i; + + (void) snprintf(door_name, sizeof (door_name), "%s%s", + DOOR_PATH, DOOR_NAME); + if ((doorfd = open64(door_name, O_RDONLY, 0)) < 0) { + (void) mutex_unlock(&_door_lock); + perror("server door open"); + return (NOSERVER); + } + + /* + * dup up the file descriptor if we have 0 - 2 + * to avoid problems with shells stdin/out/err + */ + i = 0; + while (doorfd < 3) { /* we have a reserved fd */ + tbc[i++] = doorfd; + if ((doorfd = dup(doorfd)) < 0) { + perror("couldn't dup"); + while (i--) + (void) close(tbc[i]); + doorfd = -1; + (void) mutex_unlock(&_door_lock); + return (NOSERVER); + } + } + while (i--) + (void) close(tbc[i]); + + /* + * mark this door descriptor as close on exec + */ + (void) fcntl(doorfd, F_SETFD, FD_CLOEXEC); + if (door_info(doorfd, &real_door) < 0) { + /* + * we should close doorfd because we just opened it + */ + perror("real door door_info"); + (void) close(doorfd); + doorfd = -1; + (void) mutex_unlock(&_door_lock); + return (NOSERVER); + } + if (fstat(doorfd, &st) < 0) { + perror("real door fstat"); + return (NOSERVER); + } +#ifdef DEBUG + (void) printf("\treal door %s\n", door_name); + (void) printf("\t\tuid = %d, gid = %d, mode = %o\n", st.st_uid, + st.st_gid, st.st_mode); + (void) printf("\t\toutstanding requests = %d\n", st.st_nlink-1); + (void) printf("\t\t pid = %d\n", real_door.di_target); + (void) printf("\t\t procedure = %llx\n", real_door.di_proc); + (void) printf("\t\t cookie = %llx\n", real_door.di_data); + (void) printf("\t\t attributes = %x\n", + real_door.di_attributes); + if (real_door.di_attributes & DOOR_UNREF) + (void) printf("\t\t\t UNREF\n"); + if (real_door.di_attributes & DOOR_PRIVATE) + (void) printf("\t\t\t PRIVATE\n"); + if (real_door.di_attributes & DOOR_LOCAL) + (void) printf("\t\t\t LOCAL\n"); + if (real_door.di_attributes & DOOR_REVOKED) + (void) printf("\t\t\t REVOKED\n"); + if (real_door.di_attributes & DOOR_DESCRIPTOR) + (void) printf("\t\t\t DESCRIPTOR\n"); + if (real_door.di_attributes & DOOR_RELEASE) + (void) printf("\t\t\t RELEASE\n"); + if (real_door.di_attributes & DOOR_DELAY) + (void) printf("\t\t\t DELAY\n"); + (void) printf("\t\t id = %llx\n", real_door.di_uniquifier); +#endif /* DEBUG */ + if ((real_door.di_attributes & DOOR_REVOKED) || + (real_door.di_data != (door_ptr_t)COOKIE)) { +#ifdef DEBUG + (void) printf("real door revoked\n"); +#endif /* DEBUG */ + (void) close(doorfd); + doorfd = -1; + (void) mutex_unlock(&_door_lock); + return (NOSERVER); + } + } else { + if ((door_info(doorfd, &my_door) < 0) || + (my_door.di_data != (door_ptr_t)COOKIE) || + (my_door.di_uniquifier != real_door.di_uniquifier)) { + perror("my door door_info"); + /* + * don't close it - someone else has clobbered fd + */ + doorfd = -1; + goto try_again; + } + if (fstat(doorfd, &st) < 0) { + perror("my door fstat"); + goto try_again; + } +#ifdef DEBUG + (void) sprintf(door_name, "%s%s", DOOR_PATH, DOOR_NAME); + (void) printf("\tmy door %s\n", door_name); + (void) printf("\t\tuid = %d, gid = %d, mode = %o\n", st.st_uid, + st.st_gid, st.st_mode); + (void) printf("\t\toutstanding requests = %d\n", st.st_nlink-1); + (void) printf("\t\t pid = %d\n", my_door.di_target); + (void) printf("\t\t procedure = %llx\n", my_door.di_proc); + (void) printf("\t\t cookie = %llx\n", my_door.di_data); + (void) printf("\t\t attributes = %x\n", my_door.di_attributes); + if (my_door.di_attributes & DOOR_UNREF) + (void) printf("\t\t\t UNREF\n"); + if (my_door.di_attributes & DOOR_PRIVATE) + (void) printf("\t\t\t PRIVATE\n"); + if (my_door.di_attributes & DOOR_LOCAL) + (void) printf("\t\t\t LOCAL\n"); + if (my_door.di_attributes & DOOR_REVOKED) + (void) printf("\t\t\t REVOKED\n"); + if (my_door.di_attributes & DOOR_DESCRIPTOR) + (void) printf("\t\t\t DESCRIPTOR\n"); + if (my_door.di_attributes & DOOR_RELEASE) + (void) printf("\t\t\t RELEASE\n"); + if (my_door.di_attributes & DOOR_DELAY) + (void) printf("\t\t\t DELAY\n"); + (void) printf("\t\t id = %llx\n", my_door.di_uniquifier); +#endif /* DEBUG */ + if (my_door.di_attributes & DOOR_REVOKED) { +#ifdef DEBUG + (void) printf("my door revoked\n"); +#endif /* DEBUG */ + (void) close(doorfd); /* labeld exited .... */ + doorfd = -1; /* try and restart connection */ + goto try_again; + } + } + (void) mutex_unlock(&_door_lock); + + param.data_ptr = (char *)*dptr; + param.data_size = *adata; + param.desc_ptr = NULL; + param.desc_num = 0; + param.rbuf = (char *)*dptr; + param.rsize = *ndata; + + if (door_call(doorfd, ¶m) < 0) { + if (errno == EAGAIN && busy++ < 10) { + /* adjust backoff */ + if ((ts.tv_nsec *= 10) >= NANOSEC) { + ts.tv_sec++; + ts.tv_nsec = 100; + } + (void) __nanosleep(&ts, NULL); +#ifdef DEBUG + (void) printf("door_call failed EAGAIN # %d\n", busy); +#endif /* DEBUG */ + (void) mutex_lock(&_door_lock); + goto try_again; + } + perror("door call"); + return (NOSERVER); + } + + *adata = (int)param.data_size; + *ndata = (int)param.rsize; + /*LINTED*/ + *dptr = (labeld_data_t *)param.data_ptr; + + if (*adata == 0 || *dptr == NULL) { +#ifdef DEBUG + (void) printf("\tNo data returned, size = %lu, dptr = %p\n", + (unsigned long)*adata, (void *)*dptr); +#endif /* DEBUG */ + return (NOSERVER); + } +#ifdef DEBUG + (void) printf("call buf = %x, buf size = %d, call size = %d\n", + callptr, buf_size, return_size); + (void) printf("retn buf = %x, buf size = %d, retn size = %d\n", + *dptr, *ndata, *adata); + (void) printf("\treply status = %d\n", (*dptr)->param.aret.ret); +#endif /* DEBUG */ + return ((*dptr)->param.aret.ret); + +} /* __call_labeld */ diff --git a/usr/src/lib/libtsol/common/clnt.h b/usr/src/lib/libtsol/common/clnt.h new file mode 100644 index 0000000000..bf3845e02c --- /dev/null +++ b/usr/src/lib/libtsol/common/clnt.h @@ -0,0 +1,49 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _CLNT_H +#define _CLNT_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAXCOLOR 256 /* Max size of a static color string */ +#define MIN_CMW_LEN 8 /* minimum length of clipped CMW Label */ +#define MIN_SL_LEN 3 /* minimum length of clipped SL */ +#define MIN_IL_LEN 3 /* minimum length of clipped IL */ +#define MIN_CLR_LEN 3 /* minimum length of clipped Clearance */ + +#define ALLOC_CHUNK 1024 /* size of chunk for sb*tos allocs */ + +extern int alloc_string(char **, size_t, char); +extern void set_label_view(uint_t *, uint_t); +#ifdef __cplusplus +} +#endif + +#endif /* _CLNT_H */ diff --git a/usr/src/lib/libtsol/common/getlabel.c b/usr/src/lib/libtsol/common/getlabel.c new file mode 100644 index 0000000000..9cca4019f0 --- /dev/null +++ b/usr/src/lib/libtsol/common/getlabel.c @@ -0,0 +1,66 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * String to binary label translations. + */ + +#include <ctype.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> + +#include <tsol/label.h> +#include <sys/tsol/label_macro.h> + +#include <sys/syscall.h> +#include <sys/tsol/tsyscall.h> + +#include <sys/types.h> + +/* + * getlabel(3TSOL) - get file label + * + * This is the library interface to the system call. + */ + +int +getlabel(const char *path, bslabel_t *label) +{ + return (syscall(SYS_labelsys, TSOL_GETLABEL, path, label)); +} + +/* + * fgetlabel(3TSOL) - get file label + * + * This is the library interface to the system call. + */ +int +fgetlabel(int fd, bslabel_t *label) +{ + return (syscall(SYS_labelsys, TSOL_FGETLABEL, fd, label)); +} diff --git a/usr/src/lib/libtsol/common/getpathbylabel.c b/usr/src/lib/libtsol/common/getpathbylabel.c new file mode 100644 index 0000000000..0f8c5597d0 --- /dev/null +++ b/usr/src/lib/libtsol/common/getpathbylabel.c @@ -0,0 +1,503 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + + +/* + * Name: getpathbylabel.c + * + * Description: Returns the global zone pathname corresponding + * to the specified label. The pathname does + * not need to match an existing file system object. + * + */ +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <sys/types.h> +#include <tsol/label.h> +#include <stdlib.h> +#include <zone.h> +#include <sys/mntent.h> +#include <sys/mnttab.h> +#include <stdarg.h> + +/* + * This structure is used to chain mntent structures into a list + * and to cache stat information for each member of the list. + */ +struct mntlist { + struct mnttab *mntl_mnt; + struct mntlist *mntl_next; +}; + + +/* + * Return a pointer to the trailing suffix of full that follows the prefix + * given by pref. If pref isn't a prefix of full, return NULL. Apply + * pathname semantics to the prefix test, so that pref must match at a + * component boundary. + */ +static char * +pathsuffix(char *full, char *pref) +{ + int preflen; + + if (full == NULL || pref == NULL) + return (NULL); + + preflen = strlen(pref); + if (strncmp(pref, full, preflen) != 0) + return (NULL); + + /* + * pref is a substring of full. To be a subpath, it cannot cover a + * partial component of full. The last clause of the test handles the + * special case of the root. + */ + if (full[preflen] != '\0' && full[preflen] != '/' && preflen > 1) + return (NULL); + + if (preflen == 1 && full[0] == '/') + return (full); + else + return (full + preflen); +} + +/* + * Return zero iff the path named by sub is a leading subpath + * of the path named by full. + * + * Treat null paths as matching nothing. + */ +static int +subpath(char *full, char *sub) +{ + return (pathsuffix(full, sub) == NULL); +} + +static void +tsol_mnt_free(struct mnttab *mnt) +{ + if (mnt->mnt_special) + free(mnt->mnt_special); + if (mnt->mnt_mountp) + free(mnt->mnt_mountp); + if (mnt->mnt_fstype) + free(mnt->mnt_fstype); + if (mnt->mnt_mntopts) + free(mnt->mnt_mntopts); + free(mnt); +} + +static void +tsol_mlist_free(struct mntlist *mlist) +{ + struct mntlist *mlp; + + for (mlp = mlist; mlp; mlp = mlp->mntl_next) { + struct mnttab *mnt = mlp->mntl_mnt; + + if (mnt) + tsol_mnt_free(mnt); + free(mlp); + } +} + +static struct mnttab * +mntdup(struct mnttab *mnt) +{ + struct mnttab *new; + + new = (struct mnttab *)malloc(sizeof (*new)); + if (new == NULL) + return (NULL); + + new->mnt_special = NULL; + new->mnt_mountp = NULL; + new->mnt_fstype = NULL; + new->mnt_mntopts = NULL; + + new->mnt_special = strdup(mnt->mnt_special); + if (new->mnt_special == NULL) { + tsol_mnt_free(new); + return (NULL); + } + new->mnt_mountp = strdup(mnt->mnt_mountp); + if (new->mnt_mountp == NULL) { + tsol_mnt_free(new); + return (NULL); + } + new->mnt_fstype = strdup(mnt->mnt_fstype); + if (new->mnt_fstype == NULL) { + tsol_mnt_free(new); + return (NULL); + } + new->mnt_mntopts = strdup(mnt->mnt_mntopts); + if (new->mnt_mntopts == NULL) { + tsol_mnt_free(new); + return (NULL); + } + return (new); +} + +static struct mntlist * +tsol_mkmntlist(void) +{ + FILE *mounted; + struct mntlist *mntl; + struct mntlist *mntst = NULL; + struct mnttab mnt; + + if ((mounted = fopen(MNTTAB, "r")) == NULL) { + perror(MNTTAB); + return (NULL); + } + resetmnttab(mounted); + while (getmntent(mounted, &mnt) == NULL) { + mntl = (struct mntlist *)malloc(sizeof (*mntl)); + if (mntl == NULL) { + tsol_mlist_free(mntst); + mntst = NULL; + break; + } + mntl->mntl_mnt = mntdup((struct mnttab *)(&mnt)); + if (mntl->mntl_mnt == NULL) { + tsol_mlist_free(mntst); + mntst = NULL; + break; + } + mntl->mntl_next = mntst; + mntst = mntl; + } + (void) fclose(mounted); + return (mntst); +} + +/* + * This function attempts to convert local zone NFS mounted pathnames + * into equivalent global zone NFS mounted pathnames. At present + * it only works for automounted filesystems. It depends on the + * assumption that both the local and global zone automounters + * share the same nameservices. It also assumes that any automount + * map used by a local zone is available to the global zone automounter. + * + * The algorithm used consists of three phases. + * + * 1. The local zone's mnttab is searched to find the automount map + * with the closest matching mountpath. + * + * 2. The matching autmount map name is looked up in the global zone's + * mnttab to determine the path where it should be mounted in the + * global zone. + * + * 3. A pathname covered by an appropiate autofs trigger mount in + * the global zone is generated as the resolved pathname + * + * Among the things that can go wrong is that global zone doesn't have + * a matching automount map or the mount was not done via the automounter. + * Either of these cases return a NULL path. + */ +#define ZONE_OPT "zone=" +static int +getnfspathbyautofs(struct mntlist *mlist, zoneid_t zoneid, + struct mnttab *autofs_mnt, char *globalpath, char *zonepath, int global_len) +{ + struct mntlist *mlp; + char zonematch[ZONENAME_MAX + 20]; + char zonename[ZONENAME_MAX]; + int longestmatch; + struct mnttab *mountmatch; + + if (autofs_mnt) { + mountmatch = autofs_mnt; + longestmatch = strlen(mountmatch->mnt_mountp); + } else { + /* + * First we need to get the zonename to look for + */ + if (zone_getattr(zoneid, ZONE_ATTR_NAME, zonename, + ZONENAME_MAX) == -1) { + return (0); + } + + (void) strncpy(zonematch, ZONE_OPT, sizeof (zonematch)); + (void) strlcat(zonematch, zonename, sizeof (zonematch)); + + /* + * Find the best match for an automount map that + * corresponds to the local zone's pathname + */ + longestmatch = 0; + for (mlp = mlist; mlp; mlp = mlp->mntl_next) { + struct mnttab *mnt = mlp->mntl_mnt; + int len; + int matchfound; + char *token; + char *lasts; + char mntopts[MAXPATHLEN]; + + if (subpath(globalpath, mnt->mnt_mountp) != 0) + continue; + if (strcmp(mnt->mnt_fstype, MNTTYPE_AUTOFS)) + continue; + + matchfound = 0; + (void) strncpy(mntopts, mnt->mnt_mntopts, MAXPATHLEN); + if ((token = strtok_r(mntopts, ",", &lasts)) != NULL) { + if (strcmp(token, zonematch) == 0) { + matchfound = 1; + } else while ((token = strtok_r(NULL, ",", + &lasts)) != NULL) { + if (strcmp(token, zonematch) == 0) { + matchfound = 1; + break; + } + } + } + if (matchfound) { + len = strlen(mnt->mnt_mountp); + if (len > longestmatch) { + mountmatch = mnt; + longestmatch = len; + } + } + } + } + if (longestmatch == 0) { + return (0); + } else { + /* + * Now we may have found the corresponding autofs mount + * Try to find the matching global zone autofs entry + */ + + for (mlp = mlist; mlp; mlp = mlp->mntl_next) { + char p[MAXPATHLEN]; + size_t zp_len; + size_t mp_len; + + struct mnttab *mnt = mlp->mntl_mnt; + + if (strcmp(mountmatch->mnt_special, + mnt->mnt_special) != 0) + continue; + if (strcmp(mnt->mnt_fstype, MNTTYPE_AUTOFS)) + continue; + if (strstr(mnt->mnt_mntopts, ZONE_OPT) != NULL) + continue; + /* + * OK, we have a matching global zone automap + * so adjust the path for the global zone. + */ + zp_len = strlen(zonepath); + mp_len = strlen(mnt->mnt_mountp); + (void) strncpy(p, globalpath + zp_len, MAXPATHLEN); + /* + * If both global zone and zone-relative + * mountpoint match, just use the same pathname + */ + if (strncmp(mnt->mnt_mountp, p, mp_len) == 0) { + (void) strncpy(globalpath, p, global_len); + return (1); + } else { + (void) strncpy(p, globalpath, MAXPATHLEN); + (void) strncpy(globalpath, mnt->mnt_mountp, + global_len); + (void) strlcat(globalpath, + p + strlen(mountmatch->mnt_mountp), + global_len); + return (1); + } + } + return (0); + } +} + + /* + * Find the pathname for the entry in mlist that corresponds to the + * file named by path (i.e., that names a mount table entry for the + * file system in which path lies). + * + * Return 0 is there an error. + */ + static int + getglobalpath(const char *path, zoneid_t zoneid, struct mntlist *mlist, + char *globalpath) + { + struct mntlist *mlp; + char lofspath[MAXPATHLEN]; + char zonepath[MAXPATHLEN]; + int longestmatch; + struct mnttab *mountmatch; + + if (zoneid != GLOBAL_ZONEID) { + char *prefix; + + if ((prefix = getzonerootbyid(zoneid)) == NULL) { + return (0); + } + (void) strncpy(zonepath, prefix, MAXPATHLEN); + (void) strlcpy(globalpath, prefix, MAXPATHLEN); + (void) strlcat(globalpath, path, MAXPATHLEN); + free(prefix); + } else { + (void) strlcpy(globalpath, path, MAXPATHLEN); + } + + for (;;) { + longestmatch = 0; + for (mlp = mlist; mlp; mlp = mlp->mntl_next) { + struct mnttab *mnt = mlp->mntl_mnt; + int len; + + if (subpath(globalpath, mnt->mnt_mountp) != 0) + continue; + len = strlen(mnt->mnt_mountp); + if (len > longestmatch) { + mountmatch = mnt; + longestmatch = len; + } + } + /* + * Handle interesting mounts. + */ + if ((strcmp(mountmatch->mnt_fstype, MNTTYPE_NFS) == 0) || + (strcmp(mountmatch->mnt_fstype, MNTTYPE_AUTOFS) == 0)) { + if (zoneid > GLOBAL_ZONEID) { + struct mnttab *m = NULL; + + if (strcmp(mountmatch->mnt_fstype, + MNTTYPE_AUTOFS) == 0) + m = mountmatch; + if (getnfspathbyautofs(mlist, zoneid, m, + globalpath, zonepath, MAXPATHLEN) == 0) { + return (0); + } + } + break; + } else if (strcmp(mountmatch->mnt_fstype, MNTTYPE_LOFS) == 0) { + /* + * count up what's left + */ + int remainder; + + remainder = strlen(globalpath) - longestmatch; + if (remainder > 0) { + path = pathsuffix(globalpath, + mountmatch->mnt_mountp); + (void) strlcpy(lofspath, path, MAXPATHLEN); + } + (void) strlcpy(globalpath, mountmatch->mnt_special, + MAXPATHLEN); + if (remainder > 0) { + (void) strlcat(globalpath, lofspath, + MAXPATHLEN); + } + } else { + if ((zoneid > GLOBAL_ZONEID) && + (strncmp(path, "/home/", strlen("/home/")) == 0)) { + char zonename[ZONENAME_MAX]; + + /* + * If this is a cross-zone reference to + * a home directory, it must be corrected. + * We should only get here if the zone's + * automounter hasn't yet mounted its + * autofs trigger on /home. + * + * Since it is likely to do so in the + * future, we will assume that the global + * zone already has an equivalent autofs + * mount established. By convention, + * this should be mounted at the + * /zone/<zonename> + */ + + if (zone_getattr(zoneid, ZONE_ATTR_NAME, + zonename, ZONENAME_MAX) == -1) { + return (0); + } else { + (void) snprintf(globalpath, MAXPATHLEN, + "/zone/%s%s", zonename, path); + } + } + break; + } + } + return (1); +} + + +/* + * This function is only useful for global zone callers + * It uses the global zone mnttab to translate local zone pathnames + * into global zone pathnames. + */ +char * +getpathbylabel(const char *path_name, char *resolved_path, size_t bufsize, + const bslabel_t *sl) { + char ret_path[MAXPATHLEN]; /* pathname to return */ + zoneid_t zoneid; + struct mntlist *mlist; + + if (getzoneid() != GLOBAL_ZONEID) { + errno = EINVAL; + return (NULL); + } + + if (path_name[0] != '/') { /* need absolute pathname */ + errno = EINVAL; + return (NULL); + } + + if (resolved_path == NULL) { + errno = EINVAL; + return (NULL); + } + + if ((zoneid = getzoneidbylabel(sl)) == -1) + return (NULL); + + /* + * Construct the list of mounted file systems. + */ + + if ((mlist = tsol_mkmntlist()) == NULL) { + return (NULL); + } + if (getglobalpath(path_name, zoneid, mlist, ret_path) == 0) { + tsol_mlist_free(mlist); + return (NULL); + } + tsol_mlist_free(mlist); + if (strlen(ret_path) >= bufsize) { + errno = EFAULT; + return (NULL); + } + return (strcpy(resolved_path, ret_path)); +} /* end getpathbylabel() */ diff --git a/usr/src/lib/libtsol/common/getplabel.c b/usr/src/lib/libtsol/common/getplabel.c new file mode 100644 index 0000000000..49aeeb66fe --- /dev/null +++ b/usr/src/lib/libtsol/common/getplabel.c @@ -0,0 +1,59 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdlib.h> +#include <zone.h> +#include <tsol/label.h> +#include <sys/tsol/label_macro.h> +#include <sys/types.h> +#include <sys/zone.h> + +/* + * getplabel(2TSOL) - get process sensitivity label + */ + +int +getplabel(bslabel_t *label_p) +{ + zoneid_t zoneid; + + zoneid = (int)getzoneid(); + if (zoneid == GLOBAL_ZONEID) { + bslhigh(label_p); + } else { + bslabel_t *sl; + + sl = getzonelabelbyid(zoneid); + if (sl == NULL) { + return (-1); + } else { + *label_p = *sl; + free(sl); + } + } + return (0); +} diff --git a/usr/src/lib/libtsol/common/hextob.c b/usr/src/lib/libtsol/common/hextob.c new file mode 100644 index 0000000000..758969e688 --- /dev/null +++ b/usr/src/lib/libtsol/common/hextob.c @@ -0,0 +1,97 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * hextob.c - Hexadecimal string to binary label conversion. + * + * These routines convert canonical hexadecimal representations + * of internal labels into binary form. + * + */ + +#include <stdio.h> +#include <string.h> +#include <ctype.h> + +#include <tsol/label.h> +#include <sys/tsol/label_macro.h> + +/* + * htobsl - Convert a Hexadecimal label string to a Sensitivity Label. + * + * Entry s = Hexadecimal label string to be converted. + * + * Exit label = Sensitivity Label converted, if successful. + * Unchanged, if not successful. + * + * Returns 1, If successful. + * 0, Otherwise. + * + * Calls str_to_label, m_label_free. + */ + +int +htobsl(const char *s, m_label_t *label) +{ + m_label_t *l = NULL; + + if (str_to_label(s, &l, MAC_LABEL, L_NO_CORRECTION, NULL) == -1) { + m_label_free(l); + return (0); + } + *label = *l; + m_label_free(l); + return (1); +} + +/* + * htobclear - Convert a Hexadecimal label string to a Clearance. + * + * Entry s = Hexadecimal label string to be converted. + * + * Exit clearance = Clearnace converted, if successful. + * Unchanged, if not successful. + * + * Returns 1, If successful. + * 0, Otherwise. + * + * Calls str_to_label, m_label_free. + */ + +int +htobclear(const char *s, m_label_t *clearance) +{ + m_label_t *c = NULL; + + if (str_to_label(s, &c, USER_CLEAR, L_NO_CORRECTION, NULL) == -1) { + m_label_free(c); + return (0); + } + *clearance = *c; + m_label_free(c); + return (1); +} diff --git a/usr/src/lib/libtsol/common/label.h b/usr/src/lib/libtsol/common/label.h new file mode 100644 index 0000000000..6a5bfdc205 --- /dev/null +++ b/usr/src/lib/libtsol/common/label.h @@ -0,0 +1,242 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _TSOL_LABEL_H +#define _TSOL_LABEL_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/tsol/label.h> +#include <priv.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Procedural Interface Structure Definitions */ + +struct label_info { /* structure returned by label_info */ + short ilabel_len; /* max Information Label length */ + short slabel_len; /* max Sensitivity Label length */ + short clabel_len; /* max CMW Label length */ + short clear_len; /* max Clearance Label length */ + short vers_len; /* version string length */ + short header_len; /* max len of banner page header */ + short protect_as_len; /* max len of banner page protect as */ + short caveats_len; /* max len of banner page caveats */ + short channels_len; /* max len of banner page channels */ +}; + +typedef struct label_set_identifier { /* valid label set identifier */ + int type; /* type of the set */ + char *name; /* name of the set if needed */ +} set_id; + +struct name_fields { /* names for label builder fields */ + char *class_name; /* Classifications field name */ + char *comps_name; /* Compartments field name */ + char *marks_name; /* Markings field name */ +}; + +/* Label Set Identifier Types */ + +/* + * The accreditation ranges as specified in the label encodings file. + * The name parameter is ignored. + * + * System Accreditation Range is all valid labels plus Admin High and Low. + * + * User Accreditation Range is valid user labels as defined in the + * ACCREDITATION RANGE: section of the label encodings file. + */ + +#define SYSTEM_ACCREDITATION_RANGE 1 +#define USER_ACCREDITATION_RANGE 2 + + +/* System Call Interface Definitions */ + +extern int getlabel(const char *, m_label_t *); +extern int fgetlabel(int, m_label_t *); + +extern int getplabel(m_label_t *); +extern int setflabel(const char *, m_label_t *); +extern char *getpathbylabel(const char *, char *, size_t, + const m_label_t *sl); +extern m_label_t *getzonelabelbyid(zoneid_t); +extern m_label_t *getzonelabelbyname(const char *); +extern zoneid_t getzoneidbylabel(const m_label_t *); +extern char *getzonenamebylabel(const m_label_t *); +extern char *getzonerootbyid(zoneid_t); +extern char *getzonerootbyname(const char *); +extern char *getzonerootbylabel(const m_label_t *); +extern m_label_t *getlabelbypath(const char *); + + +/* Flag word values */ + +#define ALL_ENTRIES 0x00000000 +#define ACCESS_RELATED 0x00000001 +#define ACCESS_MASK 0x0000FFFF +#define ACCESS_SHIFT 0 + +#define LONG_WORDS 0x00010000 /* use long names */ +#define SHORT_WORDS 0x00020000 /* use short names if present */ +#define LONG_CLASSIFICATION 0x00040000 /* use long classification */ +#define SHORT_CLASSIFICATION 0x00080000 /* use short classification */ +#define NO_CLASSIFICATION 0x00100000 /* don't translate the class */ +#define VIEW_INTERNAL 0x00200000 /* don't promote/demote */ +#define VIEW_EXTERNAL 0x00400000 /* promote/demote label */ + +#define NEW_LABEL 0x00000001 /* create a full new label */ +#define NO_CORRECTION 0x00000002 /* don't correct label errors */ + /* implies NEW_LABEL */ + +#define CVT_DIM 0x01 /* display word dimmed */ +#define CVT_SET 0x02 /* display word currently set */ + +/* Procedure Interface Definitions available to user */ + +/* APIs shared with the kernel are in <sys/tsol/label.h */ + +extern m_label_t *blabel_alloc(void); +extern void blabel_free(m_label_t *); +extern size_t blabel_size(void); +extern char *bsltoh(const m_label_t *); +extern char *bcleartoh(const m_label_t *); + +extern char *bsltoh_r(const m_label_t *, char *); +extern char *bcleartoh_r(const m_label_t *, char *); +extern char *h_alloc(uint8_t); +extern void h_free(char *); + +extern int htobsl(const char *, m_label_t *); +extern int htobclear(const char *, m_label_t *); + +extern m_range_t *getuserrange(const char *); +extern m_range_t *getdevicerange(const char *); + +extern int set_effective_priv(priv_op_t, int, ...); +extern int set_inheritable_priv(priv_op_t, int, ...); +extern int set_permitted_priv(priv_op_t, int, ...); +extern int is_system_labeled(void); + +/* Procedures needed for multi-level printing */ + +extern int tsol_check_admin_auth(uid_t uid); + +/* APIs implemented via labeld */ + +extern int blinset(const m_label_t *, const set_id *); +extern int labelinfo(struct label_info *); +extern ssize_t labelvers(char **, size_t); +extern char *bltocolor(const m_label_t *); +extern char *bltocolor_r(const m_label_t *, size_t, char *); + +extern ssize_t bsltos(const m_label_t *, char **, size_t, int); +extern ssize_t bcleartos(const m_label_t *, char **, size_t, int); + + +extern char *sbsltos(const m_label_t *, size_t); +extern char *sbcleartos(const m_label_t *, size_t); + + +extern int stobsl(const char *, m_label_t *, int, int *); +extern int stobclear(const char *, m_label_t *, int, int *); +extern int bslvalid(const m_label_t *); +extern int bclearvalid(const m_label_t *); + +/* Manifest human readable label names */ + +#define ADMIN_LOW "ADMIN_LOW" +#define ADMIN_HIGH "ADMIN_HIGH" + +/* DIA label conversion and parsing */ + +/* Conversion types */ + +typedef enum _m_label_str { + M_LABEL = 1, /* process or user clearance */ + M_INTERNAL = 2, /* internal form for use in public databases */ + M_COLOR = 3, /* process label color */ + PRINTER_TOP_BOTTOM = 4, /* DIA banner page top/bottom */ + PRINTER_LABEL = 5, /* DIA banner page label */ + PRINTER_CAVEATS = 6, /* DIA banner page caveats */ + PRINTER_CHANNELS = 7 /* DIA banner page handling channels */ +} m_label_str_t; + +/* Flags for conversion, not all flags apply to all types */ +#define DEF_NAMES 0x1 +#define SHORT_NAMES 0x3 /* short names are prefered where defined */ +#define LONG_NAMES 0x4 /* long names are prefered where defined */ + +extern int label_to_str(const m_label_t *, char **, const m_label_str_t, + uint_t); + +/* Parsing types */ +typedef enum _m_label_type { + MAC_LABEL = 1, /* process or object label */ + USER_CLEAR = 2 /* user's clearance (LUB) */ +} m_label_type_t; + +/* Flags for parsing */ + +#define L_DEFAULT 0x0 +#define L_MODIFY_EXISTING 0x1 /* start parsing with existing label */ +#define L_NO_CORRECTION 0x2 /* must be correct by l_e rules */ + +/* EINVAL sub codes */ + +#define M_BAD_STRING -3 /* DIA L_BAD_LABEL */ + /* bad requested label type, bad previous label type */ +#define M_BAD_LABEL -2 /* DIA L_BAD_CLASSIFICATION, */ + +extern int str_to_label(const char *, m_label_t **, const m_label_type_t, + uint_t, int *); + +extern m_label_t *m_label_alloc(const m_label_type_t); + +extern int m_label_dup(m_label_t **, const m_label_t *); + +extern void m_label_free(m_label_t *); + +/* Contract Private interfaces with the label builder GUIs */ + +extern int bslcvtfull(const m_label_t *, const m_range_t *, int, + char **, char **[], char **[], char *[], int *, int *); +extern int bslcvt(const m_label_t *, int, char **, char *[]); +extern int bclearcvtfull(const m_label_t *, const m_range_t *, int, + char **, char **[], char **[], char *[], int *, int *); +extern int bclearcvt(const m_label_t *, int, char **, char *[]); + +extern int labelfields(struct name_fields *); +extern int userdefs(m_label_t *, m_label_t *); +extern int zonecopy(m_label_t *, char *, char *, char *, int); + +#ifdef __cplusplus +} +#endif + +#endif /* !_TSOL_LABEL_H */ diff --git a/usr/src/lib/libtsol/common/labeld.h b/usr/src/lib/libtsol/common/labeld.h new file mode 100644 index 0000000000..aa95982998 --- /dev/null +++ b/usr/src/lib/libtsol/common/labeld.h @@ -0,0 +1,473 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _LABELD_H +#define _LABELD_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/types.h> +#include <tsol/label.h> +#include <sys/tsol/label_macro.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Definitions for the call parameters for the door-based label + * translation service. + */ + +#define BUFSIZE 4096 + +#define DOOR_PATH "/var/tsol/doors/" +#define DOOR_NAME "labeld" +#define COOKIE (void *)0x6c616264 /* "labd" */ + +/* Op codes */ + +/* Labeld Commands */ + +#define LABELDNULL 1 + +/* Miscellaneous */ + +#define BLINSET 10 +#define BSLVALID 11 +#define BILVALID 12 +#define BCLEARVALID 13 +#define LABELINFO 14 +#define LABELVERS 15 +#define BLTOCOLOR 16 + +/* Binary to String Label Translation */ + +#define BSLTOS 23 +#define BCLEARTOS 25 + +/* String to Binary Label Translation */ + +#define STOBSL 31 +#define STOBCLEAR 33 + +/* + * Dimming List Routines + * Contract private for label builders + */ + +#define BSLCVT 40 +#define BCLEARCVT 42 +#define LABELFIELDS 43 +#define UDEFS 44 + +#define GETFLABEL 45 +#define SETFLABEL 46 +#define ZCOPY 47 + +/* NEW LABELS */ +/* DIA printer banner labels */ + +#define PR_CAVEATS 101 +#define PR_CHANNELS 102 +#define PR_LABEL 103 +#define PR_TOP 104 + +/* DIA label to string */ + +#define LTOS 105 + +/* DIA string to label */ + +#define STOL 106 + +/* Structures */ + +typedef uint_t bufp_t; /* offset into buf[] in/out string buffer */ + +/* Null call */ + +typedef struct { + int null; +} null_call_t; + +typedef struct { + int null; +} null_ret_t; + +/* Miscellaneous interfaces */ + +typedef struct { + bslabel_t label; + int type; +} inset_call_t; + +typedef struct { + int inset; +} inset_ret_t; + +typedef struct { + bslabel_t label; +} slvalid_call_t; + +typedef struct { + int valid; +} slvalid_ret_t; + +typedef struct { + bclear_t clear; +} clrvalid_call_t; + +typedef struct { + int valid; +} clrvalid_ret_t; + +typedef struct { + int null; +} info_call_t; + +typedef struct { + struct label_info info; +} info_ret_t; + +typedef struct { + int null; +} vers_call_t; + +typedef struct { + char vers[BUFSIZE]; +} vers_ret_t; + +typedef struct { + blevel_t label; +} color_call_t; + +typedef struct { + char color[BUFSIZE]; +} color_ret_t; + +/* Binary Label to String interfaces */ + +typedef struct { + bslabel_t label; + uint_t flags; +} bsltos_call_t; + +typedef struct { + char slabel[BUFSIZE]; +} bsltos_ret_t; + +typedef struct { + bclear_t clear; + uint_t flags; +} bcleartos_call_t; + +typedef struct { + char cslabel[BUFSIZE]; +} bcleartos_ret_t; + +/* String to Binary Label interfaces */ + +typedef struct { + bslabel_t label; + uint_t flags; + char string[BUFSIZE]; +} stobsl_call_t; + +typedef struct { + bslabel_t label; +} stobsl_ret_t; + +typedef struct { + bclear_t clear; + uint_t flags; + char string[BUFSIZE]; +} stobclear_call_t; + +typedef struct { + bclear_t clear; +} stobclear_ret_t; + +/* + * The following Dimming List and Miscellaneous interfaces + * implement contract private interfaces for the label builder + * interfaces. + */ + +/* Dimming List interfaces */ + +typedef struct { + bslabel_t label; + brange_t bounds; + uint_t flags; +} bslcvt_call_t; + +typedef struct { + bufp_t string; + bufp_t dim; + bufp_t lwords; + bufp_t swords; + size_t d_len; + size_t l_len; + size_t s_len; + int first_comp; + int first_mark; + char buf[BUFSIZE]; +} cvt_ret_t; + +typedef cvt_ret_t bslcvt_ret_t; + +typedef struct { + bclear_t clear; + brange_t bounds; + uint_t flags; +} bclearcvt_call_t; + +typedef cvt_ret_t bclearcvt_ret_t; + +/* Miscellaneous interfaces */ + +typedef struct { + int null; +} fields_call_t; + +typedef struct { + bufp_t classi; + bufp_t compsi; + bufp_t marksi; + char buf[BUFSIZE]; +} fields_ret_t; + +typedef struct { + int null; +} udefs_call_t; + +typedef struct { + bslabel_t sl; + bclear_t clear; +} udefs_ret_t; + +typedef struct { + bslabel_t sl; + char pathname[BUFSIZE]; +} setfbcl_call_t; + +typedef struct { + int status; +} setfbcl_ret_t; + +typedef struct { + bslabel_t src_win_sl; + int transfer_mode; + bufp_t remote_dir; + bufp_t filename; + bufp_t local_dir; + bufp_t display; + char buf[BUFSIZE]; +} zcopy_call_t; + +typedef struct { + int status; +} zcopy_ret_t; + +typedef struct { + m_label_t label; + uint_t flags; +} pr_call_t; + +typedef struct { + char buf[BUFSIZE]; +} pr_ret_t; + +typedef struct { + m_label_t label; + uint_t flags; +} ls_call_t; + +typedef struct { + char buf[BUFSIZE]; +} ls_ret_t; + +typedef struct { + m_label_t label; + uint_t flags; + char string[BUFSIZE]; +} sl_call_t; + +typedef struct { + m_label_t label; +} sl_ret_t; + +/* Labeld operation call structure */ + +typedef struct { + uint_t op; + union { + null_call_t null_arg; + + inset_call_t inset_arg; + slvalid_call_t slvalid_arg; + clrvalid_call_t clrvalid_arg; + info_call_t info_arg; + vers_call_t vers_arg; + color_call_t color_arg; + + bsltos_call_t bsltos_arg; + bcleartos_call_t bcleartos_arg; + + stobsl_call_t stobsl_arg; + stobclear_call_t stobclear_arg; + + bslcvt_call_t bslcvt_arg; + bclearcvt_call_t bclearcvt_arg; + fields_call_t fields_arg; + udefs_call_t udefs_arg; + setfbcl_call_t setfbcl_arg; + zcopy_call_t zcopy_arg; + pr_call_t pr_arg; + ls_call_t ls_arg; + sl_call_t sl_arg; + } cargs; +} labeld_call_t; + +/* Labeld operation return structure */ + +typedef struct { + int ret; /* labeld return codes */ + int err; /* function error codes */ + union { + null_ret_t null_ret; + + inset_ret_t inset_ret; + slvalid_ret_t slvalid_ret; + clrvalid_ret_t clrvalid_ret; + info_ret_t info_ret; + vers_ret_t vers_ret; + color_ret_t color_ret; + + bsltos_ret_t bsltos_ret; + bcleartos_ret_t bcleartos_ret; + + stobsl_ret_t stobsl_ret; + stobclear_ret_t stobclear_ret; + + bslcvt_ret_t bslcvt_ret; + bclearcvt_ret_t bclearcvt_ret; + fields_ret_t fields_ret; + udefs_ret_t udefs_ret; + setfbcl_ret_t setfbcl_ret; + zcopy_ret_t zcopy_ret; + pr_ret_t pr_ret; + ls_ret_t ls_ret; + sl_ret_t sl_ret; + } rvals; +} labeld_ret_t; + +/* Labeld call/return structure */ + +typedef struct { + union { + labeld_call_t acall; + labeld_ret_t aret; + } param; +} labeld_data_t; + +#define callop param.acall.op +#define retret param.aret.ret +#define reterr param.aret.err + +#define CALL_SIZE(type, buf) (size_t)(sizeof (type) + sizeof (int) + (buf)) +#define RET_SIZE(type, buf) (size_t)(sizeof (type) + 2*sizeof (int) + (buf)) + +/* Labeld common client call function */ + +int +__call_labeld(labeld_data_t **dptr, size_t *ndata, size_t *adata); + +/* Return Codes */ + +#define SUCCESS 1 /* Call OK */ +#define NOTFOUND -1 /* Function not found */ +#define SERVERFAULT -2 /* Internal labeld error */ +#define NOSERVER -3 /* No server thread available, try later */ + +/* Flag Translation Values */ + +#define L_NEW_LABEL 0x10000000 + +/* GFI FLAGS */ + +#define GFI_FLAG_MASK 0x0000FFFF +#define GFI_ACCESS_RELATED 0x00000001 + +/* binary to ASCII */ + +#define LABELS_NO_CLASS 0x00010000 +#define LABELS_SHORT_CLASS 0x00020000 +#define LABELS_SHORT_WORDS 0x00040000 + +/* Label view */ + +#define LABELS_VIEW_INTERNAL 0x00100000 +#define LABELS_VIEW_EXTERNAL 0x00200000 + +/* Dimming list (convert -- b*cvt* ) */ + +#define LABELS_FULL_CONVERT 0x00010000 + +/* ASCII to binary */ + +#define LABELS_NEW_LABEL 0x00010000 +#define LABELS_FULL_PARSE 0x00020000 +#define LABELS_ONLY_INFO_LABEL 0x00040000 + +#define MOVE_FILE 0 +#define COPY_FILE 1 +#define LINK_FILE 2 + +#define PIPEMSG_FILEOP_ERROR 1 +#define PIPEMSG_EXIST_ERROR 2 +#define PIPEMSG_DONE 7 +#define PIPEMSG_PATH_ERROR 20 +#define PIPEMSG_ZONE_ERROR 21 +#define PIPEMSG_LABEL_ERROR 22 +#define PIPEMSG_READ_ERROR 23 +#define PIPEMSG_READONLY_ERROR 24 +#define PIPEMSG_WRITE_ERROR 25 +#define PIPEMSG_CREATE_ERROR 26 +#define PIPEMSG_DELETE_ERROR 27 +#define PIPEMSG_CANCEL 101 +#define PIPEMSG_PROCEED 102 +#define PIPEMSG_MERGE 103 +#define PIPEMSG_REPLACE_BUFFER 104 +#define PIPEMSG_RENAME_BUFFER 105 +#define PIPEMSG_MULTI_PROCEED 106 +#define PIPEMSG_RENAME_FILE 107 + +#ifdef __cplusplus +} +#endif + +#endif /* _LABELD_H */ diff --git a/usr/src/lib/libtsol/common/llib-ltsol b/usr/src/lib/libtsol/common/llib-ltsol new file mode 100644 index 0000000000..1d4acc5a3a --- /dev/null +++ b/usr/src/lib/libtsol/common/llib-ltsol @@ -0,0 +1,35 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* LINTLIBRARY */ +/* PROTOLIB1 */ + +#include <tsol/label.h> +#include <sys/tsol/label.h> +#include <sys/tsol/priv.h> +#include <sys/tsol/label_macro.h> diff --git a/usr/src/lib/libtsol/common/ltos.c b/usr/src/lib/libtsol/common/ltos.c new file mode 100644 index 0000000000..16feabbf41 --- /dev/null +++ b/usr/src/lib/libtsol/common/ltos.c @@ -0,0 +1,283 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <errno.h> +#include <stdlib.h> +#include <string.h> + +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/tsol/label_macro.h> + +#include <tsol/label.h> + +#include "clnt.h" +#include "labeld.h" + +static _mac_label_impl_t low; +static _mac_label_impl_t high; +static int inited = 0; + +/* 0x + Classification + '-' + ll + '-' + Compartments + end of string */ +#define _HEX_SIZE 2+(sizeof (Classification_t)*2)+4+\ + (sizeof (Compartments_t)*2)+1 + +/* 0x + Classification + '-' + ll + '-' + end of string */ +#define _MIN_HEX (2 + (sizeof (Classification_t)*2) + 4 + 1) + +static char digits[] = "0123456789abcdef"; + +#define HEX(h, i, l, s) \ + for (; i < s; /* */) {\ + h[i++] = digits[(unsigned int)(*l >> 4)];\ + h[i++] = digits[(unsigned int)(*l++&0xF)]; } + +static int +__hex(char **s, const m_label_t *l) +{ + char *hex; + int i = 0; + uchar_t *hl; + int hex_len; + uchar_t *len; + + hl = (uchar_t *)&(((_mac_label_impl_t *)l)->_c_len); + len = hl; + + if (*len == 0) { + /* old binary label */ + hex_len = _HEX_SIZE; + } else { + hex_len = _MIN_HEX + (*len * sizeof (uint32_t) * 2); + } + + if ((hex = malloc(hex_len)) == NULL) { + return (-1); + } + + /* header */ + + hex[i++] = '0'; + hex[i++] = 'x'; + + /* classification */ + + hl++; /* start at classification */ + HEX(hex, i, hl, 6); + + /* Add compartments length */ + hex[i++] = '-'; + HEX(hex, i, len, 9); + hex[i++] = '-'; + + /* compartments */ + HEX(hex, i, hl, hex_len-1); + hex[i] = '\0'; + + /* truncate trailing zeros */ + + while (hex[i-1] == '0' && hex[i-2] == '0') { + i -= 2; + } + hex[i] = '\0'; + + if ((*s = strdup(hex)) == NULL) { + free(hex); + return (-1); + } + + free(hex); + return (0); + +} + +/* + * label_to_str -- convert a label to the requested type of string. + * + * Entry l = label to convert; + * t = type of conversion; + * f = flags for conversion type; + * + * Exit *s = allocated converted string; + * Caller must call free() to free. + * + * Returns 0, success. + * -1, error, errno set; *s = NULL. + * + * Calls labeld + */ + +int +label_to_str(const m_label_t *l, char **s, const m_label_str_t t, uint_t f) +{ + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize; + int err; + + if (inited == 0) { + inited = 1; + _BSLLOW(&low); + _BSLHIGH(&high); + } + +#define lscall callp->param.acall.cargs.ls_arg +#define lsret callp->param.aret.rvals.ls_ret + switch (t) { + case M_LABEL: + call.callop = LTOS; + lscall.label = *l; + lscall.flags = f; + datasize = CALL_SIZE(ls_call_t, 0); + if ((err = __call_labeld(&callp, &bufsize, &datasize)) == + SUCCESS) { + if (callp->reterr != 0) { + errno = EINVAL; + *s = NULL; + return (-1); + } + if ((*s = strdup(lsret.buf)) == NULL) { + return (-1); + } + if (callp != &call) { + /* release returned buffer */ + (void) munmap((void *)callp, bufsize); + } + return (0); + } + switch (err) { + case NOSERVER: + /* server not present */ + /* special case admin_low and admin_high */ + + if (_MEQUAL(&low, (_mac_label_impl_t *)l)) { + if ((*s = strdup(ADMIN_LOW)) == NULL) { + return (-1); + } + return (0); + } else if (_MEQUAL(&high, (_mac_label_impl_t *)l)) { + if ((*s = strdup(ADMIN_HIGH)) == NULL) { + return (-1); + } + return (0); + } + errno = ENOTSUP; + break; + default: + errno = EINVAL; + break; + } + *s = NULL; + return (-1); +#undef lscall +#undef lsret + + case M_INTERNAL: { + if (!(_MTYPE(l, SUN_MAC_ID) || + _MTYPE(l, SUN_UCLR_ID))) { + errno = EINVAL; + return (-1); + } + if (_MEQUAL(&low, (_mac_label_impl_t *)l)) { + if ((*s = strdup(ADMIN_LOW)) == NULL) { + return (-1); + } + return (0); + } + if (_MEQUAL(&high, (_mac_label_impl_t *)l)) { + if ((*s = strdup(ADMIN_HIGH)) == NULL) { + return (-1); + } + return (0); + } + + return (__hex(s, l)); + } + +#define ccall callp->param.acall.cargs.color_arg +#define cret callp->param.aret.rvals.color_ret + case M_COLOR: + datasize = CALL_SIZE(color_call_t, 0); + call.callop = BLTOCOLOR; + ccall.label = *l; + + if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) { + errno = ENOTSUP; + *s = NULL; + return (-1); + } if (callp->reterr != 0) { + errno = EINVAL; + *s = NULL; + return (-1); + } + if ((*s = strdup(cret.color)) == NULL) { + return (-1); + } + return (0); +#undef ccall +#undef cret + +#define prcall callp->param.acall.cargs.pr_arg +#define prret callp->param.aret.rvals.pr_ret + case PRINTER_TOP_BOTTOM: + call.callop = PR_TOP; + break; + case PRINTER_LABEL: + call.callop = PR_LABEL; + break; + case PRINTER_CAVEATS: + call.callop = PR_CAVEATS; + break; + case PRINTER_CHANNELS: + call.callop = PR_CHANNELS; + break; + default: + errno = EINVAL; + *s = NULL; + return (-1); + } + /* do the common printer calls */ + datasize = CALL_SIZE(pr_call_t, 0); + prcall.label = *l; + prcall.flags = f; + if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) { + errno = ENOTSUP; + *s = NULL; + return (-1); + } if (callp->reterr != 0) { + errno = EINVAL; + *s = NULL; + return (-1); + } + if ((*s = strdup(prret.buf)) == NULL) { + return (-1); + } + return (0); +#undef prcall +#undef prret +} diff --git a/usr/src/lib/libtsol/common/misc.c b/usr/src/lib/libtsol/common/misc.c new file mode 100644 index 0000000000..14113f22be --- /dev/null +++ b/usr/src/lib/libtsol/common/misc.c @@ -0,0 +1,476 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + + +/* + * Miscellaneous user interfaces to trusted label functions. + * + */ + + +#include <ctype.h> +#include <stdlib.h> +#include <strings.h> + +#include <sys/mman.h> + +#include <tsol/label.h> + +#include "labeld.h" +#include "clnt.h" +#include <sys/tsol/label_macro.h> +#include <secdb.h> +#include <user_attr.h> + +static bslabel_t slow, shigh; /* static Admin Low and High SLs */ +static bclear_t clow, chigh; /* static Admin Low and High CLRs */ + +static char color[MAXCOLOR]; + + +#define incall callp->param.acall.cargs.inset_arg +#define inret callp->param.aret.rvals.inset_ret +/* + * blinset - Check in a label set. + * + * Entry label = Sensitivity Label to check. + * id = Label set identifier of set to check. + * + * Exit None. + * + * Returns -1, If label set unavailable, or server failure. + * 0, If label not in label set. + * 1, If label is in the label set. + * + * Calls __call_labeld(BLINSET), BLTYPE, BSLLOW, BSLHIGH. + * + * Uses slow, shigh. + */ + +int +blinset(const bslabel_t *label, const set_id *id) +{ + if (id->type == SYSTEM_ACCREDITATION_RANGE) { + if (!BLTYPE(&slow, SUN_SL_ID)) { + /* initialize static labels. */ + + BSLLOW(&slow); + BSLHIGH(&shigh); + } + + if (BLTYPE(label, SUN_SL_ID) && + (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh))) + + return (1); + } + if (id->type == USER_ACCREDITATION_RANGE || + id->type == SYSTEM_ACCREDITATION_RANGE) { + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize = CALL_SIZE(inset_call_t, 0); + + call.callop = BLINSET; + incall.label = *label; + incall.type = id->type; + + if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) { + /* process error */ + + return (-1); + } + return (inret.inset); + } else { + /* + * Only System and User Accreditation Ranges presently + * implemented. + */ + return (-1); + } +} +#undef incall +#undef inret + +#define slvcall callp->param.acall.cargs.slvalid_arg +#define slvret callp->param.aret.rvals.slvalid_ret +/* + * bslvalid - Check Sensitivity Label for validity. + * + * Entry label = Sensitivity Label to check. + * + * Exit None. + * + * Returns -1, If unable to access label encodings file, or server failure. + * 0, If label not valid. + * 1, If label is valid. + * + * Calls __call_labeld(BSLVALID), BLTYPE, BSLLOW, BSLHIGH. + * + * Uses slow, shigh. + * + */ + +int +bslvalid(const bslabel_t *label) +{ + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize = CALL_SIZE(slvalid_call_t, 0); + + if (!BLTYPE(&slow, SUN_SL_ID)) { + /* initialize static labels. */ + + BSLLOW(&slow); + BSLHIGH(&shigh); + } + + if (BLTYPE(label, SUN_SL_ID) && + (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh))) { + + return (1); + } + + call.callop = BSLVALID; + slvcall.label = *label; + + if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) { + /* process error */ + + return (-1); + } + return (slvret.valid); +} +#undef slvcall +#undef slvret + +#define clrvcall callp->param.acall.cargs.clrvalid_arg +#define clrvret callp->param.aret.rvals.clrvalid_ret +/* + * bclearvalid - Check Clearance for validity. + * + * Entry clearance = Clearance to check. + * + * Exit None. + * + * Returns -1, If unable to access label encodings file, or server failure. + * 0, If label not valid. + * 1, If label is valid. + * + * Calls __call_labeld(BCLEARVALID), BLTYPE, BCLEARLOW, BCLEARHIGH. + * + * Uses clow, chigh. + * + */ + +int +bclearvalid(const bclear_t *clearance) +{ + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize = CALL_SIZE(clrvalid_call_t, 0); + + if (!BLTYPE(&clow, SUN_CLR_ID)) { + /* initialize static labels. */ + + BCLEARLOW(&clow); + BCLEARHIGH(&chigh); + } + + if (BLTYPE(clearance, SUN_CLR_ID) && + (BLEQUAL(clearance, &clow) || BLEQUAL(clearance, &chigh))) { + + return (1); + } + + call.callop = BCLEARVALID; + clrvcall.clear = *clearance; + + if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) { + /* process error */ + + return (-1); + } + return (clrvret.valid); +} +#undef clrvcall +#undef clrvret + +#define inforet callp->param.aret.rvals.info_ret +/* + * labelinfo - Get information about the label encodings file. + * + * Entry info = Address of label_info structure to update. + * + * Exit info = Updated. + * + * Returns -1, If unable to access label encodings file, or server failure. + * 1, If successful. + * + * Calls __call_labeld(LABELINFO). + */ + +int +labelinfo(struct label_info *info) +{ + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize = CALL_SIZE(info_call_t, 0); + int rval; + + call.callop = LABELINFO; + + if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) { + /* process error */ + + return (-1); + } + *info = inforet.info; + return (rval); +} +#undef inforet + +#define lvret callp->param.aret.rvals.vers_ret +/* + * labelvers - Get version string of the label encodings file. + * + * Entry version = Address of string pointer to return. + * len = Length of string if pre-allocated. + * + * Exit version = Updated. + * + * Returns -1, If unable to access label encodings file, or server failure. + * 0, If unable to allocate version string, + * or pre-allocated version string to short + * (and **version = '\0'). + * length (including null) of version string, If successful. + * + * Calls __call_labeld(LABELVERS) + * malloc, strlen. + */ + +ssize_t +labelvers(char **version, size_t len) +{ + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize = CALL_SIZE(vers_call_t, 0); + size_t ver_len; + + call.callop = LABELVERS; + + if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) { + + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (-1); + } + + /* unpack length */ + + ver_len = strlen(lvret.vers) + 1; + if (*version == NULL) { + if ((*version = malloc(ver_len)) == NULL) { + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (0); + } + } else if (ver_len > len) { + **version = '\0'; + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (0); + } + (void) strcpy(*version, lvret.vers); + + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (ver_len); +} /* labelvers */ +#undef lvret + +#define ccall callp->param.acall.cargs.color_arg +#define cret callp->param.aret.rvals.color_ret +/* + * bltocolor - get ASCII color name of label. + * + * Entry label = Sensitivity Level of color to get. + * size = Size of the color_name array. + * color_name = Storage for ASCII color name string to be returned. + * + * Exit None. + * + * Returns NULL, If error (label encodings file not accessible, + * invalid label, no color for this label). + * Address of color_name parameter containing ASCII color name + * defined for the label. + * + * Calls __call_labeld(BLTOCOLOR), strlen. + */ + +char * +bltocolor_r(const blevel_t *label, size_t size, char *color_name) +{ + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize = CALL_SIZE(color_call_t, 0); + char *colorp; + + call.callop = BLTOCOLOR; + ccall.label = *label; + + if ((__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) || + (callp->reterr != 0) || + (strlen(cret.color) >= size)) { + + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (NULL); + } + + colorp = strcpy(color_name, cret.color); + + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (colorp); +} /* bltocolor_r */ +#undef ccall +#undef cret + +/* + * bltocolor - get ASCII color name of label. + * + * Entry label = Sensitivity Level of color to get. + * + * Exit None. + * + * Returns NULL, If error (label encodings file not accessible, + * invalid label, no color for this label). + * Address of statically allocated string containing ASCII + * color name defined for the classification contained + * in label. + * + * Uses color. + * + * Calls bltocolor_r. + */ + +char * +bltocolor(const blevel_t *label) +{ + return (bltocolor_r(label, sizeof (color), color)); +} /* bltocolor */ + +blevel_t * +blabel_alloc(void) +{ + return (m_label_alloc(MAC_LABEL)); +} + +void +blabel_free(blevel_t *label_p) +{ + free(label_p); +} + +size_t +blabel_size(void) +{ + return (sizeof (blevel_t)); +} + +/* + * getuserrange - get label range for user + * + * Entry username of user + * + * Exit None. + * + * Returns NULL, If memory allocation failure or userdefs failure. + * otherwise returns the allocates m_range_t with the + * user's min and max labels set. + */ + +m_range_t * +getuserrange(const char *username) +{ + char *kv_str = NULL; + userattr_t *userp = NULL; + m_range_t *range; + int err; + + /* + * Get some memory + */ + + if ((range = malloc(sizeof (m_range_t))) == NULL) { + return (NULL); + } + if ((range->lower_bound = m_label_alloc(MAC_LABEL)) == NULL) { + free(range); + return (NULL); + } + if ((range->upper_bound = m_label_alloc(USER_CLEAR)) == NULL) { + m_label_free(range->lower_bound); + free(range); + return (NULL); + } + /* + * Since user_attr entries are optional, start with + * the system default values + */ + if ((userdefs(range->lower_bound, range->upper_bound)) == -1) { + m_label_free(range->lower_bound); + m_label_free(range->upper_bound); + free(range); + return (NULL); + } + /* + * If the user has an explicit min_label or clearance, + * then use it instead. + */ + if ((userp = getusernam(username)) == NULL) { + return (range); + } + if ((kv_str = kva_match(userp->attr, USERATTR_MINLABEL)) != NULL) + (void) stobsl(kv_str, range->lower_bound, NO_CORRECTION, &err); + if ((kv_str = kva_match(userp->attr, USERATTR_CLEARANCE)) != NULL) + (void) stobclear(kv_str, range->upper_bound, NO_CORRECTION, + &err); + free_userattr(userp); + return (range); +} diff --git a/usr/src/lib/libtsol/common/private.c b/usr/src/lib/libtsol/common/private.c new file mode 100644 index 0000000000..3052624f1c --- /dev/null +++ b/usr/src/lib/libtsol/common/private.c @@ -0,0 +1,660 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Label library contract private interfaces. + * + * Binary labels to String labels with dimming word lists. + * Dimming word list titles. + * Default user labels. + */ + +#include <locale.h> +#include <stdlib.h> +#include <stdio.h> +#include <strings.h> + +#include <sys/mman.h> + +#include <tsol/label.h> + +#include "clnt.h" +#include "labeld.h" + +/* + * cvt memory: + * + * cvt: char *long_words[display_size]; Pointers to long words + * char *short_words[display_size]; Pointers to short words + * dim: char display[display_size]; Dim | Set + * + * strings associated with long and short words. + * + */ + +/* + * Sensitivity Label words. + */ + +static char *slcvt = NULL; +static int slcvtsize = 0; +static char *sldim; + +static char *slstring = NULL; +static int slstringsize = 0; +static brange_t sbounds; + +/* + * Clearance words. + */ + +static char *clrcvt = NULL; +static int clrcvtsize = 0; +static char *clrdim; + +static char *clrstring = NULL; +static int clrstringsize = 0; +static brange_t cbounds; + +static +int +alloc_words(char **words, const size_t size) +{ + if (*words == NULL) { + if ((*words = malloc(size)) == NULL) + return (0); + } else { + if ((*words = realloc(*words, size)) == NULL) { + return (0); + } + } + return (1); +} + +/* + * build_strings - Build the static strings and dimming list for a + * converted label. + * + * Entry new_string = Newly converted string. + * new_words_size = Size of words associated with newly converted + * label. + * number_of_words = Number of words associated with newly + * converted label. + * full = 1, if static words lists to be updated. + * 0, if only string and dimming list to be updated. + * + * Exit static_string_size = Updated if needed. + * static_string = Updated to new label string. + * static_words_size = Updated if needed. + * static_words = Updated to new words list, if needed. + * static_dimming = Updated to new dimming state. + * long_words = Updated to new long words pointers, if needed. + * short_words = Updated to new short words pointers, if needed. + * + * + * Returns 0, If unable to allocate memory. + * 1, If successful. + * + * Calls alloc_string, alloc_words, memcpy, strcpy, strlen. + */ + +static +int +build_strings(int *static_string_size, char **static_string, char *new_string, + int *static_words_size, int new_words_size, char **static_words, + char **static_dimming, int number_of_words, char *long_words, + char *short_words, char *dimming_list, int full) +{ + char **l; + char **s; + char *w; + char *l_w = long_words; + char *s_w = short_words; + int i; + int len; + int newsize; + + if (*static_string_size == 0) { /* Allocate string memory. */ + if ((*static_string_size = alloc_string(static_string, + *static_string_size, 'C')) == 0) + /* can't get string memory for string */ + return (0); + } + +again: + if (*static_string_size < (int)strlen(new_string)+1) { + /* need longer string */ + if ((newsize = alloc_string(static_string, *static_string_size, + 'C')) == 0) + /* can't get more string memory */ + return (0); + + *static_string_size += newsize; + goto again; + } + bcopy(new_string, *static_string, strlen(new_string) + 1); + + if (full) { + if (*static_words_size < new_words_size && + !alloc_words(static_words, new_words_size)) { + /* can't get more words memory */ + return (0); + } else { + *static_words_size = new_words_size; + } + /*LINTED*/ + l = (char **)*static_words; + s = l + number_of_words; + *static_dimming = (char *)(s + number_of_words); + w = *static_dimming + number_of_words; + for (i = 0; i < number_of_words; i++) { + *l = w; + (void) strcpy(w, l_w); + w += (len = strlen(l_w) + 1); + l_w += len; + if (*s_w == '\000') { + *s = NULL; + s_w++; + } else { + *s = w; + (void) strcpy(w, s_w); + w += (len = strlen(s_w) + 1); + s_w += len; + } + + l++; + s++; + } /* for each word entry */ + } /* if (full) */ + + bcopy(dimming_list, *static_dimming, number_of_words); + return (1); +} /* build_strings */ + +#define bsfcall callp->param.acall.cargs.bslcvt_arg +#define bsfret callp->param.aret.rvals.bslcvt_ret +/* + * bslcvtfull - Convert Sensitivity Label and initialize static + * information. + * + * Entry label = Sensitivity Label to convert and get dimming list. + * This label should lie within the bounds or the + * results may not be meaningful. + * bounds = Lower and upper bounds for words lists. Must be + * dominated by clearance. + * flags = VIEW_INTERNAL, don't promote/demote admin low/high. + * VIEW_EXTERNAL, promote/demote admin low/high. + * + * Exit string = ASCII coded Sensitivity Label. + * long_words = Array of pointers to visible long word names. + * short_words = Array of pointers to visible short word names. + * display = Array of indicators as to whether the word is present + * in the converted label (CVT_SET), and/or changeable + * (CVT_DIM). + * first_compartment = Zero based index of first compartment. + * display_size = Number of entries in the display/words lists. + * + * Returns -1, If unable to access label encodings database, or + * invalid label. + * 0, If unable to allocate static memory. + * 1, If successful. + * + * Calls RPC - LABELS_BSLCONVERT, STTBLEVEL, SETBSLABEL, TCLNT, + * build_strings, clnt_call, clnt_perror. + * + * Uses sbounds, slrcvt, slrcvtsize, slrdim, slrstring, + * slrstringsize. + */ + +int +bslcvtfull(const bslabel_t *label, const blrange_t *bounds, int flags, + char **string, char **long_words[], char **short_words[], char *display[], + int *first_compartment, int *display_size) +{ + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize = CALL_SIZE(bslcvt_call_t, 0); + int new_words_size; + int rval; + + call.callop = BSLCVT; + bsfcall.label = *label; + bsfcall.bounds.upper_bound = *bounds->upper_bound; + bsfcall.bounds.lower_bound = *bounds->lower_bound; + bsfcall.flags = LABELS_FULL_CONVERT; + set_label_view(&bsfcall.flags, flags); + + if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) { +#ifdef DEBUG + (void) fprintf(stderr, "No label server.\n"); +#endif /* DEBUG */ + return (-1); + } else if (rval != SUCCESS) { + return (-1); + } else { + if (callp->reterr != 0) + return (-1); + } + + *first_compartment = bsfret.first_comp; + *display_size = bsfret.d_len; + + new_words_size = bsfret.l_len + bsfret.s_len + bsfret.d_len + + (2 * sizeof (char *)) * bsfret.d_len; + + if (build_strings(&slstringsize, &slstring, &bsfret.buf[bsfret.string], + &slcvtsize, new_words_size, &slcvt, &sldim, bsfret.d_len, + &bsfret.buf[bsfret.lwords], &bsfret.buf[bsfret.swords], + &bsfret.buf[bsfret.dim], 1) != 1) { + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (0); + } + + /* save for bslcvt call */ + sbounds.upper_bound = *bounds->upper_bound; + sbounds.lower_bound = *bounds->lower_bound; + + *string = slstring; + *display = sldim; + /*LINTED*/ + *long_words = (char **)slcvt; + /*LINTED*/ + *short_words = (char **)(slcvt + *display_size * sizeof (char *)); + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (1); +} /* bslcvtfull */ +#undef bsfcall +#undef bsfret + +#define bsccall callp->param.acall.cargs.bslcvt_arg +#define bscret callp->param.aret.rvals.bslcvt_ret +/* + * bslcvt - Convert Sensitivity Label and update dimming information. + * + * Entry label = Sensitivity Label to convert and get dimming list. + * This label should lie within the bounds of the + * corresponding bslcvtfull call or the results may + * not be meaningful. + * flags = VIEW_INTERNAL, don't promote/demote admin low/high. + * VIEW_EXTERNAL, promote/demote admin low/high. + * + * Exit string = ASCII coded Sensitivity Label. + * display = Array of indicators as to whether the word is present + * in the converted label (CVT_SET), and/or changeable + * (CVT_DIM). + * + * Returns -1, If unable to access label encodings database, or + * invalid label. + * 0, If unable to allocate static memory. + * 1, If successful. + * + * Calls RPC - LABELS_BSLCONVERT, SETBLEVEL, SETBSLABEL, build_strings + * clnt_call, clnt_perror. + * + * Uses sbounds, slrdim, slrstring. + */ + +int +bslcvt(const bslabel_t *label, int flags, char **string, char *display[]) +{ + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize = CALL_SIZE(bslcvt_call_t, 0); + int rval; + + if (slcvt == NULL) + return (-1); /* conversion not initialized */ + + call.callop = BSLCVT; + bsccall.label = *label; + bsccall.bounds = sbounds; /* save from last bslcvtfull() call */ + bsccall.flags = 0; + set_label_view(&bsccall.flags, flags); + + if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) { +#ifdef DEBUG + (void) fprintf(stderr, "No label server.\n"); +#endif /* DEBUG */ + return (-1); + } else if (rval != SUCCESS) { + return (-1); + } else { + if (callp->reterr != 0) + return (-1); + } + + if (build_strings(&slstringsize, &slstring, &bscret.buf[bscret.string], + &slcvtsize, 0, &slcvt, &sldim, bscret.d_len, + &bscret.buf[bscret.lwords], &bscret.buf[bscret.swords], + &bscret.buf[bscret.dim], 0) != 1) { + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (0); + } + + *string = slstring; + *display = sldim; + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (1); +} /* bslcvt */ +#undef bsccall +#undef bscret + +#define bcfcall callp->param.acall.cargs.bclearcvt_arg +#define bcfret callp->param.aret.rvals.bclearcvt_ret +/* + * bclearcvtfull - Convert Clearance and initialize static information. + * + * Entry clearance = Clearance to convert and get dimming list. + * This clearance should lie within the bounds or + * the results may not be meaningful. + * bounds = Lower and upper bounds for words lists. Must be + * dominated by clearance. + * flags = VIEW_INTERNAL, don't promote/demote admin low/high. + * VIEW_EXTERNAL, promote/demote admin low/high. + * + * Exit string = ASCII coded Clearance. + * long_words = Array of pointers to visible long word names. + * short_words = Array of pointers to visible short word names. + * display = Array of indicators as to whether the word is present + * in the converted label (CVT_SET), and/or changeable + * (CVT_DIM). + * first_compartment = Zero based index of first compartment. + * display_size = Number of entries in the display/words lists. + * + * Returns -1, If unable to access label encodings database, or + * invalid label. + * 0, If unable to allocate static memory. + * 1, If successful. + * + * Calls RPC - LABELS_BCLEARCONVERT, SETBCLEAR, SETBLEVEL, TCLNT, + * build_strings, clnt_call, clnt_perror. + * + * Uses cbounds, clrcvt, clrcvtsize, clrdim, clrstring, + * clrstringsize. + */ + +int +bclearcvtfull(const bclear_t *clearance, const blrange_t *bounds, + int flags, char **string, char **long_words[], char **short_words[], + char *display[], int *first_compartment, int *display_size) +{ + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize = CALL_SIZE(bclearcvt_call_t, 0); + int new_words_size; + int rval; + + call.callop = BCLEARCVT; + bcfcall.clear = *clearance; + bcfcall.bounds.upper_bound = *bounds->upper_bound; + bcfcall.bounds.lower_bound = *bounds->lower_bound; + bcfcall.flags = LABELS_FULL_CONVERT; + set_label_view(&bcfcall.flags, flags); + + if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) { +#ifdef DEBUG + (void) fprintf(stderr, "No label server.\n"); +#endif /* DEBUG */ + return (-1); + } else if (rval != SUCCESS) { + return (-1); + } else { + if (callp->reterr != 0) + return (-1); + } + + *first_compartment = bcfret.first_comp; + *display_size = bcfret.d_len; + + new_words_size = bcfret.l_len + bcfret.s_len + bcfret.d_len + + (2 * sizeof (char *)) * bcfret.d_len; + + if (build_strings(&clrstringsize, &clrstring, + &bcfret.buf[bcfret.string], + &clrcvtsize, new_words_size, &clrcvt, + &clrdim, bcfret.d_len, + &bcfret.buf[bcfret.lwords], &bcfret.buf[bcfret.swords], + &bcfret.buf[bcfret.dim], 1) != 1) { + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (0); + } + + /* save for bclearcvt call */ + cbounds.upper_bound = *bounds->upper_bound; + cbounds.lower_bound = *bounds->lower_bound; + + *string = clrstring; + *display = clrdim; + /*LINTED*/ + *long_words = (char **)clrcvt; + /*LINTED*/ + *short_words = (char **)(clrcvt + *display_size * sizeof (char *)); + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (1); +} /* bclearcvtfull */ +#undef bcfcall +#undef bcfret + +#define bcccall callp->param.acall.cargs.bclearcvt_arg +#define bccret callp->param.aret.rvals.bclearcvt_ret +/* + * bclearcvt - Convert Clearance and update dimming inforamtion. + * + * Entry clearance = Clearance to convert and get dimming list. + * This clearance should lie within the bounds of the + * corresponding bclearcvtfull call or the results may + * not be meaningful. + * flags = VIEW_INTERNAL, don't promote/demote admin low/high. + * VIEW_EXTERNAL, promote/demote admin low/high. + * + * Exit string = ASCII coded Clearance. + * display = Array of indicators as to whether the word is present + * in the converted label (CVT_SET), and/or changeable + * (CVT_DIM). + * + * Returns -1, If unable to access label encodings database, or + * invalid label. + * 0, If unable to allocate static memory. + * 1, If successful. + * + * Calls RPC - LABELS_BCLEARCONVERT, SETBCLEAR, SETBLEVEL, build_strings, + * clnt_call, clnt_perror. + * + * Uses cbounds, clrdim, clrstring. + */ + +int +bclearcvt(const bclear_t *clearance, int flags, char **string, + char *display[]) +{ + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize = CALL_SIZE(bclearcvt_call_t, 0); + int rval; + + if (clrcvt == NULL) + return (-1); /* conversion not initialized */ + + call.callop = BCLEARCVT; + bcccall.clear = *clearance; + bcccall.bounds = cbounds; /* save from last bslcvtfull() call */ + bcccall.flags = 0; + set_label_view(&bcccall.flags, flags); + + if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) { +#ifdef DEBUG + (void) fprintf(stderr, "No label server.\n"); +#endif /* DEBUG */ + return (-1); + } else if (rval != SUCCESS) { + return (-1); + } else { + if (callp->reterr != 0) + return (-1); + } + + if (build_strings(&clrstringsize, &clrstring, + &bccret.buf[bccret.string], + &clrcvtsize, 0, &clrcvt, &clrdim, bccret.d_len, + &bccret.buf[bccret.lwords], &bccret.buf[bccret.swords], + &bccret.buf[bccret.dim], 0) != 1) { + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (0); + } + + *string = clrstring; + *display = clrdim; + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (1); +} /* bclearcvt */ +#undef bcccall +#undef bccret + +#define lfret callp->param.aret.rvals.fields_ret +/* + * labelfields - Return names for the label fields. + * + * Entry None + * + * Exit fields = Updated. + * + * Returns -1, If unable to access label encodings file, or + * labels server failure. + * 0, If unable to allocate memory. + * 1, If successful. + * + * Calls __call_labeld(LABELFIELDS). + */ + +int +labelfields(struct name_fields *fields) +{ + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize = CALL_SIZE(fields_call_t, 0); + int rval; + + call.callop = LABELFIELDS; + + if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) { + + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (-1); + } + + /* unpack results */ + + if ((fields->class_name = strdup(&lfret.buf[lfret.classi])) == NULL) { + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (0); + } + if ((fields->comps_name = strdup(&lfret.buf[lfret.compsi])) == NULL) { + free(fields->class_name); + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (0); + } + if ((fields->marks_name = strdup(&lfret.buf[lfret.marksi])) == NULL) { + free(fields->class_name); + free(fields->comps_name); + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (0); + } + + if (callp != &call) + /* release return buffer */ + (void) munmap((void *)callp, bufsize); + return (rval); +} /* labelfields */ +#undef lfret + +#define udret callp->param.aret.rvals.udefs_ret +/* + * userdefs - Get default user Sensitivity Label and Clearance. + * + * Entry None. + * + * Exit sl = default user Sensitivity Label. + * clear = default user Clearance. + * + * Returns -1, If unable to access label encodings file, or + * labels server failure. + * 1, If successful. + * + * Calls __call_labeld(UDEFS). + */ + +int +userdefs(bslabel_t *sl, bclear_t *clear) +{ + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize = CALL_SIZE(udefs_call_t, 0); + int rval; + + call.callop = UDEFS; + + if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) { + /* process error */ + + return (-1); + } + + *sl = udret.sl; + *clear = udret.clear; + return (rval); +} /* userdefs */ +#undef udret diff --git a/usr/src/lib/libtsol/common/privlib.c b/usr/src/lib/libtsol/common/privlib.c new file mode 100644 index 0000000000..3d1a8023d2 --- /dev/null +++ b/usr/src/lib/libtsol/common/privlib.c @@ -0,0 +1,179 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <errno.h> +#include <priv.h> +#include <sys/tsol/priv.h> +#include <sys/varargs.h> + +/* + * set_effective_priv(op, num_priv, priv_id1, priv_id2, ... ) + * + * Library routine to enable a user process to set its effective + * privilege set appropriately using a single call. User is + * required to specify the number of privilege ids that follow as + * arguments, rather than depending on the compiler to terminate + * the argument list with a NULL, which may be compiler-dependent. + */ +int +set_effective_priv(priv_op_t op, int num_priv, ...) +{ + priv_set_t *priv_set; + priv_t priv_id; + va_list ap; + int status; + + priv_set = priv_allocset(); + PRIV_EMPTY(priv_set); + + va_start(ap, num_priv); + while (num_priv--) { + char *priv_name; + /* + * Do sanity checking on priv_id's here to assure + * valid inputs to privilege macros. This checks + * num_priv argument as well. + */ + priv_id = va_arg(ap, priv_t); + priv_name = (char *)priv_getbynum((int)(uintptr_t)priv_id); + if (priv_name == NULL) { + errno = EINVAL; + priv_freeset(priv_set); + return (-1); + } + (void) priv_addset(priv_set, priv_name); + } + va_end(ap); + + /* + * Depend on system call to do sanity checking on "op" + */ + status = setppriv(op, PRIV_EFFECTIVE, priv_set); + priv_freeset(priv_set); + return (status); + +} /* set_effective_priv() */ + + + + +/* + * set_inheritable_priv(op, num_priv, priv_id1, priv_id2, ... ) + * + * Library routine to enable a user process to set its inheritable + * privilege set appropriately using a single call. User is + * required to specify the number of privilege ids that follow as + * arguments, rather than depending on the compiler to terminate + * the argument list with a NULL, which may be compiler-dependent. + */ +int +set_inheritable_priv(priv_op_t op, int num_priv, ...) +{ + priv_set_t *priv_set; + priv_t priv_id; + va_list ap; + int status; + + priv_set = priv_allocset(); + + PRIV_EMPTY(priv_set); + + va_start(ap, num_priv); + while (num_priv--) { + /* + * Do sanity checking on priv_id's here to assure + * valid inputs to privilege macros. This checks + * num_priv argument as well. + */ + priv_id = va_arg(ap, priv_t); + if ((char *)priv_getbynum((int)(uintptr_t)priv_id) == NULL) { + errno = EINVAL; + priv_freeset(priv_set); + return (-1); + } + (void) PRIV_ASSERT(priv_set, priv_id); + } + va_end(ap); + + /* + * Depend on system call to do sanity checking on "op" + */ + status = setppriv(op, PRIV_INHERITABLE, priv_set); + priv_freeset(priv_set); + return (status); + +} /* set_inheritable_priv() */ + + + + +/* + * set_permitted_priv(op, num_priv, priv_id1, priv_id2, ... ) + * + * Library routine to enable a user process to set its permitted + * privilege set appropriately using a single call. User is + * required to specify the number of privilege ids that follow as + * arguments, rather than depending on the compiler to terminate + * the argument list with a NULL, which may be compiler-dependent. + */ +int +set_permitted_priv(priv_op_t op, int num_priv, ...) +{ + priv_set_t *priv_set; + priv_t priv_id; + va_list ap; + int status; + + priv_set = priv_allocset(); + + PRIV_EMPTY(priv_set); + + va_start(ap, num_priv); + while (num_priv--) { + /* + * Do sanity checking on priv_id's here to assure + * valid inputs to privilege macros. This checks + * num_priv argument as well. + */ + priv_id = va_arg(ap, priv_t); + if ((char *)priv_getbynum((int)(uintptr_t)priv_id) == NULL) { + errno = EINVAL; + priv_freeset(priv_set); + return (-1); + } + (void) PRIV_ASSERT(priv_set, priv_id); + } + va_end(ap); + + /* + * Depend on system call to do sanity checking on "op" + */ + status = setppriv(op, PRIV_PERMITTED, priv_set); + priv_freeset(priv_set); + return (status); + +} /* set_permitted_priv() */ diff --git a/usr/src/lib/libtsol/common/setflabel.c b/usr/src/lib/libtsol/common/setflabel.c new file mode 100644 index 0000000000..1d645c8d23 --- /dev/null +++ b/usr/src/lib/libtsol/common/setflabel.c @@ -0,0 +1,309 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Change the label of a file + */ + +#include <ctype.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <errno.h> + +#include <tsol/label.h> + +#include "labeld.h" +#include <sys/tsol/label_macro.h> + +#include <sys/types.h> + +#include <zone.h> +#include <sys/zone.h> +#include <sys/param.h> +#include <string.h> + +static int abspath(char *, const char *, char *); + +/* + * setflabel(3TSOL) - set file label + * + * This is the library interface to the door call. + */ + +#define clcall callp->param.acall.cargs.setfbcl_arg +#define clret callp->param.aret.rvals.setfbcl_ret +/* + * + * Exit error = If error reported, the error indicator, + * -1, Unable to access label encodings file; + * 0, Invalid binary label passed; + * >0, Position after the first character in + * string of error, 1 indicates entire string. + * Otherwise, unchanged. + * + * Returns 0, If error. + * 1, If successful. + * + * Calls __call_labeld(SETFLABEL) + * + */ + +int +setflabel(const char *path, m_label_t *label) +{ + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize; + size_t path_len; + static char cwd[MAXPATHLEN]; + char canon[MAXPATHLEN]; + + + /* + * If path is relative and we haven't already determined the current + * working directory, do so now. Calculating the working directory + * here lets us do the work once, instead of (potentially) repeatedly + * in realpath(). + */ + if (*path != '/' && cwd[0] == '\0') { + if (getcwd(cwd, MAXPATHLEN) == NULL) { + cwd[0] = '\0'; + return (-1); + } + } + /* + * Find an absolute pathname in the native file system name space that + * corresponds to path, stuffing it into canon. + */ + if (abspath(cwd, path, canon) < 0) + return (-1); + + path_len = strlen(canon) + 1; + + datasize = CALL_SIZE(setfbcl_call_t, path_len - BUFSIZE); + datasize += 2; /* PAD */ + + if (datasize > bufsize) { + if ((callp = (labeld_data_t *)malloc(datasize)) == NULL) { + return (-1); + } + bufsize = datasize; + } + + callp->callop = SETFLABEL; + + clcall.sl = *label; + (void) strcpy(clcall.pathname, canon); + + if (__call_labeld(&callp, &bufsize, &datasize) == SUCCESS) { + int err = callp->reterr; + + if (callp != &call) { + /* free allocated buffer */ + free(callp); + } + /* + * reterr == 0, OK, + * reterr < 0, invalid binary label, + */ + if (err == 0) { + if (clret.status > 0) { + errno = clret.status; + return (-1); + } else { + return (0); + } + } else if (err < 0) { + err = 0; + } + errno = ECONNREFUSED; + return (-1); + } else { + if (callp != &call) { + /* free allocated buffer */ + free(callp); + } + /* server not present */ + errno = ECONNREFUSED; + return (-1); + } +} /* setflabel */ + +#undef clcall +#undef clret + +#define clcall callp->param.acall.cargs.zcopy_arg +#define clret callp->param.aret.rvals.zcopy_ret +/* + * + * Exit status = result of zone copy request + * -1, Copy not confirmed + * Otherwise, unchanged. + * + * Returns 0, If error. + * 1, If successful. + * + * Calls __call_labeld(ZCOPY) + * + */ +int +zonecopy(m_label_t *src_win_sl, char *remote_dir, char *filename, + char *local_dir, int transfer_mode) +{ + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize; + size_t strings; + size_t remote_dir_len; + size_t filename_len; + size_t local_dir_len; + size_t display_len; + char *display; + + remote_dir_len = strlen(remote_dir) + 1; + filename_len = strlen(filename) + 1; + local_dir_len = strlen(local_dir) + 1; + + if ((display = getenv("DISPLAY")) == NULL) + display = ""; + display_len = strlen(display) + 1; + + strings = remote_dir_len + filename_len + local_dir_len + display_len; + + datasize = CALL_SIZE(zcopy_call_t, strings - BUFSIZE); + + datasize += 4; /* PAD */ + + if (datasize > bufsize) { + if ((callp = (labeld_data_t *)malloc(datasize)) == NULL) { + return (NULL); + } + bufsize = datasize; + } + + strings = 0; + callp->callop = ZCOPY; + + clcall.src_win_sl = *src_win_sl; + clcall.transfer_mode = transfer_mode; + clcall.remote_dir = strings; + strings += remote_dir_len; + clcall.filename = strings; + strings += filename_len; + clcall.local_dir = strings; + strings += local_dir_len; + clcall.display = strings; + + (void) strcpy(&clcall.buf[clcall.remote_dir], remote_dir); + (void) strcpy(&clcall.buf[clcall.filename], filename); + (void) strcpy(&clcall.buf[clcall.local_dir], local_dir); + (void) strcpy(&clcall.buf[clcall.display], display); + + if (__call_labeld(&callp, &bufsize, &datasize) == SUCCESS) { + int err = callp->reterr; + + if (callp != &call) { + /* free allocated buffer */ + free(callp); + } + /* + * reterr == 0, OK, + * reterr < 0, transer not confirmed + */ + if (err == 0) { + return (clret.status); + } else if (err < 0) { + err = 0; + } + return (PIPEMSG_CANCEL); + } else { + if (callp != &call) { + /* free allocated buffer */ + free(callp); + } + /* server not present */ + return (PIPEMSG_CANCEL); + } +} + +/* + * Convert the path given in raw to canonical, absolute, symlink-free + * form, storing the result in the buffer named by canon, which must be + * at least MAXPATHLEN bytes long. If wd is non-NULL, assume that it + * points to a path for the current working directory and use it instead + * of invoking getcwd; accepting this value as an argument lets our caller + * cache the value, so that realpath (called from this routine) doesn't have + * to recalculate it each time it's given a relative pathname. + * + * Return 0 on success, -1 on failure. + */ +int +abspath(char *wd, const char *raw, char *canon) +{ + char absbuf[MAXPATHLEN]; + + /* + * Preliminary sanity check. + */ + if (raw == NULL || canon == NULL) + return (-1); + + /* + * If the path is relative, convert it to absolute form, + * using wd if it's been supplied. + */ + if (raw[0] != '/') { + char *limit = absbuf + sizeof (absbuf); + char *d; + + /* Fill in working directory. */ + if (wd != NULL) + (void) strncpy(absbuf, wd, sizeof (absbuf)); + else if (getcwd(absbuf, strlen(absbuf)) == NULL) + return (-1); + + /* Add separating slash. */ + d = absbuf + strlen(absbuf); + if (d < limit) + *d++ = '/'; + + /* Glue on the relative part of the path. */ + while (d < limit && (*d++ = *raw++)) + continue; + + raw = absbuf; + } + + /* + * Call realpath to canonicalize and resolve symlinks. + */ + return (realpath(raw, canon) == NULL ? -1 : 0); +} diff --git a/usr/src/lib/libtsol/common/stob.c b/usr/src/lib/libtsol/common/stob.c new file mode 100644 index 0000000000..e8e6780875 --- /dev/null +++ b/usr/src/lib/libtsol/common/stob.c @@ -0,0 +1,312 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * String to binary label translations. + */ + +#include <ctype.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> + +#include <tsol/label.h> + +#include "labeld.h" +#include <sys/tsol/label_macro.h> + +#undef CALL_SIZE +#define CALL_SIZE(type, buf) (size_t)(sizeof (type) - BUFSIZE + sizeof (int)\ + + (buf)) + +#if !defined(TEXT_DOMAIN) /* should be defined by Makefiles */ +#define TEXT_DOMAIN "SYS_TEST" +#endif /* TEXT_DOMAIN */ + +/* short hands */ + +#define IS_ADMIN_LOW(sl) \ + ((strncasecmp(sl, ADMIN_LOW, (sizeof (ADMIN_LOW) - 1)) == 0)) + +#define IS_ADMIN_HIGH(sh) \ + ((strncasecmp(sh, ADMIN_HIGH, (sizeof (ADMIN_HIGH) - 1)) == 0)) + +#define ISHEX(f, s) \ + (((((f) & NEW_LABEL) == ((f) | NEW_LABEL)) || \ + (((f) & NO_CORRECTION) == ((f) | NO_CORRECTION))) && \ + (((s)[0] == '0') && (((s)[1] == 'x') || ((s)[1] == 'X')))) + +#define slcall callp->param.acall.cargs.stobsl_arg +#define slret callp->param.aret.rvals.stobsl_ret +/* + * stobsl - Translate Sensitivity Label string to a Binary Sensitivity + * Label. + * + * Entry string = Sensitivity Label string to be translated. + * label = Address of Binary Sensitivity Label to be initialized or + * updated. + * flags = Flags to control translation: + * NO_CORRECTION implies NEW_LABEL. + * NEW_LABEL, Initialize the label to a valid empty + * Sensitivity Label structure. + * NO_CORRECTION, Initialize the label to a valid + * empty Sensitivity Label structure. + * Prohibit correction to the Sensitivity Label. + * Other, pass existing Sensitivity Label through for + * modification. + * + * Exit label = Translated (updated) Binary Sensitivity Label. + * error = If error reported, the error indicator, + * -1, Unable to access label encodings file; + * 0, Invalid binary label passed; + * >0, Position after the first character in + * string of error, 1 indicates entire string. + * Otherwise, unchanged. + * + * Returns 0, If error. + * 1, If successful. + * + * Calls __call_labeld(STOBSL), ISHEX, htobsl, strlen, + * isspace, + * strncasecmp. + * + * Uses ADMIN_HIGH, ADMIN_LOW. + */ + +int +stobsl(const char *string, bslabel_t *label, int flags, int *error) +{ + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize = CALL_SIZE(stobsl_call_t, strlen(string) + 1); + int rval; + char *s = (char *)string; + + while (isspace(*s)) + s++; + /* accept a leading '[' */ + if (*s == '[') { + s++; + while (isspace(*s)) + s++; + } + if (ISHEX(flags, s)) { + if (htobsl(s, label)) { + return (1); + } else { + if (error != NULL) + *error = 1; + return (0); + } + } + + if (datasize > bufsize) { + if ((callp = malloc(datasize)) == NULL) { + if (error != NULL) + *error = -1; + return (0); + } + bufsize = datasize; + } + callp->callop = STOBSL; + slcall.flags = (flags&NEW_LABEL) ? LABELS_NEW_LABEL : 0; + slcall.flags |= (flags&NO_CORRECTION) ? LABELS_FULL_PARSE : 0; + slcall.label = *label; + (void) strcpy(slcall.string, string); + + if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) { + int err = callp->reterr; + + if (callp != &call) { + /* free allocated buffer */ + free(callp); + } + /* + * reterr == 0, OK, + * reterr < 0, invalid binary label, + * reterr > 0 error position, 1 == whole string + */ + if (err == 0) { + *label = slret.label; + return (1); + } else if (err < 0) { + err = 0; + } + if (error != NULL) + *error = err; + return (0); + } else if (rval == NOSERVER) { + if (callp != &call) { + /* free allocated buffer */ + free(callp); + } + /* server not present */ + /* special case Admin High and Admin Low */ + if (IS_ADMIN_LOW(s)) { + BSLLOW(label); + } else if (IS_ADMIN_HIGH(s)) { + BSLHIGH(label); + } else { + goto err1; + } + return (1); + } + if (callp != &call) { + /* free allocated buffer */ + free(callp); + } +err1: + if (error != NULL) + *error = -1; + return (0); +} /* stobsl */ +#undef slcall +#undef slret + +#define clrcall callp->param.acall.cargs.stobclear_arg +#define clrret callp->param.aret.rvals.stobclear_ret +/* + * stobclear - Translate Clearance string to a Binary Clearance. + * + * Entry string = Clearance string to be translated. + * clearance = Address of Binary Clearance to be initialized or + * updated. + * flags = Flags to control translation: + * NO_CORRECTION implies NEW_LABEL. + * NEW_LABEL, Initialize the label to a valid empty + * Sensitivity Label structure. + * NO_CORRECTION, Initialize the label to a valid + * empty Sensitivity Label structure. + * Prohibit correction to the Sensitivity Label. + * Other, pass existing Sensitivity Label through for + * modification. + * + * Exit clearance = Translated (updated) Binary Clearance. + * error = If error reported, the error indicator, + * -1, Unable to access label encodings file; + * 0, Invalid binary label passed; + * >0, Position after the first character in + * string of error, 1 indicates entire string. + * Otherwise, unchanged. + * + * Returns 0, If error. + * 1, If successful. + * + * Calls __call_labeld(STOBCLEAR), ISHEX, htobsl, strlen, + * isspace, + * strncasecmp. + * + * Uses ADMIN_HIGH, ADMIN_LOW. + */ + +int +stobclear(const char *string, bclear_t *clearance, int flags, int *error) +{ + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize = CALL_SIZE(callp->param.acall, strlen(string) + 1); + int rval; + + if (ISHEX(flags, string)) { + if (htobclear(string, clearance)) { + return (1); + } else { + if (error != NULL) + *error = 1; + return (0); + } + } + + if (datasize > bufsize) { + if ((callp = malloc(datasize)) == NULL) { + if (error != NULL) + *error = -1; + return (0); + } + bufsize = datasize; + } + callp->callop = STOBCLEAR; + clrcall.flags = (flags&NEW_LABEL) ? LABELS_NEW_LABEL : 0; + clrcall.flags |= (flags&NO_CORRECTION) ? LABELS_FULL_PARSE : 0; + clrcall.clear = *clearance; + (void) strcpy(clrcall.string, string); + + if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) { + int err = callp->reterr; + + if (callp != &call) { + /* free allocated buffer */ + free(callp); + } + /* + * reterr == 0, OK, + * reterr < 0, invalid binary label, + * reterr > 0 error position, 1 == whole string + */ + if (err == 0) { + *clearance = clrret.clear; + return (1); + } else if (err < 0) { + err = 0; + } + if (error != NULL) + *error = err; + return (0); + } else if (rval == NOSERVER) { + char *s = (char *)string; + + if (callp != &call) { + /* free allocated buffer */ + free(callp); + } + /* server not present */ + /* special case Admin High and Admin Low */ + while (isspace(*s)) + s++; + if (IS_ADMIN_LOW(s)) { + BCLEARLOW(clearance); + } else if (IS_ADMIN_HIGH(s)) { + BCLEARHIGH(clearance); + } else { + goto err1; + } + return (1); + } + if (callp != &call) { + /* free allocated buffer */ + free(callp); + } +err1: + if (error != NULL) + *error = -1; + return (0); +} /* stobclear */ +#undef clrcall +#undef clrret diff --git a/usr/src/lib/libtsol/common/stol.c b/usr/src/lib/libtsol/common/stol.c new file mode 100644 index 0000000000..2a951b3907 --- /dev/null +++ b/usr/src/lib/libtsol/common/stol.c @@ -0,0 +1,394 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> + +#include <sys/mman.h> +#include <sys/tsol/label_macro.h> + +#include <tsol/label.h> + +#include "clnt.h" +#include "labeld.h" + +#define IS_LOW(s) \ + ((strncasecmp(s, ADMIN_LOW, (sizeof (ADMIN_LOW) - 1)) == 0) && \ + (s[sizeof (ADMIN_LOW) - 1] == '\0')) +#define IS_HIGH(s) \ + ((strncasecmp(s, ADMIN_HIGH, (sizeof (ADMIN_HIGH) - 1)) == 0) && \ + (s[sizeof (ADMIN_HIGH) - 1] == '\0')) +#define IS_HEX(f, s) \ + (((((f) == L_NO_CORRECTION)) || ((f) == L_DEFAULT)) && \ + (((s)[0] == '0') && (((s)[1] == 'x') || ((s)[1] == 'X')))) + +static boolean_t +unhex(char **h, uchar_t *l, int len) +{ + char *hx = *h; + char ch; + uchar_t byte; + + for (; len--; ) { + ch = *hx++; + if (!isxdigit(ch)) + return (B_FALSE); + if (isdigit(ch)) + byte = ch - '0'; + else + byte = ch - (isupper(ch) ? 'A' - 10 : 'a' - 10); + byte <<= 4; + ch = *hx++; + if (isdigit(ch)) + byte |= ch - '0'; + else + byte |= ch - (isupper(ch) ? 'A' - 10 : 'a' - 10); + *l++ = byte; + } + *h = hx; + return (B_TRUE); +} + +/* + * Formats accepted: + * 0x + 4 class + 64 comps + end of string + * 0x + 4 class + '-' + ll + '-' + comps + end of string + * ll = number of words to fill out the entire comps field + * presumes trailing zero for comps + * + * So in the case of 256 comps (i.e., 8 compartment words): + * 0x0006-08-7ff3f + * 0x + Classification + Compartments + end of string + * 0[xX]hhh... + */ + +static int +htol(char *s, m_label_t *l) +{ + char *h = &s[2]; /* skip 0[xX] */ + uchar_t *lp = (uchar_t *)&(((_mac_label_impl_t *)l)->_lclass); + size_t len = sizeof (_mac_label_impl_t) - 4; + int bytes; + + /* unpack classification */ + if (!unhex(&h, lp, 2)) { + goto error; + } + lp = (uchar_t *)&(((_mac_label_impl_t *)l)->_comps); + if (LCLASS(l) < LOW_CLASS || + LCLASS(l) > HIGH_CLASS) { + goto error; + } + if (h[0] == '-' && h[3] == '-') { + uchar_t size; + + /* length specified of internal text label */ + h++; /* skip '-' */ + if (!unhex(&h, &size, 1)) { + goto error; + } + size *= sizeof (uint32_t); /* words to bytes */ + if (size > len) { + /* + * internal label greater than will fit in current + * binary. + */ + goto error; + } + bzero(lp, len); + h++; /* skip '-' */ + bytes = strlen(h)/2; + } else { + bytes = (strlen(h) + 1)/2; + } + if ((bytes > len) || !unhex(&h, lp, bytes)) { + goto error; + } + return (0); +error: + errno = EINVAL; + return (-1); +} + +static int +convert_id(m_label_type_t t) +{ + switch (t) { + case MAC_LABEL: + return (SUN_MAC_ID); + case USER_CLEAR: + return (SUN_UCLR_ID); + default: + return (-1); + } +} + +/* + * str_to_label -- parse a string into the requested label type. + * + * Entry s = string to parse. + * l = label to create or modify. + * t = label type (MAC_LABEL, USER_CLEAR). + * f = flags + * L_DEFAULT, + * L_MODIFY_EXISTING, use the existing label as a basis for + * the parse string. + * L_NO_CORRECTION, s must be correct and full by the + * label_encoding rules. + * + * Exit l = parsed label value. + * e = index into string of error. + * = M_BAD_STRING (-1) or could be zero, indicates entire string, + * e = M_BAD_LABEL (-3), problems with l + * + * Returns 0, success. + * -1, failure + * errno = ENOTSUP, the underlying label mechanism + * does not support label parsing. + * ENOMEM, unable to allocate memory for l. + * EINVAL, invalid argument, l != NULL or + * invalid label type for the underlying + * label mechanism. + */ +#define _M_GOOD_LABEL -1 /* gfi L_GOOD_LABEL */ +int +str_to_label(const char *str, m_label_t **l, const m_label_type_t t, uint_t f, + int *e) +{ + char *s = (char *)str; + char *p; + labeld_data_t call; + labeld_data_t *callp = &call; + size_t bufsize = sizeof (labeld_data_t); + size_t datasize; + int err; + int id = convert_id(t); + boolean_t new = B_FALSE; + + if (*l == NULL) { + if ((*l = m_label_alloc(t)) == NULL) { + return (-1); + } + if (id == -1) { + goto badlabel; + } + _LOW_LABEL(*l, id); + new = B_TRUE; + } else if (_MTYPE(*l, SUN_INVALID_ID) && + ((f == L_NO_CORRECTION) || (f == L_DEFAULT))) { + _LOW_LABEL(*l, id); + new = B_TRUE; + } else if (!(_MTYPE(*l, SUN_MAC_ID) || _MTYPE(*l, SUN_CLR_ID))) { + goto badlabel; + } + + if (new == B_FALSE && id == -1) { + goto badlabel; + } + + /* get to the beginning of the string to parse */ + while (isspace(*s)) { + s++; + } + + /* accept a leading '[' and trailing ']' for old times sake */ + if (*s == '[') { + s++; + while (isspace(*s)) { + s++; + } + } + p = s; + while (*p != '\0' && *p != ']') { + p++; + } + + /* strip trailing spaces */ + while (p != s && isspace(*(p-1))) { + --p; + } + *p = '\0'; /* end of string */ + + /* translate hex, admin_low and admin_high */ + id = _MGETTYPE(*l); + if (IS_LOW(s)) { + _LOW_LABEL(*l, id); + return (0); + } else if (IS_HIGH(s)) { + _HIGH_LABEL(*l, id); + return (0); + } else if (IS_HEX(f, s)) { + int herr; + + herr = htol(s, *l); + return (herr); + } +#define slcall callp->param.acall.cargs.sl_arg +#define slret callp->param.aret.rvals.sl_ret + /* now try label server */ + + datasize = CALL_SIZE(sl_call_t, strlen(str) + 1); + if (datasize > bufsize) { + if ((callp = malloc(datasize)) == NULL) { + return (-1); + } + bufsize = datasize; + } + callp->callop = STOL; + slcall.label = **l; + slcall.flags = f; + if (new) + slcall.flags |= L_NEW_LABEL; + (void) strcpy(slcall.string, str); + /* + * callp->reterr = L_GOOD_LABEL (-1) == OK; + * L_BAD_CLASSIFICATION (-2) == bad input + * classification: class + * L_BAD_LABEL (-3) == either sring or input label bad + * O'E == offset in string 0 == entire string. + */ + if (__call_labeld(&callp, &bufsize, &datasize) == SUCCESS) { + + err = callp->reterr; + if (callp != &call) { + /* free allocated buffer */ + (void) free(callp); + } + switch (err) { + case _M_GOOD_LABEL: /* L_GOOD_LABEL */ + **l = slret.label; + return (0); + case M_BAD_LABEL: /* L_BAD_CLASSIFICATION */ + case M_BAD_STRING: /* L_BAD_LABEL */ + default: + errno = EINVAL; + if (e != NULL) + *e = err; + return (-1); + } + } + switch (callp->reterr) { + case NOSERVER: + errno = ENOTSUP; + break; + default: + errno = EINVAL; + break; + } + return (-1); + +badlabel: + errno = EINVAL; + if (e != NULL) + *e = M_BAD_LABEL; + return (-1); +} +#undef slcall +#undef slret + +/* + * m_label_alloc -- allocate a label structure + * + * Entry t = label type (MAC_LABEL, USER_CLEAR). + * + * Exit If error, NULL, errno set to ENOMEM + * Otherwise, pointer to m_label_t memory + */ + +/* ARGUSED */ +m_label_t * +m_label_alloc(const m_label_type_t t) +{ + m_label_t *l; + + switch (t) { + case MAC_LABEL: + case USER_CLEAR: + if ((l = malloc(sizeof (_mac_label_impl_t))) == NULL) { + return (NULL); + } + _MSETTYPE(l, SUN_INVALID_ID); + break; + default: + errno = EINVAL; + return (NULL); + } + return (l); +} + +/* + * m_label_dup -- make a duplicate copy of the given label. + * + * Entry l = label to duplicate. + * + * Exit d = duplicate copy of l. + * + * Returns 0, success + * -1, if error. + * errno = ENOTSUP, the underlying label mechanism + * does not support label duplication. + * ENOMEM, unable to allocate memory for d. + * EINVAL, invalid argument, l == NULL or + * invalid label type for the underlying + * label mechanism. + */ + +int +m_label_dup(m_label_t **d, const m_label_t *l) +{ + if (d == NULL || *d != NULL) { + errno = EINVAL; + return (-1); + } + if ((*d = malloc(sizeof (_mac_label_impl_t))) == NULL) { + errno = ENOMEM; + return (-1); + } + + (void) memcpy(*d, l, sizeof (_mac_label_impl_t)); + return (0); +} + +/* + * m_label_free -- free label structure + * + * Entry l = label to free. + * + * Exit memory freed. + * + */ + +void +m_label_free(m_label_t *l) +{ + if (l) + free(l); +} diff --git a/usr/src/lib/libtsol/common/zone.c b/usr/src/lib/libtsol/common/zone.c new file mode 100644 index 0000000000..6e4b2970a2 --- /dev/null +++ b/usr/src/lib/libtsol/common/zone.c @@ -0,0 +1,272 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdlib.h> +#include <strings.h> +#include <zone.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/tsol/label_macro.h> + +/* + * Get label from zone name + */ +m_label_t * +getzonelabelbyname(const char *zone) +{ + zoneid_t zoneid; + + if ((zoneid = getzoneidbyname(zone)) == -1) { + errno = EINVAL; + return (NULL); + } + return (getzonelabelbyid(zoneid)); +} + +/* + * Get label from zone id + */ +m_label_t * +getzonelabelbyid(zoneid_t zoneid) +{ + m_label_t *slabel; + + if ((slabel = m_label_alloc(MAC_LABEL)) == NULL) + return (NULL); + + if (zone_getattr(zoneid, ZONE_ATTR_SLBL, slabel, + sizeof (m_label_t)) < 0) { + m_label_free(slabel); + errno = EINVAL; + return (NULL); + } + + return (slabel); +} + +/* + * Get zone id from label + */ + +zoneid_t +getzoneidbylabel(const m_label_t *label) +{ + m_label_t admin_low; + m_label_t admin_high; + zoneid_t zoneid; + zoneid_t *zids; + uint_t nzents; + uint_t nzents_saved; + int i; + + bsllow(&admin_low); + bslhigh(&admin_high); + + /* Check for admin_low or admin_high; both are global zone */ + if (blequal(label, &admin_low) || blequal(label, &admin_high)) + return (GLOBAL_ZONEID); + + nzents = 0; + if (zone_list(NULL, &nzents) != 0) + return (-1); + +again: + if (nzents == 0) { + errno = EINVAL; + return (-1); + } + + /* + * Add a small amount of padding here to avoid spinning in a tight loop + * if there's a process running somewhere that's creating lots of zones + * all at once. + */ + nzents += 8; + if ((zids = malloc(nzents * sizeof (zoneid_t))) == NULL) + return (-1); + nzents_saved = nzents; + + if (zone_list(zids, &nzents) != 0) { + free(zids); + return (-1); + } + if (nzents > nzents_saved) { + /* list changed, try again */ + free(zids); + goto again; + } + + for (i = 0; i < nzents; i++) { + m_label_t test_sl; + + if (zids[i] == GLOBAL_ZONEID) + continue; + + if (zone_getattr(zids[i], ZONE_ATTR_SLBL, &test_sl, + sizeof (m_label_t)) < 0) + continue; /* Badly configured zone info */ + + if (blequal(label, &test_sl) != 0) { + zoneid = zids[i]; + free(zids); + return (zoneid); + } + } + free(zids); + errno = EINVAL; + return (-1); +} + +/* + * Get zoneroot for a zoneid + */ + +char * +getzonerootbyid(zoneid_t zoneid) +{ + char zoneroot[MAXPATHLEN]; + + if (zone_getattr(zoneid, ZONE_ATTR_ROOT, zoneroot, + sizeof (zoneroot)) == -1) { + return (NULL); + } + + return (strdup(zoneroot)); +} + +/* + * Get zoneroot for a zonename + */ + +char * +getzonerootbyname(const char *zone) +{ + zoneid_t zoneid; + + if ((zoneid = getzoneidbyname(zone)) == -1) + return (NULL); + return (getzonerootbyid(zoneid)); +} + +/* + * Get zoneroot for a label + */ + +char * +getzonerootbylabel(const m_label_t *label) +{ + zoneid_t zoneid; + + if ((zoneid = getzoneidbylabel(label)) == -1) + return (NULL); + return (getzonerootbyid(zoneid)); +} + +/* + * Get label of path relative to global zone + * + * This function must be called from the global zone + */ + +m_label_t * +getlabelbypath(const char *path) +{ + m_label_t *slabel; + zoneid_t *zids; + uint_t nzents; + uint_t nzents_saved; + int i; + + if (getzoneid() != GLOBAL_ZONEID) { + errno = EINVAL; + return (NULL); + } + + nzents = 0; + if (zone_list(NULL, &nzents) != 0) + return (NULL); + +again: + /* Add a small amount of padding to avoid loops */ + nzents += 8; + zids = malloc(nzents * sizeof (zoneid_t)); + if (zids == NULL) + return (NULL); + + nzents_saved = nzents; + + if (zone_list(zids, &nzents) != 0) { + free(zids); + return (NULL); + } + if (nzents > nzents_saved) { + /* list changed, try again */ + free(zids); + goto again; + } + + slabel = m_label_alloc(MAC_LABEL); + if (slabel == NULL) { + free(zids); + return (NULL); + } + + for (i = 0; i < nzents; i++) { + char zoneroot[MAXPATHLEN]; + int zonerootlen; + + if (zids[i] == GLOBAL_ZONEID) + continue; + + if (zone_getattr(zids[i], ZONE_ATTR_ROOT, zoneroot, + sizeof (zoneroot)) == -1) + continue; /* Badly configured zone info */ + + /* + * Need to handle the case for the /dev directory which is + * parallel to the zone's root directory. So we back up + * 4 bytes - the strlen of "root". + */ + if ((zonerootlen = strlen(zoneroot)) <= 4) + continue; /* Badly configured zone info */ + if (strncmp(path, zoneroot, zonerootlen - 4) == 0) { + /* + * If we get a match, the file is in a labeled zone. + * Return the label of that zone. + */ + if (zone_getattr(zids[i], ZONE_ATTR_SLBL, slabel, + sizeof (m_label_t)) < 0) + continue; /* Badly configured zone info */ + + free(zids); + return (slabel); + } + } + free(zids); + bsllow(slabel); + return (slabel); +} diff --git a/usr/src/lib/libtsol/i386/Makefile b/usr/src/lib/libtsol/i386/Makefile new file mode 100644 index 0000000000..fb5e32504a --- /dev/null +++ b/usr/src/lib/libtsol/i386/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +#/ + +#ident "%Z%%M% %I% %E% SMI" + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff --git a/usr/src/lib/libtsol/sparc/Makefile b/usr/src/lib/libtsol/sparc/Makefile new file mode 100644 index 0000000000..4addab0cae --- /dev/null +++ b/usr/src/lib/libtsol/sparc/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +#ident "%Z%%M% %I% %E% SMI" + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff --git a/usr/src/lib/libtsol/sparcv9/Makefile b/usr/src/lib/libtsol/sparcv9/Makefile new file mode 100644 index 0000000000..69cf39010b --- /dev/null +++ b/usr/src/lib/libtsol/sparcv9/Makefile @@ -0,0 +1,31 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +#ident "%Z%%M% %I% %E% SMI" + +include ../Makefile.com +include ../../Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64) diff --git a/usr/src/lib/libtsol/spec/Makefile b/usr/src/lib/libtsol/spec/Makefile new file mode 100644 index 0000000000..835bbc66f1 --- /dev/null +++ b/usr/src/lib/libtsol/spec/Makefile @@ -0,0 +1,28 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include $(SRC)/lib/Makefile.spec.arch diff --git a/usr/src/lib/libtsol/spec/Makefile.targ b/usr/src/lib/libtsol/spec/Makefile.targ new file mode 100644 index 0000000000..e76d79a49d --- /dev/null +++ b/usr/src/lib/libtsol/spec/Makefile.targ @@ -0,0 +1,33 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +LIBRARY = libtsol.a +VERS = .2 +OBJECTS = obsolete.o \ + private.o \ + tsol.o +SPECCPP = -I../../common diff --git a/usr/src/lib/libtsol/spec/amd64/Makefile b/usr/src/lib/libtsol/spec/amd64/Makefile new file mode 100644 index 0000000000..03d9b122a2 --- /dev/null +++ b/usr/src/lib/libtsol/spec/amd64/Makefile @@ -0,0 +1,33 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +.KEEP_STATE: + +include ../Makefile.targ +include $(SRC)/lib/Makefile.lib +include $(SRC)/lib/Makefile.lib.64 +include $(SRC)/lib/Makefile.spec diff --git a/usr/src/lib/libtsol/spec/i386/Makefile b/usr/src/lib/libtsol/spec/i386/Makefile new file mode 100644 index 0000000000..7aab1a07a8 --- /dev/null +++ b/usr/src/lib/libtsol/spec/i386/Makefile @@ -0,0 +1,32 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +.KEEP_STATE: + +include ../Makefile.targ +include $(SRC)/lib/Makefile.lib +include $(SRC)/lib/Makefile.spec diff --git a/usr/src/lib/libtsol/spec/obsolete.spec b/usr/src/lib/libtsol/spec/obsolete.spec new file mode 100644 index 0000000000..ccebc2f8b9 --- /dev/null +++ b/usr/src/lib/libtsol/spec/obsolete.spec @@ -0,0 +1,122 @@ +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# Obsolete interfaces to be removed from a future release. +# Retained to aid 3rd party initial porting from TS8. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# ident "%Z%%M% %I% %E% SMI" +# + +function bcleartoh_r +include <tsol/label.h> +declaration char *bcleartoh_r(const bclear_t *clearance, char *hex); +version SUNWprivate_1.1 +end + +function bcleartoh +include <tsol/label.h> +declaration char *bcleartoh(const bclear_t *clearance); +version SUNWprivate_1.1 +end + +function bltocolor +include <tsol/label.h> +declaration char *bltocolor(const blevel_t *label); +version SUNWprivate_1.1 +end + +function bltocolor_r +include <tsol/label.h> +declaration char *bltocolor_r(const blevel_t *label, int size, \ + char *color_name); +version SUNWprivate_1.1 +end + +function bsltoh +include <tsol/label.h> +declaration char *bsltoh(const bslabel_t *label); +version SUNWprivate_1.1 +end + +function bsltoh_r +include <tsol/label.h> +declaration char *bsltoh_r(const bslabel_t *label, char *hex); +version SUNWprivate_1.1 +end + +function bsltos +include <tsol/label.h> +declaration ssize_t bsltos(const bslabel_t *label, char **string, \ + size_t str_len, int flags); +version SUNWprivate_1.1 +end + +function h_alloc +include <tsol/label.h> +declaration char *h_alloc(unsigned char id); +version SUNWprivate_1.1 +end + +function h_free +include <tsol/label.h> +declaration void h_free(char *hex); +version SUNWprivate_1.1 +end + +function htobclear +include <tsol/label.h> +declaration int htobclear(const char *s, bclear_t *clearance); +version SUNWprivate_1.1 +end + +function htobsl +include <tsol/label.h> +declaration int htobsl(const char *s, bslabel_t *label); +version SUNWprivate_1.1 +end + +function sbcleartos +include <tsol/label.h> +declaration char *sbcleartos(const bclear_t *clearance, int len); +version SUNWprivate_1.1 +end + +function sbsltos +include <tsol/label.h> +declaration char *sbsltos(const bslabel_t *label, int len); +version SUNWprivate_1.1 +end + +function stobclear +include <tsol/label.h> +declaration int stobclear(const char *string, bclear_t *clearance, \ + int flags, int *error); +version SUNWprivate_1.1 +end + +function stobsl +include <tsol/label.h> +declaration int stobsl(const char *string, bslabel_t *label, int flags, \ + int *error); +version SUNWprivate_1.1 +end diff --git a/usr/src/lib/libtsol/spec/private.spec b/usr/src/lib/libtsol/spec/private.spec new file mode 100644 index 0000000000..c5e66ea7b6 --- /dev/null +++ b/usr/src/lib/libtsol/spec/private.spec @@ -0,0 +1,239 @@ +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# Project Private to the Trusted eXtensions project. +# Not for public consumption or to be documented. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# ident "%Z%%M% %I% %E% SMI" +# + +function bclearhigh +include <tsol/label.h> +declaration void bclearhigh(bclear_t *clearance); +version SUNWprivate_1.1 +end + +function bclearlow +include <tsol/label.h> +declaration void bclearlow(bclear_t *clearance); +version SUNWprivate_1.1 +end + +function bcleartos +include <tsol/label.h> +declaration ssize_t bcleartos(const bclear_t *clearance, char **string, \ + size_t str_len, int flags); +version SUNWprivate_1.1 +end + +function bclearundef +include <tsol/label.h> +declaration void bclearundef(bclear_t *clearance); +version SUNWprivate_1.1 +end + +function bclearvalid +include <tsol/label.h> +declaration int bclearvalid(const bclear_t *clearance); +version SUNWprivate_1.1 +end + +function bclearcvtfull +include <tsol/label.h> +declaration int bclearcvtfull(const bclear_t *clearance, \ + const blrange_t *bounds, int flags, char **string, \ + char **long_words[], char **short_words[], \ + char *display[], int *first_compartment, \ + int *display_size); +version SUNWprivate_1.1 +end + +function bclearcvt +include <tsol/label.h> +declaration int bclearcvt(const bclear_t *clearance, int flags, \ + char **string, char *display[]); +version SUNWprivate_1.1 +end + +function blinrange +include <tsol/label.h> +declaration int blinrange(const blevel_t *label, const blrange_t *range); +version SUNWprivate_1.1 +end + +function blinset +include <tsol/label.h> +declaration int blinset(const bslabel_t *label, const set_id *id); +version SUNWprivate_1.1 +end + +function blmaximum +include <tsol/label.h> +declaration void blmaximum(blevel_t *label1, const blevel_t *label2); +version SUNWprivate_1.1 +end + +function blminimum +include <tsol/label.h> +declaration void blminimum(blevel_t *label1, const blevel_t *label2); +version SUNWprivate_1.1 +end + +function bltype +include <tsol/label.h> +declaration int bltype(const void *label, uint8_t type); +version SUNWprivate_1.1 +end + +function bslcvtfull +include <tsol/label.h> +declaration int bslcvtfull(const bslabel_t *label, + const blrange_t *bounds, \ + int flags, char **string, char **long_words[], \ + char **short_words[], char *display[], \ + int *first_compartment, int *display_size); +version SUNWprivate_1.1 +end + +function bslcvt +include <tsol/label.h> +declaration int bslcvt(const bslabel_t *label, int flags, char **string, \ + char *display[]); +version SUNWprivate_1.1 +end + +function bslhigh +include <tsol/label.h> +declaration void bslhigh(bslabel_t *label); +version SUNWprivate_1.1 +end + +function bsllow +include <tsol/label.h> +declaration void bsllow(bslabel_t *label); +version SUNWprivate_1.1 +end + +function bslundef +include <tsol/label.h> +declaration void bslundef(bslabel_t *label); +version SUNWprivate_1.1 +end + +function bslvalid +include <tsol/label.h> +declaration int bslvalid(const bslabel_t *label); +version SUNWprivate_1.1 +end + +function labelinfo +include <tsol/label.h> +declaration int labelinfo(struct label_info *info); +version SUNWprivate_1.1 +end + +function labelfields +include <tsol/label.h> +declaration int labelfields(struct name_fields *fields); +version SUNWprivate_1.1 +end + +function labelvers +include <tsol/label.h> +declaration ssize_t labelvers(char **version, int len); +version SUNWprivate_1.1 +end + +function getpathbylabel +include <tsol/label.h> +declaration char *getpathbylabel(const char *path_name, \ + char *resolved_path, size_t bufsize, const bslabel_t *sl); +version SUNWprivate_1.1 +end + +function getlabelbypath +include <tsol/label.h> +declaration m_label_t *getlabelbypath(char *path); +version SUNWprivate_1.1 +end + +function blabel_alloc +include <tsol/label.h> +declaration blevel_t *blabel_alloc(void); +version SUNWprivate_1.1 +end + +function blabel_free +include <tsol/label.h> +declaration void blabel_free(blevel_t *label_p); +version SUNWprivate_1.1 +end + +function blabel_size +include <tsol/label.h> +declaration size_t blabel_size(void); +version SUNWprivate_1.1 +end + +function setbltype +include <tsol/label.h> +declaration void setbltype(void *label, uint8_t type); +version SUNWprivate_1.1 +end + +function bisinvalid +include <tsol/label.h> +declaration boolean_t bisinvalid(const void *label); +version SUNWprivate_1.1 +end + +function set_effective_priv +include <tsol/label.h> +declaration int set_effective_priv(priv_op_t op, int num_priv, ...); +version SUNWprivate_1.1 +end + +function set_inheritable_priv +include <tsol/label.h> +declaration int set_inheritable_priv(priv_op_t op, int num_priv, ...); +version SUNWprivate_1.1 +end + +function set_permitted_priv +include <tsol/label.h> +declaration int set_permitted_priv(priv_op_t op, int num_priv, ...); +version SUNWprivate_1.1 +end + +function userdefs +include <tsol/label.h> +declaration int userdefs(bslabel_t *sl, bclear_t *clear); +version SUNWprivate_1.1 +end + +function zonecopy +include <tsol/label.h> +declaration int zonecopy(bslabel_t *src_win_sl, char *remote_dir, \ + char *filename, char *local_dir, int transfer_mode); +version SUNWprivate_1.1 +end diff --git a/usr/src/lib/libtsol/spec/sparc/Makefile b/usr/src/lib/libtsol/spec/sparc/Makefile new file mode 100644 index 0000000000..7aab1a07a8 --- /dev/null +++ b/usr/src/lib/libtsol/spec/sparc/Makefile @@ -0,0 +1,32 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +.KEEP_STATE: + +include ../Makefile.targ +include $(SRC)/lib/Makefile.lib +include $(SRC)/lib/Makefile.spec diff --git a/usr/src/lib/libtsol/spec/sparcv9/Makefile b/usr/src/lib/libtsol/spec/sparcv9/Makefile new file mode 100644 index 0000000000..03d9b122a2 --- /dev/null +++ b/usr/src/lib/libtsol/spec/sparcv9/Makefile @@ -0,0 +1,33 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +.KEEP_STATE: + +include ../Makefile.targ +include $(SRC)/lib/Makefile.lib +include $(SRC)/lib/Makefile.lib.64 +include $(SRC)/lib/Makefile.spec diff --git a/usr/src/lib/libtsol/spec/tsol.spec b/usr/src/lib/libtsol/spec/tsol.spec new file mode 100644 index 0000000000..089f5eb2ec --- /dev/null +++ b/usr/src/lib/libtsol/spec/tsol.spec @@ -0,0 +1,143 @@ +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +#pragma ident "%Z%%M% %I% %E% SMI" +# + +function label_to_str +include <tsol/label.h> +declaration int label_to_str(const m_label_t *label, char **string, \ + const m_label_str_t conversion_type, uint_t flags); +version SUNW_2.1 +end + +function m_label_alloc +include <tsol/label.h> +declaration m_label_t m_label_dup(const m_label_type_t *type); +version SUNW_2.1 +end + +function m_label_dup +include <tsol/label.h> +declaration int m_label_dup(m_label_t **dst, const m_label_t *src); +version SUNW_2.1 +end + +function m_label_free +include <tsol/label.h> +declaration void m_label_free(m_label_t *label); +version SUNW_2.1 +end + +function str_to_label +include <tsol/label.h> +declaration int str_to_label(const char *str, m_label_t **label, \ + const m_label_type_t type, unit_t flags, int *error); +version SUNW_2.1 +end + +function bldominates +include <tsol/label.h> +declaration int bldominates(const m_label_t *label1, \ + const m_label_t *label2); +version SUNW_2.1 +end + +function blequal +include <tsol/label.h> +declaration int blequal(const m_label_t *label1, const m_label_t *label2); +version SUNW_2.1 +end + +function blstrictdom +include <tsol/label.h> +declaration int blstrictdom(const m_label_t *label1, \ + const m_label_t *label2); +version SUNW_2.1 +end + +function getlabel +include <tsol/label.h> +declaration int getlabel(const char *path, m_label_t *label); +version SUNW_2.1 +end + +function fgetlabel +include <tsol/label.h> +declaration int fgetlabel(int fd, m_label_t *label); +version SUNW_2.1 +end + +function getplabel +include <tsol/label.h> +declaration int getplabel(m_label_t *label_p); +version SUNW_2.1 +end + +function getzoneidbylabel +include <tsol/label.h> +declaration zoneid_t getzoneidbylabel(const m_label_t *label); +version SUNW_2.1 +end + +function getzonelabelbyid +include <tsol/label.h> +declaration m_label_t *getzonelabelbyid(zoneid_t zoneid); +version SUNW_2.1 +end + +function getzonelabelbyname +include <tsol/label.h> +declaration m_label_t *getzonelabelbyname(char *zone); +version SUNW_2.1 +end + +function getzonerootbyid +include <tsol/label.h> +declaration char *getzonerootbyid(zoneid_t zoneid); +version SUNW_2.1 +end + +function getzonerootbylabel +include <tsol/label.h> +declaration char *getzonerootbylabel(m_label_t *label); +version SUNW_2.1 +end + +function getzonerootbyname +include <tsol/label.h> +declaration char *getzonerootbyname(char *zone); +version SUNW_2.1 +end + +function setflabel +include <tsol/label.h> +declaration int setflabel(const char *path, m_label_t *label); +version SUNW_2.1 +end + +function getuserrange +include <tsol/label.h> +declaration m_range_t *getuserrange(const char *username); +version SUNW_2.1 +end diff --git a/usr/src/lib/libtsol/spec/versions b/usr/src/lib/libtsol/spec/versions new file mode 100644 index 0000000000..40f1cccb72 --- /dev/null +++ b/usr/src/lib/libtsol/spec/versions @@ -0,0 +1,45 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# vers file for libtsol +# + +sparc { + SUNW_2.1; + SUNWprivate_1.1; +} +i386 { + SUNW_2.1; + SUNWprivate_1.1; +} +sparcv9 { + SUNW_2.1; + SUNWprivate_1.1; +} +amd64 { + SUNW_2.1; + SUNWprivate_1.1; +} diff --git a/usr/src/lib/libzonecfg/common/libzonecfg.c b/usr/src/lib/libzonecfg/common/libzonecfg.c index 36862ce976..cede45643a 100644 --- a/usr/src/lib/libzonecfg/common/libzonecfg.c +++ b/usr/src/lib/libzonecfg/common/libzonecfg.c @@ -49,8 +49,6 @@ #include <arpa/inet.h> #include <netdb.h> -#include <priv.h> - #include <libxml/xmlmemory.h> #include <libxml/parser.h> @@ -125,8 +123,8 @@ #define ATTACH_FORCED "SUNWattached.xml" #define PKG_PATH "/var/sadm/pkg" #define CONTENTS_FILE "/var/sadm/install/contents" -#define ALL_ZONES "SUNW_PKG_ALLZONES=true\n" -#define THIS_ZONE "SUNW_PKG_THISZONE=true\n" +#define SUNW_PKG_ALL_ZONES "SUNW_PKG_ALLZONES=true\n" +#define SUNW_PKG_THIS_ZONE "SUNW_PKG_THISZONE=true\n" #define VERSION "VERSION=" #define PATCHLIST "PATCHLIST=" #define PATCHINFO "PATCH_INFO_" @@ -3417,7 +3415,9 @@ static const char *default_priv_list[] = { PRIV_IPC_DAC_READ, PRIV_IPC_DAC_WRITE, PRIV_IPC_OWNER, + PRIV_NET_BINDMLP, PRIV_NET_ICMPACCESS, + PRIV_NET_MAC_AWARE, PRIV_NET_PRIVADDR, PRIV_PROC_CHROOT, PRIV_SYS_AUDIT, @@ -5294,10 +5294,10 @@ get_pkginfo(char *pkginfo, struct zone_pkginfo *infop) len = strlen(infop->zpi_version); *(infop->zpi_version + len - 1) = 0; - } else if (strcmp(buf, ALL_ZONES) == 0) { + } else if (strcmp(buf, SUNW_PKG_ALL_ZONES) == 0) { infop->zpi_all_zones = B_TRUE; - } else if (strcmp(buf, THIS_ZONE) == 0) { + } else if (strcmp(buf, SUNW_PKG_THIS_ZONE) == 0) { infop->zpi_this_zone = B_TRUE; } else if (strncmp(buf, PATCHINFO, sizeof (PATCHINFO) - 1) diff --git a/usr/src/lib/nsswitch/files/Makefile.com b/usr/src/lib/nsswitch/files/Makefile.com index e71a2db442..f6105144d7 100644 --- a/usr/src/lib/nsswitch/files/Makefile.com +++ b/usr/src/lib/nsswitch/files/Makefile.com @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -18,6 +17,8 @@ # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END + + # # # Copyright 2006 Sun Microsystems, Inc. All rights reserved. @@ -49,7 +50,9 @@ OBJECTS = bootparams_getbyname.o \ getexecattr.o \ getuserattr.o \ getauuser.o \ - netmasks.o + netmasks.o \ + tsol_getrhent.o \ + tsol_gettpent.o # include common nsswitch library definitions. include ../../Makefile.com diff --git a/usr/src/lib/nsswitch/files/common/mapfile-vers b/usr/src/lib/nsswitch/files/common/mapfile-vers index a4c6b1b67f..7210caf3d7 100644 --- a/usr/src/lib/nsswitch/files/common/mapfile-vers +++ b/usr/src/lib/nsswitch/files/common/mapfile-vers @@ -1,15 +1,14 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -59,6 +58,8 @@ SUNWprivate_1.1 { _nss_files_services_constr; _nss_files_shadow_constr; _nss_files_user_attr_constr; + _nss_files_tnrhdb_constr; + _nss_files_tnrhtp_constr; local: *; }; diff --git a/usr/src/lib/nsswitch/files/common/tsol_getrhent.c b/usr/src/lib/nsswitch/files/common/tsol_getrhent.c new file mode 100644 index 0000000000..f41f606034 --- /dev/null +++ b/usr/src/lib/nsswitch/files/common/tsol_getrhent.c @@ -0,0 +1,73 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include "files_common.h" +#include <string.h> +#include <libtsnet.h> + +/* + * files/tsol_getrhent.c -- + * "files" backend for nsswitch "tnrhdb" database + */ +static int +check_addr(nss_XbyY_args_t *args) +{ + tsol_rhstr_t *rhstrp = (tsol_rhstr_t *)args->returnval; + + if ((args->key.hostaddr.type == rhstrp->family) && + (strcmp(args->key.hostaddr.addr, rhstrp->address) == 0)) + return (1); + + return (0); +} + +static nss_status_t +getbyaddr(files_backend_ptr_t be, void *a) +{ + nss_XbyY_args_t *argp = a; + + return (_nss_files_XY_all(be, argp, 1, + argp->key.hostaddr.addr, check_addr)); +} + +static files_backend_op_t tsol_rh_ops[] = { + _nss_files_destr, + _nss_files_endent, + _nss_files_setent, + _nss_files_getent_netdb, + getbyaddr +}; + +/* ARGSUSED */ +nss_backend_t * +_nss_files_tnrhdb_constr(const char *dummy1, const char *dummy2, + const char *dummy3) +{ + return (_nss_files_constr(tsol_rh_ops, + sizeof (tsol_rh_ops) / sizeof (tsol_rh_ops[0]), TNRHDB_PATH, + NSS_LINELEN_TSOL_RH, NULL)); +} diff --git a/usr/src/lib/nsswitch/files/common/tsol_gettpent.c b/usr/src/lib/nsswitch/files/common/tsol_gettpent.c new file mode 100644 index 0000000000..ae5e9ca2be --- /dev/null +++ b/usr/src/lib/nsswitch/files/common/tsol_gettpent.c @@ -0,0 +1,75 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include "files_common.h" +#include <sys/tsol/tndb.h> +#include <string.h> + +/* + * files/tsol_gettpent.c -- + * "files" backend for nsswitch "tnrhtp" database + */ +static int +check_name(nss_XbyY_args_t *args) +{ + tsol_tpstr_t *tpstrp = (tsol_tpstr_t *)args->returnval; + const char *name = args->key.name; + + if (strcmp(tpstrp->template, name) == 0) + return (1); + + return (0); +} + +static nss_status_t +getbyname(be, a) + files_backend_ptr_t be; + void *a; +{ + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; + + return (_nss_files_XY_all(be, argp, 1, argp->key.name, check_name)); +} + +static files_backend_op_t tsol_tp_ops[] = { + _nss_files_destr, + _nss_files_endent, + _nss_files_setent, + _nss_files_getent_netdb, + getbyname +}; + +nss_backend_t * +_nss_files_tnrhtp_constr(dummy1, dummy2, dummy3) + const char *dummy1, *dummy2, *dummy3; +{ + return (_nss_files_constr(tsol_tp_ops, + sizeof (tsol_tp_ops) / sizeof (tsol_tp_ops[0]), + "/etc/security/tsol/tnrhtp", + NSS_LINELEN_TSOL_TP, + NULL)); +} diff --git a/usr/src/lib/nsswitch/ldap/Makefile.com b/usr/src/lib/nsswitch/ldap/Makefile.com index 03d14aa6a7..031dd04f46 100644 --- a/usr/src/lib/nsswitch/ldap/Makefile.com +++ b/usr/src/lib/nsswitch/ldap/Makefile.com @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -18,12 +17,14 @@ # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END + + # # #ident "%Z%%M% %I% %E% SMI" # -# Copyright (c) 1999-2001 by Sun Microsystems, Inc. -# All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # # lib/nsswitch/ldap/Makefile.com @@ -51,6 +52,8 @@ OBJECTS = getauthattr.o \ getservent.o \ getspent.o \ getuserattr.o \ + tsol_getrhent.o \ + tsol_gettpent.o \ ldap_common.o \ ldap_utils.o diff --git a/usr/src/lib/nsswitch/ldap/common/ldap_common.c b/usr/src/lib/nsswitch/ldap/common/ldap_common.c index 06acfe2e9b..9d961d9d1d 100644 --- a/usr/src/lib/nsswitch/ldap/common/ldap_common.c +++ b/usr/src/lib/nsswitch/ldap/common/ldap_common.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -55,6 +54,9 @@ #define _F_GETSPENT "(objectclass=shadowAccount)" #define _F_GETUSERNAME "(objectClass=SolarisUserAttr)" #define _F_GETPROJENT "(objectClass=SolarisProject)" +#define _F_GETTNRHDB "(objectClass=ipTnetHost)" +#define _F_GETTNRHTP "(&(objectClass=ipTnetTemplate)"\ + "(SolarisAttrKeyValue=*))" #define _F_GETENT_SSD "(%s)" static struct gettablefilter { @@ -77,6 +79,8 @@ static struct gettablefilter { {(char *)_USERATTR, (char *)_F_GETUSERNAME}, {(char *)_PROJECT, (char *)_F_GETPROJENT}, {(char *)_PRINTERS, (char *)_F_GETPRINTERENT}, + {(char *)_TNRHDB, (char *)_F_GETTNRHDB}, + {(char *)_TNRHTP, (char *)_F_GETTNRHTP}, {(char *)NULL, (char *)NULL} }; diff --git a/usr/src/lib/nsswitch/ldap/common/ldap_common.h b/usr/src/lib/nsswitch/ldap/common/ldap_common.h index 292abfba54..23d5e2b1ae 100644 --- a/usr/src/lib/nsswitch/ldap/common/ldap_common.h +++ b/usr/src/lib/nsswitch/ldap/common/ldap_common.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -68,6 +67,8 @@ extern "C" { #define _SERVICES "services" #define _SHADOW "shadow" #define _USERATTR "user_attr" +#define _TNRHDB "tnrhdb" +#define _TNRHTP "tnrhtp" #define NSS_STR_PARSE_NO_ADDR (NSS_STR_PARSE_ERANGE + 100) diff --git a/usr/src/lib/nsswitch/ldap/common/mapfile-vers b/usr/src/lib/nsswitch/ldap/common/mapfile-vers index 9daed00900..ae31444846 100644 --- a/usr/src/lib/nsswitch/ldap/common/mapfile-vers +++ b/usr/src/lib/nsswitch/ldap/common/mapfile-vers @@ -1,15 +1,14 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -61,6 +60,8 @@ SUNWprivate_1.1 { _nss_ldap_shadow_constr; _nss_ldap_publickey_constr; _nss_ldap_user_attr_constr; + _nss_ldap_tnrhdb_constr; + _nss_ldap_tnrhtp_constr; local: *; }; diff --git a/usr/src/lib/nsswitch/ldap/common/tsol_getrhent.c b/usr/src/lib/nsswitch/ldap/common/tsol_getrhent.c new file mode 100644 index 0000000000..90a21988a2 --- /dev/null +++ b/usr/src/lib/nsswitch/ldap/common/tsol_getrhent.c @@ -0,0 +1,183 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <netdb.h> +#include "ldap_common.h" +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <sys/tsol/tndb.h> + +/* tnrhdb attributes filters */ +#define _TNRHDB_ADDR "ipTnetNumber" +#define _TNRHDB_TNAME "ipTnetTemplateName" +#define _F_GETTNDBBYADDR "(&(objectClass=ipTnetHost)(ipTnetNumber=%s))" +#define _F_GETTNDBBYADDR_SSD "(&(%%s)(ipTnetNumber=%s))" + +static const char *tnrhdb_attrs[] = { + _TNRHDB_ADDR, + _TNRHDB_TNAME, + NULL +}; + +static int +_nss_ldap_tnrhdb2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +{ + int i, nss_result; + int len = 0; + int buflen = 0; + char *buffer = NULL; + char *ceiling = NULL; + ns_ldap_attr_t *attrptr; + ns_ldap_result_t *result = be->result; + tsol_rhstr_t *rhstrp; + + buffer = argp->buf.buffer; + buflen = argp->buf.buflen; + if (argp->buf.result == NULL) { + nss_result = NSS_STR_PARSE_ERANGE; + goto result_tnrhdb2ent; + } + rhstrp = (tsol_rhstr_t *)(argp->buf.result); + rhstrp->family = 0; + rhstrp->address = rhstrp->template = NULL; + ceiling = buffer + buflen; + (void) memset(argp->buf.buffer, 0, buflen); + attrptr = getattr(result, 0); + if (attrptr == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_tnrhdb2ent; + } + for (i = 0; i < result->entry->attr_count; i++) { + attrptr = getattr(result, i); + if (attrptr == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_tnrhdb2ent; + } + if (strcasecmp(attrptr->attrname, _TNRHDB_ADDR) == 0) { + len = strlen(attrptr->attrvalue[0]); + if (len < 1 || (attrptr->attrvalue[0] == '\0')) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_tnrhdb2ent; + } + rhstrp->address = buffer; + buffer += len + 1; + if (buffer >= ceiling) { + nss_result = (int)NSS_STR_PARSE_ERANGE; + goto result_tnrhdb2ent; + } + (void) strcpy(rhstrp->address, attrptr->attrvalue[0]); + continue; + } + if (strcasecmp(attrptr->attrname, _TNRHDB_TNAME) == 0) { + len = strlen(attrptr->attrvalue[0]); + if (len < 1 || (attrptr->attrvalue[0] == '\0')) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_tnrhdb2ent; + } + rhstrp->template = buffer; + buffer += len + 1; + if (buffer >= ceiling) { + nss_result = (int)NSS_STR_PARSE_ERANGE; + goto result_tnrhdb2ent; + } + (void) strcpy(rhstrp->template, attrptr->attrvalue[0]); + continue; + } + } + nss_result = NSS_STR_PARSE_SUCCESS; + +#ifdef DEBUG + (void) printf("\n[tsol_getrhent.c: _nss_ldap_tnrhdb2ent]\n"); + (void) printf(" address: [%s]\n", + rhstrp->address ? rhstrp->address : "NULL"); + (void) printf("template: [%s]\n", + rhstrp->template ? rhstrp->template : "NULL"); +#endif /* DEBUG */ + +result_tnrhdb2ent: + (void) __ns_ldap_freeResult(&be->result); + return (nss_result); +} + + +static nss_status_t +getbyaddr(ldap_backend_ptr be, void *a) +{ + char searchfilter[SEARCHFILTERLEN]; + char userdata[SEARCHFILTERLEN]; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; + struct in_addr addr; + char buf[18]; + extern char *inet_ntoa_r(); + +#ifdef DEBUG + (void) fprintf(stdout, "\n[tsol_getrhent.c: getbyaddr]\n"); +#endif /* DEBUG */ + + (void) memcpy(&addr, argp->key.hostaddr.addr, sizeof (addr)); + (void) inet_ntoa_r(addr, buf); + + if (snprintf(searchfilter, sizeof (searchfilter), _F_GETTNDBBYADDR, + buf) < 0) + return ((nss_status_t)NSS_NOTFOUND); + + if (snprintf(userdata, sizeof (userdata), _F_GETTNDBBYADDR_SSD, + buf) < 0) + return ((nss_status_t)NSS_NOTFOUND); + + return (_nss_ldap_lookup(be, argp, _TNRHDB, searchfilter, NULL, + _merge_SSD_filter, userdata)); +} + + +static ldap_backend_op_t tnrhdb_ops[] = { + _nss_ldap_destr, + _nss_ldap_endent, + _nss_ldap_setent, + _nss_ldap_getent, + getbyaddr +}; + + +/* ARGSUSED */ +nss_backend_t * +_nss_ldap_tnrhdb_constr(const char *dummy1, + const char *dummy2, + const char *dummy3, + const char *dummy4, + const char *dummy5) +{ +#ifdef DEBUG + (void) fprintf(stdout, + "\n[tsol_getrhent.c: _nss_ldap_tnrhdb_constr]\n"); +#endif + return ((nss_backend_t *)_nss_ldap_constr(tnrhdb_ops, + sizeof (tnrhdb_ops)/sizeof (tnrhdb_ops[0]), _TNRHDB, + tnrhdb_attrs, _nss_ldap_tnrhdb2ent)); +} diff --git a/usr/src/lib/nsswitch/ldap/common/tsol_gettpent.c b/usr/src/lib/nsswitch/ldap/common/tsol_gettpent.c new file mode 100644 index 0000000000..b7f5423f6f --- /dev/null +++ b/usr/src/lib/nsswitch/ldap/common/tsol_gettpent.c @@ -0,0 +1,182 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include "ldap_common.h" +#include <sys/tsol/tndb.h> + +/* tnrhtp attributes filters */ +#define _TNRHTP_NAME "ipTnetTemplateName" +#define _TNRHTP_ATTRS "SolarisAttrKeyValue" +#define _F_GETTNTPBYNAME "(&(objectClass=ipTnetTemplate)"\ + "(ipTnetTemplateName=%s))" +#define _F_GETTNTPBYNAME_SSD "(&(%%s)(ipTnetTemplateName=%s))" + +static const char *tnrhtp_attrs[] = { + _TNRHTP_NAME, + _TNRHTP_ATTRS, + NULL +}; + +static int +_nss_ldap_tnrhtp2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +{ + int i, nss_result; + int len = 0; + int buflen = 0; + char *buffer = NULL; + char *ceiling = NULL; + ns_ldap_attr_t *attrptr; + ns_ldap_result_t *result = be->result; + tsol_tpstr_t *tpstrp; + + buffer = argp->buf.buffer; + buflen = argp->buf.buflen; + if (argp->buf.result == NULL) { + nss_result = (int)NSS_STR_PARSE_ERANGE; + goto result_tnrhtp2ent; + } + tpstrp = (tsol_tpstr_t *)(argp->buf.result); + tpstrp->template = tpstrp->attrs = NULL; + ceiling = buffer + buflen; + (void) memset(argp->buf.buffer, 0, buflen); + attrptr = getattr(result, 0); + if (attrptr == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_tnrhtp2ent; + } + for (i = 0; i < result->entry->attr_count; i++) { + attrptr = getattr(result, i); + if (attrptr == NULL) { + nss_result = (int)NSS_STR_PARSE_PARSE; + goto result_tnrhtp2ent; + } +#ifdef DEBUG + (void) fprintf(stdout, + "\n[tsol_gettpent.c: _nss_ldap_tnrhtp2ent %d]\n", i); + (void) fprintf(stdout, " entry value count %d: %s:%s\n", + attrptr->value_count, + attrptr->attrname ? attrptr->attrname : "NULL", + attrptr->attrvalue[0] ? attrptr->attrvalue[0] : "NULL"); +#endif /* DEBUG */ + if (strcasecmp(attrptr->attrname, _TNRHTP_NAME) == 0) { + len = strlen(attrptr->attrvalue[0]); + if (len < 1 || (attrptr->attrvalue[0] == '\0')) { + nss_result = (int)NSS_STR_PARSE_PARSE; + goto result_tnrhtp2ent; + } + tpstrp->template = buffer; + buffer += len + 1; + if (buffer >= ceiling) { + nss_result = (int)NSS_STR_PARSE_ERANGE; + goto result_tnrhtp2ent; + } + (void) strcpy(tpstrp->template, attrptr->attrvalue[0]); + continue; + } + if (strcasecmp(attrptr->attrname, _TNRHTP_ATTRS) == 0) { + len = strlen(attrptr->attrvalue[0]); + if (len < 1 || (attrptr->attrvalue[0] == '\0')) { + nss_result = (int)NSS_STR_PARSE_PARSE; + goto result_tnrhtp2ent; + } + tpstrp->attrs = buffer; + buffer += len + 1; + if (buffer >= ceiling) { + nss_result = (int)NSS_STR_PARSE_PARSE; + goto result_tnrhtp2ent; + } + (void) strcpy(tpstrp->attrs, attrptr->attrvalue[0]); + continue; + } + } + if (tpstrp->attrs == NULL) + nss_result = NSS_STR_PARSE_PARSE; + else + nss_result = NSS_STR_PARSE_SUCCESS; + +#ifdef DEBUG + (void) fprintf(stdout, "\n[tsol_gettpent.c: _nss_ldap_tnrhtp2ent]\n"); + (void) fprintf(stdout, " template: [%s]\n", + tpstrp->template ? tpstrp->template : "NULL"); + (void) fprintf(stdout, " attrs: [%s]\n", + tpstrp->attrs ? tpstrp->attrs : "NULL"); +#endif /* DEBUG */ + +result_tnrhtp2ent: + (void) __ns_ldap_freeResult(&be->result); + return (nss_result); +} + + +static nss_status_t +getbyname(ldap_backend_ptr be, void *a) +{ + char searchfilter[SEARCHFILTERLEN]; + char userdata[SEARCHFILTERLEN]; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; + +#ifdef DEBUG + (void) fprintf(stdout, "\n[tsol_gettpent.c: getbyname]\n"); +#endif /* DEBUG */ + + if (snprintf(searchfilter, SEARCHFILTERLEN, _F_GETTNTPBYNAME, + argp->key.name) < 0) + return ((nss_status_t)NSS_NOTFOUND); + + if (snprintf(userdata, sizeof (userdata), _F_GETTNTPBYNAME_SSD, + argp->key.name) < 0) + return ((nss_status_t)NSS_NOTFOUND); + + return (_nss_ldap_lookup(be, argp, _TNRHTP, searchfilter, NULL, + _merge_SSD_filter, userdata)); +} + + +static ldap_backend_op_t tnrhtp_ops[] = { + _nss_ldap_destr, + _nss_ldap_endent, + _nss_ldap_setent, + _nss_ldap_getent, + getbyname +}; + + +nss_backend_t * +_nss_ldap_tnrhtp_constr(const char *dummy1, + const char *dummy2, + const char *dummy3, + const char *dummy4, + const char *dummy5) +{ +#ifdef DEBUG + (void) fprintf(stdout, + "\n[gettnrhtpattr.c: _nss_ldap_tnrhtp_constr]\n"); +#endif + return ((nss_backend_t *)_nss_ldap_constr(tnrhtp_ops, + sizeof (tnrhtp_ops)/sizeof (tnrhtp_ops[0]), _TNRHTP, + tnrhtp_attrs, _nss_ldap_tnrhtp2ent)); +} |
