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