xref: /onnv-gate/usr/src/lib/print/libpapi-dynamic/common/nss.c (revision 2313:82bdbfa60ec9)
12264Sjacobs /*
22264Sjacobs  * CDDL HEADER START
32264Sjacobs  *
42264Sjacobs  * The contents of this file are subject to the terms of the
52264Sjacobs  * Common Development and Distribution License (the "License").
62264Sjacobs  * You may not use this file except in compliance with the License.
72264Sjacobs  *
82264Sjacobs  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92264Sjacobs  * or http://www.opensolaris.org/os/licensing.
102264Sjacobs  * See the License for the specific language governing permissions
112264Sjacobs  * and limitations under the License.
122264Sjacobs  *
132264Sjacobs  * When distributing Covered Code, include this CDDL HEADER in each
142264Sjacobs  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152264Sjacobs  * If applicable, add the following below this CDDL HEADER, with the
162264Sjacobs  * fields enclosed by brackets "[]" replaced with your own identifying
172264Sjacobs  * information: Portions Copyright [yyyy] [name of copyright owner]
182264Sjacobs  *
192264Sjacobs  * CDDL HEADER END
202264Sjacobs  */
212264Sjacobs 
222264Sjacobs /*
232264Sjacobs  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
242264Sjacobs  * Use is subject to license terms.
252264Sjacobs  *
262264Sjacobs  */
272264Sjacobs 
282264Sjacobs /* $Id: nss.c 166 2006-05-20 05:48:55Z njacobs $ */
292264Sjacobs 
302264Sjacobs #pragma ident	"%Z%%M%	%I%	%E% SMI"
312264Sjacobs 
322264Sjacobs #include <stdio.h>
332264Sjacobs #include <stdlib.h>
342264Sjacobs #include <unistd.h>
352264Sjacobs #include <string.h>
362264Sjacobs #include <ctype.h>
372264Sjacobs #include <sys/types.h>
382264Sjacobs #include <syslog.h>
392264Sjacobs #include <papi.h>
402264Sjacobs #include <uri.h>
412264Sjacobs #include <papi_impl.h>
422264Sjacobs #ifdef NSS_EMULATION
432264Sjacobs #include <nss-emulation.h>
442264Sjacobs #elif NSS_SOLARIS
452264Sjacobs #include <nss_dbdefs.h>
462264Sjacobs #endif
472264Sjacobs #include <config-site.h>
482264Sjacobs #if defined(__sun) && defined(__SVR4)
492264Sjacobs #include <sys/systeminfo.h>
502264Sjacobs #endif
512264Sjacobs 
522264Sjacobs 
532264Sjacobs static char *
542264Sjacobs bsdaddr_to_uri(char *bsdaddr)
552264Sjacobs {
562264Sjacobs 	char *result = NULL;
572264Sjacobs 
582264Sjacobs 	if (bsdaddr != NULL) {
592264Sjacobs 		char *bsd[3], *tmp, *iter = NULL;
602264Sjacobs 		char buf[512];
612264Sjacobs 
622264Sjacobs 		tmp = strdup(bsdaddr);
632264Sjacobs 
642264Sjacobs 		bsd[0] = strtok_r(tmp, ":,", &iter);
652264Sjacobs 		bsd[1] = strtok_r(NULL, ":,", &iter);
662264Sjacobs 		bsd[2] = strtok_r(NULL, ":,", &iter);
672264Sjacobs 
682264Sjacobs 		snprintf(buf, sizeof (buf), "lpd://%s/%s%s%s", bsd[0], bsd[1],
692264Sjacobs 			(bsd[2] != NULL) ? "#" : "",
702264Sjacobs 			(bsd[2] != NULL) ? bsd[2] : "");
712264Sjacobs 
722264Sjacobs 		free(tmp);
732264Sjacobs 
742264Sjacobs 		result = strdup(buf);
752264Sjacobs 	}
762264Sjacobs 
772264Sjacobs 	return (result);
782264Sjacobs }
792264Sjacobs 
802264Sjacobs #if defined(__sun) && defined(__SVR4)
81*2313Sjacobs #include <sys/socket.h>
82*2313Sjacobs #include <sys/ioctl.h>
83*2313Sjacobs #include <sys/sockio.h>
84*2313Sjacobs #include <net/if.h>
85*2313Sjacobs #include <netinet/in.h>
86*2313Sjacobs #include <arpa/inet.h>
87*2313Sjacobs #include <netdb.h>
88*2313Sjacobs 
89*2313Sjacobs static struct in6_addr **
90*2313Sjacobs local_interfaces()
91*2313Sjacobs {
92*2313Sjacobs 	struct in6_addr **result = NULL;
93*2313Sjacobs 	int s;
94*2313Sjacobs 	struct lifnum n;
95*2313Sjacobs 	struct lifconf c;
96*2313Sjacobs 	struct lifreq *r;
97*2313Sjacobs 	int count;
98*2313Sjacobs 
99*2313Sjacobs 	/* we need a socket to get the interfaces */
100*2313Sjacobs 	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
101*2313Sjacobs 		return (0);
102*2313Sjacobs 
103*2313Sjacobs 	/* get the number of interfaces */
104*2313Sjacobs 	memset(&n, 0, sizeof (n));
105*2313Sjacobs 	n.lifn_family = AF_UNSPEC;
106*2313Sjacobs 	if (ioctl(s, SIOCGLIFNUM, (char *)&n) < 0) {
107*2313Sjacobs 		close(s);
108*2313Sjacobs 		return (0);	/* no interfaces */
109*2313Sjacobs 	}
110*2313Sjacobs 
111*2313Sjacobs 	/* get the interface(s) configuration */
112*2313Sjacobs 	memset(&c, 0, sizeof (c));
113*2313Sjacobs 	c.lifc_family = AF_UNSPEC;
114*2313Sjacobs 	c.lifc_buf = calloc(n.lifn_count, sizeof (struct lifreq));
115*2313Sjacobs 	c.lifc_len = (n.lifn_count * sizeof (struct lifreq));
116*2313Sjacobs 	if (ioctl(s, SIOCGLIFCONF, (char *)&c) < 0) {
117*2313Sjacobs 		free(c.lifc_buf);
118*2313Sjacobs 		close(s);
119*2313Sjacobs 		return (0);	/* can't get interface(s) configuration */
120*2313Sjacobs 	}
121*2313Sjacobs 	close(s);
122*2313Sjacobs 
123*2313Sjacobs 	r = c.lifc_req;
124*2313Sjacobs 	for (count = c.lifc_len / sizeof (struct lifreq);
125*2313Sjacobs 	     count > 0; count--, r++) {
126*2313Sjacobs 		struct in6_addr v6[1], *addr = NULL;
127*2313Sjacobs 
128*2313Sjacobs 		switch (r->lifr_addr.ss_family) {
129*2313Sjacobs 		case AF_INET: {
130*2313Sjacobs 			struct sockaddr_in *s =
131*2313Sjacobs 				(struct sockaddr_in *)&r->lifr_addr;
132*2313Sjacobs 			IN6_INADDR_TO_V4MAPPED(&s->sin_addr, v6);
133*2313Sjacobs 			addr = v6;
134*2313Sjacobs 			}
135*2313Sjacobs 			break;
136*2313Sjacobs 		case AF_INET6: {
137*2313Sjacobs 			struct sockaddr_in6 *s =
138*2313Sjacobs 				(struct sockaddr_in6 *)&r->lifr_addr;
139*2313Sjacobs 			addr = &s->sin6_addr;
140*2313Sjacobs 			}
141*2313Sjacobs 			break;
142*2313Sjacobs 		}
143*2313Sjacobs 
144*2313Sjacobs 		if (addr != NULL) {
145*2313Sjacobs 			struct in6_addr *a = malloc(sizeof (*a));
146*2313Sjacobs 
147*2313Sjacobs 			memcpy(a, addr, sizeof (*a));
148*2313Sjacobs 			list_append(&result, a);
149*2313Sjacobs 		}
150*2313Sjacobs 	}
151*2313Sjacobs 	free(c.lifc_buf);
152*2313Sjacobs 
153*2313Sjacobs 	return (result);
154*2313Sjacobs }
155*2313Sjacobs 
156*2313Sjacobs static int
157*2313Sjacobs match_interfaces(char *host)
158*2313Sjacobs {
159*2313Sjacobs 	struct in6_addr **lif = local_interfaces();
160*2313Sjacobs 	struct hostent *hp;
161*2313Sjacobs 	int rc = 0;
162*2313Sjacobs 	int errnum;
163*2313Sjacobs 
164*2313Sjacobs 	/* are there any local interfaces */
165*2313Sjacobs 	if (lif == NULL)
166*2313Sjacobs 		return (0);
167*2313Sjacobs 
168*2313Sjacobs 	/* cycle through the host db addresses */
169*2313Sjacobs 	hp = getipnodebyname(host, AF_INET6, AI_ALL|AI_V4MAPPED, &errnum);
170*2313Sjacobs 	if (hp != NULL) {
171*2313Sjacobs 		struct in6_addr **tmp = (struct in6_addr **)hp->h_addr_list;
172*2313Sjacobs 		int i;
173*2313Sjacobs 
174*2313Sjacobs 		for (i = 0; ((rc == 0) && (tmp[i] != NULL)); i++) {
175*2313Sjacobs 			int j;
176*2313Sjacobs 
177*2313Sjacobs 			for (j = 0; ((rc == 0) && (lif[j] != NULL)); j++)
178*2313Sjacobs 				if (memcmp(tmp[i], lif[j],
179*2313Sjacobs 						sizeof (struct in6_addr)) == 0)
180*2313Sjacobs 					rc = 1;
181*2313Sjacobs 		}
182*2313Sjacobs 	}
183*2313Sjacobs 	free(lif);
184*2313Sjacobs 
185*2313Sjacobs 	return (rc);
186*2313Sjacobs }
187*2313Sjacobs 
188*2313Sjacobs static int
189*2313Sjacobs is_localhost(char *host)
190*2313Sjacobs {
191*2313Sjacobs 	char hostname[BUFSIZ];
192*2313Sjacobs 
193*2313Sjacobs 	/* is it "localhost" */
194*2313Sjacobs 	if (strncasecmp(host, "localhost", 10) == 0)
195*2313Sjacobs 		return (1);
196*2313Sjacobs 
197*2313Sjacobs 	/* is it the {nodename} */
198*2313Sjacobs 	sysinfo(SI_HOSTNAME, hostname, sizeof (hostname));
199*2313Sjacobs 	if (strncasecmp(host, hostname, strlen(hostname)) == 0)
200*2313Sjacobs 		return (1);
201*2313Sjacobs 
202*2313Sjacobs 	/* does it match one of the host's configured interfaces */
203*2313Sjacobs 	if (match_interfaces(host) != 0)
204*2313Sjacobs 		return (1);
205*2313Sjacobs 
206*2313Sjacobs 	return (0);
207*2313Sjacobs }
208*2313Sjacobs 
2092264Sjacobs /*
2102264Sjacobs  * This is an awful HACK to force the dynamic PAPI library to use the
2112264Sjacobs  * lpsched support when the destination apears to be a local lpsched
2122264Sjacobs  * queue on Solaris.
2132264Sjacobs  */
2142264Sjacobs static void
2152264Sjacobs solaris_lpsched_shortcircuit_hack(papi_attribute_t ***list)
2162264Sjacobs {
2172264Sjacobs 	papi_attribute_t *attribute;
2182264Sjacobs 	uri_t *uri = NULL;
2192264Sjacobs 	char *printer = NULL;
2202264Sjacobs 	char buf[128], buf2[128];
2212264Sjacobs 
2222264Sjacobs 	/* setting this in the calling env can be useful for debugging */
2232264Sjacobs 	if (getenv("DISABLE_LPSCHED_SHORTCIRCUIT") != NULL)
2242264Sjacobs 		return;
2252264Sjacobs 
2262264Sjacobs 	papiAttributeListGetString(*list, NULL,
2272264Sjacobs 				"printer-uri-supported", &printer);
2282264Sjacobs 	if (uri_from_string(printer, &uri) < 0)
2292264Sjacobs 		return;
2302264Sjacobs 
2312264Sjacobs 	/* already an lpsched URI ? */
2322264Sjacobs 	if (strcasecmp(uri->scheme, "lpsched") == 0)
2332264Sjacobs 		return;
2342264Sjacobs 
2352264Sjacobs 	if ((printer = strrchr(uri->path, '/')) == NULL)
2362264Sjacobs 		printer = uri->path;
2372264Sjacobs 	else
2382264Sjacobs 		printer++;
2392264Sjacobs 
2402264Sjacobs 	/* is there an lpsched queue (printer/class) */
2412264Sjacobs 	snprintf(buf, sizeof (buf), "/etc/lp/interfaces/%s", printer);
2422264Sjacobs 	snprintf(buf2, sizeof (buf2), "/etc/lp/classes/%s", printer);
2432264Sjacobs 	if ((access(buf, F_OK) < 0) && (access(buf2, F_OK) < 0))
2442264Sjacobs 		return;
2452264Sjacobs 
246*2313Sjacobs 	/* is this the "local" host */
247*2313Sjacobs 	if ((uri->host != NULL) && (is_localhost(uri->host) == 0))
248*2313Sjacobs 		return;
249*2313Sjacobs 
250*2313Sjacobs 	snprintf(buf, sizeof (buf), "lpsched://%s/printers/%s",
251*2313Sjacobs 			(uri->host ? uri->host : "localhost"), printer);
2522264Sjacobs 	papiAttributeListAddString(list, PAPI_ATTR_REPLACE,
2532264Sjacobs 			"printer-uri-supported", buf);
2542264Sjacobs }
2552264Sjacobs #endif
2562264Sjacobs 
2572264Sjacobs static void
2582264Sjacobs fill_printer_uri_supported(papi_attribute_t ***list)
2592264Sjacobs {
2602264Sjacobs 	papi_attribute_t *attribute;
2612264Sjacobs 	char *string = NULL;
2622264Sjacobs 
2632264Sjacobs 	/* do we have a printer-uri-supported */
2642264Sjacobs 	attribute = papiAttributeListFind(*list, "printer-uri-supported");
2652264Sjacobs 	if (attribute != NULL) /* we have what we need, return */
2662264Sjacobs 		return;
2672264Sjacobs 
2682264Sjacobs 	/* do we have a printer-uri to rename */
2692264Sjacobs 	attribute = papiAttributeListFind(*list, "printer-uri");
2702264Sjacobs 	if (attribute != NULL) { /* rename it in place and return */
2712264Sjacobs 		free(attribute->name);
2722264Sjacobs 		attribute->name = strdup("printer-uri-supported");
2732264Sjacobs 		return;
2742264Sjacobs 	}
2752264Sjacobs 
2762264Sjacobs 	/* do we have a printers.conf(4) "bsdaddr" to convert */
2772264Sjacobs 	papiAttributeListGetString(*list, NULL, "bsdaddr", &string);
2782264Sjacobs 	if (string != NULL) { /* parse it, convert it, add it */
2792264Sjacobs 		char *uri = bsdaddr_to_uri(string);
2802264Sjacobs 
2812264Sjacobs 		if (uri != NULL) {
2822264Sjacobs 			papiAttributeListAddString(list, PAPI_ATTR_APPEND,
2832264Sjacobs 					"printer-uri-supported", uri);
2842264Sjacobs 			papiAttributeListDelete(list, "bsdaddr");
2852264Sjacobs 			free(uri);
2862264Sjacobs 			return;
2872264Sjacobs 		}
2882264Sjacobs 	}
2892264Sjacobs 
2902264Sjacobs 	/* do we have a printers.conf(4) "rm" (and "rp") to convert */
2912264Sjacobs 	papiAttributeListGetString(*list, NULL, "rm", &string);
2922264Sjacobs 	if (string != NULL) {
2932264Sjacobs 		char *rp = NULL;
2942264Sjacobs 
2952264Sjacobs 		/* default to "printer-name", but use "rp" if we have it */
2962264Sjacobs 		papiAttributeListGetString(*list, NULL, "printer-name", &rp);
2972264Sjacobs 		papiAttributeListGetString(*list, NULL, "rp", &rp);
2982264Sjacobs 
2992264Sjacobs 		if (rp != NULL) { /* fill in the uri if we have the data */
3002264Sjacobs 			char buf[BUFSIZ];
3012264Sjacobs 
3022264Sjacobs 			snprintf(buf, sizeof (buf), "lpd://%s/printers/%s",
3032264Sjacobs 				string, rp);
3042264Sjacobs 			papiAttributeListAddString(list, PAPI_ATTR_APPEND,
3052264Sjacobs 					"printer-uri-supported", strdup(buf));
3062264Sjacobs 			return;
3072264Sjacobs 		}
3082264Sjacobs 	}
3092264Sjacobs 
3102264Sjacobs 	/* if were are here, we don't have a printer-uri-supported */
3112264Sjacobs }
3122264Sjacobs 
3132264Sjacobs #ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC
3142264Sjacobs static void
3152264Sjacobs fill_printer_uri(papi_attribute_t ***list)
3162264Sjacobs {
3172264Sjacobs 	papi_attribute_t *attribute;
3182264Sjacobs 	char *uri = NULL;
3192264Sjacobs 
3202264Sjacobs 	if ((list == NULL) || (*list == NULL))
3212264Sjacobs 		return;
3222264Sjacobs 
323*2313Sjacobs 	/* do we have a printer-uri */
3242264Sjacobs 	attribute = papiAttributeListFind(*list, "printer-uri");
3252264Sjacobs 	if (attribute != NULL) /* we have what we need, return */
3262264Sjacobs 		return;
3272264Sjacobs 
3282264Sjacobs 	/*
3292264Sjacobs 	 * this is sufficient to fool libgnomeprintpapi, but not promote it's
3302264Sjacobs 	 * use in the future.
3312264Sjacobs 	 */
3322264Sjacobs 	papiAttributeListAddString(list, PAPI_ATTR_EXCL, "printer-uri",
3332264Sjacobs 			"broken printer-uri semantic");
3342264Sjacobs }
3352264Sjacobs #endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */
3362264Sjacobs 
3372264Sjacobs static void
3382264Sjacobs cvt_all_to_member_names(papi_attribute_t ***list)
3392264Sjacobs {
3402264Sjacobs 	papi_status_t status;
3412264Sjacobs 	void *iter = NULL;
3422264Sjacobs 	char *string = NULL;
3432264Sjacobs 
3442264Sjacobs 	papiAttributeListGetString(*list, NULL, "member-names", &string);
3452264Sjacobs 	if (string != NULL) /* already have a member-names */
3462264Sjacobs 		return;
3472264Sjacobs 
3482264Sjacobs 	for (status = papiAttributeListGetString(*list, &iter, "all", &string);
3492264Sjacobs 	     status == PAPI_OK;
3502264Sjacobs 	     status = papiAttributeListGetString(*list, &iter, NULL, &string)) {
3512264Sjacobs 		char *s_iter = NULL, *value, *tmp = strdup(string);
3522264Sjacobs 
3532264Sjacobs 		for (value = strtok_r(tmp, ", \t", &s_iter);
3542264Sjacobs 		     value != NULL;
3552264Sjacobs 		     value = strtok_r(NULL, ", \t", &s_iter))
3562264Sjacobs 			papiAttributeListAddString(list, PAPI_ATTR_APPEND,
3572264Sjacobs 					"member-names", value);
3582264Sjacobs 		free(tmp);
3592264Sjacobs 	}
3602264Sjacobs }
3612264Sjacobs 
3622264Sjacobs static papi_attribute_t **
3632264Sjacobs _cvt_nss_entry_to_printer(char *entry)
3642264Sjacobs {
3652264Sjacobs 	char    *key = NULL,
3662264Sjacobs 		*cp,
3672264Sjacobs 		buf[BUFSIZ];
3682264Sjacobs 	int in_namelist = 1, buf_pos = 0;
3692264Sjacobs 	papi_attribute_t **list = NULL;
3702264Sjacobs 
3712264Sjacobs 	if (entry == NULL)
3722264Sjacobs 		return (NULL);
3732264Sjacobs 
3742264Sjacobs 	memset(buf, 0, sizeof (buf));
3752264Sjacobs 	for (cp = entry; *cp != '\0'; cp++) {
3762264Sjacobs 		switch (*cp) {
3772264Sjacobs 		case ':':	/* end of kvp */
3782264Sjacobs 			if (in_namelist != 0) {
3792264Sjacobs 				papiAttributeListAddString(&list,
3802264Sjacobs 					PAPI_ATTR_APPEND, "printer-name", buf);
3812264Sjacobs 				in_namelist = 0;
3822264Sjacobs 			} else if (key != NULL)
3832264Sjacobs 				papiAttributeListAddString(&list,
3842264Sjacobs 					PAPI_ATTR_APPEND, key, buf);
3852264Sjacobs 			memset(buf, 0, sizeof (buf));
3862264Sjacobs 			buf_pos = 0;
3872264Sjacobs 			key = NULL;
3882264Sjacobs 			break;
3892264Sjacobs 		case '=':	/* kvp seperator */
3902264Sjacobs 			if (key == NULL) {
3912264Sjacobs 				key = strdup(buf);
3922264Sjacobs 				memset(buf, 0, sizeof (buf));
3932264Sjacobs 				buf_pos = 0;
3942264Sjacobs 			} else
3952264Sjacobs 				buf[buf_pos++] = *cp;
3962264Sjacobs 			break;
3972264Sjacobs 		case '|':	/* namelist seperator */
3982264Sjacobs 			if (in_namelist != 0) {
3992264Sjacobs 				papiAttributeListAddString(&list,
4002264Sjacobs 					PAPI_ATTR_APPEND, "printer-name", buf);
4012264Sjacobs 				memset(buf, 0, sizeof (buf));
4022264Sjacobs 				buf_pos = 0;
4032264Sjacobs 			} else	/* add it to the buffer */
4042264Sjacobs 				buf[buf_pos++] = *cp;
4052264Sjacobs 			break;
4062264Sjacobs 		case '\\':	/* escape char */
4072264Sjacobs 			buf[buf_pos++] = *(++cp);
4082264Sjacobs 			break;
4092264Sjacobs 		default:
4102264Sjacobs 			buf[buf_pos++] = *cp;
4112264Sjacobs 		}
4122264Sjacobs 
4132264Sjacobs 	}
4142264Sjacobs 
4152264Sjacobs 	if (key != NULL)
4162264Sjacobs 		papiAttributeListAddString(&list, PAPI_ATTR_APPEND, key, buf);
4172264Sjacobs 
4182264Sjacobs 	/* resolve any "use" references in the configuration DB */
4192264Sjacobs 	key = NULL;
4202264Sjacobs 	papiAttributeListGetString(list, NULL, "use", &key);
4212264Sjacobs 	if (key != NULL) {
4222264Sjacobs 		papi_attribute_t **use_attrs = getprinterbyname(key, NULL);
4232264Sjacobs 
4242264Sjacobs 		list_concatenate(&list, use_attrs);
4252264Sjacobs 	}
4262264Sjacobs 
4272264Sjacobs 	fill_printer_uri_supported(&list);
4282264Sjacobs 	cvt_all_to_member_names(&list); /* convert "all" to "member-names" */
4292264Sjacobs 
4302264Sjacobs 	return (list);
4312264Sjacobs }
4322264Sjacobs 
4332264Sjacobs #if defined(NSS_SOLARIS) && !defined(NSS_EMULATION)
4342264Sjacobs 
4352264Sjacobs #ifndef	NSS_DBNAM__PRINTERS	/* not in nss_dbdefs.h because it's private */
4362264Sjacobs #define	NSS_DBNAM__PRINTERS	"_printers"
4372264Sjacobs #endif
4382264Sjacobs 
4392264Sjacobs static DEFINE_NSS_DB_ROOT(db_root);
4402264Sjacobs static DEFINE_NSS_GETENT(context);
4412264Sjacobs 
4422264Sjacobs static char *private_ns = NULL;
4432264Sjacobs static char initialized = 0;
4442264Sjacobs 
4452264Sjacobs static void
4462264Sjacobs _nss_initf_printers(p)
4472264Sjacobs     nss_db_params_t *p;
4482264Sjacobs {
4492264Sjacobs 	if (private_ns != NULL) {
4502264Sjacobs 		/*
4512264Sjacobs 		 * because we need to support a legacy interface that allows
4522264Sjacobs 		 * us to select a specific name service, we need to dummy up
4532264Sjacobs 		 * the parameters to use a private nsswitch database and set
4542264Sjacobs 		 * the * default_config entry to the name service we are
4552264Sjacobs 		 * looking into.
4562264Sjacobs 		 */
4572264Sjacobs 		p->name = NSS_DBNAM__PRINTERS;		/* "_printers" */
4582264Sjacobs 		p->default_config = private_ns;
4592264Sjacobs 		private_ns = NULL;
4602264Sjacobs 	} else if (initialized == 0) {
4612264Sjacobs 		/* regular behaviour */
4622264Sjacobs 		p->name = NSS_DBNAM_PRINTERS;	 /* "printers" */
4632264Sjacobs 		p->default_config = NSS_DEFCONF_PRINTERS;
4642264Sjacobs 		initialized = 1;
4652264Sjacobs 	}
4662264Sjacobs 	syslog(LOG_DEBUG, "database: %s, services: %s",
4672264Sjacobs 		(p->name ? p->name : "NULL"),
4682264Sjacobs 		(p->default_config ? p->default_config : "NULL"));
4692264Sjacobs }
4702264Sjacobs 
4712264Sjacobs /*
4722264Sjacobs  * Return values: 0 = success, 1 = parse error, 2 = erange ...
4732264Sjacobs  * The structure pointer passed in is a structure in the caller's space
4742264Sjacobs  * wherein the field pointers would be set to areas in the buffer if
4752264Sjacobs  * need be. instring and buffer should be separate areas.
4762264Sjacobs  */
4772264Sjacobs /* ARGSUSED */
4782264Sjacobs static int
4792264Sjacobs str2printer(const char *instr, int lenstr, void *ent, char *buffer, int buflen)
4802264Sjacobs {
4812264Sjacobs 	if (lenstr + 1 > buflen)
4822264Sjacobs 		return (NSS_STR_PARSE_ERANGE);
4832264Sjacobs 	/*
4842264Sjacobs 	 * We copy the input string into the output buffer
4852264Sjacobs 	 */
4862264Sjacobs 	(void) memcpy(buffer, instr, lenstr);
4872264Sjacobs 	buffer[lenstr] = '\0';
4882264Sjacobs 
4892264Sjacobs 	return (NSS_STR_PARSE_SUCCESS);
4902264Sjacobs }
4912264Sjacobs #endif /* NSS_SOLARIS */
4922264Sjacobs 
4932264Sjacobs int
4942264Sjacobs setprinterentry(int stayopen, char *ns)
4952264Sjacobs {
4962264Sjacobs #ifdef NSS_EMULATION
4972264Sjacobs 	emul_setprinterentry(stayopen);
4982264Sjacobs #elif NSS_SOLARIS
4992264Sjacobs 	initialized = 0;
5002264Sjacobs 	private_ns = ns;
5012264Sjacobs 	nss_setent(&db_root, _nss_initf_printers, &context);
5022264Sjacobs #endif
5032264Sjacobs 	return (0);
5042264Sjacobs }
5052264Sjacobs 
5062264Sjacobs 
5072264Sjacobs int
5082264Sjacobs endprinterentry(int i)
5092264Sjacobs {
5102264Sjacobs #ifdef NSS_EMULATION
5112264Sjacobs 	emul_endprinterentry();
5122264Sjacobs #elif NSS_SOLARIS
5132264Sjacobs 	initialized = 0;
5142264Sjacobs 	nss_endent(&db_root, _nss_initf_printers, &context);
5152264Sjacobs 	nss_delete(&db_root);
5162264Sjacobs #endif
5172264Sjacobs 	return (0);
5182264Sjacobs }
5192264Sjacobs 
5202264Sjacobs /* ARGSUSED2 */
5212264Sjacobs papi_attribute_t **
5222264Sjacobs getprinterentry(char *ns)
5232264Sjacobs {
5242264Sjacobs 	papi_attribute_t **result = NULL;
5252264Sjacobs 
5262264Sjacobs #if defined(NSS_EMULATION) || defined(NSS_SOLARIS)
5272264Sjacobs 	char buf[10240];
5282264Sjacobs 	nss_status_t	res = NSS_NOTFOUND;
5292264Sjacobs 
5302264Sjacobs #ifdef NSS_EMULATION
5312264Sjacobs 	res = emul_getprinterentry_r(buf, sizeof (buf));
5322264Sjacobs #elif NSS_SOLARIS
5332264Sjacobs 	nss_XbyY_args_t arg;
5342264Sjacobs 
5352264Sjacobs 	NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer);
5362264Sjacobs 	res = nss_getent(&db_root, _nss_initf_printers, &context, &arg);
5372264Sjacobs 	(void) NSS_XbyY_FINI(&arg);
5382264Sjacobs #endif
5392264Sjacobs 
5402264Sjacobs 	if (res != NSS_SUCCESS)
5412264Sjacobs 		buf[0] = '\0';
5422264Sjacobs 
5432264Sjacobs 	result = _cvt_nss_entry_to_printer(buf);
544*2313Sjacobs #if defined(__sun) && defined(__SVR4)
545*2313Sjacobs 	solaris_lpsched_shortcircuit_hack(&result);
546*2313Sjacobs #endif
5472264Sjacobs #ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC
5482264Sjacobs 	fill_printer_uri(&result);
5492264Sjacobs #endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */
5502264Sjacobs #endif
5512264Sjacobs 
5522264Sjacobs #ifdef DEBUG
5532264Sjacobs 	printf("getprinterentry(%s): 0x%8.8x\n", (ns ? ns : "NULL"), result);
5542264Sjacobs 	if (result != NULL) {
5552264Sjacobs 		char buf[4096];
5562264Sjacobs 
5572264Sjacobs 		papiAttributeListToString(result, "\n\t", buf, sizeof (buf));
5582264Sjacobs 		printf("\t%s\n", buf);
5592264Sjacobs 	}
5602264Sjacobs #endif /* DEBUG */
5612264Sjacobs 
5622264Sjacobs 	return (result);
5632264Sjacobs }
5642264Sjacobs 
5652264Sjacobs 
5662264Sjacobs papi_attribute_t **
5672264Sjacobs getprinterbyname(char *name, char *ns)
5682264Sjacobs {
5692264Sjacobs 	papi_attribute_t **result = NULL;
5702264Sjacobs 
5712264Sjacobs 	if (strstr(name, "://") != NULL) {	/* shortcut for URI form */
5722264Sjacobs 		papiAttributeListAddString(&result, PAPI_ATTR_APPEND,
5732264Sjacobs 				"printer-name", name);
5742264Sjacobs 		papiAttributeListAddString(&result, PAPI_ATTR_APPEND,
5752264Sjacobs 				"printer-uri-supported", name);
5762264Sjacobs 	} else if (strchr(name, ':') != NULL) {	/* shortcut for POSIX form */
5772264Sjacobs 		char *uri = bsdaddr_to_uri(name);
5782264Sjacobs 
5792264Sjacobs 		papiAttributeListAddString(&result, PAPI_ATTR_APPEND,
5802264Sjacobs 				"printer-name", name);
5812264Sjacobs 		if (uri != NULL) {
5822264Sjacobs 			papiAttributeListAddString(&result, PAPI_ATTR_APPEND,
5832264Sjacobs 					"printer-uri-supported", uri);
5842264Sjacobs 			free(uri);
5852264Sjacobs 		}
5862264Sjacobs 	} else {				/* anything else */
5872264Sjacobs #if defined(NSS_EMULATION) || defined(NSS_SOLARIS)
5882264Sjacobs 		char buf[10240];
5892264Sjacobs 		nss_status_t	res = NSS_NOTFOUND;
5902264Sjacobs 
5912264Sjacobs #ifdef NSS_EMULATION
5922264Sjacobs 		res = emul_getprinterbyname_r(name, buf, sizeof (buf));
5932264Sjacobs #elif NSS_SOLARIS
5942264Sjacobs 		nss_XbyY_args_t arg;
5952264Sjacobs 
5962264Sjacobs 		private_ns = ns;
5972264Sjacobs 		NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer);
5982264Sjacobs 		arg.key.name = name;
5992264Sjacobs 		res = nss_search(&db_root, _nss_initf_printers,
6002264Sjacobs 				NSS_DBOP_PRINTERS_BYNAME, &arg);
6012264Sjacobs 		(void) NSS_XbyY_FINI(&arg);
6022264Sjacobs 
6032264Sjacobs 		if (res != NSS_SUCCESS)
6042264Sjacobs 			buf[0] = '\0';
6052264Sjacobs #endif
6062264Sjacobs 
6072264Sjacobs 		result = _cvt_nss_entry_to_printer(buf);
6082264Sjacobs #endif
6092264Sjacobs 	}
610*2313Sjacobs #if defined(__sun) && defined(__SVR4)
611*2313Sjacobs 	solaris_lpsched_shortcircuit_hack(&result);
612*2313Sjacobs #endif
6132264Sjacobs #ifdef DEBUG
6142264Sjacobs 	printf("getprinterbyname(%s): %s = 0x%8.8x\n", (ns ? ns : "NULL"),
6152264Sjacobs 		name, result);
6162264Sjacobs 	if (result != NULL) {
6172264Sjacobs 		char buf[4096];
6182264Sjacobs 
6192264Sjacobs 		papiAttributeListToString(result, "\n\t", buf, sizeof (buf));
6202264Sjacobs 		printf("\t%s\n", buf);
6212264Sjacobs 	}
6222264Sjacobs #endif /* DEBUG */
6232264Sjacobs 
6242264Sjacobs 	return (result);
6252264Sjacobs }
626