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 40papi_status_t 41papiServiceCreate(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 80void 81papiServiceDestroy(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 */ 99papi_status_t 100papiServiceSetPeer(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 127papi_status_t 128papiServiceSetUserName(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 139papi_status_t 140papiServiceSetPassword(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 151papi_status_t 152papiServiceSetEncryption(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 164papi_status_t 165papiServiceSetAuthCB(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 178papi_status_t 179papiServiceSetAppData(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 191char * 192papiServiceGetServiceName(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 204char * 205papiServiceGetUserName(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 217char * 218papiServiceGetPassword(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 230papi_encryption_t 231papiServiceGetEncryption(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 243void * 244papiServiceGetAppData(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 255papi_attribute_t ** 256papiServiceGetAttributeList(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 269char * 270papiServiceGetStatusMessage(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 282void 283detailed_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