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
5cb5caa98Sdjl  * Common Development and Distribution License (the "License").
6cb5caa98Sdjl  * 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 /*
22cb5caa98Sdjl  * 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 weak _nss_ldap__printers_constr = _nss_ldap_printers_constr
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include "ldap_common.h"
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate static void append_attr(char *buf, char *attr);
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate /* printer attributes filters */
337c478bd9Sstevel@tonic-gate #define	_F_GETPRINTERBYNAME	\
347c478bd9Sstevel@tonic-gate 	"(&(objectClass=sunPrinter)(|(printer-name=%s)(printer-aliases=%s)))"
357c478bd9Sstevel@tonic-gate 
36cb5caa98Sdjl #define	PRINTER_PREFIX	"printer-"
37cb5caa98Sdjl #define	SUNWPR_PREFIX	"sunwpr-"
38cb5caa98Sdjl 
397c478bd9Sstevel@tonic-gate /*
407c478bd9Sstevel@tonic-gate  * Attributes from the following classes:
417c478bd9Sstevel@tonic-gate  * 	printerService
427c478bd9Sstevel@tonic-gate  * 	printerAbstact
437c478bd9Sstevel@tonic-gate  * 	sunPrinter
447c478bd9Sstevel@tonic-gate  */
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate /*
477c478bd9Sstevel@tonic-gate  * Get all attributes.
487c478bd9Sstevel@tonic-gate  */
497c478bd9Sstevel@tonic-gate static const char **printer_attrs = NULL;
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate /*
53cb5caa98Sdjl  * _nss_ldap_printers2str is the data marshaling method for the printers
547c478bd9Sstevel@tonic-gate  * getXbyY backend processes. This method is called after a successful
557c478bd9Sstevel@tonic-gate  * ldap search has been performed. This method will parse the ldap search
567c478bd9Sstevel@tonic-gate  * values into argp->buf.buffer. Three error conditions are expected and
577c478bd9Sstevel@tonic-gate  * returned to nsswitch.
58cb5caa98Sdjl  * In order to be compatible with old data output, the code is commented out
59cb5caa98Sdjl  * with NSS_LDAP_PRINTERS. The NSS_LDAP_PRINTERS section is for future
60cb5caa98Sdjl  * refrences if it's decided to fix the output format.
617c478bd9Sstevel@tonic-gate  */
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate static int
_nss_ldap_printers2str(ldap_backend_ptr be,nss_XbyY_args_t * argp)64cb5caa98Sdjl _nss_ldap_printers2str(ldap_backend_ptr be, nss_XbyY_args_t *argp)
657c478bd9Sstevel@tonic-gate {
667c478bd9Sstevel@tonic-gate 	int			i, j;
677c478bd9Sstevel@tonic-gate 	int			nss_result;
68cb5caa98Sdjl 	int			buflen = 0, len;
69cb5caa98Sdjl 	char			*buffer = NULL;
70cb5caa98Sdjl 	char			**name, *attrname;
717c478bd9Sstevel@tonic-gate 	ns_ldap_attr_t		*attr;
727c478bd9Sstevel@tonic-gate 	ns_ldap_result_t	*result = be->result;
73cb5caa98Sdjl #ifdef	NSS_LDAP_PRINTERS
74cb5caa98Sdjl 	int			slen, plen;
75cb5caa98Sdjl #endif
767c478bd9Sstevel@tonic-gate 
77cb5caa98Sdjl 	if (result == NULL)
78cb5caa98Sdjl 		return (NSS_STR_PARSE_PARSE);
79cb5caa98Sdjl 
80cb5caa98Sdjl 	buflen = argp->buf.buflen;
81cb5caa98Sdjl 	if (argp->buf.result != NULL) {
82cb5caa98Sdjl 		be->buffer = calloc(1, buflen);
83cb5caa98Sdjl 		if (be->buffer == NULL)
84cb5caa98Sdjl 			return (NSS_STR_PARSE_PARSE);
85cb5caa98Sdjl 		be->buflen = buflen;
86cb5caa98Sdjl 		buffer = be->buffer;
87cb5caa98Sdjl 	} else {
88cb5caa98Sdjl 		buffer = argp->buf.buffer;
89cb5caa98Sdjl 		(void) memset(argp->buf.buffer, 0, buflen);
907c478bd9Sstevel@tonic-gate 	}
917c478bd9Sstevel@tonic-gate 
92cb5caa98Sdjl 	nss_result = NSS_STR_PARSE_SUCCESS;
937c478bd9Sstevel@tonic-gate 
94cb5caa98Sdjl #ifdef	NSS_LDAP_PRINTERS
95cb5caa98Sdjl 	slen = strlen(SUNWPR_PREFIX);
96cb5caa98Sdjl 	plen = strlen(PRINTER_PREFIX);
97cb5caa98Sdjl #endif
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate 	/*
100cb5caa98Sdjl 	 * Pick out the printer name and aliases
1017c478bd9Sstevel@tonic-gate 	 */
102cb5caa98Sdjl 	name = __ns_ldap_getAttr(result->entry, "printer-name");
103cb5caa98Sdjl 	if (name == NULL || name[0] == NULL) {
104cb5caa98Sdjl 		nss_result = NSS_STR_PARSE_PARSE;
105cb5caa98Sdjl 		goto result_printers2str;
1067c478bd9Sstevel@tonic-gate 	}
107cb5caa98Sdjl 	len = snprintf(buffer, buflen, "%s", name[0]);
108cb5caa98Sdjl 	TEST_AND_ADJUST(len, buffer, buflen, result_printers2str);
109cb5caa98Sdjl 
110cb5caa98Sdjl #ifdef	NSS_LDAP_PRINTERS
111cb5caa98Sdjl 	attr = __ns_ldap_getAttrStruct(result->entry, "printer-aliases");
112cb5caa98Sdjl 	if (attr != NULL && attr->attrvalue != NULL) {
113cb5caa98Sdjl 		for (i = 0; i < attr->value_count; i++) {
114cb5caa98Sdjl 			len = snprintf(buffer, buflen, "|%s",
115cb5caa98Sdjl 					attr->attrvalue[i]);
116cb5caa98Sdjl 			TEST_AND_ADJUST(len, buffer, buflen,
117cb5caa98Sdjl 					result_printers2str);
118cb5caa98Sdjl 		}
1197c478bd9Sstevel@tonic-gate 	}
120cb5caa98Sdjl #endif
1217c478bd9Sstevel@tonic-gate 	/*
1227c478bd9Sstevel@tonic-gate 	 * Add the rest of the attributes
1237c478bd9Sstevel@tonic-gate 	 */
1247c478bd9Sstevel@tonic-gate 	for (i = 0; i < result->entry->attr_count; i++) {
1257c478bd9Sstevel@tonic-gate 		attr = getattr(result, i);
1267c478bd9Sstevel@tonic-gate 		if (attr == NULL) {
127cb5caa98Sdjl 			nss_result = NSS_STR_PARSE_PARSE;
128cb5caa98Sdjl 			goto result_printers2str;
1297c478bd9Sstevel@tonic-gate 		}
1307c478bd9Sstevel@tonic-gate 		/*
1317c478bd9Sstevel@tonic-gate 		 * The attribute contains key=value
1327c478bd9Sstevel@tonic-gate 		 */
1337c478bd9Sstevel@tonic-gate 		if (strcasecmp(attr->attrname, "sun-printer-kvp") == 0) {
1347c478bd9Sstevel@tonic-gate 			for (j = 0; j < attr->value_count; j++) {
1357c478bd9Sstevel@tonic-gate 				len = strlen(attr->attrvalue[j]);
1365135ad20SToomas Soome 				if (len < 1 ) {
1375135ad20SToomas Soome 					*buffer = '\0';
1387c478bd9Sstevel@tonic-gate 					nss_result = (int)NSS_STR_PARSE_PARSE;
139cb5caa98Sdjl 					goto result_printers2str;
1407c478bd9Sstevel@tonic-gate 				}
141cb5caa98Sdjl 				len =  snprintf(buffer, buflen, ":%s",
142cb5caa98Sdjl 						attr->attrvalue[j]);
143cb5caa98Sdjl 				TEST_AND_ADJUST(len, buffer, buflen,
144cb5caa98Sdjl 						result_printers2str);
1457c478bd9Sstevel@tonic-gate 			}
1467c478bd9Sstevel@tonic-gate 		} else {
1477c478bd9Sstevel@tonic-gate 			/*
148cb5caa98Sdjl 			 * Skip some attr names
1497c478bd9Sstevel@tonic-gate 			 */
150cb5caa98Sdjl #ifdef	NSS_LDAP_PRINTERS
151cb5caa98Sdjl 			if (strcasecmp(attr->attrname, "printer-name") == 0 ||
152cb5caa98Sdjl 				strcasecmp(attr->attrname, "dn") == 0 ||
153cb5caa98Sdjl 				strcasecmp(attr->attrname,
154cb5caa98Sdjl 					"objectclass") == 0 ||
155cb5caa98Sdjl 				strcasecmp(attr->attrname,
156cb5caa98Sdjl 					"printer-uri") == 0 ||
157cb5caa98Sdjl 				strcasecmp(attr->attrname,
158cb5caa98Sdjl 					"printer-aliases") == 0)
159cb5caa98Sdjl #else
160cb5caa98Sdjl 			if (strcasecmp(attr->attrname, "printer-name") == 0)
161cb5caa98Sdjl #endif
1627c478bd9Sstevel@tonic-gate 				continue;
1637c478bd9Sstevel@tonic-gate 			}
1647c478bd9Sstevel@tonic-gate 			/*
165cb5caa98Sdjl 			 * Translate attr name ->key name
1667c478bd9Sstevel@tonic-gate 			 */
167cb5caa98Sdjl 			if (strcmp(attr->attrname, "sun-printer-bsdaddr")
168cb5caa98Sdjl 					== 0)
169cb5caa98Sdjl 				attrname = "bsdaddr";
170cb5caa98Sdjl #ifdef	NSS_LDAP_PRINTERS
171cb5caa98Sdjl 			else if (strcmp(attr->attrname, "printer-info")
172cb5caa98Sdjl 					== 0)
173cb5caa98Sdjl 				attrname = "description";
174cb5caa98Sdjl 			else if (strcmp(attr->attrname, "sunwpr-support")
175cb5caa98Sdjl 					== 0)
176cb5caa98Sdjl 				attrname = "itopssupported";
177cb5caa98Sdjl 			else if (strncmp(attr->attrname, PRINTER_PREFIX, plen)
178cb5caa98Sdjl 					== 0)
179cb5caa98Sdjl 				attrname = attr->attrname + plen;
180cb5caa98Sdjl 			else if (strncmp(attr->attrname, SUNWPR_PREFIX, slen)
181cb5caa98Sdjl 					== 0)
182cb5caa98Sdjl 				attrname = attr->attrname + slen;
183cb5caa98Sdjl #endif
184cb5caa98Sdjl 			else
185cb5caa98Sdjl 				attrname = attr->attrname;
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate 			/*
188cb5caa98Sdjl 			 * The attrname is the key. The attribute
1897c478bd9Sstevel@tonic-gate 			 * data is the value.
1907c478bd9Sstevel@tonic-gate 			 */
191cb5caa98Sdjl 			len = snprintf(buffer, buflen, ":%s=", attrname);
192cb5caa98Sdjl 			TEST_AND_ADJUST(len, buffer, buflen,
193cb5caa98Sdjl 					result_printers2str);
194cb5caa98Sdjl 
1957c478bd9Sstevel@tonic-gate 			for (j = 0; j < attr->value_count; j++) {
1967c478bd9Sstevel@tonic-gate 				int k;
1977c478bd9Sstevel@tonic-gate 				char *kp;
1987c478bd9Sstevel@tonic-gate 
199cb5caa98Sdjl 				if (attr->attrvalue[j] == NULL) {
200cb5caa98Sdjl 					*buffer = 0;
201cb5caa98Sdjl 					nss_result = NSS_STR_PARSE_PARSE;
202cb5caa98Sdjl 					goto result_printers2str;
203cb5caa98Sdjl 				}
2047c478bd9Sstevel@tonic-gate 				len = strlen(attr->attrvalue[j]);
205cb5caa98Sdjl 				if (len < 1) {
2067c478bd9Sstevel@tonic-gate 					*buffer = 0;
207cb5caa98Sdjl 					nss_result = NSS_STR_PARSE_PARSE;
208cb5caa98Sdjl 					goto result_printers2str;
2097c478bd9Sstevel@tonic-gate 				}
2107c478bd9Sstevel@tonic-gate 				/*
2117c478bd9Sstevel@tonic-gate 				 * Add extra for any colons which need to
2127c478bd9Sstevel@tonic-gate 				 * be backslashed plus ending ':' or ','.
2137c478bd9Sstevel@tonic-gate 				 */
2147c478bd9Sstevel@tonic-gate 				k = 0;
215*6e6545bfSToomas Soome 				for (kp = attr->attrvalue[j]; *kp != '\0'; kp++)
2167c478bd9Sstevel@tonic-gate 					if (*kp == ':')
217cb5caa98Sdjl 						/* count ':' in value */
2187c478bd9Sstevel@tonic-gate 						k++;
219cb5caa98Sdjl 				if (j == 0)
220cb5caa98Sdjl 					/* first time */
221cb5caa98Sdjl 					len += k;
222cb5caa98Sdjl 				else
223cb5caa98Sdjl 					/* add ',' */
224cb5caa98Sdjl 					len += k + 1;
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate 				if (len > buflen) {
227cb5caa98Sdjl 					nss_result = NSS_STR_PARSE_ERANGE;
228cb5caa98Sdjl 					goto result_printers2str;
2297c478bd9Sstevel@tonic-gate 				}
230cb5caa98Sdjl 				if (j > 0)
231cb5caa98Sdjl 					*buffer++ = ',';
232cb5caa98Sdjl 
233cb5caa98Sdjl 				(void) append_attr(buffer,
2347c478bd9Sstevel@tonic-gate 					    attr->attrvalue[j]);
235cb5caa98Sdjl 				buffer += strlen(attr->attrvalue[j]) + k;
236cb5caa98Sdjl 				buflen -= len;
2377c478bd9Sstevel@tonic-gate 			}
2387c478bd9Sstevel@tonic-gate 	}
2397c478bd9Sstevel@tonic-gate 
240cb5caa98Sdjl 	if (argp->buf.result != NULL)
241cb5caa98Sdjl 		be->buflen = strlen(be->buffer);
2427c478bd9Sstevel@tonic-gate 
243cb5caa98Sdjl result_printers2str:
2447c478bd9Sstevel@tonic-gate 	(void) __ns_ldap_freeResult(&be->result);
2457c478bd9Sstevel@tonic-gate 	return ((int)nss_result);
2467c478bd9Sstevel@tonic-gate }
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate /*
2497c478bd9Sstevel@tonic-gate  * Attributes which contain colons must be backslashed.
2507c478bd9Sstevel@tonic-gate  */
2517c478bd9Sstevel@tonic-gate static void
append_attr(char * buf,char * attr)2527c478bd9Sstevel@tonic-gate append_attr(char *buf, char *attr)
2537c478bd9Sstevel@tonic-gate {
2547c478bd9Sstevel@tonic-gate 	char *cp, *bp;
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate 	if (strchr(attr, ':') == NULL) {
2577c478bd9Sstevel@tonic-gate 		(void) strcat(buf, attr);
2587c478bd9Sstevel@tonic-gate 		return;
2597c478bd9Sstevel@tonic-gate 	}
260cb5caa98Sdjl 	bp = buf;
2617c478bd9Sstevel@tonic-gate 	cp = attr;
262*6e6545bfSToomas Soome 	while (*cp != '\0') {
2637c478bd9Sstevel@tonic-gate 		if (*cp == ':') {
2647c478bd9Sstevel@tonic-gate 			*bp++ = '\\';
2657c478bd9Sstevel@tonic-gate 		}
2667c478bd9Sstevel@tonic-gate 		*bp++ = *cp++;
2677c478bd9Sstevel@tonic-gate 	}
2687c478bd9Sstevel@tonic-gate }
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate /*
2717c478bd9Sstevel@tonic-gate  * getbyname gets printer attributes by printer name. This function
2727c478bd9Sstevel@tonic-gate  * constructs an ldap search filter using the printer name invocation
2737c478bd9Sstevel@tonic-gate  * parameter and the getprinterbyname search filter defined. Once the
2747c478bd9Sstevel@tonic-gate  * filter is constructed, we search for matching entries and marshal
2757c478bd9Sstevel@tonic-gate  * the data results into argp->buf.buffer for the frontend process.
276cb5caa98Sdjl  * The function _nss_ldap_printers2str performs the data marshaling.
2777c478bd9Sstevel@tonic-gate  */
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate static nss_status_t
getbyname(ldap_backend_ptr be,void * a)2807c478bd9Sstevel@tonic-gate getbyname(ldap_backend_ptr be, void *a)
2817c478bd9Sstevel@tonic-gate {
2827c478bd9Sstevel@tonic-gate 	char		printername[BUFSIZ];
2837c478bd9Sstevel@tonic-gate 	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
2847c478bd9Sstevel@tonic-gate 	char		searchfilter[SEARCHFILTERLEN];
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate 	(void) strncpy(printername, argp->key.name, BUFSIZ);
2877c478bd9Sstevel@tonic-gate 	if (snprintf(searchfilter, SEARCHFILTERLEN,
2887c478bd9Sstevel@tonic-gate 		_F_GETPRINTERBYNAME, printername, printername) < 0)
2897c478bd9Sstevel@tonic-gate 		return ((nss_status_t)NSS_NOTFOUND);
2907c478bd9Sstevel@tonic-gate 
2917c478bd9Sstevel@tonic-gate 	return ((nss_status_t)_nss_ldap_lookup(be, argp,
2927c478bd9Sstevel@tonic-gate 		_PRINTERS, searchfilter, NULL, NULL, NULL));
2937c478bd9Sstevel@tonic-gate }
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate static ldap_backend_op_t printers_ops[] = {
2967c478bd9Sstevel@tonic-gate 	_nss_ldap_destr,
2977c478bd9Sstevel@tonic-gate 	_nss_ldap_endent,
2987c478bd9Sstevel@tonic-gate 	_nss_ldap_setent,
2997c478bd9Sstevel@tonic-gate 	_nss_ldap_getent,
3007c478bd9Sstevel@tonic-gate 	getbyname,
3017c478bd9Sstevel@tonic-gate };
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate /*
3057c478bd9Sstevel@tonic-gate  * _nss_ldap_printers_constr is where life begins. This function calls
3067c478bd9Sstevel@tonic-gate  * the generic ldap constructor function to define and build the abstract
3077c478bd9Sstevel@tonic-gate  * data types required to support ldap operations.
3087c478bd9Sstevel@tonic-gate  */
3097c478bd9Sstevel@tonic-gate 
3107c478bd9Sstevel@tonic-gate /*ARGSUSED0*/
3117c478bd9Sstevel@tonic-gate nss_backend_t *
_nss_ldap_printers_constr(const char * dummy1,const char * dummy2,const char * dummy3)3127c478bd9Sstevel@tonic-gate _nss_ldap_printers_constr(const char *dummy1, const char *dummy2,
3137c478bd9Sstevel@tonic-gate 			const char *dummy3)
3147c478bd9Sstevel@tonic-gate {
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate 	return ((nss_backend_t *)_nss_ldap_constr(printers_ops,
3177c478bd9Sstevel@tonic-gate 		sizeof (printers_ops)/sizeof (printers_ops[0]), _PRINTERS,
318cb5caa98Sdjl 		printer_attrs, _nss_ldap_printers2str));
3197c478bd9Sstevel@tonic-gate }
320