1*2264Sjacobs /*
2*2264Sjacobs  * CDDL HEADER START
3*2264Sjacobs  *
4*2264Sjacobs  * The contents of this file are subject to the terms of the
5*2264Sjacobs  * Common Development and Distribution License (the "License").
6*2264Sjacobs  * You may not use this file except in compliance with the License.
7*2264Sjacobs  *
8*2264Sjacobs  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*2264Sjacobs  * or http://www.opensolaris.org/os/licensing.
10*2264Sjacobs  * See the License for the specific language governing permissions
11*2264Sjacobs  * and limitations under the License.
12*2264Sjacobs  *
13*2264Sjacobs  * When distributing Covered Code, include this CDDL HEADER in each
14*2264Sjacobs  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*2264Sjacobs  * If applicable, add the following below this CDDL HEADER, with the
16*2264Sjacobs  * fields enclosed by brackets "[]" replaced with your own identifying
17*2264Sjacobs  * information: Portions Copyright [yyyy] [name of copyright owner]
18*2264Sjacobs  *
19*2264Sjacobs  * CDDL HEADER END
20*2264Sjacobs  */
21*2264Sjacobs /*
22*2264Sjacobs  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23*2264Sjacobs  * Use is subject to license terms.
24*2264Sjacobs  */
25*2264Sjacobs 
26*2264Sjacobs #pragma ident	"%Z%%M%	%I%	%E% SMI"
27*2264Sjacobs 
28*2264Sjacobs /*LINTLIBRARY*/
29*2264Sjacobs 
30*2264Sjacobs #include <stdio.h>
31*2264Sjacobs #include <stdlib.h>
32*2264Sjacobs #include <unistd.h>
33*2264Sjacobs #include <sys/types.h>
34*2264Sjacobs #include <string.h>
35*2264Sjacobs #include <stdarg.h>
36*2264Sjacobs #include <dlfcn.h>
37*2264Sjacobs #include <nss_dbdefs.h>
38*2264Sjacobs #include <syslog.h>
39*2264Sjacobs 
40*2264Sjacobs #include <ns.h>
41*2264Sjacobs #include <list.h>
42*2264Sjacobs #include <misc.h>
43*2264Sjacobs 
44*2264Sjacobs 
45*2264Sjacobs /*
46*2264Sjacobs  * because legacy code can use a variety of values for various name
47*2264Sjacobs  * services, this routine is needed to "normalize" them.
48*2264Sjacobs  */
49*2264Sjacobs char *
50*2264Sjacobs normalize_ns_name(char *ns)
51*2264Sjacobs {
52*2264Sjacobs 	if (ns == NULL)
53*2264Sjacobs 		return (NULL);
54*2264Sjacobs 	else if ((strcasecmp(ns, "files") == 0) ||
55*2264Sjacobs 			(strcasecmp(ns, "system") == 0) ||
56*2264Sjacobs 			(strcasecmp(ns, "etc") == 0))
57*2264Sjacobs 		return ("files");
58*2264Sjacobs 	else if (strcasecmp(ns, "nis") == 0)
59*2264Sjacobs 		return ("nis");
60*2264Sjacobs 	else if (strcasecmp(ns, "ldap") == 0)
61*2264Sjacobs 		return ("ldap");
62*2264Sjacobs 	else if ((strcasecmp(ns, "nisplus") == 0) ||
63*2264Sjacobs 			(strcasecmp(ns, "nis+") == 0))
64*2264Sjacobs 		return ("nisplus");
65*2264Sjacobs 	else
66*2264Sjacobs 		return (ns);
67*2264Sjacobs }
68*2264Sjacobs 
69*2264Sjacobs 
70*2264Sjacobs /*
71*2264Sjacobs  * FUNCTION:
72*2264Sjacobs  *	void ns_printer_destroy(ns_printer_t *printer)
73*2264Sjacobs  * INPUT:
74*2264Sjacobs  *	ns_printer_t *printer - a pointer to the printer "object" to destroy
75*2264Sjacobs  * DESCRIPTION:
76*2264Sjacobs  *	This function will free all of the memory associated with a printer
77*2264Sjacobs  *	object.  It does this by walking the structure ad freeing everything
78*2264Sjacobs  *	underneath it, with the exception of the object source field.  This
79*2264Sjacobs  *	field is not filled in with newly allocated space when it is
80*2264Sjacobs  *	generated
81*2264Sjacobs  */
82*2264Sjacobs void
83*2264Sjacobs ns_printer_destroy(ns_printer_t *printer)
84*2264Sjacobs {
85*2264Sjacobs 	if (printer != NULL) {
86*2264Sjacobs 		if (printer->attributes != NULL) {	/* attributes */
87*2264Sjacobs 			extern void ns_kvp_destroy(ns_kvp_t *);
88*2264Sjacobs 
89*2264Sjacobs 			list_iterate((void **)printer->attributes,
90*2264Sjacobs 				(VFUNC_T)ns_kvp_destroy);
91*2264Sjacobs 			free(printer->attributes);
92*2264Sjacobs 		}
93*2264Sjacobs 		if (printer->aliases != NULL) {		/* aliases */
94*2264Sjacobs 			free(printer->aliases);
95*2264Sjacobs 		}
96*2264Sjacobs 		if (printer->name != NULL)		/* primary name */
97*2264Sjacobs 			free(printer->name);
98*2264Sjacobs 		free(printer);
99*2264Sjacobs 	}
100*2264Sjacobs }
101*2264Sjacobs 
102*2264Sjacobs 
103*2264Sjacobs /*
104*2264Sjacobs  * FUNCTION:
105*2264Sjacobs  *	ns_printer_t **ns_printer_get_list()
106*2264Sjacobs  * OUTPUT:
107*2264Sjacobs  *	ns_printer_t ** (return value) - an array of pointers to printer
108*2264Sjacobs  *					 objects.
109*2264Sjacobs  * DESCRIPTION:
110*2264Sjacobs  *	This function will return a list of all printer objects found in every
111*2264Sjacobs  *	configuration interface.
112*2264Sjacobs  */
113*2264Sjacobs ns_printer_t **
114*2264Sjacobs ns_printer_get_list(const char *ns)
115*2264Sjacobs {
116*2264Sjacobs 	char	    buf[NSS_LINELEN_PRINTERS];
117*2264Sjacobs 	ns_printer_t    **printer_list = NULL;
118*2264Sjacobs 
119*2264Sjacobs 	(void) setprinterentry(0, (char *)ns);
120*2264Sjacobs 
121*2264Sjacobs 	ns = normalize_ns_name((char *)ns);
122*2264Sjacobs 	while (getprinterentry(buf, sizeof (buf), (char *)ns) == 0) {
123*2264Sjacobs 		ns_printer_t *printer =
124*2264Sjacobs 			(ns_printer_t *)_cvt_nss_entry_to_printer(buf, NULL);
125*2264Sjacobs 
126*2264Sjacobs 		printer_list = (ns_printer_t **)list_append(
127*2264Sjacobs 					(void **)printer_list,
128*2264Sjacobs 					(void *)printer);
129*2264Sjacobs 	}
130*2264Sjacobs 
131*2264Sjacobs 	(void) endprinterentry();
132*2264Sjacobs 
133*2264Sjacobs 	return (printer_list);
134*2264Sjacobs }
135*2264Sjacobs 
136*2264Sjacobs 
137*2264Sjacobs /*
138*2264Sjacobs  * This function looks for the named printer in the supplied
139*2264Sjacobs  * name service (ns), or the name services configured under
140*2264Sjacobs  * the nsswitch.
141*2264Sjacobs  */
142*2264Sjacobs ns_printer_t *
143*2264Sjacobs ns_printer_get_name(const char *name, const char *ns)
144*2264Sjacobs {
145*2264Sjacobs 	ns_printer_t *result = NULL;
146*2264Sjacobs 	char buf[NSS_LINELEN_PRINTERS];
147*2264Sjacobs 
148*2264Sjacobs 	/*
149*2264Sjacobs 	 * Reset printer entries to the start so we know we will always
150*2264Sjacobs 	 * pick up the correct entry
151*2264Sjacobs 	 */
152*2264Sjacobs 	endprinterentry();
153*2264Sjacobs 
154*2264Sjacobs 	if ((result = (ns_printer_t *)posix_name(name)) != NULL)
155*2264Sjacobs 		return (result);
156*2264Sjacobs 
157*2264Sjacobs 	ns = normalize_ns_name((char *)ns);
158*2264Sjacobs 	if (getprinterbyname((char *)name, buf, sizeof (buf), (char *)ns) == 0)
159*2264Sjacobs 		result = (ns_printer_t *)_cvt_nss_entry_to_printer(buf, NULL);
160*2264Sjacobs 
161*2264Sjacobs 	return (result);
162*2264Sjacobs }
163*2264Sjacobs 
164*2264Sjacobs 
165*2264Sjacobs /*
166*2264Sjacobs  * FUNCTION:
167*2264Sjacobs  *	int ns_printer_put(const ns_printer_t *printer)
168*2264Sjacobs  * INPUT:
169*2264Sjacobs  *	const ns_printer_t *printer - a printer object
170*2264Sjacobs  * DESCRIPTION:
171*2264Sjacobs  *	This function attempts to put the data in the printer object back
172*2264Sjacobs  *	to the "name service" specified in the source field of the object.
173*2264Sjacobs  */
174*2264Sjacobs int
175*2264Sjacobs ns_printer_put(const ns_printer_t *printer)
176*2264Sjacobs {
177*2264Sjacobs 	char func[32];
178*2264Sjacobs 	int (*fpt)();
179*2264Sjacobs 
180*2264Sjacobs 	if ((printer == NULL) || (printer->source == NULL))
181*2264Sjacobs 		return (-1);
182*2264Sjacobs 
183*2264Sjacobs 	if (snprintf(func, sizeof (func), "%s_put_printer",
184*2264Sjacobs 		normalize_ns_name(printer->source)) >= sizeof (func)) {
185*2264Sjacobs 			syslog(LOG_ERR, "ns_printer_put: buffer overflow");
186*2264Sjacobs 			return (-1);
187*2264Sjacobs 	}
188*2264Sjacobs 
189*2264Sjacobs 	if ((fpt = (int (*)())dlsym(RTLD_DEFAULT, func)) != NULL)
190*2264Sjacobs 		return ((*fpt)(printer));
191*2264Sjacobs 
192*2264Sjacobs 	return (-1);
193*2264Sjacobs }
194