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