xref: /titanic_44/usr/src/cmd/lp/lib/lp/tx.c (revision f967d548b23673f68e7356c6c741329b7698269c)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 
26 #include <sys/types.h>
27 #include <sys/zone.h>
28 #include <syslog.h>
29 #include <strings.h>
30 
31 #include <ucred.h>
32 #include "tsol/label.h"
33 /* lpsched include files */
34 #if defined PS_FAULTED
35 #undef  PS_FAULTED
36 #endif /* PS_FAULTED */
37 #include "lp.h"
38 #include <sys/tsol/label_macro.h>
39 
40 /*
41  * get_labeled_zonename - gets the the zonename with the same label.
42  *
43  *	Input:
44  *		slabel - USER_CLEAR label to match
45  *
46  *	Output:
47  *		-1 - zonename with that label could not be found
48  *			or no memory for zonename
49  *		 0 - label was GLOBAL_ZONENAME
50  *		 addr - zonename of zone matching USER_CLEAR label
51  *			must be retuened by calling Free(addr)
52  *
53  */
54 
55 char *
56 get_labeled_zonename(char *slabel)
57 {
58 	m_label_t	*bsl = NULL;
59 	int	err = 0;
60 	ssize_t	zonename_size = -1;
61 	zoneid_t	zid = -1;
62 	char *zname = NULL;
63 
64 	syslog(LOG_DEBUG, "lpsched: get_labeled_zonename %s", slabel);
65 	/*
66 	 * convert the label to binary.
67 	 */
68 	if (str_to_label(slabel, &bsl, USER_CLEAR,
69 	    L_NO_CORRECTION, &err) == -1) {
70 		/* label could not be converted, error */
71 		syslog(LOG_WARNING,
72 		    "lpsched: %s: label not recognized (error==%d)",
73 		    slabel, err);
74 		return ((char *)-1);
75 	}
76 	if ((zid = getzoneidbylabel(bsl)) < 0) {
77 		/* no zone with that label, cannot send mail */
78 		syslog(LOG_WARNING,
79 		    "lpsched: cannot send mail, no zone with %s label",
80 		    slabel);
81 		m_label_free(bsl);
82 		return ((char *)-1);
83 	}
84 	zname = Malloc(ZONENAME_MAX + 1);
85 	if ((zonename_size = getzonenamebyid(zid, zname, ZONENAME_MAX + 1))
86 	    == -1) {
87 		/* cannot get zone name, cannot send mail */
88 		syslog(LOG_WARNING,
89 		    "lpsched: cannot send mail, no zone name for %s",
90 		    slabel);
91 		m_label_free(bsl);
92 		Free(zname);
93 		return ((char *)-1);
94 	} else {
95 		m_label_free(bsl);
96 		if (strcmp(zname, GLOBAL_ZONENAME) == 0) {
97 			Free(zname);
98 			zname = NULL;
99 		}
100 	}
101 	return (zname);
102 }
103 
104 int
105 get_peer_label(int fd, char **slabel)
106 {
107 	if (is_system_labeled()) {
108 		ucred_t *uc = NULL;
109 		m_label_t *sl;
110 		m_label_t admin_low;
111 		m_label_t admin_high;
112 		char *pslabel = NULL; /* peer's slabel */
113 
114 		if ((fd < 0) || (slabel == NULL)) {
115 			errno = EINVAL;
116 			return (-1);
117 		}
118 		bsllow(&admin_low);
119 		bslhigh(&admin_high);
120 
121 		if (getpeerucred(fd, &uc) == -1)
122 			return (-1);
123 
124 		sl = ucred_getlabel(uc);
125 
126 		/*
127 		 * Remote print requests from the global zone
128 		 * arrive at admin_low, make them admin_high to
129 		 * avoid downgrade.
130 		 */
131 		if (blequal(sl, &admin_low)) {
132 			sl = &admin_high;
133 			syslog(LOG_DEBUG, "get_peer_label(): upgrade"
134 			    " admin_low label to admin_high");
135 		}
136 
137 		if (label_to_str(sl, &pslabel, M_INTERNAL, DEF_NAMES) != 0)
138 			syslog(LOG_WARNING, "label_to_str(): %m");
139 		ucred_free(uc);
140 
141 		if (pslabel != NULL) {
142 			syslog(LOG_DEBUG, "get_peer_label(%d, %s): becomes %s",
143 			    fd, (*slabel ? *slabel : "NULL"), pslabel);
144 			if (*slabel != NULL)
145 				free(*slabel);
146 			*slabel = strdup(pslabel);
147 		}
148 	}
149 
150 	return (0);
151 }
152