/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma weak _nss_ldap__printers_constr = _nss_ldap_printers_constr #include "ldap_common.h" static void append_attr(char *buf, char *attr); /* printer attributes filters */ #define _F_GETPRINTERBYNAME \ "(&(objectClass=sunPrinter)(|(printer-name=%s)(printer-aliases=%s)))" #define PRINTER_PREFIX "printer-" #define SUNWPR_PREFIX "sunwpr-" /* * Attributes from the following classes: * printerService * printerAbstact * sunPrinter */ /* * Get all attributes. */ static const char **printer_attrs = NULL; /* * _nss_ldap_printers2str is the data marshaling method for the printers * getXbyY backend processes. This method is called after a successful * ldap search has been performed. This method will parse the ldap search * values into argp->buf.buffer. Three error conditions are expected and * returned to nsswitch. * In order to be compatible with old data output, the code is commented out * with NSS_LDAP_PRINTERS. The NSS_LDAP_PRINTERS section is for future * refrences if it's decided to fix the output format. */ static int _nss_ldap_printers2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { int i, j; int nss_result; int buflen = 0, len; char *buffer = NULL; char **name, *attrname; ns_ldap_attr_t *attr; ns_ldap_result_t *result = be->result; #ifdef NSS_LDAP_PRINTERS int slen, plen; #endif if (result == NULL) return (NSS_STR_PARSE_PARSE); buflen = argp->buf.buflen; if (argp->buf.result != NULL) { be->buffer = calloc(1, buflen); if (be->buffer == NULL) return (NSS_STR_PARSE_PARSE); be->buflen = buflen; buffer = be->buffer; } else { buffer = argp->buf.buffer; (void) memset(argp->buf.buffer, 0, buflen); } nss_result = NSS_STR_PARSE_SUCCESS; #ifdef NSS_LDAP_PRINTERS slen = strlen(SUNWPR_PREFIX); plen = strlen(PRINTER_PREFIX); #endif /* * Pick out the printer name and aliases */ name = __ns_ldap_getAttr(result->entry, "printer-name"); if (name == NULL || name[0] == NULL) { nss_result = NSS_STR_PARSE_PARSE; goto result_printers2str; } len = snprintf(buffer, buflen, "%s", name[0]); TEST_AND_ADJUST(len, buffer, buflen, result_printers2str); #ifdef NSS_LDAP_PRINTERS attr = __ns_ldap_getAttrStruct(result->entry, "printer-aliases"); if (attr != NULL && attr->attrvalue != NULL) { for (i = 0; i < attr->value_count; i++) { len = snprintf(buffer, buflen, "|%s", attr->attrvalue[i]); TEST_AND_ADJUST(len, buffer, buflen, result_printers2str); } } #endif /* * Add the rest of the attributes */ for (i = 0; i < result->entry->attr_count; i++) { attr = getattr(result, i); if (attr == NULL) { nss_result = NSS_STR_PARSE_PARSE; goto result_printers2str; } /* * The attribute contains key=value */ if (strcasecmp(attr->attrname, "sun-printer-kvp") == 0) { for (j = 0; j < attr->value_count; j++) { len = strlen(attr->attrvalue[j]); if (len < 1 ) { *buffer = '\0'; nss_result = (int)NSS_STR_PARSE_PARSE; goto result_printers2str; } len = snprintf(buffer, buflen, ":%s", attr->attrvalue[j]); TEST_AND_ADJUST(len, buffer, buflen, result_printers2str); } } else { /* * Skip some attr names */ #ifdef NSS_LDAP_PRINTERS if (strcasecmp(attr->attrname, "printer-name") == 0 || strcasecmp(attr->attrname, "dn") == 0 || strcasecmp(attr->attrname, "objectclass") == 0 || strcasecmp(attr->attrname, "printer-uri") == 0 || strcasecmp(attr->attrname, "printer-aliases") == 0) #else if (strcasecmp(attr->attrname, "printer-name") == 0) #endif continue; } /* * Translate attr name ->key name */ if (strcmp(attr->attrname, "sun-printer-bsdaddr") == 0) attrname = "bsdaddr"; #ifdef NSS_LDAP_PRINTERS else if (strcmp(attr->attrname, "printer-info") == 0) attrname = "description"; else if (strcmp(attr->attrname, "sunwpr-support") == 0) attrname = "itopssupported"; else if (strncmp(attr->attrname, PRINTER_PREFIX, plen) == 0) attrname = attr->attrname + plen; else if (strncmp(attr->attrname, SUNWPR_PREFIX, slen) == 0) attrname = attr->attrname + slen; #endif else attrname = attr->attrname; /* * The attrname is the key. The attribute * data is the value. */ len = snprintf(buffer, buflen, ":%s=", attrname); TEST_AND_ADJUST(len, buffer, buflen, result_printers2str); for (j = 0; j < attr->value_count; j++) { int k; char *kp; if (attr->attrvalue[j] == NULL) { *buffer = 0; nss_result = NSS_STR_PARSE_PARSE; goto result_printers2str; } len = strlen(attr->attrvalue[j]); if (len < 1) { *buffer = 0; nss_result = NSS_STR_PARSE_PARSE; goto result_printers2str; } /* * Add extra for any colons which need to * be backslashed plus ending ':' or ','. */ k = 0; for (kp = attr->attrvalue[j]; *kp != '\0'; kp++) if (*kp == ':') /* count ':' in value */ k++; if (j == 0) /* first time */ len += k; else /* add ',' */ len += k + 1; if (len > buflen) { nss_result = NSS_STR_PARSE_ERANGE; goto result_printers2str; } if (j > 0) *buffer++ = ','; (void) append_attr(buffer, attr->attrvalue[j]); buffer += strlen(attr->attrvalue[j]) + k; buflen -= len; } } if (argp->buf.result != NULL) be->buflen = strlen(be->buffer); result_printers2str: (void) __ns_ldap_freeResult(&be->result); return ((int)nss_result); } /* * Attributes which contain colons must be backslashed. */ static void append_attr(char *buf, char *attr) { char *cp, *bp; if (strchr(attr, ':') == NULL) { (void) strcat(buf, attr); return; } bp = buf; cp = attr; while (*cp != '\0') { if (*cp == ':') { *bp++ = '\\'; } *bp++ = *cp++; } } /* * getbyname gets printer attributes by printer name. This function * constructs an ldap search filter using the printer name invocation * parameter and the getprinterbyname search filter defined. Once the * filter is constructed, we search for matching entries and marshal * the data results into argp->buf.buffer for the frontend process. * The function _nss_ldap_printers2str performs the data marshaling. */ static nss_status_t getbyname(ldap_backend_ptr be, void *a) { char printername[BUFSIZ]; nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; char searchfilter[SEARCHFILTERLEN]; (void) strncpy(printername, argp->key.name, BUFSIZ); if (snprintf(searchfilter, SEARCHFILTERLEN, _F_GETPRINTERBYNAME, printername, printername) < 0) return ((nss_status_t)NSS_NOTFOUND); return ((nss_status_t)_nss_ldap_lookup(be, argp, _PRINTERS, searchfilter, NULL, NULL, NULL)); } static ldap_backend_op_t printers_ops[] = { _nss_ldap_destr, _nss_ldap_endent, _nss_ldap_setent, _nss_ldap_getent, getbyname, }; /* * _nss_ldap_printers_constr is where life begins. This function calls * the generic ldap constructor function to define and build the abstract * data types required to support ldap operations. */ /*ARGSUSED0*/ nss_backend_t * _nss_ldap_printers_constr(const char *dummy1, const char *dummy2, const char *dummy3) { return ((nss_backend_t *)_nss_ldap_constr(printers_ops, sizeof (printers_ops)/sizeof (printers_ops[0]), _PRINTERS, printer_attrs, _nss_ldap_printers2str)); }