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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #pragma weak _nss_ldap__printers_constr = _nss_ldap_printers_constr 30 31 #include "ldap_common.h" 32 33 static void append_attr(char *buf, char *attr); 34 35 /* printer attributes filters */ 36 #define _F_GETPRINTERBYNAME \ 37 "(&(objectClass=sunPrinter)(|(printer-name=%s)(printer-aliases=%s)))" 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_printers2ent 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 */ 59 60 static int 61 _nss_ldap_printers2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) 62 { 63 int i, j; 64 int nss_result; 65 int buflen = (int)0; 66 unsigned long len = 0L; 67 char *cp = (char *)NULL; 68 char *buffer = (char *)NULL; 69 ns_ldap_attr_t *attr; 70 ns_ldap_result_t *result = be->result; 71 72 buffer = argp->buf.buffer; 73 buflen = (size_t)argp->buf.buflen; 74 if (!argp->buf.result) { 75 nss_result = (int)NSS_STR_PARSE_ERANGE; 76 goto result_printers2ent; 77 } 78 79 nss_result = (int)NSS_STR_PARSE_SUCCESS; 80 (void) memset(argp->buf.buffer, 0, buflen); 81 82 /* Make sure our buffer stays NULL terminated */ 83 buflen--; 84 85 attr = getattr(result, 0); 86 if (attr == NULL) { 87 nss_result = (int)NSS_STR_PARSE_PARSE; 88 goto result_printers2ent; 89 } 90 91 /* 92 * Pick out the printer name. 93 */ 94 for (i = 0; i < result->entry->attr_count; i++) { 95 attr = getattr(result, i); 96 if (attr == NULL) { 97 nss_result = (int)NSS_STR_PARSE_PARSE; 98 goto result_printers2ent; 99 } 100 if (strcasecmp(attr->attrname, "printer-name") == 0) { 101 len = strlen(attr->attrvalue[0]); 102 if (len < 1 || (attr->attrvalue[0] == '\0')) { 103 *buffer = 0; 104 nss_result = (int)NSS_STR_PARSE_PARSE; 105 goto result_printers2ent; 106 } 107 if (len > buflen) { 108 nss_result = (int)NSS_STR_PARSE_ERANGE; 109 goto result_printers2ent; 110 } 111 (void) strcpy(buffer, attr->attrvalue[0]); 112 } 113 } 114 115 /* 116 * Should never happen since it is mandatory but bail if 117 * we don't have a printer name. 118 */ 119 if (buffer[0] == NULL) { 120 nss_result = (int)NSS_STR_PARSE_PARSE; 121 goto result_printers2ent; 122 } 123 124 /* 125 * Add the rest of the attributes 126 */ 127 for (i = 0; i < result->entry->attr_count; i++) { 128 attr = getattr(result, i); 129 if (attr == NULL) { 130 nss_result = (int)NSS_STR_PARSE_PARSE; 131 goto result_printers2ent; 132 } 133 /* 134 * The attribute contains key=value 135 */ 136 if (strcasecmp(attr->attrname, "sun-printer-kvp") == 0) { 137 for (j = 0; j < attr->value_count; j++) { 138 len = strlen(attr->attrvalue[j]); 139 if (len < 1 || 140 (attr->attrvalue[j] == '\0')) { 141 *buffer = 0; 142 nss_result = (int)NSS_STR_PARSE_PARSE; 143 goto result_printers2ent; 144 } 145 len += strlen(buffer) + 1; /* 1 for ':' */ 146 if (len > buflen) { 147 nss_result = (int)NSS_STR_PARSE_ERANGE; 148 goto result_printers2ent; 149 } 150 if ((cp = strrchr(buffer, '\0')) != NULL) { 151 *cp = ':'; 152 (void) strcat(buffer, 153 attr->attrvalue[j]); 154 } 155 } 156 } else { 157 /* 158 * Skip the printer name 159 */ 160 if (strcmp(attr->attrname, "printer-name") == 0) { 161 continue; 162 } 163 /* 164 * Translate sun-printer-bsdaddr -> bsdaddr 165 */ 166 if (strcmp(attr->attrname, "sun-printer-bsdaddr") == 167 0) { 168 if (attr->attrname != NULL) { 169 free(attr->attrname); 170 } 171 attr->attrname = strdup("bsdaddr"); 172 } 173 174 /* 175 * The attribute name is the key. The attribute 176 * data is the value. 177 */ 178 for (j = 0; j < attr->value_count; j++) { 179 int k; 180 char *kp; 181 182 len = strlen(attr->attrvalue[j]); 183 if (len < 1 || 184 (attr->attrvalue[j] == '\0')) { 185 *buffer = 0; 186 nss_result = (int)NSS_STR_PARSE_PARSE; 187 goto result_printers2ent; 188 } 189 /* 190 * Add extra for any colons which need to 191 * be backslashed plus ending ':' or ','. 192 */ 193 k = 0; 194 for (kp = attr->attrvalue[j]; *kp != NULL; kp++) 195 if (*kp == ':') 196 k++; 197 len += strlen(buffer) + k; 198 199 if (j == 0) { 200 len += strlen(attr->attrname) + 1; 201 } 202 if (len > buflen) { 203 nss_result = (int)NSS_STR_PARSE_ERANGE; 204 goto result_printers2ent; 205 } 206 if ((cp = strrchr(buffer, '\0')) != NULL) { 207 if (j == 0) { 208 *cp = ':'; 209 (void) strcat(buffer, 210 attr->attrname); 211 (void) strcat(buffer, "="); 212 } else { 213 *cp = ','; 214 } 215 (void) append_attr(buffer, 216 attr->attrvalue[j]); 217 } 218 } 219 } 220 } 221 222 #ifdef DEBUG 223 (void) fprintf(stdout, "\n[getprinter.c: _nss_ldap_printers2ent]\n"); 224 (void) fprintf(stdout, " printers: [%s]\n", buffer); 225 #endif 226 227 result_printers2ent: 228 (void) __ns_ldap_freeResult(&be->result); 229 return ((int)nss_result); 230 } 231 232 /* 233 * Attributes which contain colons must be backslashed. 234 */ 235 static void 236 append_attr(char *buf, char *attr) 237 { 238 char *cp, *bp; 239 240 if (strchr(attr, ':') == NULL) { 241 (void) strcat(buf, attr); 242 return; 243 } 244 bp = buf + strlen(buf); 245 cp = attr; 246 while (*cp != NULL) { 247 if (*cp == ':') { 248 *bp++ = '\\'; 249 } 250 *bp++ = *cp++; 251 } 252 } 253 254 /* 255 * getbyname gets printer attributes by printer name. This function 256 * constructs an ldap search filter using the printer name invocation 257 * parameter and the getprinterbyname search filter defined. Once the 258 * filter is constructed, we search for matching entries and marshal 259 * the data results into argp->buf.buffer for the frontend process. 260 * The function * _nss_ldap_printers2ent performs the data marshaling. 261 */ 262 263 static nss_status_t 264 getbyname(ldap_backend_ptr be, void *a) 265 { 266 char printername[BUFSIZ]; 267 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 268 char searchfilter[SEARCHFILTERLEN]; 269 270 (void) strncpy(printername, argp->key.name, BUFSIZ); 271 if (snprintf(searchfilter, SEARCHFILTERLEN, 272 _F_GETPRINTERBYNAME, printername, printername) < 0) 273 return ((nss_status_t)NSS_NOTFOUND); 274 275 return ((nss_status_t)_nss_ldap_lookup(be, argp, 276 _PRINTERS, searchfilter, NULL, NULL, NULL)); 277 } 278 279 static ldap_backend_op_t printers_ops[] = { 280 _nss_ldap_destr, 281 _nss_ldap_endent, 282 _nss_ldap_setent, 283 _nss_ldap_getent, 284 getbyname, 285 }; 286 287 288 /* 289 * _nss_ldap_printers_constr is where life begins. This function calls 290 * the generic ldap constructor function to define and build the abstract 291 * data types required to support ldap operations. 292 */ 293 294 /*ARGSUSED0*/ 295 nss_backend_t * 296 _nss_ldap_printers_constr(const char *dummy1, const char *dummy2, 297 const char *dummy3) 298 { 299 300 #ifdef DEBUG 301 (void) fprintf(stdout, 302 "\n[getprinterent.c: _nss_ldap_printers_constr]\n"); 303 #endif 304 305 return ((nss_backend_t *)_nss_ldap_constr(printers_ops, 306 sizeof (printers_ops)/sizeof (printers_ops[0]), _PRINTERS, 307 printer_attrs, _nss_ldap_printers2ent)); 308 } 309