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