xref: /onnv-gate/usr/src/cmd/lp/lib/papi/service.c (revision 2264:b2b9267d002d)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51676Sjpk  * Common Development and Distribution License (the "License").
61676Sjpk  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
221676Sjpk  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate /*LINTLIBRARY*/
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #include <stdlib.h>
310Sstevel@tonic-gate #include <stdio.h>
320Sstevel@tonic-gate #include <stdarg.h>
330Sstevel@tonic-gate #include <string.h>
340Sstevel@tonic-gate #include <alloca.h>
350Sstevel@tonic-gate #include <libintl.h>
360Sstevel@tonic-gate #include <papi_impl.h>
370Sstevel@tonic-gate 
381676Sjpk #include <tsol/label.h>
391676Sjpk 
400Sstevel@tonic-gate 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*2264Sjacobs papiServiceCreate(papi_service_t *handle, char *service_name,
42*2264Sjacobs 		char *user_name, char *password,
43*2264Sjacobs 		int (*authCB)(papi_service_t svc, void *app_data),
44*2264Sjacobs 		papi_encryption_t encryption, void *app_data)
450Sstevel@tonic-gate {
460Sstevel@tonic-gate 	service_t *svc = NULL;
470Sstevel@tonic-gate 	char *path = Lp_FIFO;
480Sstevel@tonic-gate 
490Sstevel@tonic-gate 	if (handle == NULL)
500Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
510Sstevel@tonic-gate 
520Sstevel@tonic-gate 	if ((*handle = svc = calloc(1, sizeof (*svc))) == NULL)
530Sstevel@tonic-gate 		return (PAPI_TEMPORARY_ERROR);
540Sstevel@tonic-gate 
550Sstevel@tonic-gate 	svc->md = mconnect(path, 0, 0);
560Sstevel@tonic-gate 	if (svc->md == NULL) {
570Sstevel@tonic-gate 		detailed_error(svc,
580Sstevel@tonic-gate 			gettext("can't connect to spooler for %s: %s"),
590Sstevel@tonic-gate 			(service_name ? service_name : ""), strerror(errno));
600Sstevel@tonic-gate 		return (PAPI_SERVICE_UNAVAILABLE);
610Sstevel@tonic-gate 	}
620Sstevel@tonic-gate 
630Sstevel@tonic-gate 	svc->msgbuf_size = MSGMAX;
640Sstevel@tonic-gate 	if ((svc->msgbuf = calloc(1, svc->msgbuf_size)) == NULL)
650Sstevel@tonic-gate 		return (PAPI_TEMPORARY_ERROR);
660Sstevel@tonic-gate 
670Sstevel@tonic-gate 	if (service_name != NULL)
680Sstevel@tonic-gate 		papiAttributeListAddString(&svc->attributes, PAPI_ATTR_EXCL,
690Sstevel@tonic-gate 				"service-name", service_name);
700Sstevel@tonic-gate 
710Sstevel@tonic-gate 	(void) papiServiceSetUserName(svc, user_name);
720Sstevel@tonic-gate 	(void) papiServiceSetPassword(svc, password);
730Sstevel@tonic-gate 	(void) papiServiceSetAuthCB(svc, authCB);
740Sstevel@tonic-gate 	(void) papiServiceSetAppData(svc, app_data);
750Sstevel@tonic-gate 	(void) papiServiceSetEncryption(svc, encryption);
760Sstevel@tonic-gate 
770Sstevel@tonic-gate 	return (PAPI_OK);
780Sstevel@tonic-gate }
790Sstevel@tonic-gate 
800Sstevel@tonic-gate void
papiServiceDestroy(papi_service_t handle)810Sstevel@tonic-gate papiServiceDestroy(papi_service_t handle)
820Sstevel@tonic-gate {
830Sstevel@tonic-gate 	service_t *svc = handle;
840Sstevel@tonic-gate 
850Sstevel@tonic-gate 	if (svc != NULL) {
860Sstevel@tonic-gate 		if (svc->md != NULL)
870Sstevel@tonic-gate 			mdisconnect(svc->md);
880Sstevel@tonic-gate 		if (svc->msgbuf != NULL)
890Sstevel@tonic-gate 			free(svc->msgbuf);
900Sstevel@tonic-gate 		papiAttributeListFree(svc->attributes);
910Sstevel@tonic-gate 		free(svc);
920Sstevel@tonic-gate 	}
930Sstevel@tonic-gate }
940Sstevel@tonic-gate 
951676Sjpk /*
961676Sjpk  * interface for passing a peer's connection to gather sensitivity labeling
971676Sjpk  * from for Trusted Solaris.
981676Sjpk  */
991676Sjpk papi_status_t
papiServiceSetPeer(papi_service_t handle,int peerfd)1001676Sjpk papiServiceSetPeer(papi_service_t handle, int peerfd)
1011676Sjpk {
1021676Sjpk 	papi_status_t result = PAPI_OK;
1031676Sjpk 	service_t *svc = handle;
1041676Sjpk 
1051676Sjpk 	if (svc == NULL)
1061676Sjpk 		return (PAPI_BAD_ARGUMENT);
1071676Sjpk 
1081688Srica 	if (is_system_labeled()) {
1091676Sjpk 		short status;
1101676Sjpk 
1111676Sjpk 		if ((snd_msg(svc, S_PASS_PEER_CONNECTION) < 0) ||
1121676Sjpk 		    (ioctl(svc->md->writefd, I_SENDFD, peerfd) < 0) ||
1131676Sjpk 		    (rcv_msg(svc, R_PASS_PEER_CONNECTION, &status) < 0))
1141676Sjpk 			status = MTRANSMITERR;
1151676Sjpk 
1161676Sjpk 		if (status != MOK) {
1171676Sjpk 			detailed_error(svc,
1181676Sjpk 				gettext("failed to send peer connection: %s"),
1191676Sjpk 				lpsched_status_string(status));
1201676Sjpk 			result = lpsched_status_to_papi_status(status);
1211676Sjpk 		}
1221676Sjpk 	}
1231676Sjpk 
1241676Sjpk 	return (result);
1251676Sjpk }
1261676Sjpk 
1270Sstevel@tonic-gate papi_status_t
papiServiceSetUserName(papi_service_t handle,char * user_name)128*2264Sjacobs papiServiceSetUserName(papi_service_t handle, char *user_name)
1290Sstevel@tonic-gate {
1300Sstevel@tonic-gate 	service_t *svc = handle;
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate 	if (svc == NULL)
1330Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate 	return (papiAttributeListAddString(&svc->attributes, PAPI_ATTR_REPLACE,
1360Sstevel@tonic-gate 				"user-name", user_name));
1370Sstevel@tonic-gate }
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate papi_status_t
papiServiceSetPassword(papi_service_t handle,char * password)140*2264Sjacobs papiServiceSetPassword(papi_service_t handle, char *password)
1410Sstevel@tonic-gate {
1420Sstevel@tonic-gate 	service_t *svc = handle;
1430Sstevel@tonic-gate 
1440Sstevel@tonic-gate 	if (svc == NULL)
1450Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate 	return (papiAttributeListAddString(&svc->attributes, PAPI_ATTR_REPLACE,
1480Sstevel@tonic-gate 				"password", password));
1490Sstevel@tonic-gate }
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate papi_status_t
papiServiceSetEncryption(papi_service_t handle,papi_encryption_t encryption)1520Sstevel@tonic-gate papiServiceSetEncryption(papi_service_t handle,
153*2264Sjacobs 			papi_encryption_t encryption)
1540Sstevel@tonic-gate {
1550Sstevel@tonic-gate 	service_t *svc = handle;
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate 	if (svc == NULL)
1580Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate 	return (papiAttributeListAddInteger(&svc->attributes, PAPI_ATTR_REPLACE,
1610Sstevel@tonic-gate 				"encryption", (int)encryption));
1620Sstevel@tonic-gate }
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate papi_status_t
papiServiceSetAuthCB(papi_service_t handle,int (* authCB)(papi_service_t svc,void * app_data))1650Sstevel@tonic-gate papiServiceSetAuthCB(papi_service_t handle,
166*2264Sjacobs 			int (*authCB)(papi_service_t svc, void *app_data))
1670Sstevel@tonic-gate {
1680Sstevel@tonic-gate 	service_t *svc = handle;
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate 	if (svc == NULL)
1710Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
1720Sstevel@tonic-gate 
173*2264Sjacobs 	svc->authCB = (int (*)(papi_service_t svc, void *app_data))authCB;
1740Sstevel@tonic-gate 
1750Sstevel@tonic-gate 	return (PAPI_OK);
1760Sstevel@tonic-gate }
1770Sstevel@tonic-gate 
1780Sstevel@tonic-gate papi_status_t
papiServiceSetAppData(papi_service_t handle,void * app_data)179*2264Sjacobs papiServiceSetAppData(papi_service_t handle, void *app_data)
1800Sstevel@tonic-gate {
1810Sstevel@tonic-gate 	service_t *svc = handle;
1820Sstevel@tonic-gate 
1830Sstevel@tonic-gate 	if (svc == NULL)
1840Sstevel@tonic-gate 		return (PAPI_BAD_ARGUMENT);
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate 	svc->app_data = (void *)app_data;
1870Sstevel@tonic-gate 
1880Sstevel@tonic-gate 	return (PAPI_OK);
1890Sstevel@tonic-gate }
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate char *
papiServiceGetServiceName(papi_service_t handle)1920Sstevel@tonic-gate papiServiceGetServiceName(papi_service_t handle)
1930Sstevel@tonic-gate {
1940Sstevel@tonic-gate 	service_t *svc = handle;
1950Sstevel@tonic-gate 	char *result = NULL;
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate 	if (svc != NULL)
1980Sstevel@tonic-gate 		papiAttributeListGetString(svc->attributes, NULL,
1990Sstevel@tonic-gate 					"service-name", &result);
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 	return (result);
2020Sstevel@tonic-gate }
2030Sstevel@tonic-gate 
2040Sstevel@tonic-gate char *
papiServiceGetUserName(papi_service_t handle)2050Sstevel@tonic-gate papiServiceGetUserName(papi_service_t handle)
2060Sstevel@tonic-gate {
2070Sstevel@tonic-gate 	service_t *svc = handle;
2080Sstevel@tonic-gate 	char *result = NULL;
2090Sstevel@tonic-gate 
2100Sstevel@tonic-gate 	if (svc != NULL)
2110Sstevel@tonic-gate 		papiAttributeListGetString(svc->attributes, NULL,
2120Sstevel@tonic-gate 					"user-name", &result);
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate 	return (result);
2150Sstevel@tonic-gate }
2160Sstevel@tonic-gate 
2170Sstevel@tonic-gate char *
papiServiceGetPassword(papi_service_t handle)2180Sstevel@tonic-gate papiServiceGetPassword(papi_service_t handle)
2190Sstevel@tonic-gate {
2200Sstevel@tonic-gate 	service_t *svc = handle;
2210Sstevel@tonic-gate 	char *result = NULL;
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate 	if (svc != NULL)
2240Sstevel@tonic-gate 		papiAttributeListGetString(svc->attributes, NULL,
2250Sstevel@tonic-gate 					"password", &result);
2260Sstevel@tonic-gate 
2270Sstevel@tonic-gate 	return (result);
2280Sstevel@tonic-gate }
2290Sstevel@tonic-gate 
2300Sstevel@tonic-gate papi_encryption_t
papiServiceGetEncryption(papi_service_t handle)2310Sstevel@tonic-gate papiServiceGetEncryption(papi_service_t handle)
2320Sstevel@tonic-gate {
2330Sstevel@tonic-gate 	service_t *svc = handle;
2340Sstevel@tonic-gate 	papi_encryption_t result = PAPI_ENCRYPT_NEVER;
2350Sstevel@tonic-gate 
2360Sstevel@tonic-gate 	if (svc != NULL)
2370Sstevel@tonic-gate 		papiAttributeListGetInteger(svc->attributes, NULL,
2380Sstevel@tonic-gate 					"encryption", (int *)&result);
2390Sstevel@tonic-gate 
2400Sstevel@tonic-gate 	return (result);
2410Sstevel@tonic-gate }
2420Sstevel@tonic-gate 
2430Sstevel@tonic-gate void *
papiServiceGetAppData(papi_service_t handle)2440Sstevel@tonic-gate papiServiceGetAppData(papi_service_t handle)
2450Sstevel@tonic-gate {
2460Sstevel@tonic-gate 	service_t *svc = handle;
2470Sstevel@tonic-gate 	void *result = NULL;
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate 	if (svc != NULL)
2500Sstevel@tonic-gate 		result = svc->app_data;
2510Sstevel@tonic-gate 
2520Sstevel@tonic-gate 	return (result);
2530Sstevel@tonic-gate }
2540Sstevel@tonic-gate 
255*2264Sjacobs papi_attribute_t **
papiServiceGetAttributeList(papi_service_t handle)256*2264Sjacobs papiServiceGetAttributeList(papi_service_t handle)
257*2264Sjacobs {
258*2264Sjacobs 	service_t *svc = handle;
259*2264Sjacobs 	papi_attribute_t **result = NULL;
260*2264Sjacobs 
261*2264Sjacobs 	if (svc != NULL) {
262*2264Sjacobs 		lpsched_service_information(&svc->attributes);
263*2264Sjacobs 		result = svc->attributes;
264*2264Sjacobs 	}
265*2264Sjacobs 
266*2264Sjacobs 	return (result);
267*2264Sjacobs }
268*2264Sjacobs 
2690Sstevel@tonic-gate char *
papiServiceGetStatusMessage(papi_service_t handle)2700Sstevel@tonic-gate papiServiceGetStatusMessage(papi_service_t handle)
2710Sstevel@tonic-gate {
2720Sstevel@tonic-gate 	service_t *svc = handle;
2730Sstevel@tonic-gate 	char *result = NULL;
2740Sstevel@tonic-gate 
2750Sstevel@tonic-gate 	if (svc != NULL)
2760Sstevel@tonic-gate 		papiAttributeListGetString(svc->attributes, NULL,
2770Sstevel@tonic-gate 					"detailed-status-message", &result);
2780Sstevel@tonic-gate 
2790Sstevel@tonic-gate 	return (result);
2800Sstevel@tonic-gate }
2810Sstevel@tonic-gate 
2820Sstevel@tonic-gate void
detailed_error(service_t * svc,char * fmt,...)2830Sstevel@tonic-gate detailed_error(service_t *svc, char *fmt, ...)
2840Sstevel@tonic-gate {
2850Sstevel@tonic-gate 	if ((svc != NULL) && (fmt != NULL)) {
2860Sstevel@tonic-gate 		va_list ap;
2870Sstevel@tonic-gate 		size_t size;
2880Sstevel@tonic-gate 		char *message = alloca(BUFSIZ);
2890Sstevel@tonic-gate 
2900Sstevel@tonic-gate 		va_start(ap, fmt);
2910Sstevel@tonic-gate 		/*
2920Sstevel@tonic-gate 		 * fill in the message.  If the buffer is too small, allocate
2930Sstevel@tonic-gate 		 * one that is large enough and fill it in.
2940Sstevel@tonic-gate 		 */
2950Sstevel@tonic-gate 		if ((size = vsnprintf(message, BUFSIZ, fmt, ap)) >= BUFSIZ)
2960Sstevel@tonic-gate 			if ((message = alloca(size)) != NULL)
2970Sstevel@tonic-gate 				vsnprintf(message, size, fmt, ap);
2980Sstevel@tonic-gate 		va_end(ap);
2990Sstevel@tonic-gate 
3000Sstevel@tonic-gate 		papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND,
3010Sstevel@tonic-gate 					"detailed-status-message", message);
3020Sstevel@tonic-gate 	}
3030Sstevel@tonic-gate }
304