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