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
papiServiceCreate(papi_service_t * handle,char * service_name,char * user_name,char * password,int (* authCB)(papi_service_t svc,void * app_data),papi_encryption_t encryption,void * app_data)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
papiServiceDestroy(papi_service_t handle)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
papiServiceSetPeer(papi_service_t handle,int peerfd)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
papiServiceSetUserName(papi_service_t handle,char * user_name)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
papiServiceSetPassword(papi_service_t handle,char * password)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
papiServiceSetEncryption(papi_service_t handle,papi_encryption_t encryption)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
papiServiceSetAuthCB(papi_service_t handle,int (* authCB)(papi_service_t svc,void * app_data))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
papiServiceSetAppData(papi_service_t handle,void * app_data)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 *
papiServiceGetServiceName(papi_service_t handle)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 *
papiServiceGetUserName(papi_service_t handle)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 *
papiServiceGetPassword(papi_service_t handle)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
papiServiceGetEncryption(papi_service_t handle)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 *
papiServiceGetAppData(papi_service_t handle)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 **
papiServiceGetAttributeList(papi_service_t handle)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 *
papiServiceGetStatusMessage(papi_service_t handle)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
detailed_error(service_t * svc,char * fmt,...)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