xref: /titanic_41/usr/src/lib/nsswitch/ldap/common/getprinter.c (revision cb5caa98562cf06753163f558cbcfe30b8f4673a)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*cb5caa98Sdjl  * Common Development and Distribution License (the "License").
6*cb5caa98Sdjl  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*cb5caa98Sdjl  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #pragma weak _nss_ldap__printers_constr = _nss_ldap_printers_constr
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include "ldap_common.h"
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate static void append_attr(char *buf, char *attr);
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate /* printer attributes filters */
357c478bd9Sstevel@tonic-gate #define	_F_GETPRINTERBYNAME	\
367c478bd9Sstevel@tonic-gate 	"(&(objectClass=sunPrinter)(|(printer-name=%s)(printer-aliases=%s)))"
377c478bd9Sstevel@tonic-gate 
38*cb5caa98Sdjl #define	PRINTER_PREFIX	"printer-"
39*cb5caa98Sdjl #define	SUNWPR_PREFIX	"sunwpr-"
40*cb5caa98Sdjl 
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate  * Attributes from the following classes:
437c478bd9Sstevel@tonic-gate  * 	printerService
447c478bd9Sstevel@tonic-gate  * 	printerAbstact
457c478bd9Sstevel@tonic-gate  * 	sunPrinter
467c478bd9Sstevel@tonic-gate  */
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate /*
497c478bd9Sstevel@tonic-gate  * Get all attributes.
507c478bd9Sstevel@tonic-gate  */
517c478bd9Sstevel@tonic-gate static const char **printer_attrs = NULL;
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate /*
55*cb5caa98Sdjl  * _nss_ldap_printers2str is the data marshaling method for the printers
567c478bd9Sstevel@tonic-gate  * getXbyY backend processes. This method is called after a successful
577c478bd9Sstevel@tonic-gate  * ldap search has been performed. This method will parse the ldap search
587c478bd9Sstevel@tonic-gate  * values into argp->buf.buffer. Three error conditions are expected and
597c478bd9Sstevel@tonic-gate  * returned to nsswitch.
60*cb5caa98Sdjl  * In order to be compatible with old data output, the code is commented out
61*cb5caa98Sdjl  * with NSS_LDAP_PRINTERS. The NSS_LDAP_PRINTERS section is for future
62*cb5caa98Sdjl  * refrences if it's decided to fix the output format.
637c478bd9Sstevel@tonic-gate  */
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate static int
_nss_ldap_printers2str(ldap_backend_ptr be,nss_XbyY_args_t * argp)66*cb5caa98Sdjl _nss_ldap_printers2str(ldap_backend_ptr be, nss_XbyY_args_t *argp)
677c478bd9Sstevel@tonic-gate {
687c478bd9Sstevel@tonic-gate 	int			i, j;
697c478bd9Sstevel@tonic-gate 	int			nss_result;
70*cb5caa98Sdjl 	int			buflen = 0, len;
71*cb5caa98Sdjl 	char			*buffer = NULL;
72*cb5caa98Sdjl 	char			**name, *attrname;
737c478bd9Sstevel@tonic-gate 	ns_ldap_attr_t		*attr;
747c478bd9Sstevel@tonic-gate 	ns_ldap_result_t	*result = be->result;
75*cb5caa98Sdjl #ifdef	NSS_LDAP_PRINTERS
76*cb5caa98Sdjl 	int			slen, plen;
77*cb5caa98Sdjl #endif
787c478bd9Sstevel@tonic-gate 
79*cb5caa98Sdjl 	if (result == NULL)
80*cb5caa98Sdjl 		return (NSS_STR_PARSE_PARSE);
81*cb5caa98Sdjl 
82*cb5caa98Sdjl 	buflen = argp->buf.buflen;
83*cb5caa98Sdjl 	if (argp->buf.result != NULL) {
84*cb5caa98Sdjl 		be->buffer = calloc(1, buflen);
85*cb5caa98Sdjl 		if (be->buffer == NULL)
86*cb5caa98Sdjl 			return (NSS_STR_PARSE_PARSE);
87*cb5caa98Sdjl 		be->buflen = buflen;
88*cb5caa98Sdjl 		buffer = be->buffer;
89*cb5caa98Sdjl 	} else {
907c478bd9Sstevel@tonic-gate 		buffer = argp->buf.buffer;
917c478bd9Sstevel@tonic-gate 		(void) memset(argp->buf.buffer, 0, buflen);
927c478bd9Sstevel@tonic-gate 	}
937c478bd9Sstevel@tonic-gate 
94*cb5caa98Sdjl 	nss_result = NSS_STR_PARSE_SUCCESS;
95*cb5caa98Sdjl 
96*cb5caa98Sdjl #ifdef	NSS_LDAP_PRINTERS
97*cb5caa98Sdjl 	slen = strlen(SUNWPR_PREFIX);
98*cb5caa98Sdjl 	plen = strlen(PRINTER_PREFIX);
99*cb5caa98Sdjl #endif
100*cb5caa98Sdjl 
1017c478bd9Sstevel@tonic-gate 	/*
102*cb5caa98Sdjl 	 * Pick out the printer name and aliases
1037c478bd9Sstevel@tonic-gate 	 */
104*cb5caa98Sdjl 	name = __ns_ldap_getAttr(result->entry, "printer-name");
105*cb5caa98Sdjl 	if (name == NULL || name[0] == NULL) {
106*cb5caa98Sdjl 		nss_result = NSS_STR_PARSE_PARSE;
107*cb5caa98Sdjl 		goto result_printers2str;
1087c478bd9Sstevel@tonic-gate 	}
109*cb5caa98Sdjl 	len = snprintf(buffer, buflen, "%s", name[0]);
110*cb5caa98Sdjl 	TEST_AND_ADJUST(len, buffer, buflen, result_printers2str);
1117c478bd9Sstevel@tonic-gate 
112*cb5caa98Sdjl #ifdef	NSS_LDAP_PRINTERS
113*cb5caa98Sdjl 	attr = __ns_ldap_getAttrStruct(result->entry, "printer-aliases");
114*cb5caa98Sdjl 	if (attr != NULL && attr->attrvalue != NULL) {
115*cb5caa98Sdjl 		for (i = 0; i < attr->value_count; i++) {
116*cb5caa98Sdjl 			len = snprintf(buffer, buflen, "|%s",
117*cb5caa98Sdjl 					attr->attrvalue[i]);
118*cb5caa98Sdjl 			TEST_AND_ADJUST(len, buffer, buflen,
119*cb5caa98Sdjl 					result_printers2str);
1207c478bd9Sstevel@tonic-gate 		}
121*cb5caa98Sdjl 	}
122*cb5caa98Sdjl #endif
1237c478bd9Sstevel@tonic-gate 	/*
1247c478bd9Sstevel@tonic-gate 	 * Add the rest of the attributes
1257c478bd9Sstevel@tonic-gate 	 */
1267c478bd9Sstevel@tonic-gate 	for (i = 0; i < result->entry->attr_count; i++) {
1277c478bd9Sstevel@tonic-gate 		attr = getattr(result, i);
1287c478bd9Sstevel@tonic-gate 		if (attr == NULL) {
129*cb5caa98Sdjl 			nss_result = NSS_STR_PARSE_PARSE;
130*cb5caa98Sdjl 			goto result_printers2str;
1317c478bd9Sstevel@tonic-gate 		}
1327c478bd9Sstevel@tonic-gate 		/*
1337c478bd9Sstevel@tonic-gate 		 * The attribute contains key=value
1347c478bd9Sstevel@tonic-gate 		 */
1357c478bd9Sstevel@tonic-gate 		if (strcasecmp(attr->attrname, "sun-printer-kvp") == 0) {
1367c478bd9Sstevel@tonic-gate 			for (j = 0; j < attr->value_count; j++) {
1377c478bd9Sstevel@tonic-gate 				len = strlen(attr->attrvalue[j]);
1387c478bd9Sstevel@tonic-gate 				if (len < 1 ||
1397c478bd9Sstevel@tonic-gate 				    (attr->attrvalue[j] == '\0')) {
1407c478bd9Sstevel@tonic-gate 					*buffer = 0;
1417c478bd9Sstevel@tonic-gate 					nss_result = (int)NSS_STR_PARSE_PARSE;
142*cb5caa98Sdjl 					goto result_printers2str;
1437c478bd9Sstevel@tonic-gate 				}
144*cb5caa98Sdjl 				len =  snprintf(buffer, buflen, ":%s",
1457c478bd9Sstevel@tonic-gate 						attr->attrvalue[j]);
146*cb5caa98Sdjl 				TEST_AND_ADJUST(len, buffer, buflen,
147*cb5caa98Sdjl 						result_printers2str);
1487c478bd9Sstevel@tonic-gate 			}
1497c478bd9Sstevel@tonic-gate 		} else {
1507c478bd9Sstevel@tonic-gate 			/*
151*cb5caa98Sdjl 			 * Skip some attr names
1527c478bd9Sstevel@tonic-gate 			 */
153*cb5caa98Sdjl #ifdef	NSS_LDAP_PRINTERS
154*cb5caa98Sdjl 			if (strcasecmp(attr->attrname, "printer-name") == 0 ||
155*cb5caa98Sdjl 				strcasecmp(attr->attrname, "dn") == 0 ||
156*cb5caa98Sdjl 				strcasecmp(attr->attrname,
157*cb5caa98Sdjl 					"objectclass") == 0 ||
158*cb5caa98Sdjl 				strcasecmp(attr->attrname,
159*cb5caa98Sdjl 					"printer-uri") == 0 ||
160*cb5caa98Sdjl 				strcasecmp(attr->attrname,
161*cb5caa98Sdjl 					"printer-aliases") == 0)
162*cb5caa98Sdjl #else
163*cb5caa98Sdjl 			if (strcasecmp(attr->attrname, "printer-name") == 0)
164*cb5caa98Sdjl #endif
1657c478bd9Sstevel@tonic-gate 				continue;
1667c478bd9Sstevel@tonic-gate 			}
1677c478bd9Sstevel@tonic-gate 			/*
168*cb5caa98Sdjl 			 * Translate attr name ->key name
1697c478bd9Sstevel@tonic-gate 			 */
170*cb5caa98Sdjl 			if (strcmp(attr->attrname, "sun-printer-bsdaddr")
171*cb5caa98Sdjl 					== 0)
172*cb5caa98Sdjl 				attrname = "bsdaddr";
173*cb5caa98Sdjl #ifdef	NSS_LDAP_PRINTERS
174*cb5caa98Sdjl 			else if (strcmp(attr->attrname, "printer-info")
175*cb5caa98Sdjl 					== 0)
176*cb5caa98Sdjl 				attrname = "description";
177*cb5caa98Sdjl 			else if (strcmp(attr->attrname, "sunwpr-support")
178*cb5caa98Sdjl 					== 0)
179*cb5caa98Sdjl 				attrname = "itopssupported";
180*cb5caa98Sdjl 			else if (strncmp(attr->attrname, PRINTER_PREFIX, plen)
181*cb5caa98Sdjl 					== 0)
182*cb5caa98Sdjl 				attrname = attr->attrname + plen;
183*cb5caa98Sdjl 			else if (strncmp(attr->attrname, SUNWPR_PREFIX, slen)
184*cb5caa98Sdjl 					== 0)
185*cb5caa98Sdjl 				attrname = attr->attrname + slen;
186*cb5caa98Sdjl #endif
187*cb5caa98Sdjl 			else
188*cb5caa98Sdjl 				attrname = attr->attrname;
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate 			/*
191*cb5caa98Sdjl 			 * The attrname is the key. The attribute
1927c478bd9Sstevel@tonic-gate 			 * data is the value.
1937c478bd9Sstevel@tonic-gate 			 */
194*cb5caa98Sdjl 			len = snprintf(buffer, buflen, ":%s=", attrname);
195*cb5caa98Sdjl 			TEST_AND_ADJUST(len, buffer, buflen,
196*cb5caa98Sdjl 					result_printers2str);
197*cb5caa98Sdjl 
1987c478bd9Sstevel@tonic-gate 			for (j = 0; j < attr->value_count; j++) {
1997c478bd9Sstevel@tonic-gate 				int k;
2007c478bd9Sstevel@tonic-gate 				char *kp;
2017c478bd9Sstevel@tonic-gate 
202*cb5caa98Sdjl 				if (attr->attrvalue[j] == NULL) {
2037c478bd9Sstevel@tonic-gate 					*buffer = 0;
204*cb5caa98Sdjl 					nss_result = NSS_STR_PARSE_PARSE;
205*cb5caa98Sdjl 					goto result_printers2str;
206*cb5caa98Sdjl 				}
207*cb5caa98Sdjl 				len = strlen(attr->attrvalue[j]);
208*cb5caa98Sdjl 				if (len < 1) {
209*cb5caa98Sdjl 					*buffer = 0;
210*cb5caa98Sdjl 					nss_result = NSS_STR_PARSE_PARSE;
211*cb5caa98Sdjl 					goto result_printers2str;
2127c478bd9Sstevel@tonic-gate 				}
2137c478bd9Sstevel@tonic-gate 				/*
2147c478bd9Sstevel@tonic-gate 				 * Add extra for any colons which need to
2157c478bd9Sstevel@tonic-gate 				 * be backslashed plus ending ':' or ','.
2167c478bd9Sstevel@tonic-gate 				 */
2177c478bd9Sstevel@tonic-gate 				k = 0;
2187c478bd9Sstevel@tonic-gate 				for (kp = attr->attrvalue[j]; *kp != NULL; kp++)
2197c478bd9Sstevel@tonic-gate 					if (*kp == ':')
220*cb5caa98Sdjl 						/* count ':' in value */
2217c478bd9Sstevel@tonic-gate 						k++;
222*cb5caa98Sdjl 				if (j == 0)
223*cb5caa98Sdjl 					/* first time */
224*cb5caa98Sdjl 					len += k;
225*cb5caa98Sdjl 				else
226*cb5caa98Sdjl 					/* add ',' */
227*cb5caa98Sdjl 					len += k + 1;
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 				if (len > buflen) {
230*cb5caa98Sdjl 					nss_result = NSS_STR_PARSE_ERANGE;
231*cb5caa98Sdjl 					goto result_printers2str;
2327c478bd9Sstevel@tonic-gate 				}
233*cb5caa98Sdjl 				if (j > 0)
234*cb5caa98Sdjl 					*buffer++ = ',';
235*cb5caa98Sdjl 
2367c478bd9Sstevel@tonic-gate 				(void) append_attr(buffer,
2377c478bd9Sstevel@tonic-gate 					    attr->attrvalue[j]);
238*cb5caa98Sdjl 				buffer += strlen(attr->attrvalue[j]) + k;
239*cb5caa98Sdjl 				buflen -= len;
2407c478bd9Sstevel@tonic-gate 			}
2417c478bd9Sstevel@tonic-gate 	}
2427c478bd9Sstevel@tonic-gate 
243*cb5caa98Sdjl 	if (argp->buf.result != NULL)
244*cb5caa98Sdjl 		be->buflen = strlen(be->buffer);
2457c478bd9Sstevel@tonic-gate 
246*cb5caa98Sdjl result_printers2str:
2477c478bd9Sstevel@tonic-gate 	(void) __ns_ldap_freeResult(&be->result);
2487c478bd9Sstevel@tonic-gate 	return ((int)nss_result);
2497c478bd9Sstevel@tonic-gate }
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate /*
2527c478bd9Sstevel@tonic-gate  * Attributes which contain colons must be backslashed.
2537c478bd9Sstevel@tonic-gate  */
2547c478bd9Sstevel@tonic-gate static void
append_attr(char * buf,char * attr)2557c478bd9Sstevel@tonic-gate append_attr(char *buf, char *attr)
2567c478bd9Sstevel@tonic-gate {
2577c478bd9Sstevel@tonic-gate 	char *cp, *bp;
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate 	if (strchr(attr, ':') == NULL) {
2607c478bd9Sstevel@tonic-gate 		(void) strcat(buf, attr);
2617c478bd9Sstevel@tonic-gate 		return;
2627c478bd9Sstevel@tonic-gate 	}
263*cb5caa98Sdjl 	bp = buf;
2647c478bd9Sstevel@tonic-gate 	cp = attr;
2657c478bd9Sstevel@tonic-gate 	while (*cp != NULL) {
2667c478bd9Sstevel@tonic-gate 		if (*cp == ':') {
2677c478bd9Sstevel@tonic-gate 			*bp++ = '\\';
2687c478bd9Sstevel@tonic-gate 		}
2697c478bd9Sstevel@tonic-gate 		*bp++ = *cp++;
2707c478bd9Sstevel@tonic-gate 	}
2717c478bd9Sstevel@tonic-gate }
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate /*
2747c478bd9Sstevel@tonic-gate  * getbyname gets printer attributes by printer name. This function
2757c478bd9Sstevel@tonic-gate  * constructs an ldap search filter using the printer name invocation
2767c478bd9Sstevel@tonic-gate  * parameter and the getprinterbyname search filter defined. Once the
2777c478bd9Sstevel@tonic-gate  * filter is constructed, we search for matching entries and marshal
2787c478bd9Sstevel@tonic-gate  * the data results into argp->buf.buffer for the frontend process.
279*cb5caa98Sdjl  * The function _nss_ldap_printers2str performs the data marshaling.
2807c478bd9Sstevel@tonic-gate  */
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate static nss_status_t
getbyname(ldap_backend_ptr be,void * a)2837c478bd9Sstevel@tonic-gate getbyname(ldap_backend_ptr be, void *a)
2847c478bd9Sstevel@tonic-gate {
2857c478bd9Sstevel@tonic-gate 	char		printername[BUFSIZ];
2867c478bd9Sstevel@tonic-gate 	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
2877c478bd9Sstevel@tonic-gate 	char		searchfilter[SEARCHFILTERLEN];
2887c478bd9Sstevel@tonic-gate 
2897c478bd9Sstevel@tonic-gate 	(void) strncpy(printername, argp->key.name, BUFSIZ);
2907c478bd9Sstevel@tonic-gate 	if (snprintf(searchfilter, SEARCHFILTERLEN,
2917c478bd9Sstevel@tonic-gate 		_F_GETPRINTERBYNAME, printername, printername) < 0)
2927c478bd9Sstevel@tonic-gate 		return ((nss_status_t)NSS_NOTFOUND);
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 	return ((nss_status_t)_nss_ldap_lookup(be, argp,
2957c478bd9Sstevel@tonic-gate 		_PRINTERS, searchfilter, NULL, NULL, NULL));
2967c478bd9Sstevel@tonic-gate }
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate static ldap_backend_op_t printers_ops[] = {
2997c478bd9Sstevel@tonic-gate 	_nss_ldap_destr,
3007c478bd9Sstevel@tonic-gate 	_nss_ldap_endent,
3017c478bd9Sstevel@tonic-gate 	_nss_ldap_setent,
3027c478bd9Sstevel@tonic-gate 	_nss_ldap_getent,
3037c478bd9Sstevel@tonic-gate 	getbyname,
3047c478bd9Sstevel@tonic-gate };
3057c478bd9Sstevel@tonic-gate 
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate /*
3087c478bd9Sstevel@tonic-gate  * _nss_ldap_printers_constr is where life begins. This function calls
3097c478bd9Sstevel@tonic-gate  * the generic ldap constructor function to define and build the abstract
3107c478bd9Sstevel@tonic-gate  * data types required to support ldap operations.
3117c478bd9Sstevel@tonic-gate  */
3127c478bd9Sstevel@tonic-gate 
3137c478bd9Sstevel@tonic-gate /*ARGSUSED0*/
3147c478bd9Sstevel@tonic-gate nss_backend_t *
_nss_ldap_printers_constr(const char * dummy1,const char * dummy2,const char * dummy3)3157c478bd9Sstevel@tonic-gate _nss_ldap_printers_constr(const char *dummy1, const char *dummy2,
3167c478bd9Sstevel@tonic-gate 			const char *dummy3)
3177c478bd9Sstevel@tonic-gate {
3187c478bd9Sstevel@tonic-gate 
3197c478bd9Sstevel@tonic-gate 	return ((nss_backend_t *)_nss_ldap_constr(printers_ops,
3207c478bd9Sstevel@tonic-gate 		sizeof (printers_ops)/sizeof (printers_ops[0]), _PRINTERS,
321*cb5caa98Sdjl 		printer_attrs, _nss_ldap_printers2str));
3227c478bd9Sstevel@tonic-gate }
323