1355b4669Sjacobs /* 2355b4669Sjacobs * CDDL HEADER START 3355b4669Sjacobs * 4355b4669Sjacobs * The contents of this file are subject to the terms of the 5355b4669Sjacobs * Common Development and Distribution License (the "License"). 6355b4669Sjacobs * You may not use this file except in compliance with the License. 7355b4669Sjacobs * 8355b4669Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9355b4669Sjacobs * or http://www.opensolaris.org/os/licensing. 10355b4669Sjacobs * See the License for the specific language governing permissions 11355b4669Sjacobs * and limitations under the License. 12355b4669Sjacobs * 13355b4669Sjacobs * When distributing Covered Code, include this CDDL HEADER in each 14355b4669Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15355b4669Sjacobs * If applicable, add the following below this CDDL HEADER, with the 16355b4669Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying 17355b4669Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner] 18355b4669Sjacobs * 19355b4669Sjacobs * CDDL HEADER END 20355b4669Sjacobs */ 21355b4669Sjacobs 22355b4669Sjacobs /* 23*36615d24Sjacobs * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24355b4669Sjacobs * Use is subject to license terms. 25355b4669Sjacobs * 26355b4669Sjacobs */ 27355b4669Sjacobs 289c378f4bSjacobs /* Id: nss.c 180 2006-07-20 17:33:02Z njacobs $ */ 29355b4669Sjacobs 30355b4669Sjacobs #pragma ident "%Z%%M% %I% %E% SMI" 31355b4669Sjacobs 32355b4669Sjacobs #include <stdio.h> 33355b4669Sjacobs #include <stdlib.h> 34355b4669Sjacobs #include <unistd.h> 35355b4669Sjacobs #include <string.h> 36355b4669Sjacobs #include <ctype.h> 37355b4669Sjacobs #include <sys/types.h> 38355b4669Sjacobs #include <syslog.h> 39355b4669Sjacobs #include <papi.h> 40355b4669Sjacobs #include <uri.h> 41355b4669Sjacobs #include <papi_impl.h> 42355b4669Sjacobs #ifdef NSS_EMULATION 43355b4669Sjacobs #include <nss-emulation.h> 44355b4669Sjacobs #elif NSS_SOLARIS 45355b4669Sjacobs #include <nss_dbdefs.h> 46355b4669Sjacobs #endif 47355b4669Sjacobs #include <config-site.h> 48355b4669Sjacobs #if defined(__sun) && defined(__SVR4) 49355b4669Sjacobs #include <sys/systeminfo.h> 50355b4669Sjacobs #endif 51355b4669Sjacobs 52355b4669Sjacobs 53355b4669Sjacobs static char * 549c378f4bSjacobs bsdaddr_to_uri(papi_attribute_t **list, char *bsdaddr) 55355b4669Sjacobs { 56355b4669Sjacobs char *result = NULL; 57355b4669Sjacobs 58355b4669Sjacobs if (bsdaddr != NULL) { 59355b4669Sjacobs char *bsd[3], *tmp, *iter = NULL; 60355b4669Sjacobs char buf[512]; 61355b4669Sjacobs 62355b4669Sjacobs tmp = strdup(bsdaddr); 63355b4669Sjacobs 64355b4669Sjacobs bsd[0] = strtok_r(tmp, ":,", &iter); 659c378f4bSjacobs if ((bsd[1] = strtok_r(NULL, ":,", &iter)) == NULL) 669c378f4bSjacobs papiAttributeListGetString(list, NULL, 679c378f4bSjacobs "printer-name", &bsd[1]); 68355b4669Sjacobs bsd[2] = strtok_r(NULL, ":,", &iter); 69355b4669Sjacobs 709c378f4bSjacobs snprintf(buf, sizeof (buf), "lpd://%s/printers/%s%s%s", bsd[0], 719c378f4bSjacobs (bsd[1] != NULL) ? bsd[1] : "", 72355b4669Sjacobs (bsd[2] != NULL) ? "#" : "", 73355b4669Sjacobs (bsd[2] != NULL) ? bsd[2] : ""); 74355b4669Sjacobs 75355b4669Sjacobs free(tmp); 76355b4669Sjacobs 77355b4669Sjacobs result = strdup(buf); 78355b4669Sjacobs } 79355b4669Sjacobs 80355b4669Sjacobs return (result); 81355b4669Sjacobs } 82355b4669Sjacobs 83355b4669Sjacobs #if defined(__sun) && defined(__SVR4) 840ce6acb8Sjacobs #include <sys/socket.h> 850ce6acb8Sjacobs #include <sys/ioctl.h> 860ce6acb8Sjacobs #include <sys/sockio.h> 870ce6acb8Sjacobs #include <net/if.h> 880ce6acb8Sjacobs #include <netinet/in.h> 890ce6acb8Sjacobs #include <arpa/inet.h> 900ce6acb8Sjacobs #include <netdb.h> 910ce6acb8Sjacobs 920ce6acb8Sjacobs static struct in6_addr ** 930ce6acb8Sjacobs local_interfaces() 940ce6acb8Sjacobs { 950ce6acb8Sjacobs struct in6_addr **result = NULL; 960ce6acb8Sjacobs int s; 970ce6acb8Sjacobs struct lifnum n; 980ce6acb8Sjacobs struct lifconf c; 990ce6acb8Sjacobs struct lifreq *r; 1000ce6acb8Sjacobs int count; 1010ce6acb8Sjacobs 1020ce6acb8Sjacobs /* we need a socket to get the interfaces */ 1030ce6acb8Sjacobs if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 1040ce6acb8Sjacobs return (0); 1050ce6acb8Sjacobs 1060ce6acb8Sjacobs /* get the number of interfaces */ 1070ce6acb8Sjacobs memset(&n, 0, sizeof (n)); 1080ce6acb8Sjacobs n.lifn_family = AF_UNSPEC; 1090ce6acb8Sjacobs if (ioctl(s, SIOCGLIFNUM, (char *)&n) < 0) { 1100ce6acb8Sjacobs close(s); 1110ce6acb8Sjacobs return (0); /* no interfaces */ 1120ce6acb8Sjacobs } 1130ce6acb8Sjacobs 1140ce6acb8Sjacobs /* get the interface(s) configuration */ 1150ce6acb8Sjacobs memset(&c, 0, sizeof (c)); 1160ce6acb8Sjacobs c.lifc_family = AF_UNSPEC; 1170ce6acb8Sjacobs c.lifc_buf = calloc(n.lifn_count, sizeof (struct lifreq)); 1180ce6acb8Sjacobs c.lifc_len = (n.lifn_count * sizeof (struct lifreq)); 1190ce6acb8Sjacobs if (ioctl(s, SIOCGLIFCONF, (char *)&c) < 0) { 1200ce6acb8Sjacobs free(c.lifc_buf); 1210ce6acb8Sjacobs close(s); 1220ce6acb8Sjacobs return (0); /* can't get interface(s) configuration */ 1230ce6acb8Sjacobs } 1240ce6acb8Sjacobs close(s); 1250ce6acb8Sjacobs 1260ce6acb8Sjacobs r = c.lifc_req; 1270ce6acb8Sjacobs for (count = c.lifc_len / sizeof (struct lifreq); 1280ce6acb8Sjacobs count > 0; count--, r++) { 1290ce6acb8Sjacobs struct in6_addr v6[1], *addr = NULL; 1300ce6acb8Sjacobs 1310ce6acb8Sjacobs switch (r->lifr_addr.ss_family) { 1320ce6acb8Sjacobs case AF_INET: { 1330ce6acb8Sjacobs struct sockaddr_in *s = 1340ce6acb8Sjacobs (struct sockaddr_in *)&r->lifr_addr; 1350ce6acb8Sjacobs IN6_INADDR_TO_V4MAPPED(&s->sin_addr, v6); 1360ce6acb8Sjacobs addr = v6; 1370ce6acb8Sjacobs } 1380ce6acb8Sjacobs break; 1390ce6acb8Sjacobs case AF_INET6: { 1400ce6acb8Sjacobs struct sockaddr_in6 *s = 1410ce6acb8Sjacobs (struct sockaddr_in6 *)&r->lifr_addr; 1420ce6acb8Sjacobs addr = &s->sin6_addr; 1430ce6acb8Sjacobs } 1440ce6acb8Sjacobs break; 1450ce6acb8Sjacobs } 1460ce6acb8Sjacobs 1470ce6acb8Sjacobs if (addr != NULL) { 1480ce6acb8Sjacobs struct in6_addr *a = malloc(sizeof (*a)); 1490ce6acb8Sjacobs 1500ce6acb8Sjacobs memcpy(a, addr, sizeof (*a)); 1510ce6acb8Sjacobs list_append(&result, a); 1520ce6acb8Sjacobs } 1530ce6acb8Sjacobs } 1540ce6acb8Sjacobs free(c.lifc_buf); 1550ce6acb8Sjacobs 1560ce6acb8Sjacobs return (result); 1570ce6acb8Sjacobs } 1580ce6acb8Sjacobs 1590ce6acb8Sjacobs static int 1600ce6acb8Sjacobs match_interfaces(char *host) 1610ce6acb8Sjacobs { 1620ce6acb8Sjacobs struct in6_addr **lif = local_interfaces(); 1630ce6acb8Sjacobs struct hostent *hp; 1640ce6acb8Sjacobs int rc = 0; 1650ce6acb8Sjacobs int errnum; 1660ce6acb8Sjacobs 1670ce6acb8Sjacobs /* are there any local interfaces */ 1680ce6acb8Sjacobs if (lif == NULL) 1690ce6acb8Sjacobs return (0); 1700ce6acb8Sjacobs 1710ce6acb8Sjacobs /* cycle through the host db addresses */ 1720ce6acb8Sjacobs hp = getipnodebyname(host, AF_INET6, AI_ALL|AI_V4MAPPED, &errnum); 1730ce6acb8Sjacobs if (hp != NULL) { 1740ce6acb8Sjacobs struct in6_addr **tmp = (struct in6_addr **)hp->h_addr_list; 1750ce6acb8Sjacobs int i; 1760ce6acb8Sjacobs 1770ce6acb8Sjacobs for (i = 0; ((rc == 0) && (tmp[i] != NULL)); i++) { 1780ce6acb8Sjacobs int j; 1790ce6acb8Sjacobs 1800ce6acb8Sjacobs for (j = 0; ((rc == 0) && (lif[j] != NULL)); j++) 1810ce6acb8Sjacobs if (memcmp(tmp[i], lif[j], 1820ce6acb8Sjacobs sizeof (struct in6_addr)) == 0) 1830ce6acb8Sjacobs rc = 1; 1840ce6acb8Sjacobs } 1850ce6acb8Sjacobs } 1860ce6acb8Sjacobs free(lif); 1870ce6acb8Sjacobs 1880ce6acb8Sjacobs return (rc); 1890ce6acb8Sjacobs } 1900ce6acb8Sjacobs 1910ce6acb8Sjacobs static int 1920ce6acb8Sjacobs is_localhost(char *host) 1930ce6acb8Sjacobs { 1940ce6acb8Sjacobs char hostname[BUFSIZ]; 1950ce6acb8Sjacobs 1960ce6acb8Sjacobs /* is it "localhost" */ 1970ce6acb8Sjacobs if (strncasecmp(host, "localhost", 10) == 0) 1980ce6acb8Sjacobs return (1); 1990ce6acb8Sjacobs 2000ce6acb8Sjacobs /* is it the {nodename} */ 2010ce6acb8Sjacobs sysinfo(SI_HOSTNAME, hostname, sizeof (hostname)); 2020ce6acb8Sjacobs if (strncasecmp(host, hostname, strlen(hostname)) == 0) 2030ce6acb8Sjacobs return (1); 2040ce6acb8Sjacobs 2050ce6acb8Sjacobs /* does it match one of the host's configured interfaces */ 2060ce6acb8Sjacobs if (match_interfaces(host) != 0) 2070ce6acb8Sjacobs return (1); 2080ce6acb8Sjacobs 2090ce6acb8Sjacobs return (0); 2100ce6acb8Sjacobs } 2110ce6acb8Sjacobs 212355b4669Sjacobs /* 213355b4669Sjacobs * This is an awful HACK to force the dynamic PAPI library to use the 214355b4669Sjacobs * lpsched support when the destination apears to be a local lpsched 215355b4669Sjacobs * queue on Solaris. 216355b4669Sjacobs */ 217355b4669Sjacobs static void 218355b4669Sjacobs solaris_lpsched_shortcircuit_hack(papi_attribute_t ***list) 219355b4669Sjacobs { 220355b4669Sjacobs papi_attribute_t *attribute; 221355b4669Sjacobs uri_t *uri = NULL; 222355b4669Sjacobs char *printer = NULL; 223355b4669Sjacobs char buf[128], buf2[128]; 224355b4669Sjacobs 225355b4669Sjacobs /* setting this in the calling env can be useful for debugging */ 226355b4669Sjacobs if (getenv("DISABLE_LPSCHED_SHORTCIRCUIT") != NULL) 227355b4669Sjacobs return; 228355b4669Sjacobs 229355b4669Sjacobs papiAttributeListGetString(*list, NULL, 230355b4669Sjacobs "printer-uri-supported", &printer); 231355b4669Sjacobs if (uri_from_string(printer, &uri) < 0) 232355b4669Sjacobs return; 233355b4669Sjacobs 234355b4669Sjacobs /* already an lpsched URI ? */ 235355b4669Sjacobs if (strcasecmp(uri->scheme, "lpsched") == 0) 236355b4669Sjacobs return; 237355b4669Sjacobs 238355b4669Sjacobs if ((printer = strrchr(uri->path, '/')) == NULL) 239355b4669Sjacobs printer = uri->path; 240355b4669Sjacobs else 241355b4669Sjacobs printer++; 242355b4669Sjacobs 243355b4669Sjacobs /* is there an lpsched queue (printer/class) */ 244355b4669Sjacobs snprintf(buf, sizeof (buf), "/etc/lp/interfaces/%s", printer); 245355b4669Sjacobs snprintf(buf2, sizeof (buf2), "/etc/lp/classes/%s", printer); 246355b4669Sjacobs if ((access(buf, F_OK) < 0) && (access(buf2, F_OK) < 0)) 247355b4669Sjacobs return; 248355b4669Sjacobs 2490ce6acb8Sjacobs /* is this the "local" host */ 2500ce6acb8Sjacobs if ((uri->host != NULL) && (is_localhost(uri->host) == 0)) 2510ce6acb8Sjacobs return; 2520ce6acb8Sjacobs 2530ce6acb8Sjacobs snprintf(buf, sizeof (buf), "lpsched://%s/printers/%s", 2540ce6acb8Sjacobs (uri->host ? uri->host : "localhost"), printer); 255355b4669Sjacobs papiAttributeListAddString(list, PAPI_ATTR_REPLACE, 256355b4669Sjacobs "printer-uri-supported", buf); 257355b4669Sjacobs } 258355b4669Sjacobs #endif 259355b4669Sjacobs 260355b4669Sjacobs static void 261355b4669Sjacobs fill_printer_uri_supported(papi_attribute_t ***list) 262355b4669Sjacobs { 263355b4669Sjacobs papi_attribute_t *attribute; 264355b4669Sjacobs char *string = NULL; 265355b4669Sjacobs 266355b4669Sjacobs /* do we have a printer-uri-supported */ 267355b4669Sjacobs attribute = papiAttributeListFind(*list, "printer-uri-supported"); 268355b4669Sjacobs if (attribute != NULL) /* we have what we need, return */ 269355b4669Sjacobs return; 270355b4669Sjacobs 271*36615d24Sjacobs /* do we have a printer-uri (in URI form) to rename */ 272355b4669Sjacobs attribute = papiAttributeListFind(*list, "printer-uri"); 273*36615d24Sjacobs if ((attribute != NULL) && 274*36615d24Sjacobs (attribute->type == PAPI_STRING) && 275*36615d24Sjacobs (attribute->values != NULL) && 276*36615d24Sjacobs (attribute->values[0]->string != NULL) && 277*36615d24Sjacobs (strstr(attribute->values[0]->string, "://") != NULL)) { 278*36615d24Sjacobs /* rename it in place and return */ 279355b4669Sjacobs free(attribute->name); 280355b4669Sjacobs attribute->name = strdup("printer-uri-supported"); 281355b4669Sjacobs return; 282355b4669Sjacobs } 283355b4669Sjacobs 284355b4669Sjacobs /* do we have a printers.conf(4) "bsdaddr" to convert */ 285355b4669Sjacobs papiAttributeListGetString(*list, NULL, "bsdaddr", &string); 286355b4669Sjacobs if (string != NULL) { /* parse it, convert it, add it */ 2879c378f4bSjacobs char *uri = bsdaddr_to_uri(*list, string); 288355b4669Sjacobs 289355b4669Sjacobs if (uri != NULL) { 290355b4669Sjacobs papiAttributeListAddString(list, PAPI_ATTR_APPEND, 291355b4669Sjacobs "printer-uri-supported", uri); 292355b4669Sjacobs papiAttributeListDelete(list, "bsdaddr"); 293355b4669Sjacobs free(uri); 294355b4669Sjacobs return; 295355b4669Sjacobs } 296355b4669Sjacobs } 297355b4669Sjacobs 298355b4669Sjacobs /* do we have a printers.conf(4) "rm" (and "rp") to convert */ 299355b4669Sjacobs papiAttributeListGetString(*list, NULL, "rm", &string); 300355b4669Sjacobs if (string != NULL) { 301355b4669Sjacobs char *rp = NULL; 302355b4669Sjacobs 303355b4669Sjacobs /* default to "printer-name", but use "rp" if we have it */ 304355b4669Sjacobs papiAttributeListGetString(*list, NULL, "printer-name", &rp); 305355b4669Sjacobs papiAttributeListGetString(*list, NULL, "rp", &rp); 306355b4669Sjacobs 307355b4669Sjacobs if (rp != NULL) { /* fill in the uri if we have the data */ 308355b4669Sjacobs char buf[BUFSIZ]; 309355b4669Sjacobs 310355b4669Sjacobs snprintf(buf, sizeof (buf), "lpd://%s/printers/%s", 311355b4669Sjacobs string, rp); 312355b4669Sjacobs papiAttributeListAddString(list, PAPI_ATTR_APPEND, 313355b4669Sjacobs "printer-uri-supported", strdup(buf)); 314355b4669Sjacobs return; 315355b4669Sjacobs } 316355b4669Sjacobs } 317355b4669Sjacobs 318355b4669Sjacobs /* if were are here, we don't have a printer-uri-supported */ 319355b4669Sjacobs } 320355b4669Sjacobs 321355b4669Sjacobs #ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC 322355b4669Sjacobs static void 323355b4669Sjacobs fill_printer_uri(papi_attribute_t ***list) 324355b4669Sjacobs { 325355b4669Sjacobs papi_attribute_t *attribute; 326355b4669Sjacobs char *uri = NULL; 327355b4669Sjacobs 328355b4669Sjacobs if ((list == NULL) || (*list == NULL)) 329355b4669Sjacobs return; 330355b4669Sjacobs 3310ce6acb8Sjacobs /* do we have a printer-uri */ 332355b4669Sjacobs attribute = papiAttributeListFind(*list, "printer-uri"); 333355b4669Sjacobs if (attribute != NULL) /* we have what we need, return */ 334355b4669Sjacobs return; 335355b4669Sjacobs 336355b4669Sjacobs /* 337355b4669Sjacobs * this is sufficient to fool libgnomeprintpapi, but not promote it's 338355b4669Sjacobs * use in the future. 339355b4669Sjacobs */ 340355b4669Sjacobs papiAttributeListAddString(list, PAPI_ATTR_EXCL, "printer-uri", 341355b4669Sjacobs "broken printer-uri semantic"); 342355b4669Sjacobs } 343355b4669Sjacobs #endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */ 344355b4669Sjacobs 345355b4669Sjacobs static void 346355b4669Sjacobs cvt_all_to_member_names(papi_attribute_t ***list) 347355b4669Sjacobs { 348355b4669Sjacobs papi_status_t status; 349355b4669Sjacobs void *iter = NULL; 350355b4669Sjacobs char *string = NULL; 351355b4669Sjacobs 352355b4669Sjacobs papiAttributeListGetString(*list, NULL, "member-names", &string); 353355b4669Sjacobs if (string != NULL) /* already have a member-names */ 354355b4669Sjacobs return; 355355b4669Sjacobs 356355b4669Sjacobs for (status = papiAttributeListGetString(*list, &iter, "all", &string); 357355b4669Sjacobs status == PAPI_OK; 358355b4669Sjacobs status = papiAttributeListGetString(*list, &iter, NULL, &string)) { 359355b4669Sjacobs char *s_iter = NULL, *value, *tmp = strdup(string); 360355b4669Sjacobs 361355b4669Sjacobs for (value = strtok_r(tmp, ", \t", &s_iter); 362355b4669Sjacobs value != NULL; 363355b4669Sjacobs value = strtok_r(NULL, ", \t", &s_iter)) 364355b4669Sjacobs papiAttributeListAddString(list, PAPI_ATTR_APPEND, 365355b4669Sjacobs "member-names", value); 366355b4669Sjacobs free(tmp); 367355b4669Sjacobs } 368355b4669Sjacobs } 369355b4669Sjacobs 370355b4669Sjacobs static papi_attribute_t ** 371355b4669Sjacobs _cvt_nss_entry_to_printer(char *entry) 372355b4669Sjacobs { 373355b4669Sjacobs char *key = NULL, 374355b4669Sjacobs *cp, 375355b4669Sjacobs buf[BUFSIZ]; 376355b4669Sjacobs int in_namelist = 1, buf_pos = 0; 377355b4669Sjacobs papi_attribute_t **list = NULL; 378355b4669Sjacobs 379355b4669Sjacobs if (entry == NULL) 380355b4669Sjacobs return (NULL); 381355b4669Sjacobs 382355b4669Sjacobs memset(buf, 0, sizeof (buf)); 383355b4669Sjacobs for (cp = entry; *cp != '\0'; cp++) { 384355b4669Sjacobs switch (*cp) { 385355b4669Sjacobs case ':': /* end of kvp */ 386355b4669Sjacobs if (in_namelist != 0) { 387355b4669Sjacobs papiAttributeListAddString(&list, 388355b4669Sjacobs PAPI_ATTR_APPEND, "printer-name", buf); 389355b4669Sjacobs in_namelist = 0; 390355b4669Sjacobs } else if (key != NULL) 391355b4669Sjacobs papiAttributeListAddString(&list, 392355b4669Sjacobs PAPI_ATTR_APPEND, key, buf); 393355b4669Sjacobs memset(buf, 0, sizeof (buf)); 394355b4669Sjacobs buf_pos = 0; 395355b4669Sjacobs key = NULL; 396355b4669Sjacobs break; 397355b4669Sjacobs case '=': /* kvp seperator */ 398355b4669Sjacobs if (key == NULL) { 399355b4669Sjacobs key = strdup(buf); 400355b4669Sjacobs memset(buf, 0, sizeof (buf)); 401355b4669Sjacobs buf_pos = 0; 402355b4669Sjacobs } else 403355b4669Sjacobs buf[buf_pos++] = *cp; 404355b4669Sjacobs break; 405355b4669Sjacobs case '|': /* namelist seperator */ 406355b4669Sjacobs if (in_namelist != 0) { 407355b4669Sjacobs papiAttributeListAddString(&list, 408355b4669Sjacobs PAPI_ATTR_APPEND, "printer-name", buf); 409355b4669Sjacobs memset(buf, 0, sizeof (buf)); 410355b4669Sjacobs buf_pos = 0; 411355b4669Sjacobs } else /* add it to the buffer */ 412355b4669Sjacobs buf[buf_pos++] = *cp; 413355b4669Sjacobs break; 414355b4669Sjacobs case '\\': /* escape char */ 415355b4669Sjacobs buf[buf_pos++] = *(++cp); 416355b4669Sjacobs break; 417355b4669Sjacobs default: 418355b4669Sjacobs buf[buf_pos++] = *cp; 419355b4669Sjacobs } 420355b4669Sjacobs 421355b4669Sjacobs } 422355b4669Sjacobs 423355b4669Sjacobs if (key != NULL) 424355b4669Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_APPEND, key, buf); 425355b4669Sjacobs 426355b4669Sjacobs /* resolve any "use" references in the configuration DB */ 427355b4669Sjacobs key = NULL; 428355b4669Sjacobs papiAttributeListGetString(list, NULL, "use", &key); 429355b4669Sjacobs if (key != NULL) { 430355b4669Sjacobs papi_attribute_t **use_attrs = getprinterbyname(key, NULL); 431355b4669Sjacobs 432355b4669Sjacobs list_concatenate(&list, use_attrs); 433355b4669Sjacobs } 434355b4669Sjacobs 435355b4669Sjacobs fill_printer_uri_supported(&list); 436355b4669Sjacobs cvt_all_to_member_names(&list); /* convert "all" to "member-names" */ 437355b4669Sjacobs 438355b4669Sjacobs return (list); 439355b4669Sjacobs } 440355b4669Sjacobs 441355b4669Sjacobs #if defined(NSS_SOLARIS) && !defined(NSS_EMULATION) 442355b4669Sjacobs 443355b4669Sjacobs #ifndef NSS_DBNAM__PRINTERS /* not in nss_dbdefs.h because it's private */ 444355b4669Sjacobs #define NSS_DBNAM__PRINTERS "_printers" 445355b4669Sjacobs #endif 446355b4669Sjacobs 447355b4669Sjacobs static DEFINE_NSS_DB_ROOT(db_root); 448355b4669Sjacobs static DEFINE_NSS_GETENT(context); 449355b4669Sjacobs 450355b4669Sjacobs static char *private_ns = NULL; 451355b4669Sjacobs 452355b4669Sjacobs static void 453355b4669Sjacobs _nss_initf_printers(p) 454355b4669Sjacobs nss_db_params_t *p; 455355b4669Sjacobs { 456355b4669Sjacobs if (private_ns != NULL) { 457355b4669Sjacobs /* 458355b4669Sjacobs * because we need to support a legacy interface that allows 459355b4669Sjacobs * us to select a specific name service, we need to dummy up 460355b4669Sjacobs * the parameters to use a private nsswitch database and set 461355b4669Sjacobs * the * default_config entry to the name service we are 462355b4669Sjacobs * looking into. 463355b4669Sjacobs */ 464355b4669Sjacobs p->name = NSS_DBNAM__PRINTERS; /* "_printers" */ 465355b4669Sjacobs p->default_config = private_ns; 466fe1de1a1Sjacobs } else { 467355b4669Sjacobs /* regular behaviour */ 468355b4669Sjacobs p->name = NSS_DBNAM_PRINTERS; /* "printers" */ 469355b4669Sjacobs p->default_config = NSS_DEFCONF_PRINTERS; 470355b4669Sjacobs } 471fe1de1a1Sjacobs syslog(LOG_DEBUG, "database: %s, default: %s", 472355b4669Sjacobs (p->name ? p->name : "NULL"), 473355b4669Sjacobs (p->default_config ? p->default_config : "NULL")); 474355b4669Sjacobs } 475355b4669Sjacobs 476355b4669Sjacobs /* 477355b4669Sjacobs * Return values: 0 = success, 1 = parse error, 2 = erange ... 478355b4669Sjacobs * The structure pointer passed in is a structure in the caller's space 479355b4669Sjacobs * wherein the field pointers would be set to areas in the buffer if 480355b4669Sjacobs * need be. instring and buffer should be separate areas. 481355b4669Sjacobs */ 482355b4669Sjacobs /* ARGSUSED */ 483355b4669Sjacobs static int 484355b4669Sjacobs str2printer(const char *instr, int lenstr, void *ent, char *buffer, int buflen) 485355b4669Sjacobs { 486355b4669Sjacobs if (lenstr + 1 > buflen) 487355b4669Sjacobs return (NSS_STR_PARSE_ERANGE); 48832232bf4Sjacobs 48932232bf4Sjacobs /* skip entries that begin with '#' */ 49032232bf4Sjacobs if (instr[0] == '#') 49132232bf4Sjacobs return (NSS_STR_PARSE_PARSE); 49232232bf4Sjacobs 493355b4669Sjacobs /* 494355b4669Sjacobs * We copy the input string into the output buffer 495355b4669Sjacobs */ 496355b4669Sjacobs (void) memcpy(buffer, instr, lenstr); 497355b4669Sjacobs buffer[lenstr] = '\0'; 498355b4669Sjacobs 499355b4669Sjacobs return (NSS_STR_PARSE_SUCCESS); 500355b4669Sjacobs } 501355b4669Sjacobs #endif /* NSS_SOLARIS */ 502355b4669Sjacobs 503355b4669Sjacobs int 504355b4669Sjacobs setprinterentry(int stayopen, char *ns) 505355b4669Sjacobs { 506355b4669Sjacobs #ifdef NSS_EMULATION 507355b4669Sjacobs emul_setprinterentry(stayopen); 508355b4669Sjacobs #elif NSS_SOLARIS 509355b4669Sjacobs private_ns = ns; 510355b4669Sjacobs nss_setent(&db_root, _nss_initf_printers, &context); 511fe1de1a1Sjacobs private_ns = NULL; 512355b4669Sjacobs #endif 513355b4669Sjacobs return (0); 514355b4669Sjacobs } 515355b4669Sjacobs 516355b4669Sjacobs 517355b4669Sjacobs int 518355b4669Sjacobs endprinterentry(int i) 519355b4669Sjacobs { 520355b4669Sjacobs #ifdef NSS_EMULATION 521355b4669Sjacobs emul_endprinterentry(); 522355b4669Sjacobs #elif NSS_SOLARIS 523355b4669Sjacobs nss_endent(&db_root, _nss_initf_printers, &context); 524355b4669Sjacobs nss_delete(&db_root); 525fe1de1a1Sjacobs private_ns = NULL; 526355b4669Sjacobs #endif 527355b4669Sjacobs return (0); 528355b4669Sjacobs } 529355b4669Sjacobs 530355b4669Sjacobs /* ARGSUSED2 */ 531355b4669Sjacobs papi_attribute_t ** 532355b4669Sjacobs getprinterentry(char *ns) 533355b4669Sjacobs { 534355b4669Sjacobs papi_attribute_t **result = NULL; 535355b4669Sjacobs 536355b4669Sjacobs #if defined(NSS_EMULATION) || defined(NSS_SOLARIS) 537355b4669Sjacobs char buf[10240]; 538355b4669Sjacobs nss_status_t res = NSS_NOTFOUND; 539355b4669Sjacobs 540355b4669Sjacobs #ifdef NSS_EMULATION 541355b4669Sjacobs res = emul_getprinterentry_r(buf, sizeof (buf)); 542355b4669Sjacobs #elif NSS_SOLARIS 543355b4669Sjacobs nss_XbyY_args_t arg; 544355b4669Sjacobs 545fe1de1a1Sjacobs private_ns = ns; 546355b4669Sjacobs NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer); 547355b4669Sjacobs res = nss_getent(&db_root, _nss_initf_printers, &context, &arg); 548355b4669Sjacobs (void) NSS_XbyY_FINI(&arg); 549fe1de1a1Sjacobs private_ns = NULL; 550355b4669Sjacobs #endif 551355b4669Sjacobs 552355b4669Sjacobs if (res != NSS_SUCCESS) 553355b4669Sjacobs buf[0] = '\0'; 554355b4669Sjacobs 555355b4669Sjacobs result = _cvt_nss_entry_to_printer(buf); 5560ce6acb8Sjacobs #if defined(__sun) && defined(__SVR4) 5570ce6acb8Sjacobs solaris_lpsched_shortcircuit_hack(&result); 5580ce6acb8Sjacobs #endif 559355b4669Sjacobs #ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC 560355b4669Sjacobs fill_printer_uri(&result); 561355b4669Sjacobs #endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */ 562355b4669Sjacobs #endif 563355b4669Sjacobs 564355b4669Sjacobs #ifdef DEBUG 565355b4669Sjacobs printf("getprinterentry(%s): 0x%8.8x\n", (ns ? ns : "NULL"), result); 566355b4669Sjacobs if (result != NULL) { 567355b4669Sjacobs char buf[4096]; 568355b4669Sjacobs 569355b4669Sjacobs papiAttributeListToString(result, "\n\t", buf, sizeof (buf)); 570355b4669Sjacobs printf("\t%s\n", buf); 571355b4669Sjacobs } 572355b4669Sjacobs #endif /* DEBUG */ 573355b4669Sjacobs 574355b4669Sjacobs return (result); 575355b4669Sjacobs } 576355b4669Sjacobs 577355b4669Sjacobs 578355b4669Sjacobs papi_attribute_t ** 579355b4669Sjacobs getprinterbyname(char *name, char *ns) 580355b4669Sjacobs { 581355b4669Sjacobs papi_attribute_t **result = NULL; 582355b4669Sjacobs 583355b4669Sjacobs if (strstr(name, "://") != NULL) { /* shortcut for URI form */ 584355b4669Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 585355b4669Sjacobs "printer-name", name); 586355b4669Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 587355b4669Sjacobs "printer-uri-supported", name); 588355b4669Sjacobs } else if (strchr(name, ':') != NULL) { /* shortcut for POSIX form */ 5899c378f4bSjacobs char *uri = bsdaddr_to_uri(result, name); 590355b4669Sjacobs 591355b4669Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 592355b4669Sjacobs "printer-name", name); 593355b4669Sjacobs if (uri != NULL) { 594355b4669Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 595355b4669Sjacobs "printer-uri-supported", uri); 596355b4669Sjacobs free(uri); 597355b4669Sjacobs } 598355b4669Sjacobs } else { /* anything else */ 599355b4669Sjacobs #if defined(NSS_EMULATION) || defined(NSS_SOLARIS) 600355b4669Sjacobs char buf[10240]; 601355b4669Sjacobs nss_status_t res = NSS_NOTFOUND; 602355b4669Sjacobs 603355b4669Sjacobs #ifdef NSS_EMULATION 604355b4669Sjacobs res = emul_getprinterbyname_r(name, buf, sizeof (buf)); 605355b4669Sjacobs #elif NSS_SOLARIS 606355b4669Sjacobs nss_XbyY_args_t arg; 607355b4669Sjacobs 608355b4669Sjacobs private_ns = ns; 609355b4669Sjacobs NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer); 610355b4669Sjacobs arg.key.name = name; 611355b4669Sjacobs res = nss_search(&db_root, _nss_initf_printers, 612355b4669Sjacobs NSS_DBOP_PRINTERS_BYNAME, &arg); 613355b4669Sjacobs (void) NSS_XbyY_FINI(&arg); 614fe1de1a1Sjacobs private_ns = NULL; 615355b4669Sjacobs 616355b4669Sjacobs if (res != NSS_SUCCESS) 617355b4669Sjacobs buf[0] = '\0'; 618355b4669Sjacobs #endif 619355b4669Sjacobs 620355b4669Sjacobs result = _cvt_nss_entry_to_printer(buf); 621355b4669Sjacobs #endif 622355b4669Sjacobs } 6230ce6acb8Sjacobs #if defined(__sun) && defined(__SVR4) 6240ce6acb8Sjacobs solaris_lpsched_shortcircuit_hack(&result); 6250ce6acb8Sjacobs #endif 626355b4669Sjacobs #ifdef DEBUG 627355b4669Sjacobs printf("getprinterbyname(%s): %s = 0x%8.8x\n", (ns ? ns : "NULL"), 628355b4669Sjacobs name, result); 629355b4669Sjacobs if (result != NULL) { 630355b4669Sjacobs char buf[4096]; 631355b4669Sjacobs 632355b4669Sjacobs papiAttributeListToString(result, "\n\t", buf, sizeof (buf)); 633355b4669Sjacobs printf("\t%s\n", buf); 634355b4669Sjacobs } 635355b4669Sjacobs #endif /* DEBUG */ 636355b4669Sjacobs 637355b4669Sjacobs return (result); 638355b4669Sjacobs } 639