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