1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma weak _nss_ldap__printers_constr = _nss_ldap_printers_constr 27 28 #include "ldap_common.h" 29 30 static void append_attr(char *buf, char *attr); 31 32 /* printer attributes filters */ 33 #define _F_GETPRINTERBYNAME \ 34 "(&(objectClass=sunPrinter)(|(printer-name=%s)(printer-aliases=%s)))" 35 36 #define PRINTER_PREFIX "printer-" 37 #define SUNWPR_PREFIX "sunwpr-" 38 39 /* 40 * Attributes from the following classes: 41 * printerService 42 * printerAbstact 43 * sunPrinter 44 */ 45 46 /* 47 * Get all attributes. 48 */ 49 static const char **printer_attrs = NULL; 50 51 52 /* 53 * _nss_ldap_printers2str is the data marshaling method for the printers 54 * getXbyY backend processes. This method is called after a successful 55 * ldap search has been performed. This method will parse the ldap search 56 * values into argp->buf.buffer. Three error conditions are expected and 57 * returned to nsswitch. 58 * In order to be compatible with old data output, the code is commented out 59 * with NSS_LDAP_PRINTERS. The NSS_LDAP_PRINTERS section is for future 60 * refrences if it's decided to fix the output format. 61 */ 62 63 static int 64 _nss_ldap_printers2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) 65 { 66 int i, j; 67 int nss_result; 68 int buflen = 0, len; 69 char *buffer = NULL; 70 char **name, *attrname; 71 ns_ldap_attr_t *attr; 72 ns_ldap_result_t *result = be->result; 73 #ifdef NSS_LDAP_PRINTERS 74 int slen, plen; 75 #endif 76 77 if (result == NULL) 78 return (NSS_STR_PARSE_PARSE); 79 80 buflen = argp->buf.buflen; 81 if (argp->buf.result != NULL) { 82 be->buffer = calloc(1, buflen); 83 if (be->buffer == NULL) 84 return (NSS_STR_PARSE_PARSE); 85 be->buflen = buflen; 86 buffer = be->buffer; 87 } else { 88 buffer = argp->buf.buffer; 89 (void) memset(argp->buf.buffer, 0, buflen); 90 } 91 92 nss_result = NSS_STR_PARSE_SUCCESS; 93 94 #ifdef NSS_LDAP_PRINTERS 95 slen = strlen(SUNWPR_PREFIX); 96 plen = strlen(PRINTER_PREFIX); 97 #endif 98 99 /* 100 * Pick out the printer name and aliases 101 */ 102 name = __ns_ldap_getAttr(result->entry, "printer-name"); 103 if (name == NULL || name[0] == NULL) { 104 nss_result = NSS_STR_PARSE_PARSE; 105 goto result_printers2str; 106 } 107 len = snprintf(buffer, buflen, "%s", name[0]); 108 TEST_AND_ADJUST(len, buffer, buflen, result_printers2str); 109 110 #ifdef NSS_LDAP_PRINTERS 111 attr = __ns_ldap_getAttrStruct(result->entry, "printer-aliases"); 112 if (attr != NULL && attr->attrvalue != NULL) { 113 for (i = 0; i < attr->value_count; i++) { 114 len = snprintf(buffer, buflen, "|%s", 115 attr->attrvalue[i]); 116 TEST_AND_ADJUST(len, buffer, buflen, 117 result_printers2str); 118 } 119 } 120 #endif 121 /* 122 * Add the rest of the attributes 123 */ 124 for (i = 0; i < result->entry->attr_count; i++) { 125 attr = getattr(result, i); 126 if (attr == NULL) { 127 nss_result = NSS_STR_PARSE_PARSE; 128 goto result_printers2str; 129 } 130 /* 131 * The attribute contains key=value 132 */ 133 if (strcasecmp(attr->attrname, "sun-printer-kvp") == 0) { 134 for (j = 0; j < attr->value_count; j++) { 135 len = strlen(attr->attrvalue[j]); 136 if (len < 1 ) { 137 *buffer = '\0'; 138 nss_result = (int)NSS_STR_PARSE_PARSE; 139 goto result_printers2str; 140 } 141 len = snprintf(buffer, buflen, ":%s", 142 attr->attrvalue[j]); 143 TEST_AND_ADJUST(len, buffer, buflen, 144 result_printers2str); 145 } 146 } else { 147 /* 148 * Skip some attr names 149 */ 150 #ifdef NSS_LDAP_PRINTERS 151 if (strcasecmp(attr->attrname, "printer-name") == 0 || 152 strcasecmp(attr->attrname, "dn") == 0 || 153 strcasecmp(attr->attrname, 154 "objectclass") == 0 || 155 strcasecmp(attr->attrname, 156 "printer-uri") == 0 || 157 strcasecmp(attr->attrname, 158 "printer-aliases") == 0) 159 #else 160 if (strcasecmp(attr->attrname, "printer-name") == 0) 161 #endif 162 continue; 163 } 164 /* 165 * Translate attr name ->key name 166 */ 167 if (strcmp(attr->attrname, "sun-printer-bsdaddr") 168 == 0) 169 attrname = "bsdaddr"; 170 #ifdef NSS_LDAP_PRINTERS 171 else if (strcmp(attr->attrname, "printer-info") 172 == 0) 173 attrname = "description"; 174 else if (strcmp(attr->attrname, "sunwpr-support") 175 == 0) 176 attrname = "itopssupported"; 177 else if (strncmp(attr->attrname, PRINTER_PREFIX, plen) 178 == 0) 179 attrname = attr->attrname + plen; 180 else if (strncmp(attr->attrname, SUNWPR_PREFIX, slen) 181 == 0) 182 attrname = attr->attrname + slen; 183 #endif 184 else 185 attrname = attr->attrname; 186 187 /* 188 * The attrname is the key. The attribute 189 * data is the value. 190 */ 191 len = snprintf(buffer, buflen, ":%s=", attrname); 192 TEST_AND_ADJUST(len, buffer, buflen, 193 result_printers2str); 194 195 for (j = 0; j < attr->value_count; j++) { 196 int k; 197 char *kp; 198 199 if (attr->attrvalue[j] == NULL) { 200 *buffer = 0; 201 nss_result = NSS_STR_PARSE_PARSE; 202 goto result_printers2str; 203 } 204 len = strlen(attr->attrvalue[j]); 205 if (len < 1) { 206 *buffer = 0; 207 nss_result = NSS_STR_PARSE_PARSE; 208 goto result_printers2str; 209 } 210 /* 211 * Add extra for any colons which need to 212 * be backslashed plus ending ':' or ','. 213 */ 214 k = 0; 215 for (kp = attr->attrvalue[j]; *kp != '\0'; kp++) 216 if (*kp == ':') 217 /* count ':' in value */ 218 k++; 219 if (j == 0) 220 /* first time */ 221 len += k; 222 else 223 /* add ',' */ 224 len += k + 1; 225 226 if (len > buflen) { 227 nss_result = NSS_STR_PARSE_ERANGE; 228 goto result_printers2str; 229 } 230 if (j > 0) 231 *buffer++ = ','; 232 233 (void) append_attr(buffer, 234 attr->attrvalue[j]); 235 buffer += strlen(attr->attrvalue[j]) + k; 236 buflen -= len; 237 } 238 } 239 240 if (argp->buf.result != NULL) 241 be->buflen = strlen(be->buffer); 242 243 result_printers2str: 244 (void) __ns_ldap_freeResult(&be->result); 245 return ((int)nss_result); 246 } 247 248 /* 249 * Attributes which contain colons must be backslashed. 250 */ 251 static void 252 append_attr(char *buf, char *attr) 253 { 254 char *cp, *bp; 255 256 if (strchr(attr, ':') == NULL) { 257 (void) strcat(buf, attr); 258 return; 259 } 260 bp = buf; 261 cp = attr; 262 while (*cp != '\0') { 263 if (*cp == ':') { 264 *bp++ = '\\'; 265 } 266 *bp++ = *cp++; 267 } 268 } 269 270 /* 271 * getbyname gets printer attributes by printer name. This function 272 * constructs an ldap search filter using the printer name invocation 273 * parameter and the getprinterbyname search filter defined. Once the 274 * filter is constructed, we search for matching entries and marshal 275 * the data results into argp->buf.buffer for the frontend process. 276 * The function _nss_ldap_printers2str performs the data marshaling. 277 */ 278 279 static nss_status_t 280 getbyname(ldap_backend_ptr be, void *a) 281 { 282 char printername[BUFSIZ]; 283 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 284 char searchfilter[SEARCHFILTERLEN]; 285 286 (void) strncpy(printername, argp->key.name, BUFSIZ); 287 if (snprintf(searchfilter, SEARCHFILTERLEN, 288 _F_GETPRINTERBYNAME, printername, printername) < 0) 289 return ((nss_status_t)NSS_NOTFOUND); 290 291 return ((nss_status_t)_nss_ldap_lookup(be, argp, 292 _PRINTERS, searchfilter, NULL, NULL, NULL)); 293 } 294 295 static ldap_backend_op_t printers_ops[] = { 296 _nss_ldap_destr, 297 _nss_ldap_endent, 298 _nss_ldap_setent, 299 _nss_ldap_getent, 300 getbyname, 301 }; 302 303 304 /* 305 * _nss_ldap_printers_constr is where life begins. This function calls 306 * the generic ldap constructor function to define and build the abstract 307 * data types required to support ldap operations. 308 */ 309 310 /*ARGSUSED0*/ 311 nss_backend_t * 312 _nss_ldap_printers_constr(const char *dummy1, const char *dummy2, 313 const char *dummy3) 314 { 315 316 return ((nss_backend_t *)_nss_ldap_constr(printers_ops, 317 sizeof (printers_ops)/sizeof (printers_ops[0]), _PRINTERS, 318 printer_attrs, _nss_ldap_printers2str)); 319 } 320