xref: /illumos-gate/usr/src/cmd/lp/lib/papi/service.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  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*LINTLIBRARY*/
29 
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <stdarg.h>
33 #include <string.h>
34 #include <alloca.h>
35 #include <libintl.h>
36 #include <papi_impl.h>
37 
38 #include <tsol/label.h>
39 
40 papi_status_t
41 papiServiceCreate(papi_service_t *handle, char *service_name,
42 		char *user_name, char *password,
43 		int (*authCB)(papi_service_t svc, void *app_data),
44 		papi_encryption_t encryption, void *app_data)
45 {
46 	service_t *svc = NULL;
47 	char *path = Lp_FIFO;
48 
49 	if (handle == NULL)
50 		return (PAPI_BAD_ARGUMENT);
51 
52 	if ((*handle = svc = calloc(1, sizeof (*svc))) == NULL)
53 		return (PAPI_TEMPORARY_ERROR);
54 
55 	svc->md = mconnect(path, 0, 0);
56 	if (svc->md == NULL) {
57 		detailed_error(svc,
58 			gettext("can't connect to spooler for %s: %s"),
59 			(service_name ? service_name : ""), strerror(errno));
60 		return (PAPI_SERVICE_UNAVAILABLE);
61 	}
62 
63 	svc->msgbuf_size = MSGMAX;
64 	if ((svc->msgbuf = calloc(1, svc->msgbuf_size)) == NULL)
65 		return (PAPI_TEMPORARY_ERROR);
66 
67 	if (service_name != NULL)
68 		papiAttributeListAddString(&svc->attributes, PAPI_ATTR_EXCL,
69 				"service-name", service_name);
70 
71 	(void) papiServiceSetUserName(svc, user_name);
72 	(void) papiServiceSetPassword(svc, password);
73 	(void) papiServiceSetAuthCB(svc, authCB);
74 	(void) papiServiceSetAppData(svc, app_data);
75 	(void) papiServiceSetEncryption(svc, encryption);
76 
77 	return (PAPI_OK);
78 }
79 
80 void
81 papiServiceDestroy(papi_service_t handle)
82 {
83 	service_t *svc = handle;
84 
85 	if (svc != NULL) {
86 		if (svc->md != NULL)
87 			mdisconnect(svc->md);
88 		if (svc->msgbuf != NULL)
89 			free(svc->msgbuf);
90 		papiAttributeListFree(svc->attributes);
91 		free(svc);
92 	}
93 }
94 
95 /*
96  * interface for passing a peer's connection to gather sensitivity labeling
97  * from for Trusted Solaris.
98  */
99 papi_status_t
100 papiServiceSetPeer(papi_service_t handle, int peerfd)
101 {
102 	papi_status_t result = PAPI_OK;
103 	service_t *svc = handle;
104 
105 	if (svc == NULL)
106 		return (PAPI_BAD_ARGUMENT);
107 
108 	if (is_system_labeled()) {
109 		short status;
110 
111 		if ((snd_msg(svc, S_PASS_PEER_CONNECTION) < 0) ||
112 		    (ioctl(svc->md->writefd, I_SENDFD, peerfd) < 0) ||
113 		    (rcv_msg(svc, R_PASS_PEER_CONNECTION, &status) < 0))
114 			status = MTRANSMITERR;
115 
116 		if (status != MOK) {
117 			detailed_error(svc,
118 				gettext("failed to send peer connection: %s"),
119 				lpsched_status_string(status));
120 			result = lpsched_status_to_papi_status(status);
121 		}
122 	}
123 
124 	return (result);
125 }
126 
127 papi_status_t
128 papiServiceSetUserName(papi_service_t handle, char *user_name)
129 {
130 	service_t *svc = handle;
131 
132 	if (svc == NULL)
133 		return (PAPI_BAD_ARGUMENT);
134 
135 	return (papiAttributeListAddString(&svc->attributes, PAPI_ATTR_REPLACE,
136 				"user-name", user_name));
137 }
138 
139 papi_status_t
140 papiServiceSetPassword(papi_service_t handle, char *password)
141 {
142 	service_t *svc = handle;
143 
144 	if (svc == NULL)
145 		return (PAPI_BAD_ARGUMENT);
146 
147 	return (papiAttributeListAddString(&svc->attributes, PAPI_ATTR_REPLACE,
148 				"password", password));
149 }
150 
151 papi_status_t
152 papiServiceSetEncryption(papi_service_t handle,
153 			papi_encryption_t encryption)
154 {
155 	service_t *svc = handle;
156 
157 	if (svc == NULL)
158 		return (PAPI_BAD_ARGUMENT);
159 
160 	return (papiAttributeListAddInteger(&svc->attributes, PAPI_ATTR_REPLACE,
161 				"encryption", (int)encryption));
162 }
163 
164 papi_status_t
165 papiServiceSetAuthCB(papi_service_t handle,
166 			int (*authCB)(papi_service_t svc, void *app_data))
167 {
168 	service_t *svc = handle;
169 
170 	if (svc == NULL)
171 		return (PAPI_BAD_ARGUMENT);
172 
173 	svc->authCB = (int (*)(papi_service_t svc, void *app_data))authCB;
174 
175 	return (PAPI_OK);
176 }
177 
178 papi_status_t
179 papiServiceSetAppData(papi_service_t handle, void *app_data)
180 {
181 	service_t *svc = handle;
182 
183 	if (svc == NULL)
184 		return (PAPI_BAD_ARGUMENT);
185 
186 	svc->app_data = (void *)app_data;
187 
188 	return (PAPI_OK);
189 }
190 
191 char *
192 papiServiceGetServiceName(papi_service_t handle)
193 {
194 	service_t *svc = handle;
195 	char *result = NULL;
196 
197 	if (svc != NULL)
198 		papiAttributeListGetString(svc->attributes, NULL,
199 					"service-name", &result);
200 
201 	return (result);
202 }
203 
204 char *
205 papiServiceGetUserName(papi_service_t handle)
206 {
207 	service_t *svc = handle;
208 	char *result = NULL;
209 
210 	if (svc != NULL)
211 		papiAttributeListGetString(svc->attributes, NULL,
212 					"user-name", &result);
213 
214 	return (result);
215 }
216 
217 char *
218 papiServiceGetPassword(papi_service_t handle)
219 {
220 	service_t *svc = handle;
221 	char *result = NULL;
222 
223 	if (svc != NULL)
224 		papiAttributeListGetString(svc->attributes, NULL,
225 					"password", &result);
226 
227 	return (result);
228 }
229 
230 papi_encryption_t
231 papiServiceGetEncryption(papi_service_t handle)
232 {
233 	service_t *svc = handle;
234 	papi_encryption_t result = PAPI_ENCRYPT_NEVER;
235 
236 	if (svc != NULL)
237 		papiAttributeListGetInteger(svc->attributes, NULL,
238 					"encryption", (int *)&result);
239 
240 	return (result);
241 }
242 
243 void *
244 papiServiceGetAppData(papi_service_t handle)
245 {
246 	service_t *svc = handle;
247 	void *result = NULL;
248 
249 	if (svc != NULL)
250 		result = svc->app_data;
251 
252 	return (result);
253 }
254 
255 papi_attribute_t **
256 papiServiceGetAttributeList(papi_service_t handle)
257 {
258 	service_t *svc = handle;
259 	papi_attribute_t **result = NULL;
260 
261 	if (svc != NULL) {
262 		lpsched_service_information(&svc->attributes);
263 		result = svc->attributes;
264 	}
265 
266 	return (result);
267 }
268 
269 char *
270 papiServiceGetStatusMessage(papi_service_t handle)
271 {
272 	service_t *svc = handle;
273 	char *result = NULL;
274 
275 	if (svc != NULL)
276 		papiAttributeListGetString(svc->attributes, NULL,
277 					"detailed-status-message", &result);
278 
279 	return (result);
280 }
281 
282 void
283 detailed_error(service_t *svc, char *fmt, ...)
284 {
285 	if ((svc != NULL) && (fmt != NULL)) {
286 		va_list ap;
287 		size_t size;
288 		char *message = alloca(BUFSIZ);
289 
290 		va_start(ap, fmt);
291 		/*
292 		 * fill in the message.  If the buffer is too small, allocate
293 		 * one that is large enough and fill it in.
294 		 */
295 		if ((size = vsnprintf(message, BUFSIZ, fmt, ap)) >= BUFSIZ)
296 			if ((message = alloca(size)) != NULL)
297 				vsnprintf(message, size, fmt, ap);
298 		va_end(ap);
299 
300 		papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND,
301 					"detailed-status-message", message);
302 	}
303 }
304