xref: /illumos-gate/usr/src/cmd/lp/lib/secure/secure.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
33 
34 #include "string.h"
35 #include "sys/param.h"
36 #include "stdlib.h"
37 
38 #include "lp.h"
39 #include "secure.h"
40 #include <tsol/label.h>
41 
42 /**
43  ** getsecure() - EXTRACT SECURE REQUEST STRUCTURE FROM DISK FILE
44  **/
45 
46 SECURE *
47 getsecure(char *file)
48 {
49 	SECURE		*secp;
50 
51 	char			buf[BUFSIZ],
52 				*path;
53 
54 	int fd;
55 
56 	int			fld;
57 
58 
59 	if (*file == '/')
60 		path = Strdup(file);
61 	else
62 		path = makepath(Lp_Requests, file, (char *)0);
63 	if (!path)
64 		return (0);
65 
66 	if ((fd = open_locked(path, "r", MODE_NOREAD)) < 0) {
67 		Free (path);
68 		return (0);
69 	}
70 	Free (path);
71 
72 	secp = calloc(sizeof (*secp), 1);
73 
74 	secp->user = 0;
75 	errno = 0;
76 	for (
77 		fld = 0;
78 		fld < SC_MAX && fdgets(buf, BUFSIZ, fd);
79 		fld++
80 	) {
81 		buf[strlen(buf) - 1] = 0;
82 		switch (fld) {
83 
84 		case SC_REQID:
85 			secp->req_id = Strdup(buf);
86 			break;
87 
88 		case SC_UID:
89 			secp->uid = (uid_t)atol(buf);
90 			break;
91 
92 		case SC_USER:
93 			secp->user = Strdup(buf);
94 			break;
95 
96 		case SC_GID:
97 			secp->gid = (gid_t)atol(buf);
98 			break;
99 
100 		case SC_SIZE:
101 			secp->size = (size_t)atol(buf);
102 			break;
103 
104 		case SC_DATE:
105 			secp->date = (time_t)atol(buf);
106 			break;
107 
108 		case SC_SLABEL:
109 			secp->slabel = Strdup(buf);
110 			break;
111 		}
112 	}
113 	if (errno != 0 || fld != SC_MAX) {
114 		int			save_errno = errno;
115 
116 		freesecure (secp);
117 		close(fd);
118 		errno = save_errno;
119 		return (0);
120 	}
121 	close(fd);
122 
123 	/*
124 	 * Now go through the structure and see if we have
125 	 * anything strange.
126 	 */
127 	if (
128 	        secp->uid > MAXUID
129 	     || !secp->user
130 	     || secp->gid > MAXUID
131 	     || secp->size == 0
132 	     || secp->date <= 0
133 	) {
134 		freesecure (secp);
135 		errno = EBADF;
136 		return (0);
137 	}
138 
139 	return (secp);
140 }
141 
142 /**
143  ** putsecure() - WRITE SECURE REQUEST STRUCTURE TO DISK FILE
144  **/
145 
146 int
147 putsecure(char *file, SECURE *secbufp)
148 {
149 	char			*path;
150 
151 	int fd;
152 
153 	int			fld;
154 
155 	if (*file == '/')
156 		path = Strdup(file);
157 	else
158 		path = makepath(Lp_Requests, file, (char *)0);
159 	if (!path)
160 		return (-1);
161 
162 	if ((fd = open_locked(path, "w", MODE_NOREAD)) < 0) {
163 		Free (path);
164 		return (-1);
165 	}
166 	Free (path);
167 
168 	if (
169 		!secbufp->req_id ||
170 		!secbufp->user
171 	)
172 		return (-1);
173 
174 	for (fld = 0; fld < SC_MAX; fld++)
175 
176 		switch (fld) {
177 
178 		case SC_REQID:
179 			(void)fdprintf(fd, "%s\n", secbufp->req_id);
180 			break;
181 
182 		case SC_UID:
183 			(void)fdprintf(fd, "%u\n", secbufp->uid);
184 			break;
185 
186 		case SC_USER:
187 			(void)fdprintf(fd, "%s\n", secbufp->user);
188 			break;
189 
190 		case SC_GID:
191 			(void)fdprintf(fd, "%u\n", secbufp->gid);
192 			break;
193 
194 		case SC_SIZE:
195 			(void)fdprintf(fd, "%lu\n", secbufp->size);
196 			break;
197 
198 		case SC_DATE:
199 			(void)fdprintf(fd, "%ld\n", secbufp->date);
200 			break;
201 
202 		case SC_SLABEL:
203 			if (secbufp->slabel == NULL) {
204 				if (is_system_labeled()) {
205 					m_label_t *sl;
206 
207 					sl = m_label_alloc(MAC_LABEL);
208 					(void) getplabel(sl);
209 					if (label_to_str(sl, &(secbufp->slabel),
210 					    M_INTERNAL, DEF_NAMES) != 0) {
211 						perror("label_to_str");
212 						secbufp->slabel =
213 						    strdup("bad_label");
214 					}
215 					m_label_free(sl);
216 					(void) fdprintf(fd, "%s\n",
217 					    secbufp->slabel);
218 				} else {
219 					(void) fdprintf(fd, "none\n");
220 				}
221 			} else {
222 				(void) fdprintf(fd, "%s\n", secbufp->slabel);
223 			}
224 			break;
225 		}
226 	close(fd);
227 
228 	return (0);
229 }
230 
231 /*
232 **  rmsecure ()
233 **
234 **	o  'reqfilep' is of the form 'node-name/request-file'
235 **	   e.g. 'sfcalv/123-0'.
236 */
237 int
238 rmsecure (char *reqfilep)
239 {
240 	int	n;
241 	char *	pathp;
242 
243 	pathp = makepath (Lp_Requests, reqfilep, (char *) 0);
244 	if (! pathp)
245 		return	-1;
246 
247 	n = Unlink (pathp);
248 	Free (pathp);
249 
250 	return	n;
251 }
252 
253 /**
254  ** freesecure() - FREE A SECURE STRUCTURE
255  **/
256 
257 void
258 freesecure(SECURE *secbufp)
259 {
260 	if (!secbufp)
261 		return;
262 	if (secbufp->req_id)
263 		Free (secbufp->req_id);
264 	if (secbufp->user)
265 		Free (secbufp->user);
266 	Free (secbufp);
267 
268 	return;
269 }
270