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