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 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 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 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 * 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