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
46SECURE *
47getsecure(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
146int
147putsecure(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*/
237int
238rmsecure (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
257void
258freesecure(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