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