17c478bd9Sstevel@tonic-gate /* 2*e9af4bc0SJohn Beck * Copyright (c) 1998-2008 Sendmail, Inc. and its suppliers. 37c478bd9Sstevel@tonic-gate * All rights reserved. 47c478bd9Sstevel@tonic-gate * Copyright (c) 1992, 1995-1997 Eric P. Allman. All rights reserved. 57c478bd9Sstevel@tonic-gate * Copyright (c) 1992, 1993 67c478bd9Sstevel@tonic-gate * The Regents of the University of California. All rights reserved. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * By using this file, you agree to the terms and conditions set 97c478bd9Sstevel@tonic-gate * forth in the LICENSE file which can be found at the top level of 107c478bd9Sstevel@tonic-gate * the sendmail distribution. 117c478bd9Sstevel@tonic-gate * 127c478bd9Sstevel@tonic-gate */ 137c478bd9Sstevel@tonic-gate 147c478bd9Sstevel@tonic-gate /* 157800901eSjbeck * Copyright 1996-2007 Sun Microsystems, Inc. All rights reserved. 167c478bd9Sstevel@tonic-gate * Use is subject to license terms. 177c478bd9Sstevel@tonic-gate */ 187c478bd9Sstevel@tonic-gate 197c478bd9Sstevel@tonic-gate #include <sendmail.h> 207c478bd9Sstevel@tonic-gate 21*e9af4bc0SJohn Beck SM_RCSID("@(#)$Id: map.c,v 8.705 2009/08/11 22:22:40 ca Exp $") 227c478bd9Sstevel@tonic-gate 237c478bd9Sstevel@tonic-gate #if LDAPMAP 247c478bd9Sstevel@tonic-gate # include <sm/ldap.h> 257c478bd9Sstevel@tonic-gate #endif /* LDAPMAP */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #if NDBM 287c478bd9Sstevel@tonic-gate # include <ndbm.h> 297c478bd9Sstevel@tonic-gate # ifdef R_FIRST 307c478bd9Sstevel@tonic-gate ERROR README: You are running the Berkeley DB version of ndbm.h. See 317c478bd9Sstevel@tonic-gate ERROR README: the README file about tweaking Berkeley DB so it can 327c478bd9Sstevel@tonic-gate ERROR README: coexist with NDBM, or delete -DNDBM from the Makefile 337c478bd9Sstevel@tonic-gate ERROR README: and use -DNEWDB instead. 347c478bd9Sstevel@tonic-gate # endif /* R_FIRST */ 357c478bd9Sstevel@tonic-gate #endif /* NDBM */ 367c478bd9Sstevel@tonic-gate #if NEWDB 377c478bd9Sstevel@tonic-gate # include "sm/bdb.h" 387c478bd9Sstevel@tonic-gate #endif /* NEWDB */ 397c478bd9Sstevel@tonic-gate #if NIS 407c478bd9Sstevel@tonic-gate struct dom_binding; /* forward reference needed on IRIX */ 417c478bd9Sstevel@tonic-gate # include <rpcsvc/ypclnt.h> 427c478bd9Sstevel@tonic-gate # if NDBM 437c478bd9Sstevel@tonic-gate # define NDBM_YP_COMPAT /* create YP-compatible NDBM files */ 447c478bd9Sstevel@tonic-gate # endif /* NDBM */ 457c478bd9Sstevel@tonic-gate #endif /* NIS */ 467c478bd9Sstevel@tonic-gate 47058561cbSjbeck #include "map.h" 48058561cbSjbeck 497c478bd9Sstevel@tonic-gate #if NEWDB 507c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR < 2 517c478bd9Sstevel@tonic-gate static bool db_map_open __P((MAP *, int, char *, DBTYPE, const void *)); 527c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR < 2 */ 537c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR == 2 547c478bd9Sstevel@tonic-gate static bool db_map_open __P((MAP *, int, char *, DBTYPE, DB_INFO *)); 557c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR == 2 */ 567c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR > 2 577c478bd9Sstevel@tonic-gate static bool db_map_open __P((MAP *, int, char *, DBTYPE, void **)); 587c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR > 2 */ 597c478bd9Sstevel@tonic-gate #endif /* NEWDB */ 607c478bd9Sstevel@tonic-gate static bool extract_canonname __P((char *, char *, char *, char[], int)); 617c478bd9Sstevel@tonic-gate static void map_close __P((STAB *, int)); 627c478bd9Sstevel@tonic-gate static void map_init __P((STAB *, int)); 637c478bd9Sstevel@tonic-gate #ifdef LDAPMAP 647c478bd9Sstevel@tonic-gate static STAB * ldapmap_findconn __P((SM_LDAP_STRUCT *)); 657c478bd9Sstevel@tonic-gate #endif /* LDAPMAP */ 667c478bd9Sstevel@tonic-gate #if NISPLUS 677c478bd9Sstevel@tonic-gate static bool nisplus_getcanonname __P((char *, int, int *)); 687c478bd9Sstevel@tonic-gate #endif /* NISPLUS */ 697c478bd9Sstevel@tonic-gate #if NIS 707c478bd9Sstevel@tonic-gate static bool nis_getcanonname __P((char *, int, int *)); 717c478bd9Sstevel@tonic-gate #endif /* NIS */ 727c478bd9Sstevel@tonic-gate #if NETINFO 737c478bd9Sstevel@tonic-gate static bool ni_getcanonname __P((char *, int, int *)); 747c478bd9Sstevel@tonic-gate #endif /* NETINFO */ 757c478bd9Sstevel@tonic-gate static bool text_getcanonname __P((char *, int, int *)); 767c478bd9Sstevel@tonic-gate #if SOCKETMAP 777c478bd9Sstevel@tonic-gate static STAB *socket_map_findconn __P((const char*)); 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate /* XXX arbitrary limit for sanity */ 807c478bd9Sstevel@tonic-gate # define SOCKETMAP_MAXL 1000000 817c478bd9Sstevel@tonic-gate #endif /* SOCKETMAP */ 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate /* default error message for trying to open a map in write mode */ 847c478bd9Sstevel@tonic-gate #ifdef ENOSYS 857c478bd9Sstevel@tonic-gate # define SM_EMAPCANTWRITE ENOSYS 867c478bd9Sstevel@tonic-gate #else /* ENOSYS */ 877c478bd9Sstevel@tonic-gate # ifdef EFTYPE 887c478bd9Sstevel@tonic-gate # define SM_EMAPCANTWRITE EFTYPE 897c478bd9Sstevel@tonic-gate # else /* EFTYPE */ 907c478bd9Sstevel@tonic-gate # define SM_EMAPCANTWRITE ENXIO 917c478bd9Sstevel@tonic-gate # endif /* EFTYPE */ 927c478bd9Sstevel@tonic-gate #endif /* ENOSYS */ 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate /* 957c478bd9Sstevel@tonic-gate ** MAP.C -- implementations for various map classes. 967c478bd9Sstevel@tonic-gate ** 977c478bd9Sstevel@tonic-gate ** Each map class implements a series of functions: 987c478bd9Sstevel@tonic-gate ** 997c478bd9Sstevel@tonic-gate ** bool map_parse(MAP *map, char *args) 1007c478bd9Sstevel@tonic-gate ** Parse the arguments from the config file. Return true 1017c478bd9Sstevel@tonic-gate ** if they were ok, false otherwise. Fill in map with the 1027c478bd9Sstevel@tonic-gate ** values. 1037c478bd9Sstevel@tonic-gate ** 1047c478bd9Sstevel@tonic-gate ** char *map_lookup(MAP *map, char *key, char **args, int *pstat) 1057c478bd9Sstevel@tonic-gate ** Look up the key in the given map. If found, do any 1067c478bd9Sstevel@tonic-gate ** rewriting the map wants (including "args" if desired) 1077c478bd9Sstevel@tonic-gate ** and return the value. Set *pstat to the appropriate status 1087c478bd9Sstevel@tonic-gate ** on error and return NULL. Args will be NULL if called 1097c478bd9Sstevel@tonic-gate ** from the alias routines, although this should probably 1107c478bd9Sstevel@tonic-gate ** not be relied upon. It is suggested you call map_rewrite 1117c478bd9Sstevel@tonic-gate ** to return the results -- it takes care of null termination 1127c478bd9Sstevel@tonic-gate ** and uses a dynamically expanded buffer as needed. 1137c478bd9Sstevel@tonic-gate ** 1147c478bd9Sstevel@tonic-gate ** void map_store(MAP *map, char *key, char *value) 1157c478bd9Sstevel@tonic-gate ** Store the key:value pair in the map. 1167c478bd9Sstevel@tonic-gate ** 1177c478bd9Sstevel@tonic-gate ** bool map_open(MAP *map, int mode) 1187c478bd9Sstevel@tonic-gate ** Open the map for the indicated mode. Mode should 1197c478bd9Sstevel@tonic-gate ** be either O_RDONLY or O_RDWR. Return true if it 1207c478bd9Sstevel@tonic-gate ** was opened successfully, false otherwise. If the open 1217c478bd9Sstevel@tonic-gate ** failed and the MF_OPTIONAL flag is not set, it should 1227c478bd9Sstevel@tonic-gate ** also print an error. If the MF_ALIAS bit is set 1237c478bd9Sstevel@tonic-gate ** and this map class understands the @:@ convention, it 1247c478bd9Sstevel@tonic-gate ** should call aliaswait() before returning. 1257c478bd9Sstevel@tonic-gate ** 1267c478bd9Sstevel@tonic-gate ** void map_close(MAP *map) 1277c478bd9Sstevel@tonic-gate ** Close the map. 1287c478bd9Sstevel@tonic-gate ** 1297c478bd9Sstevel@tonic-gate ** This file also includes the implementation for getcanonname. 1307c478bd9Sstevel@tonic-gate ** It is currently implemented in a pretty ad-hoc manner; it ought 1317c478bd9Sstevel@tonic-gate ** to be more properly integrated into the map structure. 1327c478bd9Sstevel@tonic-gate */ 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate #if O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL 1357c478bd9Sstevel@tonic-gate # define LOCK_ON_OPEN 1 /* we can open/create a locked file */ 1367c478bd9Sstevel@tonic-gate #else /* O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL */ 1377c478bd9Sstevel@tonic-gate # define LOCK_ON_OPEN 0 /* no such luck -- bend over backwards */ 1387c478bd9Sstevel@tonic-gate #endif /* O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL */ 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate /* 1417c478bd9Sstevel@tonic-gate ** MAP_PARSEARGS -- parse config line arguments for database lookup 1427c478bd9Sstevel@tonic-gate ** 1437c478bd9Sstevel@tonic-gate ** This is a generic version of the map_parse method. 1447c478bd9Sstevel@tonic-gate ** 1457c478bd9Sstevel@tonic-gate ** Parameters: 1467c478bd9Sstevel@tonic-gate ** map -- the map being initialized. 1477c478bd9Sstevel@tonic-gate ** ap -- a pointer to the args on the config line. 1487c478bd9Sstevel@tonic-gate ** 1497c478bd9Sstevel@tonic-gate ** Returns: 1507c478bd9Sstevel@tonic-gate ** true -- if everything parsed OK. 1517c478bd9Sstevel@tonic-gate ** false -- otherwise. 1527c478bd9Sstevel@tonic-gate ** 1537c478bd9Sstevel@tonic-gate ** Side Effects: 1547c478bd9Sstevel@tonic-gate ** null terminates the filename; stores it in map 1557c478bd9Sstevel@tonic-gate */ 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate bool 1587c478bd9Sstevel@tonic-gate map_parseargs(map, ap) 1597c478bd9Sstevel@tonic-gate MAP *map; 1607c478bd9Sstevel@tonic-gate char *ap; 1617c478bd9Sstevel@tonic-gate { 1627c478bd9Sstevel@tonic-gate register char *p = ap; 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate /* 1657c478bd9Sstevel@tonic-gate ** There is no check whether there is really an argument, 1667c478bd9Sstevel@tonic-gate ** but that's not important enough to warrant extra code. 1677c478bd9Sstevel@tonic-gate */ 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate map->map_mflags |= MF_TRY0NULL|MF_TRY1NULL; 1707c478bd9Sstevel@tonic-gate map->map_spacesub = SpaceSub; /* default value */ 1717c478bd9Sstevel@tonic-gate for (;;) 1727c478bd9Sstevel@tonic-gate { 1737c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 1747c478bd9Sstevel@tonic-gate p++; 1757c478bd9Sstevel@tonic-gate if (*p != '-') 1767c478bd9Sstevel@tonic-gate break; 1777c478bd9Sstevel@tonic-gate switch (*++p) 1787c478bd9Sstevel@tonic-gate { 1797c478bd9Sstevel@tonic-gate case 'N': 1807c478bd9Sstevel@tonic-gate map->map_mflags |= MF_INCLNULL; 1817c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_TRY0NULL; 1827c478bd9Sstevel@tonic-gate break; 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate case 'O': 1857c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_TRY1NULL; 1867c478bd9Sstevel@tonic-gate break; 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate case 'o': 1897c478bd9Sstevel@tonic-gate map->map_mflags |= MF_OPTIONAL; 1907c478bd9Sstevel@tonic-gate break; 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate case 'f': 1937c478bd9Sstevel@tonic-gate map->map_mflags |= MF_NOFOLDCASE; 1947c478bd9Sstevel@tonic-gate break; 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate case 'm': 1977c478bd9Sstevel@tonic-gate map->map_mflags |= MF_MATCHONLY; 1987c478bd9Sstevel@tonic-gate break; 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate case 'A': 2017c478bd9Sstevel@tonic-gate map->map_mflags |= MF_APPEND; 2027c478bd9Sstevel@tonic-gate break; 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate case 'q': 2057c478bd9Sstevel@tonic-gate map->map_mflags |= MF_KEEPQUOTES; 2067c478bd9Sstevel@tonic-gate break; 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate case 'a': 2097c478bd9Sstevel@tonic-gate map->map_app = ++p; 2107c478bd9Sstevel@tonic-gate break; 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate case 'T': 2137c478bd9Sstevel@tonic-gate map->map_tapp = ++p; 2147c478bd9Sstevel@tonic-gate break; 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate case 'k': 2177c478bd9Sstevel@tonic-gate while (isascii(*++p) && isspace(*p)) 2187c478bd9Sstevel@tonic-gate continue; 2197c478bd9Sstevel@tonic-gate map->map_keycolnm = p; 2207c478bd9Sstevel@tonic-gate break; 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate case 'v': 2237c478bd9Sstevel@tonic-gate while (isascii(*++p) && isspace(*p)) 2247c478bd9Sstevel@tonic-gate continue; 2257c478bd9Sstevel@tonic-gate map->map_valcolnm = p; 2267c478bd9Sstevel@tonic-gate break; 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate case 'z': 2297c478bd9Sstevel@tonic-gate if (*++p != '\\') 2307c478bd9Sstevel@tonic-gate map->map_coldelim = *p; 2317c478bd9Sstevel@tonic-gate else 2327c478bd9Sstevel@tonic-gate { 2337c478bd9Sstevel@tonic-gate switch (*++p) 2347c478bd9Sstevel@tonic-gate { 2357c478bd9Sstevel@tonic-gate case 'n': 2367c478bd9Sstevel@tonic-gate map->map_coldelim = '\n'; 2377c478bd9Sstevel@tonic-gate break; 2387c478bd9Sstevel@tonic-gate 2397c478bd9Sstevel@tonic-gate case 't': 2407c478bd9Sstevel@tonic-gate map->map_coldelim = '\t'; 2417c478bd9Sstevel@tonic-gate break; 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate default: 2447c478bd9Sstevel@tonic-gate map->map_coldelim = '\\'; 2457c478bd9Sstevel@tonic-gate } 2467c478bd9Sstevel@tonic-gate } 2477c478bd9Sstevel@tonic-gate break; 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate case 't': 2507c478bd9Sstevel@tonic-gate map->map_mflags |= MF_NODEFER; 2517c478bd9Sstevel@tonic-gate break; 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate case 'S': 2557c478bd9Sstevel@tonic-gate map->map_spacesub = *++p; 2567c478bd9Sstevel@tonic-gate break; 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate case 'D': 2597c478bd9Sstevel@tonic-gate map->map_mflags |= MF_DEFER; 2607c478bd9Sstevel@tonic-gate break; 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate default: 2637c478bd9Sstevel@tonic-gate syserr("Illegal option %c map %s", *p, map->map_mname); 2647c478bd9Sstevel@tonic-gate break; 2657c478bd9Sstevel@tonic-gate } 2667c478bd9Sstevel@tonic-gate while (*p != '\0' && !(isascii(*p) && isspace(*p))) 2677c478bd9Sstevel@tonic-gate p++; 2687c478bd9Sstevel@tonic-gate if (*p != '\0') 2697c478bd9Sstevel@tonic-gate *p++ = '\0'; 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate if (map->map_app != NULL) 2727c478bd9Sstevel@tonic-gate map->map_app = newstr(map->map_app); 2737c478bd9Sstevel@tonic-gate if (map->map_tapp != NULL) 2747c478bd9Sstevel@tonic-gate map->map_tapp = newstr(map->map_tapp); 2757c478bd9Sstevel@tonic-gate if (map->map_keycolnm != NULL) 2767c478bd9Sstevel@tonic-gate map->map_keycolnm = newstr(map->map_keycolnm); 2777c478bd9Sstevel@tonic-gate if (map->map_valcolnm != NULL) 2787c478bd9Sstevel@tonic-gate map->map_valcolnm = newstr(map->map_valcolnm); 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate if (*p != '\0') 2817c478bd9Sstevel@tonic-gate { 2827c478bd9Sstevel@tonic-gate map->map_file = p; 2837c478bd9Sstevel@tonic-gate while (*p != '\0' && !(isascii(*p) && isspace(*p))) 2847c478bd9Sstevel@tonic-gate p++; 2857c478bd9Sstevel@tonic-gate if (*p != '\0') 2867c478bd9Sstevel@tonic-gate *p++ = '\0'; 2877c478bd9Sstevel@tonic-gate map->map_file = newstr(map->map_file); 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate while (*p != '\0' && isascii(*p) && isspace(*p)) 2917c478bd9Sstevel@tonic-gate p++; 2927c478bd9Sstevel@tonic-gate if (*p != '\0') 2937c478bd9Sstevel@tonic-gate map->map_rebuild = newstr(p); 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate if (map->map_file == NULL && 2967c478bd9Sstevel@tonic-gate !bitset(MCF_OPTFILE, map->map_class->map_cflags)) 2977c478bd9Sstevel@tonic-gate { 2987c478bd9Sstevel@tonic-gate syserr("No file name for %s map %s", 2997c478bd9Sstevel@tonic-gate map->map_class->map_cname, map->map_mname); 3007c478bd9Sstevel@tonic-gate return false; 3017c478bd9Sstevel@tonic-gate } 3027c478bd9Sstevel@tonic-gate return true; 3037c478bd9Sstevel@tonic-gate } 3047c478bd9Sstevel@tonic-gate /* 3057c478bd9Sstevel@tonic-gate ** MAP_REWRITE -- rewrite a database key, interpolating %n indications. 3067c478bd9Sstevel@tonic-gate ** 3077c478bd9Sstevel@tonic-gate ** It also adds the map_app string. It can be used as a utility 3087c478bd9Sstevel@tonic-gate ** in the map_lookup method. 3097c478bd9Sstevel@tonic-gate ** 3107c478bd9Sstevel@tonic-gate ** Parameters: 3117c478bd9Sstevel@tonic-gate ** map -- the map that causes this. 3127c478bd9Sstevel@tonic-gate ** s -- the string to rewrite, NOT necessarily null terminated. 3137c478bd9Sstevel@tonic-gate ** slen -- the length of s. 3147c478bd9Sstevel@tonic-gate ** av -- arguments to interpolate into buf. 3157c478bd9Sstevel@tonic-gate ** 3167c478bd9Sstevel@tonic-gate ** Returns: 3177c478bd9Sstevel@tonic-gate ** Pointer to rewritten result. This is static data that 3187c478bd9Sstevel@tonic-gate ** should be copied if it is to be saved! 3197c478bd9Sstevel@tonic-gate */ 3207c478bd9Sstevel@tonic-gate 3217c478bd9Sstevel@tonic-gate char * 3227c478bd9Sstevel@tonic-gate map_rewrite(map, s, slen, av) 3237c478bd9Sstevel@tonic-gate register MAP *map; 3247c478bd9Sstevel@tonic-gate register const char *s; 3257c478bd9Sstevel@tonic-gate size_t slen; 3267c478bd9Sstevel@tonic-gate char **av; 3277c478bd9Sstevel@tonic-gate { 3287c478bd9Sstevel@tonic-gate register char *bp; 3297c478bd9Sstevel@tonic-gate register char c; 3307c478bd9Sstevel@tonic-gate char **avp; 3317c478bd9Sstevel@tonic-gate register char *ap; 3327c478bd9Sstevel@tonic-gate size_t l; 3337c478bd9Sstevel@tonic-gate size_t len; 3347c478bd9Sstevel@tonic-gate static size_t buflen = 0; 3357c478bd9Sstevel@tonic-gate static char *buf = NULL; 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate if (tTd(39, 1)) 3387c478bd9Sstevel@tonic-gate { 3397c478bd9Sstevel@tonic-gate sm_dprintf("map_rewrite(%.*s), av =", (int) slen, s); 3407c478bd9Sstevel@tonic-gate if (av == NULL) 3417c478bd9Sstevel@tonic-gate sm_dprintf(" (nullv)"); 3427c478bd9Sstevel@tonic-gate else 3437c478bd9Sstevel@tonic-gate { 3447c478bd9Sstevel@tonic-gate for (avp = av; *avp != NULL; avp++) 3457c478bd9Sstevel@tonic-gate sm_dprintf("\n\t%s", *avp); 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate sm_dprintf("\n"); 3487c478bd9Sstevel@tonic-gate } 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate /* count expected size of output (can safely overestimate) */ 3517c478bd9Sstevel@tonic-gate l = len = slen; 3527c478bd9Sstevel@tonic-gate if (av != NULL) 3537c478bd9Sstevel@tonic-gate { 3547c478bd9Sstevel@tonic-gate const char *sp = s; 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate while (l-- > 0 && (c = *sp++) != '\0') 3577c478bd9Sstevel@tonic-gate { 3587c478bd9Sstevel@tonic-gate if (c != '%') 3597c478bd9Sstevel@tonic-gate continue; 3607c478bd9Sstevel@tonic-gate if (l-- <= 0) 3617c478bd9Sstevel@tonic-gate break; 3627c478bd9Sstevel@tonic-gate c = *sp++; 3637c478bd9Sstevel@tonic-gate if (!(isascii(c) && isdigit(c))) 3647c478bd9Sstevel@tonic-gate continue; 3657c478bd9Sstevel@tonic-gate for (avp = av; --c >= '0' && *avp != NULL; avp++) 3667c478bd9Sstevel@tonic-gate continue; 3677c478bd9Sstevel@tonic-gate if (*avp == NULL) 3687c478bd9Sstevel@tonic-gate continue; 3697c478bd9Sstevel@tonic-gate len += strlen(*avp); 3707c478bd9Sstevel@tonic-gate } 3717c478bd9Sstevel@tonic-gate } 3727c478bd9Sstevel@tonic-gate if (map->map_app != NULL) 3737c478bd9Sstevel@tonic-gate len += strlen(map->map_app); 3747c478bd9Sstevel@tonic-gate if (buflen < ++len) 3757c478bd9Sstevel@tonic-gate { 3767c478bd9Sstevel@tonic-gate /* need to malloc additional space */ 3777c478bd9Sstevel@tonic-gate buflen = len; 3787c478bd9Sstevel@tonic-gate if (buf != NULL) 3797c478bd9Sstevel@tonic-gate sm_free(buf); 3807c478bd9Sstevel@tonic-gate buf = sm_pmalloc_x(buflen); 3817c478bd9Sstevel@tonic-gate } 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate bp = buf; 3847c478bd9Sstevel@tonic-gate if (av == NULL) 3857c478bd9Sstevel@tonic-gate { 3867c478bd9Sstevel@tonic-gate memmove(bp, s, slen); 3877c478bd9Sstevel@tonic-gate bp += slen; 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate /* assert(len > slen); */ 3907c478bd9Sstevel@tonic-gate len -= slen; 3917c478bd9Sstevel@tonic-gate } 3927c478bd9Sstevel@tonic-gate else 3937c478bd9Sstevel@tonic-gate { 3947c478bd9Sstevel@tonic-gate while (slen-- > 0 && (c = *s++) != '\0') 3957c478bd9Sstevel@tonic-gate { 3967c478bd9Sstevel@tonic-gate if (c != '%') 3977c478bd9Sstevel@tonic-gate { 3987c478bd9Sstevel@tonic-gate pushc: 3997c478bd9Sstevel@tonic-gate if (len-- <= 1) 4007c478bd9Sstevel@tonic-gate break; 4017c478bd9Sstevel@tonic-gate *bp++ = c; 4027c478bd9Sstevel@tonic-gate continue; 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate if (slen-- <= 0 || (c = *s++) == '\0') 4057c478bd9Sstevel@tonic-gate c = '%'; 4067c478bd9Sstevel@tonic-gate if (c == '%') 4077c478bd9Sstevel@tonic-gate goto pushc; 4087c478bd9Sstevel@tonic-gate if (!(isascii(c) && isdigit(c))) 4097c478bd9Sstevel@tonic-gate { 4107c478bd9Sstevel@tonic-gate if (len-- <= 1) 4117c478bd9Sstevel@tonic-gate break; 4127c478bd9Sstevel@tonic-gate *bp++ = '%'; 4137c478bd9Sstevel@tonic-gate goto pushc; 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate for (avp = av; --c >= '0' && *avp != NULL; avp++) 4167c478bd9Sstevel@tonic-gate continue; 4177c478bd9Sstevel@tonic-gate if (*avp == NULL) 4187c478bd9Sstevel@tonic-gate continue; 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate /* transliterate argument into output string */ 4217c478bd9Sstevel@tonic-gate for (ap = *avp; (c = *ap++) != '\0' && len > 0; --len) 4227c478bd9Sstevel@tonic-gate *bp++ = c; 4237c478bd9Sstevel@tonic-gate } 4247c478bd9Sstevel@tonic-gate } 4257c478bd9Sstevel@tonic-gate if (map->map_app != NULL && len > 0) 4267c478bd9Sstevel@tonic-gate (void) sm_strlcpy(bp, map->map_app, len); 4277c478bd9Sstevel@tonic-gate else 4287c478bd9Sstevel@tonic-gate *bp = '\0'; 4297c478bd9Sstevel@tonic-gate if (tTd(39, 1)) 4307c478bd9Sstevel@tonic-gate sm_dprintf("map_rewrite => %s\n", buf); 4317c478bd9Sstevel@tonic-gate return buf; 4327c478bd9Sstevel@tonic-gate } 4337c478bd9Sstevel@tonic-gate /* 4347c478bd9Sstevel@tonic-gate ** INITMAPS -- rebuild alias maps 4357c478bd9Sstevel@tonic-gate ** 4367c478bd9Sstevel@tonic-gate ** Parameters: 4377c478bd9Sstevel@tonic-gate ** none. 4387c478bd9Sstevel@tonic-gate ** 4397c478bd9Sstevel@tonic-gate ** Returns: 4407c478bd9Sstevel@tonic-gate ** none. 4417c478bd9Sstevel@tonic-gate */ 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate void 4447c478bd9Sstevel@tonic-gate initmaps() 4457c478bd9Sstevel@tonic-gate { 4467c478bd9Sstevel@tonic-gate #if XDEBUG 4477c478bd9Sstevel@tonic-gate checkfd012("entering initmaps"); 4487c478bd9Sstevel@tonic-gate #endif /* XDEBUG */ 4497c478bd9Sstevel@tonic-gate stabapply(map_init, 0); 4507c478bd9Sstevel@tonic-gate #if XDEBUG 4517c478bd9Sstevel@tonic-gate checkfd012("exiting initmaps"); 4527c478bd9Sstevel@tonic-gate #endif /* XDEBUG */ 4537c478bd9Sstevel@tonic-gate } 4547c478bd9Sstevel@tonic-gate /* 4557c478bd9Sstevel@tonic-gate ** MAP_INIT -- rebuild a map 4567c478bd9Sstevel@tonic-gate ** 4577c478bd9Sstevel@tonic-gate ** Parameters: 4587c478bd9Sstevel@tonic-gate ** s -- STAB entry: if map: try to rebuild 4597c478bd9Sstevel@tonic-gate ** unused -- unused variable 4607c478bd9Sstevel@tonic-gate ** 4617c478bd9Sstevel@tonic-gate ** Returns: 4627c478bd9Sstevel@tonic-gate ** none. 4637c478bd9Sstevel@tonic-gate ** 4647c478bd9Sstevel@tonic-gate ** Side Effects: 4657c478bd9Sstevel@tonic-gate ** will close already open rebuildable map. 4667c478bd9Sstevel@tonic-gate */ 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate /* ARGSUSED1 */ 4697c478bd9Sstevel@tonic-gate static void 4707c478bd9Sstevel@tonic-gate map_init(s, unused) 4717c478bd9Sstevel@tonic-gate register STAB *s; 4727c478bd9Sstevel@tonic-gate int unused; 4737c478bd9Sstevel@tonic-gate { 4747c478bd9Sstevel@tonic-gate register MAP *map; 4757c478bd9Sstevel@tonic-gate 4767c478bd9Sstevel@tonic-gate /* has to be a map */ 4777c478bd9Sstevel@tonic-gate if (s->s_symtype != ST_MAP) 4787c478bd9Sstevel@tonic-gate return; 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gate map = &s->s_map; 4817c478bd9Sstevel@tonic-gate if (!bitset(MF_VALID, map->map_mflags)) 4827c478bd9Sstevel@tonic-gate return; 4837c478bd9Sstevel@tonic-gate 4847c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 4857c478bd9Sstevel@tonic-gate sm_dprintf("map_init(%s:%s, %s)\n", 4867c478bd9Sstevel@tonic-gate map->map_class->map_cname == NULL ? "NULL" : 4877c478bd9Sstevel@tonic-gate map->map_class->map_cname, 4887c478bd9Sstevel@tonic-gate map->map_mname == NULL ? "NULL" : map->map_mname, 4897c478bd9Sstevel@tonic-gate map->map_file == NULL ? "NULL" : map->map_file); 4907c478bd9Sstevel@tonic-gate 4917c478bd9Sstevel@tonic-gate if (!bitset(MF_ALIAS, map->map_mflags) || 4927c478bd9Sstevel@tonic-gate !bitset(MCF_REBUILDABLE, map->map_class->map_cflags)) 4937c478bd9Sstevel@tonic-gate { 4947c478bd9Sstevel@tonic-gate if (tTd(38, 3)) 4957c478bd9Sstevel@tonic-gate sm_dprintf("\tnot rebuildable\n"); 4967c478bd9Sstevel@tonic-gate return; 4977c478bd9Sstevel@tonic-gate } 4987c478bd9Sstevel@tonic-gate 4997c478bd9Sstevel@tonic-gate /* if already open, close it (for nested open) */ 5007c478bd9Sstevel@tonic-gate if (bitset(MF_OPEN, map->map_mflags)) 5017c478bd9Sstevel@tonic-gate { 5027c478bd9Sstevel@tonic-gate map->map_mflags |= MF_CLOSING; 5037c478bd9Sstevel@tonic-gate map->map_class->map_close(map); 5047c478bd9Sstevel@tonic-gate map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING); 5057c478bd9Sstevel@tonic-gate } 5067c478bd9Sstevel@tonic-gate 5077c478bd9Sstevel@tonic-gate (void) rebuildaliases(map, false); 5087c478bd9Sstevel@tonic-gate return; 5097c478bd9Sstevel@tonic-gate } 5107c478bd9Sstevel@tonic-gate /* 5117c478bd9Sstevel@tonic-gate ** OPENMAP -- open a map 5127c478bd9Sstevel@tonic-gate ** 5137c478bd9Sstevel@tonic-gate ** Parameters: 5147c478bd9Sstevel@tonic-gate ** map -- map to open (it must not be open). 5157c478bd9Sstevel@tonic-gate ** 5167c478bd9Sstevel@tonic-gate ** Returns: 5177c478bd9Sstevel@tonic-gate ** whether open succeeded. 5187c478bd9Sstevel@tonic-gate */ 5197c478bd9Sstevel@tonic-gate 5207c478bd9Sstevel@tonic-gate bool 5217c478bd9Sstevel@tonic-gate openmap(map) 5227c478bd9Sstevel@tonic-gate MAP *map; 5237c478bd9Sstevel@tonic-gate { 5247c478bd9Sstevel@tonic-gate bool restore = false; 5257c478bd9Sstevel@tonic-gate bool savehold = HoldErrs; 5267c478bd9Sstevel@tonic-gate bool savequick = QuickAbort; 5277c478bd9Sstevel@tonic-gate int saveerrors = Errors; 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate if (!bitset(MF_VALID, map->map_mflags)) 5307c478bd9Sstevel@tonic-gate return false; 5317c478bd9Sstevel@tonic-gate 5327c478bd9Sstevel@tonic-gate /* better safe than sorry... */ 5337c478bd9Sstevel@tonic-gate if (bitset(MF_OPEN, map->map_mflags)) 5347c478bd9Sstevel@tonic-gate return true; 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate /* Don't send a map open error out via SMTP */ 5377c478bd9Sstevel@tonic-gate if ((OnlyOneError || QuickAbort) && 5387c478bd9Sstevel@tonic-gate (OpMode == MD_SMTP || OpMode == MD_DAEMON)) 5397c478bd9Sstevel@tonic-gate { 5407c478bd9Sstevel@tonic-gate restore = true; 5417c478bd9Sstevel@tonic-gate HoldErrs = true; 5427c478bd9Sstevel@tonic-gate QuickAbort = false; 5437c478bd9Sstevel@tonic-gate } 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate errno = 0; 5467c478bd9Sstevel@tonic-gate if (map->map_class->map_open(map, O_RDONLY)) 5477c478bd9Sstevel@tonic-gate { 5487c478bd9Sstevel@tonic-gate if (tTd(38, 4)) 5497c478bd9Sstevel@tonic-gate sm_dprintf("openmap()\t%s:%s %s: valid\n", 5507c478bd9Sstevel@tonic-gate map->map_class->map_cname == NULL ? "NULL" : 5517c478bd9Sstevel@tonic-gate map->map_class->map_cname, 5527c478bd9Sstevel@tonic-gate map->map_mname == NULL ? "NULL" : 5537c478bd9Sstevel@tonic-gate map->map_mname, 5547c478bd9Sstevel@tonic-gate map->map_file == NULL ? "NULL" : 5557c478bd9Sstevel@tonic-gate map->map_file); 5567c478bd9Sstevel@tonic-gate map->map_mflags |= MF_OPEN; 5577c478bd9Sstevel@tonic-gate map->map_pid = CurrentPid; 5587c478bd9Sstevel@tonic-gate } 5597c478bd9Sstevel@tonic-gate else 5607c478bd9Sstevel@tonic-gate { 5617c478bd9Sstevel@tonic-gate if (tTd(38, 4)) 5627c478bd9Sstevel@tonic-gate sm_dprintf("openmap()\t%s:%s %s: invalid%s%s\n", 5637c478bd9Sstevel@tonic-gate map->map_class->map_cname == NULL ? "NULL" : 5647c478bd9Sstevel@tonic-gate map->map_class->map_cname, 5657c478bd9Sstevel@tonic-gate map->map_mname == NULL ? "NULL" : 5667c478bd9Sstevel@tonic-gate map->map_mname, 5677c478bd9Sstevel@tonic-gate map->map_file == NULL ? "NULL" : 5687c478bd9Sstevel@tonic-gate map->map_file, 5697c478bd9Sstevel@tonic-gate errno == 0 ? "" : ": ", 5707c478bd9Sstevel@tonic-gate errno == 0 ? "" : sm_errstring(errno)); 5717c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 5727c478bd9Sstevel@tonic-gate { 5737c478bd9Sstevel@tonic-gate extern MAPCLASS BogusMapClass; 5747c478bd9Sstevel@tonic-gate 5757c478bd9Sstevel@tonic-gate map->map_orgclass = map->map_class; 5767c478bd9Sstevel@tonic-gate map->map_class = &BogusMapClass; 5777c478bd9Sstevel@tonic-gate map->map_mflags |= MF_OPEN|MF_OPENBOGUS; 5787c478bd9Sstevel@tonic-gate map->map_pid = CurrentPid; 5797c478bd9Sstevel@tonic-gate } 5807c478bd9Sstevel@tonic-gate else 5817c478bd9Sstevel@tonic-gate { 5827c478bd9Sstevel@tonic-gate /* don't try again */ 5837c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_VALID; 5847c478bd9Sstevel@tonic-gate } 5857c478bd9Sstevel@tonic-gate } 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate if (restore) 5887c478bd9Sstevel@tonic-gate { 5897c478bd9Sstevel@tonic-gate Errors = saveerrors; 5907c478bd9Sstevel@tonic-gate HoldErrs = savehold; 5917c478bd9Sstevel@tonic-gate QuickAbort = savequick; 5927c478bd9Sstevel@tonic-gate } 5937c478bd9Sstevel@tonic-gate 5947c478bd9Sstevel@tonic-gate return bitset(MF_OPEN, map->map_mflags); 5957c478bd9Sstevel@tonic-gate } 5967c478bd9Sstevel@tonic-gate /* 5977c478bd9Sstevel@tonic-gate ** CLOSEMAPS -- close all open maps opened by the current pid. 5987c478bd9Sstevel@tonic-gate ** 5997c478bd9Sstevel@tonic-gate ** Parameters: 6007c478bd9Sstevel@tonic-gate ** bogus -- only close bogus maps. 6017c478bd9Sstevel@tonic-gate ** 6027c478bd9Sstevel@tonic-gate ** Returns: 6037c478bd9Sstevel@tonic-gate ** none. 6047c478bd9Sstevel@tonic-gate */ 6057c478bd9Sstevel@tonic-gate 6067c478bd9Sstevel@tonic-gate void 6077c478bd9Sstevel@tonic-gate closemaps(bogus) 6087c478bd9Sstevel@tonic-gate bool bogus; 6097c478bd9Sstevel@tonic-gate { 6107c478bd9Sstevel@tonic-gate stabapply(map_close, bogus); 6117c478bd9Sstevel@tonic-gate } 6127c478bd9Sstevel@tonic-gate /* 6137c478bd9Sstevel@tonic-gate ** MAP_CLOSE -- close a map opened by the current pid. 6147c478bd9Sstevel@tonic-gate ** 6157c478bd9Sstevel@tonic-gate ** Parameters: 6167c478bd9Sstevel@tonic-gate ** s -- STAB entry: if map: try to close 6177c478bd9Sstevel@tonic-gate ** bogus -- only close bogus maps or MCF_NOTPERSIST maps. 6187c478bd9Sstevel@tonic-gate ** 6197c478bd9Sstevel@tonic-gate ** Returns: 6207c478bd9Sstevel@tonic-gate ** none. 6217c478bd9Sstevel@tonic-gate */ 6227c478bd9Sstevel@tonic-gate 6237c478bd9Sstevel@tonic-gate /* ARGSUSED1 */ 6247c478bd9Sstevel@tonic-gate static void 6257c478bd9Sstevel@tonic-gate map_close(s, bogus) 6267c478bd9Sstevel@tonic-gate register STAB *s; 6277c478bd9Sstevel@tonic-gate int bogus; /* int because of stabapply(), used as bool */ 6287c478bd9Sstevel@tonic-gate { 6297c478bd9Sstevel@tonic-gate MAP *map; 6307c478bd9Sstevel@tonic-gate extern MAPCLASS BogusMapClass; 6317c478bd9Sstevel@tonic-gate 6327c478bd9Sstevel@tonic-gate if (s->s_symtype != ST_MAP) 6337c478bd9Sstevel@tonic-gate return; 6347c478bd9Sstevel@tonic-gate 6357c478bd9Sstevel@tonic-gate map = &s->s_map; 6367c478bd9Sstevel@tonic-gate 6377c478bd9Sstevel@tonic-gate /* 6387c478bd9Sstevel@tonic-gate ** close the map iff: 6397c478bd9Sstevel@tonic-gate ** it is valid and open and opened by this process 6407c478bd9Sstevel@tonic-gate ** and (!bogus or it's a bogus map or it is not persistent) 6417c478bd9Sstevel@tonic-gate ** negate this: return iff 6427c478bd9Sstevel@tonic-gate ** it is not valid or it is not open or not opened by this process 6437c478bd9Sstevel@tonic-gate ** or (bogus and it's not a bogus map and it's not not-persistent) 6447c478bd9Sstevel@tonic-gate */ 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate if (!bitset(MF_VALID, map->map_mflags) || 6477c478bd9Sstevel@tonic-gate !bitset(MF_OPEN, map->map_mflags) || 6487c478bd9Sstevel@tonic-gate bitset(MF_CLOSING, map->map_mflags) || 6497c478bd9Sstevel@tonic-gate map->map_pid != CurrentPid || 6507c478bd9Sstevel@tonic-gate (bogus && map->map_class != &BogusMapClass && 6517c478bd9Sstevel@tonic-gate !bitset(MCF_NOTPERSIST, map->map_class->map_cflags))) 6527c478bd9Sstevel@tonic-gate return; 6537c478bd9Sstevel@tonic-gate 6547c478bd9Sstevel@tonic-gate if (map->map_class == &BogusMapClass && map->map_orgclass != NULL && 6557c478bd9Sstevel@tonic-gate map->map_orgclass != &BogusMapClass) 6567c478bd9Sstevel@tonic-gate map->map_class = map->map_orgclass; 6577c478bd9Sstevel@tonic-gate if (tTd(38, 5)) 6587c478bd9Sstevel@tonic-gate sm_dprintf("closemaps: closing %s (%s)\n", 6597c478bd9Sstevel@tonic-gate map->map_mname == NULL ? "NULL" : map->map_mname, 6607c478bd9Sstevel@tonic-gate map->map_file == NULL ? "NULL" : map->map_file); 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate if (!bitset(MF_OPENBOGUS, map->map_mflags)) 6637c478bd9Sstevel@tonic-gate { 6647c478bd9Sstevel@tonic-gate map->map_mflags |= MF_CLOSING; 6657c478bd9Sstevel@tonic-gate map->map_class->map_close(map); 6667c478bd9Sstevel@tonic-gate } 6677c478bd9Sstevel@tonic-gate map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_OPENBOGUS|MF_CLOSING); 6687c478bd9Sstevel@tonic-gate } 669d25d47eeSjbeck 670d25d47eeSjbeck #if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) 671d25d47eeSjbeck extern int getdomainname(); 672d25d47eeSjbeck 673d25d47eeSjbeck /* this is mainly for backward compatibility in Sun environment */ 674d25d47eeSjbeck static char * 675d25d47eeSjbeck sun_init_domain() 676d25d47eeSjbeck { 677d25d47eeSjbeck /* 678d25d47eeSjbeck ** Get the domain name from the kernel. 679d25d47eeSjbeck ** If it does not start with a leading dot, then remove 680d25d47eeSjbeck ** the first component. Since leading dots are funny Unix 681d25d47eeSjbeck ** files, we treat a leading "+" the same as a leading dot. 682d25d47eeSjbeck ** Finally, force there to be at least one dot in the domain name 683d25d47eeSjbeck ** (i.e. top-level domains are not allowed, like "com", must be 684d25d47eeSjbeck ** something like "sun.com"). 685d25d47eeSjbeck */ 686d25d47eeSjbeck 687d25d47eeSjbeck char buf[MAXNAME]; 688d25d47eeSjbeck char *period, *autodomain; 689d25d47eeSjbeck 690d25d47eeSjbeck if (getdomainname(buf, sizeof buf) < 0) 691d25d47eeSjbeck return NULL; 692d25d47eeSjbeck 693d25d47eeSjbeck if (buf[0] == '\0') 694d25d47eeSjbeck return NULL; 695d25d47eeSjbeck 696d25d47eeSjbeck if (tTd(0, 20)) 697d25d47eeSjbeck printf("domainname = %s\n", buf); 698d25d47eeSjbeck 699d25d47eeSjbeck if (buf[0] == '+') 700d25d47eeSjbeck buf[0] = '.'; 701d25d47eeSjbeck period = strchr(buf, '.'); 702d25d47eeSjbeck if (period == NULL) 703d25d47eeSjbeck autodomain = buf; 704d25d47eeSjbeck else 705d25d47eeSjbeck autodomain = period + 1; 706d25d47eeSjbeck if (strchr(autodomain, '.') == NULL) 707d25d47eeSjbeck return newstr(buf); 708d25d47eeSjbeck else 709d25d47eeSjbeck return newstr(autodomain); 710d25d47eeSjbeck } 711d25d47eeSjbeck #endif /* SUN_EXTENSIONS && SUN_INIT_DOMAIN */ 712d25d47eeSjbeck 7137c478bd9Sstevel@tonic-gate /* 7147c478bd9Sstevel@tonic-gate ** GETCANONNAME -- look up name using service switch 7157c478bd9Sstevel@tonic-gate ** 7167c478bd9Sstevel@tonic-gate ** Parameters: 7177c478bd9Sstevel@tonic-gate ** host -- the host name to look up. 7187c478bd9Sstevel@tonic-gate ** hbsize -- the size of the host buffer. 7197c478bd9Sstevel@tonic-gate ** trymx -- if set, try MX records. 7207c478bd9Sstevel@tonic-gate ** pttl -- pointer to return TTL (can be NULL). 7217c478bd9Sstevel@tonic-gate ** 7227c478bd9Sstevel@tonic-gate ** Returns: 7237c478bd9Sstevel@tonic-gate ** true -- if the host was found. 7247c478bd9Sstevel@tonic-gate ** false -- otherwise. 7257c478bd9Sstevel@tonic-gate */ 7267c478bd9Sstevel@tonic-gate 7277c478bd9Sstevel@tonic-gate bool 7287c478bd9Sstevel@tonic-gate getcanonname(host, hbsize, trymx, pttl) 7297c478bd9Sstevel@tonic-gate char *host; 7307c478bd9Sstevel@tonic-gate int hbsize; 7317c478bd9Sstevel@tonic-gate bool trymx; 7327c478bd9Sstevel@tonic-gate int *pttl; 7337c478bd9Sstevel@tonic-gate { 7347c478bd9Sstevel@tonic-gate int nmaps; 7357c478bd9Sstevel@tonic-gate int mapno; 7367c478bd9Sstevel@tonic-gate bool found = false; 7377c478bd9Sstevel@tonic-gate bool got_tempfail = false; 738*e9af4bc0SJohn Beck auto int status = EX_UNAVAILABLE; 7397c478bd9Sstevel@tonic-gate char *maptype[MAXMAPSTACK]; 7407c478bd9Sstevel@tonic-gate short mapreturn[MAXMAPACTIONS]; 7417c478bd9Sstevel@tonic-gate #if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) 7427c478bd9Sstevel@tonic-gate bool should_try_nis_domain = false; 7437c478bd9Sstevel@tonic-gate static char *nis_domain = NULL; 7447c478bd9Sstevel@tonic-gate #endif 7457c478bd9Sstevel@tonic-gate 7467c478bd9Sstevel@tonic-gate nmaps = switch_map_find("hosts", maptype, mapreturn); 7477c478bd9Sstevel@tonic-gate if (pttl != 0) 7487c478bd9Sstevel@tonic-gate *pttl = SM_DEFAULT_TTL; 7497c478bd9Sstevel@tonic-gate for (mapno = 0; mapno < nmaps; mapno++) 7507c478bd9Sstevel@tonic-gate { 7517c478bd9Sstevel@tonic-gate int i; 7527c478bd9Sstevel@tonic-gate 7537c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 7547c478bd9Sstevel@tonic-gate sm_dprintf("getcanonname(%s), trying %s\n", 7557c478bd9Sstevel@tonic-gate host, maptype[mapno]); 7567c478bd9Sstevel@tonic-gate if (strcmp("files", maptype[mapno]) == 0) 7577c478bd9Sstevel@tonic-gate { 7587c478bd9Sstevel@tonic-gate found = text_getcanonname(host, hbsize, &status); 7597c478bd9Sstevel@tonic-gate } 7607c478bd9Sstevel@tonic-gate #if NIS 7617c478bd9Sstevel@tonic-gate else if (strcmp("nis", maptype[mapno]) == 0) 7627c478bd9Sstevel@tonic-gate { 7637c478bd9Sstevel@tonic-gate found = nis_getcanonname(host, hbsize, &status); 7647c478bd9Sstevel@tonic-gate # if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) 7657c478bd9Sstevel@tonic-gate if (nis_domain == NULL) 7667c478bd9Sstevel@tonic-gate nis_domain = sun_init_domain(); 767d25d47eeSjbeck # endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */ 7687c478bd9Sstevel@tonic-gate } 7697c478bd9Sstevel@tonic-gate #endif /* NIS */ 7707c478bd9Sstevel@tonic-gate #if NISPLUS 7717c478bd9Sstevel@tonic-gate else if (strcmp("nisplus", maptype[mapno]) == 0) 7727c478bd9Sstevel@tonic-gate { 7737c478bd9Sstevel@tonic-gate found = nisplus_getcanonname(host, hbsize, &status); 7747c478bd9Sstevel@tonic-gate # if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) 7757c478bd9Sstevel@tonic-gate if (nis_domain == NULL) 7767c478bd9Sstevel@tonic-gate nis_domain = sun_init_domain(); 777d25d47eeSjbeck # endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */ 7787c478bd9Sstevel@tonic-gate } 7797c478bd9Sstevel@tonic-gate #endif /* NISPLUS */ 7807c478bd9Sstevel@tonic-gate #if NAMED_BIND 7817c478bd9Sstevel@tonic-gate else if (strcmp("dns", maptype[mapno]) == 0) 7827c478bd9Sstevel@tonic-gate { 7837c478bd9Sstevel@tonic-gate found = dns_getcanonname(host, hbsize, trymx, &status, pttl); 7847c478bd9Sstevel@tonic-gate } 7857c478bd9Sstevel@tonic-gate #endif /* NAMED_BIND */ 7867c478bd9Sstevel@tonic-gate #if NETINFO 7877c478bd9Sstevel@tonic-gate else if (strcmp("netinfo", maptype[mapno]) == 0) 7887c478bd9Sstevel@tonic-gate { 7897c478bd9Sstevel@tonic-gate found = ni_getcanonname(host, hbsize, &status); 7907c478bd9Sstevel@tonic-gate } 7917c478bd9Sstevel@tonic-gate #endif /* NETINFO */ 7927c478bd9Sstevel@tonic-gate else 7937c478bd9Sstevel@tonic-gate { 7947c478bd9Sstevel@tonic-gate found = false; 7957c478bd9Sstevel@tonic-gate status = EX_UNAVAILABLE; 7967c478bd9Sstevel@tonic-gate } 7977c478bd9Sstevel@tonic-gate 7987c478bd9Sstevel@tonic-gate /* 7997c478bd9Sstevel@tonic-gate ** Heuristic: if $m is not set, we are running during system 8007c478bd9Sstevel@tonic-gate ** startup. In this case, when a name is apparently found 8017c478bd9Sstevel@tonic-gate ** but has no dot, treat is as not found. This avoids 8027c478bd9Sstevel@tonic-gate ** problems if /etc/hosts has no FQDN but is listed first 8037c478bd9Sstevel@tonic-gate ** in the service switch. 8047c478bd9Sstevel@tonic-gate */ 8057c478bd9Sstevel@tonic-gate 8067c478bd9Sstevel@tonic-gate if (found && 8077c478bd9Sstevel@tonic-gate (macvalue('m', CurEnv) != NULL || strchr(host, '.') != NULL)) 8087c478bd9Sstevel@tonic-gate break; 8097c478bd9Sstevel@tonic-gate 8107c478bd9Sstevel@tonic-gate #if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) 8117c478bd9Sstevel@tonic-gate if (found) 8127c478bd9Sstevel@tonic-gate should_try_nis_domain = true; 8137c478bd9Sstevel@tonic-gate /* but don't break, as we need to try all methods first */ 814d25d47eeSjbeck #endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */ 8157c478bd9Sstevel@tonic-gate 8167c478bd9Sstevel@tonic-gate /* see if we should continue */ 8177c478bd9Sstevel@tonic-gate if (status == EX_TEMPFAIL) 8187c478bd9Sstevel@tonic-gate { 8197c478bd9Sstevel@tonic-gate i = MA_TRYAGAIN; 8207c478bd9Sstevel@tonic-gate got_tempfail = true; 8217c478bd9Sstevel@tonic-gate } 8227c478bd9Sstevel@tonic-gate else if (status == EX_NOTFOUND) 8237c478bd9Sstevel@tonic-gate i = MA_NOTFOUND; 8247c478bd9Sstevel@tonic-gate else 8257c478bd9Sstevel@tonic-gate i = MA_UNAVAIL; 8267c478bd9Sstevel@tonic-gate if (bitset(1 << mapno, mapreturn[i])) 8277c478bd9Sstevel@tonic-gate break; 8287c478bd9Sstevel@tonic-gate } 8297c478bd9Sstevel@tonic-gate 8307c478bd9Sstevel@tonic-gate if (found) 8317c478bd9Sstevel@tonic-gate { 8327c478bd9Sstevel@tonic-gate char *d; 8337c478bd9Sstevel@tonic-gate 8347c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 8357c478bd9Sstevel@tonic-gate sm_dprintf("getcanonname(%s), found\n", host); 8367c478bd9Sstevel@tonic-gate 8377c478bd9Sstevel@tonic-gate /* 8387c478bd9Sstevel@tonic-gate ** If returned name is still single token, compensate 8397c478bd9Sstevel@tonic-gate ** by tagging on $m. This is because some sites set 8407c478bd9Sstevel@tonic-gate ** up their DNS or NIS databases wrong. 8417c478bd9Sstevel@tonic-gate */ 8427c478bd9Sstevel@tonic-gate 8437c478bd9Sstevel@tonic-gate if ((d = strchr(host, '.')) == NULL || d[1] == '\0') 8447c478bd9Sstevel@tonic-gate { 8457c478bd9Sstevel@tonic-gate d = macvalue('m', CurEnv); 8467c478bd9Sstevel@tonic-gate if (d != NULL && 8477c478bd9Sstevel@tonic-gate hbsize > (int) (strlen(host) + strlen(d) + 1)) 8487c478bd9Sstevel@tonic-gate { 8497c478bd9Sstevel@tonic-gate if (host[strlen(host) - 1] != '.') 8507c478bd9Sstevel@tonic-gate (void) sm_strlcat2(host, ".", d, 8517c478bd9Sstevel@tonic-gate hbsize); 8527c478bd9Sstevel@tonic-gate else 8537c478bd9Sstevel@tonic-gate (void) sm_strlcat(host, d, hbsize); 8547c478bd9Sstevel@tonic-gate } 8557c478bd9Sstevel@tonic-gate else 8567c478bd9Sstevel@tonic-gate { 8577c478bd9Sstevel@tonic-gate #if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) 8587c478bd9Sstevel@tonic-gate if (VendorCode == VENDOR_SUN && 8597c478bd9Sstevel@tonic-gate should_try_nis_domain) 8607c478bd9Sstevel@tonic-gate { 8617c478bd9Sstevel@tonic-gate goto try_nis_domain; 8627c478bd9Sstevel@tonic-gate } 863d25d47eeSjbeck #endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */ 8647c478bd9Sstevel@tonic-gate return false; 8657c478bd9Sstevel@tonic-gate } 8667c478bd9Sstevel@tonic-gate } 8677c478bd9Sstevel@tonic-gate return true; 8687c478bd9Sstevel@tonic-gate } 8697c478bd9Sstevel@tonic-gate 8707c478bd9Sstevel@tonic-gate #if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) 8717c478bd9Sstevel@tonic-gate if (VendorCode == VENDOR_SUN && should_try_nis_domain) 8727c478bd9Sstevel@tonic-gate { 8737c478bd9Sstevel@tonic-gate try_nis_domain: 8747c478bd9Sstevel@tonic-gate if (nis_domain != NULL && 8757c478bd9Sstevel@tonic-gate strlen(nis_domain) + strlen(host) + 1 < hbsize) 8767c478bd9Sstevel@tonic-gate { 8777c478bd9Sstevel@tonic-gate (void) sm_strlcat2(host, ".", nis_domain, hbsize); 8787c478bd9Sstevel@tonic-gate return true; 8797c478bd9Sstevel@tonic-gate } 8807c478bd9Sstevel@tonic-gate } 881d25d47eeSjbeck #endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */ 8827c478bd9Sstevel@tonic-gate 8837c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 8847c478bd9Sstevel@tonic-gate sm_dprintf("getcanonname(%s), failed, status=%d\n", host, 8857c478bd9Sstevel@tonic-gate status); 8867c478bd9Sstevel@tonic-gate 8877c478bd9Sstevel@tonic-gate if (got_tempfail) 8887c478bd9Sstevel@tonic-gate SM_SET_H_ERRNO(TRY_AGAIN); 8897c478bd9Sstevel@tonic-gate else 8907c478bd9Sstevel@tonic-gate SM_SET_H_ERRNO(HOST_NOT_FOUND); 8917c478bd9Sstevel@tonic-gate 8927c478bd9Sstevel@tonic-gate return false; 8937c478bd9Sstevel@tonic-gate } 8947c478bd9Sstevel@tonic-gate /* 8957c478bd9Sstevel@tonic-gate ** EXTRACT_CANONNAME -- extract canonical name from /etc/hosts entry 8967c478bd9Sstevel@tonic-gate ** 8977c478bd9Sstevel@tonic-gate ** Parameters: 8987c478bd9Sstevel@tonic-gate ** name -- the name against which to match. 8997c478bd9Sstevel@tonic-gate ** dot -- where to reinsert '.' to get FQDN 9007c478bd9Sstevel@tonic-gate ** line -- the /etc/hosts line. 9017c478bd9Sstevel@tonic-gate ** cbuf -- the location to store the result. 9027c478bd9Sstevel@tonic-gate ** cbuflen -- the size of cbuf. 9037c478bd9Sstevel@tonic-gate ** 9047c478bd9Sstevel@tonic-gate ** Returns: 9057c478bd9Sstevel@tonic-gate ** true -- if the line matched the desired name. 9067c478bd9Sstevel@tonic-gate ** false -- otherwise. 9077c478bd9Sstevel@tonic-gate */ 9087c478bd9Sstevel@tonic-gate 9097c478bd9Sstevel@tonic-gate static bool 9107c478bd9Sstevel@tonic-gate extract_canonname(name, dot, line, cbuf, cbuflen) 9117c478bd9Sstevel@tonic-gate char *name; 9127c478bd9Sstevel@tonic-gate char *dot; 9137c478bd9Sstevel@tonic-gate char *line; 9147c478bd9Sstevel@tonic-gate char cbuf[]; 9157c478bd9Sstevel@tonic-gate int cbuflen; 9167c478bd9Sstevel@tonic-gate { 9177c478bd9Sstevel@tonic-gate int i; 9187c478bd9Sstevel@tonic-gate char *p; 9197c478bd9Sstevel@tonic-gate bool found = false; 9207c478bd9Sstevel@tonic-gate 9217c478bd9Sstevel@tonic-gate cbuf[0] = '\0'; 9227c478bd9Sstevel@tonic-gate if (line[0] == '#') 9237c478bd9Sstevel@tonic-gate return false; 9247c478bd9Sstevel@tonic-gate 9257c478bd9Sstevel@tonic-gate for (i = 1; ; i++) 9267c478bd9Sstevel@tonic-gate { 9277c478bd9Sstevel@tonic-gate char nbuf[MAXNAME + 1]; 9287c478bd9Sstevel@tonic-gate 929058561cbSjbeck p = get_column(line, i, '\0', nbuf, sizeof(nbuf)); 9307c478bd9Sstevel@tonic-gate if (p == NULL) 9317c478bd9Sstevel@tonic-gate break; 9327c478bd9Sstevel@tonic-gate if (*p == '\0') 9337c478bd9Sstevel@tonic-gate continue; 9347c478bd9Sstevel@tonic-gate if (cbuf[0] == '\0' || 9357c478bd9Sstevel@tonic-gate (strchr(cbuf, '.') == NULL && strchr(p, '.') != NULL)) 9367c478bd9Sstevel@tonic-gate { 9377c478bd9Sstevel@tonic-gate (void) sm_strlcpy(cbuf, p, cbuflen); 9387c478bd9Sstevel@tonic-gate } 9397c478bd9Sstevel@tonic-gate if (sm_strcasecmp(name, p) == 0) 9407c478bd9Sstevel@tonic-gate found = true; 9417c478bd9Sstevel@tonic-gate else if (dot != NULL) 9427c478bd9Sstevel@tonic-gate { 9437c478bd9Sstevel@tonic-gate /* try looking for the FQDN as well */ 9447c478bd9Sstevel@tonic-gate *dot = '.'; 9457c478bd9Sstevel@tonic-gate if (sm_strcasecmp(name, p) == 0) 9467c478bd9Sstevel@tonic-gate found = true; 9477c478bd9Sstevel@tonic-gate *dot = '\0'; 9487c478bd9Sstevel@tonic-gate } 9497c478bd9Sstevel@tonic-gate } 9507c478bd9Sstevel@tonic-gate if (found && strchr(cbuf, '.') == NULL) 9517c478bd9Sstevel@tonic-gate { 9527c478bd9Sstevel@tonic-gate /* try to add a domain on the end of the name */ 9537c478bd9Sstevel@tonic-gate char *domain = macvalue('m', CurEnv); 9547c478bd9Sstevel@tonic-gate 9557c478bd9Sstevel@tonic-gate if (domain != NULL && 9567c478bd9Sstevel@tonic-gate strlen(domain) + (i = strlen(cbuf)) + 1 < (size_t) cbuflen) 9577c478bd9Sstevel@tonic-gate { 9587c478bd9Sstevel@tonic-gate p = &cbuf[i]; 9597c478bd9Sstevel@tonic-gate *p++ = '.'; 9607c478bd9Sstevel@tonic-gate (void) sm_strlcpy(p, domain, cbuflen - i - 1); 9617c478bd9Sstevel@tonic-gate } 9627c478bd9Sstevel@tonic-gate } 9637c478bd9Sstevel@tonic-gate return found; 9647c478bd9Sstevel@tonic-gate } 9657c478bd9Sstevel@tonic-gate 9667c478bd9Sstevel@tonic-gate /* 9677c478bd9Sstevel@tonic-gate ** DNS modules 9687c478bd9Sstevel@tonic-gate */ 9697c478bd9Sstevel@tonic-gate 9707c478bd9Sstevel@tonic-gate #if NAMED_BIND 9717c478bd9Sstevel@tonic-gate # if DNSMAP 9727c478bd9Sstevel@tonic-gate 9737c478bd9Sstevel@tonic-gate # include "sm_resolve.h" 9747c478bd9Sstevel@tonic-gate # if NETINET || NETINET6 9757c478bd9Sstevel@tonic-gate # include <arpa/inet.h> 9767c478bd9Sstevel@tonic-gate # endif /* NETINET || NETINET6 */ 9777c478bd9Sstevel@tonic-gate 9787c478bd9Sstevel@tonic-gate /* 9797c478bd9Sstevel@tonic-gate ** DNS_MAP_OPEN -- stub to check proper value for dns map type 9807c478bd9Sstevel@tonic-gate */ 9817c478bd9Sstevel@tonic-gate 9827c478bd9Sstevel@tonic-gate bool 9837c478bd9Sstevel@tonic-gate dns_map_open(map, mode) 9847c478bd9Sstevel@tonic-gate MAP *map; 9857c478bd9Sstevel@tonic-gate int mode; 9867c478bd9Sstevel@tonic-gate { 9877c478bd9Sstevel@tonic-gate if (tTd(38,2)) 9887c478bd9Sstevel@tonic-gate sm_dprintf("dns_map_open(%s, %d)\n", map->map_mname, mode); 9897c478bd9Sstevel@tonic-gate 9907c478bd9Sstevel@tonic-gate mode &= O_ACCMODE; 9917c478bd9Sstevel@tonic-gate if (mode != O_RDONLY) 9927c478bd9Sstevel@tonic-gate { 9937c478bd9Sstevel@tonic-gate /* issue a pseudo-error message */ 9947c478bd9Sstevel@tonic-gate errno = SM_EMAPCANTWRITE; 9957c478bd9Sstevel@tonic-gate return false; 9967c478bd9Sstevel@tonic-gate } 9977c478bd9Sstevel@tonic-gate return true; 9987c478bd9Sstevel@tonic-gate } 9997c478bd9Sstevel@tonic-gate 10007c478bd9Sstevel@tonic-gate /* 10017c478bd9Sstevel@tonic-gate ** DNS_MAP_PARSEARGS -- parse dns map definition args. 10027c478bd9Sstevel@tonic-gate ** 10037c478bd9Sstevel@tonic-gate ** Parameters: 10047c478bd9Sstevel@tonic-gate ** map -- pointer to MAP 10057c478bd9Sstevel@tonic-gate ** args -- pointer to the args on the config line. 10067c478bd9Sstevel@tonic-gate ** 10077c478bd9Sstevel@tonic-gate ** Returns: 10087c478bd9Sstevel@tonic-gate ** true -- if everything parsed OK. 10097c478bd9Sstevel@tonic-gate ** false -- otherwise. 10107c478bd9Sstevel@tonic-gate */ 10117c478bd9Sstevel@tonic-gate 10127c478bd9Sstevel@tonic-gate #define map_sizelimit map_lockfd /* overload field */ 10137c478bd9Sstevel@tonic-gate 10147c478bd9Sstevel@tonic-gate struct dns_map 10157c478bd9Sstevel@tonic-gate { 10167c478bd9Sstevel@tonic-gate int dns_m_type; 10177c478bd9Sstevel@tonic-gate }; 10187c478bd9Sstevel@tonic-gate 10197c478bd9Sstevel@tonic-gate bool 10207c478bd9Sstevel@tonic-gate dns_map_parseargs(map,args) 10217c478bd9Sstevel@tonic-gate MAP *map; 10227c478bd9Sstevel@tonic-gate char *args; 10237c478bd9Sstevel@tonic-gate { 10247c478bd9Sstevel@tonic-gate register char *p = args; 10257c478bd9Sstevel@tonic-gate struct dns_map *map_p; 10267c478bd9Sstevel@tonic-gate 1027058561cbSjbeck map_p = (struct dns_map *) xalloc(sizeof(*map_p)); 10287c478bd9Sstevel@tonic-gate map_p->dns_m_type = -1; 10297c478bd9Sstevel@tonic-gate map->map_mflags |= MF_TRY0NULL|MF_TRY1NULL; 10307c478bd9Sstevel@tonic-gate 10317c478bd9Sstevel@tonic-gate for (;;) 10327c478bd9Sstevel@tonic-gate { 10337c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 10347c478bd9Sstevel@tonic-gate p++; 10357c478bd9Sstevel@tonic-gate if (*p != '-') 10367c478bd9Sstevel@tonic-gate break; 10377c478bd9Sstevel@tonic-gate switch (*++p) 10387c478bd9Sstevel@tonic-gate { 10397c478bd9Sstevel@tonic-gate case 'N': 10407c478bd9Sstevel@tonic-gate map->map_mflags |= MF_INCLNULL; 10417c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_TRY0NULL; 10427c478bd9Sstevel@tonic-gate break; 10437c478bd9Sstevel@tonic-gate 10447c478bd9Sstevel@tonic-gate case 'O': 10457c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_TRY1NULL; 10467c478bd9Sstevel@tonic-gate break; 10477c478bd9Sstevel@tonic-gate 10487c478bd9Sstevel@tonic-gate case 'o': 10497c478bd9Sstevel@tonic-gate map->map_mflags |= MF_OPTIONAL; 10507c478bd9Sstevel@tonic-gate break; 10517c478bd9Sstevel@tonic-gate 10527c478bd9Sstevel@tonic-gate case 'f': 10537c478bd9Sstevel@tonic-gate map->map_mflags |= MF_NOFOLDCASE; 10547c478bd9Sstevel@tonic-gate break; 10557c478bd9Sstevel@tonic-gate 10567c478bd9Sstevel@tonic-gate case 'm': 10577c478bd9Sstevel@tonic-gate map->map_mflags |= MF_MATCHONLY; 10587c478bd9Sstevel@tonic-gate break; 10597c478bd9Sstevel@tonic-gate 10607c478bd9Sstevel@tonic-gate case 'A': 10617c478bd9Sstevel@tonic-gate map->map_mflags |= MF_APPEND; 10627c478bd9Sstevel@tonic-gate break; 10637c478bd9Sstevel@tonic-gate 10647c478bd9Sstevel@tonic-gate case 'q': 10657c478bd9Sstevel@tonic-gate map->map_mflags |= MF_KEEPQUOTES; 10667c478bd9Sstevel@tonic-gate break; 10677c478bd9Sstevel@tonic-gate 10687c478bd9Sstevel@tonic-gate case 't': 10697c478bd9Sstevel@tonic-gate map->map_mflags |= MF_NODEFER; 10707c478bd9Sstevel@tonic-gate break; 10717c478bd9Sstevel@tonic-gate 10727c478bd9Sstevel@tonic-gate case 'a': 10737c478bd9Sstevel@tonic-gate map->map_app = ++p; 10747c478bd9Sstevel@tonic-gate break; 10757c478bd9Sstevel@tonic-gate 10767c478bd9Sstevel@tonic-gate case 'T': 10777c478bd9Sstevel@tonic-gate map->map_tapp = ++p; 10787c478bd9Sstevel@tonic-gate break; 10797c478bd9Sstevel@tonic-gate 10807c478bd9Sstevel@tonic-gate case 'd': 10817c478bd9Sstevel@tonic-gate { 10827c478bd9Sstevel@tonic-gate char *h; 10837c478bd9Sstevel@tonic-gate 10847c478bd9Sstevel@tonic-gate ++p; 10857c478bd9Sstevel@tonic-gate h = strchr(p, ' '); 10867c478bd9Sstevel@tonic-gate if (h != NULL) 10877c478bd9Sstevel@tonic-gate *h = '\0'; 10887c478bd9Sstevel@tonic-gate map->map_timeout = convtime(p, 's'); 10897c478bd9Sstevel@tonic-gate if (h != NULL) 10907c478bd9Sstevel@tonic-gate *h = ' '; 10917c478bd9Sstevel@tonic-gate } 10927c478bd9Sstevel@tonic-gate break; 10937c478bd9Sstevel@tonic-gate 10947c478bd9Sstevel@tonic-gate case 'r': 10957c478bd9Sstevel@tonic-gate while (isascii(*++p) && isspace(*p)) 10967c478bd9Sstevel@tonic-gate continue; 10977c478bd9Sstevel@tonic-gate map->map_retry = atoi(p); 10987c478bd9Sstevel@tonic-gate break; 10997c478bd9Sstevel@tonic-gate 11007c478bd9Sstevel@tonic-gate case 'z': 11017c478bd9Sstevel@tonic-gate if (*++p != '\\') 11027c478bd9Sstevel@tonic-gate map->map_coldelim = *p; 11037c478bd9Sstevel@tonic-gate else 11047c478bd9Sstevel@tonic-gate { 11057c478bd9Sstevel@tonic-gate switch (*++p) 11067c478bd9Sstevel@tonic-gate { 11077c478bd9Sstevel@tonic-gate case 'n': 11087c478bd9Sstevel@tonic-gate map->map_coldelim = '\n'; 11097c478bd9Sstevel@tonic-gate break; 11107c478bd9Sstevel@tonic-gate 11117c478bd9Sstevel@tonic-gate case 't': 11127c478bd9Sstevel@tonic-gate map->map_coldelim = '\t'; 11137c478bd9Sstevel@tonic-gate break; 11147c478bd9Sstevel@tonic-gate 11157c478bd9Sstevel@tonic-gate default: 11167c478bd9Sstevel@tonic-gate map->map_coldelim = '\\'; 11177c478bd9Sstevel@tonic-gate } 11187c478bd9Sstevel@tonic-gate } 11197c478bd9Sstevel@tonic-gate break; 11207c478bd9Sstevel@tonic-gate 11217c478bd9Sstevel@tonic-gate case 'Z': 11227c478bd9Sstevel@tonic-gate while (isascii(*++p) && isspace(*p)) 11237c478bd9Sstevel@tonic-gate continue; 11247c478bd9Sstevel@tonic-gate map->map_sizelimit = atoi(p); 11257c478bd9Sstevel@tonic-gate break; 11267c478bd9Sstevel@tonic-gate 11277c478bd9Sstevel@tonic-gate /* Start of dns_map specific args */ 11287c478bd9Sstevel@tonic-gate case 'R': /* search field */ 11297c478bd9Sstevel@tonic-gate { 11307c478bd9Sstevel@tonic-gate char *h; 11317c478bd9Sstevel@tonic-gate 11327c478bd9Sstevel@tonic-gate while (isascii(*++p) && isspace(*p)) 11337c478bd9Sstevel@tonic-gate continue; 11347c478bd9Sstevel@tonic-gate h = strchr(p, ' '); 11357c478bd9Sstevel@tonic-gate if (h != NULL) 11367c478bd9Sstevel@tonic-gate *h = '\0'; 11377c478bd9Sstevel@tonic-gate map_p->dns_m_type = dns_string_to_type(p); 11387c478bd9Sstevel@tonic-gate if (h != NULL) 11397c478bd9Sstevel@tonic-gate *h = ' '; 11407c478bd9Sstevel@tonic-gate if (map_p->dns_m_type < 0) 11417c478bd9Sstevel@tonic-gate syserr("dns map %s: wrong type %s", 11427c478bd9Sstevel@tonic-gate map->map_mname, p); 11437c478bd9Sstevel@tonic-gate } 11447c478bd9Sstevel@tonic-gate break; 11457c478bd9Sstevel@tonic-gate 11467c478bd9Sstevel@tonic-gate case 'B': /* base domain */ 11477c478bd9Sstevel@tonic-gate { 11487c478bd9Sstevel@tonic-gate char *h; 11497c478bd9Sstevel@tonic-gate 11507c478bd9Sstevel@tonic-gate while (isascii(*++p) && isspace(*p)) 11517c478bd9Sstevel@tonic-gate continue; 11527c478bd9Sstevel@tonic-gate h = strchr(p, ' '); 11537c478bd9Sstevel@tonic-gate if (h != NULL) 11547c478bd9Sstevel@tonic-gate *h = '\0'; 11557c478bd9Sstevel@tonic-gate 11567c478bd9Sstevel@tonic-gate /* 11577c478bd9Sstevel@tonic-gate ** slight abuse of map->map_file; it isn't 11587c478bd9Sstevel@tonic-gate ** used otherwise in this map type. 11597c478bd9Sstevel@tonic-gate */ 11607c478bd9Sstevel@tonic-gate 11617c478bd9Sstevel@tonic-gate map->map_file = newstr(p); 11627c478bd9Sstevel@tonic-gate if (h != NULL) 11637c478bd9Sstevel@tonic-gate *h = ' '; 11647c478bd9Sstevel@tonic-gate } 11657c478bd9Sstevel@tonic-gate break; 11667c478bd9Sstevel@tonic-gate } 11677c478bd9Sstevel@tonic-gate while (*p != '\0' && !(isascii(*p) && isspace(*p))) 11687c478bd9Sstevel@tonic-gate p++; 11697c478bd9Sstevel@tonic-gate if (*p != '\0') 11707c478bd9Sstevel@tonic-gate *p++ = '\0'; 11717c478bd9Sstevel@tonic-gate } 11727c478bd9Sstevel@tonic-gate if (map_p->dns_m_type < 0) 11737c478bd9Sstevel@tonic-gate syserr("dns map %s: missing -R type", map->map_mname); 11747c478bd9Sstevel@tonic-gate if (map->map_app != NULL) 11757c478bd9Sstevel@tonic-gate map->map_app = newstr(map->map_app); 11767c478bd9Sstevel@tonic-gate if (map->map_tapp != NULL) 11777c478bd9Sstevel@tonic-gate map->map_tapp = newstr(map->map_tapp); 11787c478bd9Sstevel@tonic-gate 11797c478bd9Sstevel@tonic-gate /* 1180058561cbSjbeck ** Assumption: assert(sizeof(int) <= sizeof(ARBPTR_T)); 11817c478bd9Sstevel@tonic-gate ** Even if this assumption is wrong, we use only one byte, 11827c478bd9Sstevel@tonic-gate ** so it doesn't really matter. 11837c478bd9Sstevel@tonic-gate */ 11847c478bd9Sstevel@tonic-gate 11857c478bd9Sstevel@tonic-gate map->map_db1 = (ARBPTR_T) map_p; 11867c478bd9Sstevel@tonic-gate return true; 11877c478bd9Sstevel@tonic-gate } 11887c478bd9Sstevel@tonic-gate 11897c478bd9Sstevel@tonic-gate /* 11907c478bd9Sstevel@tonic-gate ** DNS_MAP_LOOKUP -- perform dns map lookup. 11917c478bd9Sstevel@tonic-gate ** 11927c478bd9Sstevel@tonic-gate ** Parameters: 11937c478bd9Sstevel@tonic-gate ** map -- pointer to MAP 11947c478bd9Sstevel@tonic-gate ** name -- name to lookup 11957c478bd9Sstevel@tonic-gate ** av -- arguments to interpolate into buf. 11967c478bd9Sstevel@tonic-gate ** statp -- pointer to status (EX_) 11977c478bd9Sstevel@tonic-gate ** 11987c478bd9Sstevel@tonic-gate ** Returns: 11997c478bd9Sstevel@tonic-gate ** result of lookup if succeeded. 12007c478bd9Sstevel@tonic-gate ** NULL -- otherwise. 12017c478bd9Sstevel@tonic-gate */ 12027c478bd9Sstevel@tonic-gate 12037c478bd9Sstevel@tonic-gate char * 12047c478bd9Sstevel@tonic-gate dns_map_lookup(map, name, av, statp) 12057c478bd9Sstevel@tonic-gate MAP *map; 12067c478bd9Sstevel@tonic-gate char *name; 12077c478bd9Sstevel@tonic-gate char **av; 12087c478bd9Sstevel@tonic-gate int *statp; 12097c478bd9Sstevel@tonic-gate { 12107c478bd9Sstevel@tonic-gate int resnum = 0; 12117c478bd9Sstevel@tonic-gate char *vp = NULL, *result = NULL; 12127c478bd9Sstevel@tonic-gate size_t vsize; 12137c478bd9Sstevel@tonic-gate struct dns_map *map_p; 12147c478bd9Sstevel@tonic-gate RESOURCE_RECORD_T *rr = NULL; 12157c478bd9Sstevel@tonic-gate DNS_REPLY_T *r = NULL; 12167c478bd9Sstevel@tonic-gate # if NETINET6 12177c478bd9Sstevel@tonic-gate static char buf6[INET6_ADDRSTRLEN]; 12187c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 12197c478bd9Sstevel@tonic-gate 12207c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 12217c478bd9Sstevel@tonic-gate sm_dprintf("dns_map_lookup(%s, %s)\n", 12227c478bd9Sstevel@tonic-gate map->map_mname, name); 12237c478bd9Sstevel@tonic-gate 12247c478bd9Sstevel@tonic-gate map_p = (struct dns_map *)(map->map_db1); 12257c478bd9Sstevel@tonic-gate if (map->map_file != NULL && *map->map_file != '\0') 12267c478bd9Sstevel@tonic-gate { 12277c478bd9Sstevel@tonic-gate size_t len; 12287c478bd9Sstevel@tonic-gate char *appdomain; 12297c478bd9Sstevel@tonic-gate 12307c478bd9Sstevel@tonic-gate len = strlen(map->map_file) + strlen(name) + 2; 12317c478bd9Sstevel@tonic-gate appdomain = (char *) sm_malloc(len); 12327c478bd9Sstevel@tonic-gate if (appdomain == NULL) 12337c478bd9Sstevel@tonic-gate { 12347c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 12357c478bd9Sstevel@tonic-gate return NULL; 12367c478bd9Sstevel@tonic-gate } 12377c478bd9Sstevel@tonic-gate (void) sm_strlcpyn(appdomain, len, 3, name, ".", map->map_file); 12387c478bd9Sstevel@tonic-gate r = dns_lookup_int(appdomain, C_IN, map_p->dns_m_type, 12397c478bd9Sstevel@tonic-gate map->map_timeout, map->map_retry); 12407c478bd9Sstevel@tonic-gate sm_free(appdomain); 12417c478bd9Sstevel@tonic-gate } 12427c478bd9Sstevel@tonic-gate else 12437c478bd9Sstevel@tonic-gate { 12447c478bd9Sstevel@tonic-gate r = dns_lookup_int(name, C_IN, map_p->dns_m_type, 12457c478bd9Sstevel@tonic-gate map->map_timeout, map->map_retry); 12467c478bd9Sstevel@tonic-gate } 12477c478bd9Sstevel@tonic-gate 12487c478bd9Sstevel@tonic-gate if (r == NULL) 12497c478bd9Sstevel@tonic-gate { 12507c478bd9Sstevel@tonic-gate result = NULL; 12517c478bd9Sstevel@tonic-gate if (h_errno == TRY_AGAIN || transienterror(errno)) 12527c478bd9Sstevel@tonic-gate *statp = EX_TEMPFAIL; 12537c478bd9Sstevel@tonic-gate else 12547c478bd9Sstevel@tonic-gate *statp = EX_NOTFOUND; 12557c478bd9Sstevel@tonic-gate goto cleanup; 12567c478bd9Sstevel@tonic-gate } 12577c478bd9Sstevel@tonic-gate *statp = EX_OK; 12587c478bd9Sstevel@tonic-gate for (rr = r->dns_r_head; rr != NULL; rr = rr->rr_next) 12597c478bd9Sstevel@tonic-gate { 12607c478bd9Sstevel@tonic-gate char *type = NULL; 12617c478bd9Sstevel@tonic-gate char *value = NULL; 12627c478bd9Sstevel@tonic-gate 12637c478bd9Sstevel@tonic-gate switch (rr->rr_type) 12647c478bd9Sstevel@tonic-gate { 12657c478bd9Sstevel@tonic-gate case T_NS: 12667c478bd9Sstevel@tonic-gate type = "T_NS"; 12677c478bd9Sstevel@tonic-gate value = rr->rr_u.rr_txt; 12687c478bd9Sstevel@tonic-gate break; 12697c478bd9Sstevel@tonic-gate case T_CNAME: 12707c478bd9Sstevel@tonic-gate type = "T_CNAME"; 12717c478bd9Sstevel@tonic-gate value = rr->rr_u.rr_txt; 12727c478bd9Sstevel@tonic-gate break; 12737c478bd9Sstevel@tonic-gate case T_AFSDB: 12747c478bd9Sstevel@tonic-gate type = "T_AFSDB"; 12757c478bd9Sstevel@tonic-gate value = rr->rr_u.rr_mx->mx_r_domain; 12767c478bd9Sstevel@tonic-gate break; 12777c478bd9Sstevel@tonic-gate case T_SRV: 12787c478bd9Sstevel@tonic-gate type = "T_SRV"; 12797c478bd9Sstevel@tonic-gate value = rr->rr_u.rr_srv->srv_r_target; 12807c478bd9Sstevel@tonic-gate break; 12817c478bd9Sstevel@tonic-gate case T_PTR: 12827c478bd9Sstevel@tonic-gate type = "T_PTR"; 12837c478bd9Sstevel@tonic-gate value = rr->rr_u.rr_txt; 12847c478bd9Sstevel@tonic-gate break; 12857c478bd9Sstevel@tonic-gate case T_TXT: 12867c478bd9Sstevel@tonic-gate type = "T_TXT"; 12877c478bd9Sstevel@tonic-gate value = rr->rr_u.rr_txt; 12887c478bd9Sstevel@tonic-gate break; 12897c478bd9Sstevel@tonic-gate case T_MX: 12907c478bd9Sstevel@tonic-gate type = "T_MX"; 12917c478bd9Sstevel@tonic-gate value = rr->rr_u.rr_mx->mx_r_domain; 12927c478bd9Sstevel@tonic-gate break; 12937c478bd9Sstevel@tonic-gate # if NETINET 12947c478bd9Sstevel@tonic-gate case T_A: 12957c478bd9Sstevel@tonic-gate type = "T_A"; 12967c478bd9Sstevel@tonic-gate value = inet_ntoa(*(rr->rr_u.rr_a)); 12977c478bd9Sstevel@tonic-gate break; 12987c478bd9Sstevel@tonic-gate # endif /* NETINET */ 12997c478bd9Sstevel@tonic-gate # if NETINET6 13007c478bd9Sstevel@tonic-gate case T_AAAA: 13017c478bd9Sstevel@tonic-gate type = "T_AAAA"; 13027c478bd9Sstevel@tonic-gate value = anynet_ntop(rr->rr_u.rr_aaaa, buf6, 1303058561cbSjbeck sizeof(buf6)); 13047c478bd9Sstevel@tonic-gate break; 13057c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 13067c478bd9Sstevel@tonic-gate } 13077c478bd9Sstevel@tonic-gate 13087c478bd9Sstevel@tonic-gate (void) strreplnonprt(value, 'X'); 13097c478bd9Sstevel@tonic-gate if (map_p->dns_m_type != rr->rr_type) 13107c478bd9Sstevel@tonic-gate { 13117c478bd9Sstevel@tonic-gate if (tTd(38, 40)) 13127c478bd9Sstevel@tonic-gate sm_dprintf("\tskipping type %s (%d) value %s\n", 13137c478bd9Sstevel@tonic-gate type != NULL ? type : "<UNKNOWN>", 13147c478bd9Sstevel@tonic-gate rr->rr_type, 13157c478bd9Sstevel@tonic-gate value != NULL ? value : "<NO VALUE>"); 13167c478bd9Sstevel@tonic-gate continue; 13177c478bd9Sstevel@tonic-gate } 13187c478bd9Sstevel@tonic-gate 13197c478bd9Sstevel@tonic-gate # if NETINET6 13207c478bd9Sstevel@tonic-gate if (rr->rr_type == T_AAAA && value == NULL) 13217c478bd9Sstevel@tonic-gate { 13227c478bd9Sstevel@tonic-gate result = NULL; 13237c478bd9Sstevel@tonic-gate *statp = EX_DATAERR; 13247c478bd9Sstevel@tonic-gate if (tTd(38, 40)) 13257c478bd9Sstevel@tonic-gate sm_dprintf("\tbad T_AAAA conversion\n"); 13267c478bd9Sstevel@tonic-gate goto cleanup; 13277c478bd9Sstevel@tonic-gate } 13287c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 13297c478bd9Sstevel@tonic-gate if (tTd(38, 40)) 13307c478bd9Sstevel@tonic-gate sm_dprintf("\tfound type %s (%d) value %s\n", 13317c478bd9Sstevel@tonic-gate type != NULL ? type : "<UNKNOWN>", 13327c478bd9Sstevel@tonic-gate rr->rr_type, 13337c478bd9Sstevel@tonic-gate value != NULL ? value : "<NO VALUE>"); 13347c478bd9Sstevel@tonic-gate if (value != NULL && 13357c478bd9Sstevel@tonic-gate (map->map_coldelim == '\0' || 13367c478bd9Sstevel@tonic-gate map->map_sizelimit == 1 || 13377c478bd9Sstevel@tonic-gate bitset(MF_MATCHONLY, map->map_mflags))) 13387c478bd9Sstevel@tonic-gate { 13397c478bd9Sstevel@tonic-gate /* Only care about the first match */ 13407c478bd9Sstevel@tonic-gate vp = newstr(value); 13417c478bd9Sstevel@tonic-gate break; 13427c478bd9Sstevel@tonic-gate } 13437c478bd9Sstevel@tonic-gate else if (vp == NULL) 13447c478bd9Sstevel@tonic-gate { 13457c478bd9Sstevel@tonic-gate /* First result */ 13467c478bd9Sstevel@tonic-gate vp = newstr(value); 13477c478bd9Sstevel@tonic-gate } 13487c478bd9Sstevel@tonic-gate else 13497c478bd9Sstevel@tonic-gate { 13507c478bd9Sstevel@tonic-gate /* concatenate the results */ 13517c478bd9Sstevel@tonic-gate int sz; 13527c478bd9Sstevel@tonic-gate char *new; 13537c478bd9Sstevel@tonic-gate 13547c478bd9Sstevel@tonic-gate sz = strlen(vp) + strlen(value) + 2; 13557c478bd9Sstevel@tonic-gate new = xalloc(sz); 13567c478bd9Sstevel@tonic-gate (void) sm_snprintf(new, sz, "%s%c%s", 13577c478bd9Sstevel@tonic-gate vp, map->map_coldelim, value); 13587c478bd9Sstevel@tonic-gate sm_free(vp); 13597c478bd9Sstevel@tonic-gate vp = new; 13607c478bd9Sstevel@tonic-gate if (map->map_sizelimit > 0 && 13617c478bd9Sstevel@tonic-gate ++resnum >= map->map_sizelimit) 13627c478bd9Sstevel@tonic-gate break; 13637c478bd9Sstevel@tonic-gate } 13647c478bd9Sstevel@tonic-gate } 13657c478bd9Sstevel@tonic-gate if (vp == NULL) 13667c478bd9Sstevel@tonic-gate { 13677c478bd9Sstevel@tonic-gate result = NULL; 13687c478bd9Sstevel@tonic-gate *statp = EX_NOTFOUND; 13697c478bd9Sstevel@tonic-gate if (tTd(38, 40)) 13707c478bd9Sstevel@tonic-gate sm_dprintf("\tno match found\n"); 13717c478bd9Sstevel@tonic-gate goto cleanup; 13727c478bd9Sstevel@tonic-gate } 13737c478bd9Sstevel@tonic-gate 13747c478bd9Sstevel@tonic-gate /* Cleanly truncate for rulesets */ 13757c478bd9Sstevel@tonic-gate truncate_at_delim(vp, PSBUFSIZE / 2, map->map_coldelim); 13767c478bd9Sstevel@tonic-gate 13777c478bd9Sstevel@tonic-gate vsize = strlen(vp); 13787c478bd9Sstevel@tonic-gate 13797c478bd9Sstevel@tonic-gate if (LogLevel > 9) 13807c478bd9Sstevel@tonic-gate sm_syslog(LOG_INFO, CurEnv->e_id, "dns %.100s => %s", 13817c478bd9Sstevel@tonic-gate name, vp); 13827c478bd9Sstevel@tonic-gate if (bitset(MF_MATCHONLY, map->map_mflags)) 13837c478bd9Sstevel@tonic-gate result = map_rewrite(map, name, strlen(name), NULL); 13847c478bd9Sstevel@tonic-gate else 13857c478bd9Sstevel@tonic-gate result = map_rewrite(map, vp, vsize, av); 13867c478bd9Sstevel@tonic-gate 13877c478bd9Sstevel@tonic-gate cleanup: 13887c478bd9Sstevel@tonic-gate if (vp != NULL) 13897c478bd9Sstevel@tonic-gate sm_free(vp); 13907c478bd9Sstevel@tonic-gate if (r != NULL) 13917c478bd9Sstevel@tonic-gate dns_free_data(r); 13927c478bd9Sstevel@tonic-gate return result; 13937c478bd9Sstevel@tonic-gate } 13947c478bd9Sstevel@tonic-gate # endif /* DNSMAP */ 13957c478bd9Sstevel@tonic-gate #endif /* NAMED_BIND */ 13967c478bd9Sstevel@tonic-gate 13977c478bd9Sstevel@tonic-gate /* 13987c478bd9Sstevel@tonic-gate ** NDBM modules 13997c478bd9Sstevel@tonic-gate */ 14007c478bd9Sstevel@tonic-gate 14017c478bd9Sstevel@tonic-gate #if NDBM 14027c478bd9Sstevel@tonic-gate 14037c478bd9Sstevel@tonic-gate /* 14047c478bd9Sstevel@tonic-gate ** NDBM_MAP_OPEN -- DBM-style map open 14057c478bd9Sstevel@tonic-gate */ 14067c478bd9Sstevel@tonic-gate 14077c478bd9Sstevel@tonic-gate bool 14087c478bd9Sstevel@tonic-gate ndbm_map_open(map, mode) 14097c478bd9Sstevel@tonic-gate MAP *map; 14107c478bd9Sstevel@tonic-gate int mode; 14117c478bd9Sstevel@tonic-gate { 14127c478bd9Sstevel@tonic-gate register DBM *dbm; 14137c478bd9Sstevel@tonic-gate int save_errno; 14147c478bd9Sstevel@tonic-gate int dfd; 14157c478bd9Sstevel@tonic-gate int pfd; 14167c478bd9Sstevel@tonic-gate long sff; 14177c478bd9Sstevel@tonic-gate int ret; 14187c478bd9Sstevel@tonic-gate int smode = S_IREAD; 14197c478bd9Sstevel@tonic-gate char dirfile[MAXPATHLEN]; 14207c478bd9Sstevel@tonic-gate char pagfile[MAXPATHLEN]; 14217c478bd9Sstevel@tonic-gate struct stat st; 14227c478bd9Sstevel@tonic-gate struct stat std, stp; 14237c478bd9Sstevel@tonic-gate 14247c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 14257c478bd9Sstevel@tonic-gate sm_dprintf("ndbm_map_open(%s, %s, %d)\n", 14267c478bd9Sstevel@tonic-gate map->map_mname, map->map_file, mode); 14277c478bd9Sstevel@tonic-gate map->map_lockfd = -1; 14287c478bd9Sstevel@tonic-gate mode &= O_ACCMODE; 14297c478bd9Sstevel@tonic-gate 14307c478bd9Sstevel@tonic-gate /* do initial file and directory checks */ 1431058561cbSjbeck if (sm_strlcpyn(dirfile, sizeof(dirfile), 2, 1432058561cbSjbeck map->map_file, ".dir") >= sizeof(dirfile) || 1433058561cbSjbeck sm_strlcpyn(pagfile, sizeof(pagfile), 2, 1434058561cbSjbeck map->map_file, ".pag") >= sizeof(pagfile)) 14357c478bd9Sstevel@tonic-gate { 14367c478bd9Sstevel@tonic-gate errno = 0; 14377c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 14387c478bd9Sstevel@tonic-gate syserr("dbm map \"%s\": map file %s name too long", 14397c478bd9Sstevel@tonic-gate map->map_mname, map->map_file); 14407c478bd9Sstevel@tonic-gate return false; 14417c478bd9Sstevel@tonic-gate } 14427c478bd9Sstevel@tonic-gate sff = SFF_ROOTOK|SFF_REGONLY; 14437c478bd9Sstevel@tonic-gate if (mode == O_RDWR) 14447c478bd9Sstevel@tonic-gate { 14457c478bd9Sstevel@tonic-gate sff |= SFF_CREAT; 14467c478bd9Sstevel@tonic-gate if (!bitnset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail)) 14477c478bd9Sstevel@tonic-gate sff |= SFF_NOSLINK; 14487c478bd9Sstevel@tonic-gate if (!bitnset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail)) 14497c478bd9Sstevel@tonic-gate sff |= SFF_NOHLINK; 14507c478bd9Sstevel@tonic-gate smode = S_IWRITE; 14517c478bd9Sstevel@tonic-gate } 14527c478bd9Sstevel@tonic-gate else 14537c478bd9Sstevel@tonic-gate { 14547c478bd9Sstevel@tonic-gate if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail)) 14557c478bd9Sstevel@tonic-gate sff |= SFF_NOWLINK; 14567c478bd9Sstevel@tonic-gate } 14577c478bd9Sstevel@tonic-gate if (!bitnset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail)) 14587c478bd9Sstevel@tonic-gate sff |= SFF_SAFEDIRPATH; 14597c478bd9Sstevel@tonic-gate ret = safefile(dirfile, RunAsUid, RunAsGid, RunAsUserName, 14607c478bd9Sstevel@tonic-gate sff, smode, &std); 14617c478bd9Sstevel@tonic-gate if (ret == 0) 14627c478bd9Sstevel@tonic-gate ret = safefile(pagfile, RunAsUid, RunAsGid, RunAsUserName, 14637c478bd9Sstevel@tonic-gate sff, smode, &stp); 14647c478bd9Sstevel@tonic-gate 14657c478bd9Sstevel@tonic-gate if (ret != 0) 14667c478bd9Sstevel@tonic-gate { 14677c478bd9Sstevel@tonic-gate char *prob = "unsafe"; 14687c478bd9Sstevel@tonic-gate 14697c478bd9Sstevel@tonic-gate /* cannot open this map */ 14707c478bd9Sstevel@tonic-gate if (ret == ENOENT) 14717c478bd9Sstevel@tonic-gate prob = "missing"; 14727c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 14737c478bd9Sstevel@tonic-gate sm_dprintf("\t%s map file: %d\n", prob, ret); 14747c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 14757c478bd9Sstevel@tonic-gate syserr("dbm map \"%s\": %s map file %s", 14767c478bd9Sstevel@tonic-gate map->map_mname, prob, map->map_file); 14777c478bd9Sstevel@tonic-gate return false; 14787c478bd9Sstevel@tonic-gate } 14797c478bd9Sstevel@tonic-gate if (std.st_mode == ST_MODE_NOFILE) 14807c478bd9Sstevel@tonic-gate mode |= O_CREAT|O_EXCL; 14817c478bd9Sstevel@tonic-gate 14827c478bd9Sstevel@tonic-gate # if LOCK_ON_OPEN 14837c478bd9Sstevel@tonic-gate if (mode == O_RDONLY) 14847c478bd9Sstevel@tonic-gate mode |= O_SHLOCK; 14857c478bd9Sstevel@tonic-gate else 14867c478bd9Sstevel@tonic-gate mode |= O_TRUNC|O_EXLOCK; 14877c478bd9Sstevel@tonic-gate # else /* LOCK_ON_OPEN */ 14887c478bd9Sstevel@tonic-gate if ((mode & O_ACCMODE) == O_RDWR) 14897c478bd9Sstevel@tonic-gate { 14907c478bd9Sstevel@tonic-gate # if NOFTRUNCATE 14917c478bd9Sstevel@tonic-gate /* 14927c478bd9Sstevel@tonic-gate ** Warning: race condition. Try to lock the file as 14937c478bd9Sstevel@tonic-gate ** quickly as possible after opening it. 14947c478bd9Sstevel@tonic-gate ** This may also have security problems on some systems, 14957c478bd9Sstevel@tonic-gate ** but there isn't anything we can do about it. 14967c478bd9Sstevel@tonic-gate */ 14977c478bd9Sstevel@tonic-gate 14987c478bd9Sstevel@tonic-gate mode |= O_TRUNC; 14997c478bd9Sstevel@tonic-gate # else /* NOFTRUNCATE */ 15007c478bd9Sstevel@tonic-gate /* 15017c478bd9Sstevel@tonic-gate ** This ugly code opens the map without truncating it, 15027c478bd9Sstevel@tonic-gate ** locks the file, then truncates it. Necessary to 15037c478bd9Sstevel@tonic-gate ** avoid race conditions. 15047c478bd9Sstevel@tonic-gate */ 15057c478bd9Sstevel@tonic-gate 15067c478bd9Sstevel@tonic-gate int dirfd; 15077c478bd9Sstevel@tonic-gate int pagfd; 15087c478bd9Sstevel@tonic-gate long sff = SFF_CREAT|SFF_OPENASROOT; 15097c478bd9Sstevel@tonic-gate 15107c478bd9Sstevel@tonic-gate if (!bitnset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail)) 15117c478bd9Sstevel@tonic-gate sff |= SFF_NOSLINK; 15127c478bd9Sstevel@tonic-gate if (!bitnset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail)) 15137c478bd9Sstevel@tonic-gate sff |= SFF_NOHLINK; 15147c478bd9Sstevel@tonic-gate 15157c478bd9Sstevel@tonic-gate dirfd = safeopen(dirfile, mode, DBMMODE, sff); 15167c478bd9Sstevel@tonic-gate pagfd = safeopen(pagfile, mode, DBMMODE, sff); 15177c478bd9Sstevel@tonic-gate 15187c478bd9Sstevel@tonic-gate if (dirfd < 0 || pagfd < 0) 15197c478bd9Sstevel@tonic-gate { 15207c478bd9Sstevel@tonic-gate save_errno = errno; 15217c478bd9Sstevel@tonic-gate if (dirfd >= 0) 15227c478bd9Sstevel@tonic-gate (void) close(dirfd); 15237c478bd9Sstevel@tonic-gate if (pagfd >= 0) 15247c478bd9Sstevel@tonic-gate (void) close(pagfd); 15257c478bd9Sstevel@tonic-gate errno = save_errno; 15267c478bd9Sstevel@tonic-gate syserr("ndbm_map_open: cannot create database %s", 15277c478bd9Sstevel@tonic-gate map->map_file); 15287c478bd9Sstevel@tonic-gate return false; 15297c478bd9Sstevel@tonic-gate } 15307c478bd9Sstevel@tonic-gate if (ftruncate(dirfd, (off_t) 0) < 0 || 15317c478bd9Sstevel@tonic-gate ftruncate(pagfd, (off_t) 0) < 0) 15327c478bd9Sstevel@tonic-gate { 15337c478bd9Sstevel@tonic-gate save_errno = errno; 15347c478bd9Sstevel@tonic-gate (void) close(dirfd); 15357c478bd9Sstevel@tonic-gate (void) close(pagfd); 15367c478bd9Sstevel@tonic-gate errno = save_errno; 15377c478bd9Sstevel@tonic-gate syserr("ndbm_map_open: cannot truncate %s.{dir,pag}", 15387c478bd9Sstevel@tonic-gate map->map_file); 15397c478bd9Sstevel@tonic-gate return false; 15407c478bd9Sstevel@tonic-gate } 15417c478bd9Sstevel@tonic-gate 15427c478bd9Sstevel@tonic-gate /* if new file, get "before" bits for later filechanged check */ 15437c478bd9Sstevel@tonic-gate if (std.st_mode == ST_MODE_NOFILE && 15447c478bd9Sstevel@tonic-gate (fstat(dirfd, &std) < 0 || fstat(pagfd, &stp) < 0)) 15457c478bd9Sstevel@tonic-gate { 15467c478bd9Sstevel@tonic-gate save_errno = errno; 15477c478bd9Sstevel@tonic-gate (void) close(dirfd); 15487c478bd9Sstevel@tonic-gate (void) close(pagfd); 15497c478bd9Sstevel@tonic-gate errno = save_errno; 15507c478bd9Sstevel@tonic-gate syserr("ndbm_map_open(%s.{dir,pag}): cannot fstat pre-opened file", 15517c478bd9Sstevel@tonic-gate map->map_file); 15527c478bd9Sstevel@tonic-gate return false; 15537c478bd9Sstevel@tonic-gate } 15547c478bd9Sstevel@tonic-gate 15557c478bd9Sstevel@tonic-gate /* have to save the lock for the duration (bletch) */ 15567c478bd9Sstevel@tonic-gate map->map_lockfd = dirfd; 15577c478bd9Sstevel@tonic-gate (void) close(pagfd); 15587c478bd9Sstevel@tonic-gate 15597c478bd9Sstevel@tonic-gate /* twiddle bits for dbm_open */ 15607c478bd9Sstevel@tonic-gate mode &= ~(O_CREAT|O_EXCL); 15617c478bd9Sstevel@tonic-gate # endif /* NOFTRUNCATE */ 15627c478bd9Sstevel@tonic-gate } 15637c478bd9Sstevel@tonic-gate # endif /* LOCK_ON_OPEN */ 15647c478bd9Sstevel@tonic-gate 15657c478bd9Sstevel@tonic-gate /* open the database */ 15667c478bd9Sstevel@tonic-gate dbm = dbm_open(map->map_file, mode, DBMMODE); 15677c478bd9Sstevel@tonic-gate if (dbm == NULL) 15687c478bd9Sstevel@tonic-gate { 15697c478bd9Sstevel@tonic-gate save_errno = errno; 15707c478bd9Sstevel@tonic-gate if (bitset(MF_ALIAS, map->map_mflags) && 15717c478bd9Sstevel@tonic-gate aliaswait(map, ".pag", false)) 15727c478bd9Sstevel@tonic-gate return true; 15737c478bd9Sstevel@tonic-gate # if !LOCK_ON_OPEN && !NOFTRUNCATE 15747c478bd9Sstevel@tonic-gate if (map->map_lockfd >= 0) 15757c478bd9Sstevel@tonic-gate (void) close(map->map_lockfd); 15767c478bd9Sstevel@tonic-gate # endif /* !LOCK_ON_OPEN && !NOFTRUNCATE */ 15777c478bd9Sstevel@tonic-gate errno = save_errno; 15787c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 15797c478bd9Sstevel@tonic-gate syserr("Cannot open DBM database %s", map->map_file); 15807c478bd9Sstevel@tonic-gate return false; 15817c478bd9Sstevel@tonic-gate } 15827c478bd9Sstevel@tonic-gate dfd = dbm_dirfno(dbm); 15837c478bd9Sstevel@tonic-gate pfd = dbm_pagfno(dbm); 15847c478bd9Sstevel@tonic-gate if (dfd == pfd) 15857c478bd9Sstevel@tonic-gate { 15867c478bd9Sstevel@tonic-gate /* heuristic: if files are linked, this is actually gdbm */ 15877c478bd9Sstevel@tonic-gate dbm_close(dbm); 15887c478bd9Sstevel@tonic-gate # if !LOCK_ON_OPEN && !NOFTRUNCATE 15897c478bd9Sstevel@tonic-gate if (map->map_lockfd >= 0) 15907c478bd9Sstevel@tonic-gate (void) close(map->map_lockfd); 15917c478bd9Sstevel@tonic-gate # endif /* !LOCK_ON_OPEN && !NOFTRUNCATE */ 15927c478bd9Sstevel@tonic-gate errno = 0; 15937c478bd9Sstevel@tonic-gate syserr("dbm map \"%s\": cannot support GDBM", 15947c478bd9Sstevel@tonic-gate map->map_mname); 15957c478bd9Sstevel@tonic-gate return false; 15967c478bd9Sstevel@tonic-gate } 15977c478bd9Sstevel@tonic-gate 15987c478bd9Sstevel@tonic-gate if (filechanged(dirfile, dfd, &std) || 15997c478bd9Sstevel@tonic-gate filechanged(pagfile, pfd, &stp)) 16007c478bd9Sstevel@tonic-gate { 16017c478bd9Sstevel@tonic-gate save_errno = errno; 16027c478bd9Sstevel@tonic-gate dbm_close(dbm); 16037c478bd9Sstevel@tonic-gate # if !LOCK_ON_OPEN && !NOFTRUNCATE 16047c478bd9Sstevel@tonic-gate if (map->map_lockfd >= 0) 16057c478bd9Sstevel@tonic-gate (void) close(map->map_lockfd); 16067c478bd9Sstevel@tonic-gate # endif /* !LOCK_ON_OPEN && !NOFTRUNCATE */ 16077c478bd9Sstevel@tonic-gate errno = save_errno; 16087c478bd9Sstevel@tonic-gate syserr("ndbm_map_open(%s): file changed after open", 16097c478bd9Sstevel@tonic-gate map->map_file); 16107c478bd9Sstevel@tonic-gate return false; 16117c478bd9Sstevel@tonic-gate } 16127c478bd9Sstevel@tonic-gate 16137c478bd9Sstevel@tonic-gate map->map_db1 = (ARBPTR_T) dbm; 16147c478bd9Sstevel@tonic-gate 16157c478bd9Sstevel@tonic-gate /* 16167c478bd9Sstevel@tonic-gate ** Need to set map_mtime before the call to aliaswait() 16177c478bd9Sstevel@tonic-gate ** as aliaswait() will call map_lookup() which requires 16187c478bd9Sstevel@tonic-gate ** map_mtime to be set 16197c478bd9Sstevel@tonic-gate */ 16207c478bd9Sstevel@tonic-gate 16217c478bd9Sstevel@tonic-gate if (fstat(pfd, &st) >= 0) 16227c478bd9Sstevel@tonic-gate map->map_mtime = st.st_mtime; 16237c478bd9Sstevel@tonic-gate 16247c478bd9Sstevel@tonic-gate if (mode == O_RDONLY) 16257c478bd9Sstevel@tonic-gate { 16267c478bd9Sstevel@tonic-gate # if LOCK_ON_OPEN 16277c478bd9Sstevel@tonic-gate if (dfd >= 0) 16287c478bd9Sstevel@tonic-gate (void) lockfile(dfd, map->map_file, ".dir", LOCK_UN); 16297c478bd9Sstevel@tonic-gate if (pfd >= 0) 16307c478bd9Sstevel@tonic-gate (void) lockfile(pfd, map->map_file, ".pag", LOCK_UN); 16317c478bd9Sstevel@tonic-gate # endif /* LOCK_ON_OPEN */ 16327c478bd9Sstevel@tonic-gate if (bitset(MF_ALIAS, map->map_mflags) && 16337c478bd9Sstevel@tonic-gate !aliaswait(map, ".pag", true)) 16347c478bd9Sstevel@tonic-gate return false; 16357c478bd9Sstevel@tonic-gate } 16367c478bd9Sstevel@tonic-gate else 16377c478bd9Sstevel@tonic-gate { 16387c478bd9Sstevel@tonic-gate map->map_mflags |= MF_LOCKED; 16397c478bd9Sstevel@tonic-gate if (geteuid() == 0 && TrustedUid != 0) 16407c478bd9Sstevel@tonic-gate { 16417c478bd9Sstevel@tonic-gate # if HASFCHOWN 16427c478bd9Sstevel@tonic-gate if (fchown(dfd, TrustedUid, -1) < 0 || 16437c478bd9Sstevel@tonic-gate fchown(pfd, TrustedUid, -1) < 0) 16447c478bd9Sstevel@tonic-gate { 16457c478bd9Sstevel@tonic-gate int err = errno; 16467c478bd9Sstevel@tonic-gate 16477c478bd9Sstevel@tonic-gate sm_syslog(LOG_ALERT, NOQID, 16487c478bd9Sstevel@tonic-gate "ownership change on %s failed: %s", 16497c478bd9Sstevel@tonic-gate map->map_file, sm_errstring(err)); 16507c478bd9Sstevel@tonic-gate message("050 ownership change on %s failed: %s", 16517c478bd9Sstevel@tonic-gate map->map_file, sm_errstring(err)); 16527c478bd9Sstevel@tonic-gate } 16537c478bd9Sstevel@tonic-gate # else /* HASFCHOWN */ 16547c478bd9Sstevel@tonic-gate sm_syslog(LOG_ALERT, NOQID, 16557c478bd9Sstevel@tonic-gate "no fchown(): cannot change ownership on %s", 16567c478bd9Sstevel@tonic-gate map->map_file); 16577c478bd9Sstevel@tonic-gate message("050 no fchown(): cannot change ownership on %s", 16587c478bd9Sstevel@tonic-gate map->map_file); 16597c478bd9Sstevel@tonic-gate # endif /* HASFCHOWN */ 16607c478bd9Sstevel@tonic-gate } 16617c478bd9Sstevel@tonic-gate } 16627c478bd9Sstevel@tonic-gate return true; 16637c478bd9Sstevel@tonic-gate } 16647c478bd9Sstevel@tonic-gate 16657c478bd9Sstevel@tonic-gate 16667c478bd9Sstevel@tonic-gate /* 16677c478bd9Sstevel@tonic-gate ** NDBM_MAP_LOOKUP -- look up a datum in a DBM-type map 16687c478bd9Sstevel@tonic-gate */ 16697c478bd9Sstevel@tonic-gate 16707c478bd9Sstevel@tonic-gate char * 16717c478bd9Sstevel@tonic-gate ndbm_map_lookup(map, name, av, statp) 16727c478bd9Sstevel@tonic-gate MAP *map; 16737c478bd9Sstevel@tonic-gate char *name; 16747c478bd9Sstevel@tonic-gate char **av; 16757c478bd9Sstevel@tonic-gate int *statp; 16767c478bd9Sstevel@tonic-gate { 16777c478bd9Sstevel@tonic-gate datum key, val; 16787c478bd9Sstevel@tonic-gate int dfd, pfd; 16797c478bd9Sstevel@tonic-gate char keybuf[MAXNAME + 1]; 16807c478bd9Sstevel@tonic-gate struct stat stbuf; 16817c478bd9Sstevel@tonic-gate 16827c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 16837c478bd9Sstevel@tonic-gate sm_dprintf("ndbm_map_lookup(%s, %s)\n", 16847c478bd9Sstevel@tonic-gate map->map_mname, name); 16857c478bd9Sstevel@tonic-gate 16867c478bd9Sstevel@tonic-gate key.dptr = name; 16877c478bd9Sstevel@tonic-gate key.dsize = strlen(name); 16887c478bd9Sstevel@tonic-gate if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 16897c478bd9Sstevel@tonic-gate { 1690058561cbSjbeck if (key.dsize > sizeof(keybuf) - 1) 1691058561cbSjbeck key.dsize = sizeof(keybuf) - 1; 16927c478bd9Sstevel@tonic-gate memmove(keybuf, key.dptr, key.dsize); 16937c478bd9Sstevel@tonic-gate keybuf[key.dsize] = '\0'; 16947c478bd9Sstevel@tonic-gate makelower(keybuf); 16957c478bd9Sstevel@tonic-gate key.dptr = keybuf; 16967c478bd9Sstevel@tonic-gate } 16977c478bd9Sstevel@tonic-gate lockdbm: 16987c478bd9Sstevel@tonic-gate dfd = dbm_dirfno((DBM *) map->map_db1); 16997c478bd9Sstevel@tonic-gate if (dfd >= 0 && !bitset(MF_LOCKED, map->map_mflags)) 17007c478bd9Sstevel@tonic-gate (void) lockfile(dfd, map->map_file, ".dir", LOCK_SH); 17017c478bd9Sstevel@tonic-gate pfd = dbm_pagfno((DBM *) map->map_db1); 17027c478bd9Sstevel@tonic-gate if (pfd < 0 || fstat(pfd, &stbuf) < 0 || 17037c478bd9Sstevel@tonic-gate stbuf.st_mtime > map->map_mtime) 17047c478bd9Sstevel@tonic-gate { 17057c478bd9Sstevel@tonic-gate /* Reopen the database to sync the cache */ 17067c478bd9Sstevel@tonic-gate int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR 17077c478bd9Sstevel@tonic-gate : O_RDONLY; 17087c478bd9Sstevel@tonic-gate 17097c478bd9Sstevel@tonic-gate if (dfd >= 0 && !bitset(MF_LOCKED, map->map_mflags)) 17107c478bd9Sstevel@tonic-gate (void) lockfile(dfd, map->map_file, ".dir", LOCK_UN); 17117c478bd9Sstevel@tonic-gate map->map_mflags |= MF_CLOSING; 17127c478bd9Sstevel@tonic-gate map->map_class->map_close(map); 17137c478bd9Sstevel@tonic-gate map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING); 17147c478bd9Sstevel@tonic-gate if (map->map_class->map_open(map, omode)) 17157c478bd9Sstevel@tonic-gate { 17167c478bd9Sstevel@tonic-gate map->map_mflags |= MF_OPEN; 17177c478bd9Sstevel@tonic-gate map->map_pid = CurrentPid; 1718*e9af4bc0SJohn Beck if ((omode & O_ACCMODE) == O_RDWR) 17197c478bd9Sstevel@tonic-gate map->map_mflags |= MF_WRITABLE; 17207c478bd9Sstevel@tonic-gate goto lockdbm; 17217c478bd9Sstevel@tonic-gate } 17227c478bd9Sstevel@tonic-gate else 17237c478bd9Sstevel@tonic-gate { 17247c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 17257c478bd9Sstevel@tonic-gate { 17267c478bd9Sstevel@tonic-gate extern MAPCLASS BogusMapClass; 17277c478bd9Sstevel@tonic-gate 17287c478bd9Sstevel@tonic-gate *statp = EX_TEMPFAIL; 17297c478bd9Sstevel@tonic-gate map->map_orgclass = map->map_class; 17307c478bd9Sstevel@tonic-gate map->map_class = &BogusMapClass; 17317c478bd9Sstevel@tonic-gate map->map_mflags |= MF_OPEN; 17327c478bd9Sstevel@tonic-gate map->map_pid = CurrentPid; 17337c478bd9Sstevel@tonic-gate syserr("Cannot reopen NDBM database %s", 17347c478bd9Sstevel@tonic-gate map->map_file); 17357c478bd9Sstevel@tonic-gate } 17367c478bd9Sstevel@tonic-gate return NULL; 17377c478bd9Sstevel@tonic-gate } 17387c478bd9Sstevel@tonic-gate } 17397c478bd9Sstevel@tonic-gate val.dptr = NULL; 17407c478bd9Sstevel@tonic-gate if (bitset(MF_TRY0NULL, map->map_mflags)) 17417c478bd9Sstevel@tonic-gate { 17427c478bd9Sstevel@tonic-gate val = dbm_fetch((DBM *) map->map_db1, key); 17437c478bd9Sstevel@tonic-gate if (val.dptr != NULL) 17447c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_TRY1NULL; 17457c478bd9Sstevel@tonic-gate } 17467c478bd9Sstevel@tonic-gate if (val.dptr == NULL && bitset(MF_TRY1NULL, map->map_mflags)) 17477c478bd9Sstevel@tonic-gate { 17487c478bd9Sstevel@tonic-gate key.dsize++; 17497c478bd9Sstevel@tonic-gate val = dbm_fetch((DBM *) map->map_db1, key); 17507c478bd9Sstevel@tonic-gate if (val.dptr != NULL) 17517c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_TRY0NULL; 17527c478bd9Sstevel@tonic-gate } 17537c478bd9Sstevel@tonic-gate if (dfd >= 0 && !bitset(MF_LOCKED, map->map_mflags)) 17547c478bd9Sstevel@tonic-gate (void) lockfile(dfd, map->map_file, ".dir", LOCK_UN); 17557c478bd9Sstevel@tonic-gate if (val.dptr == NULL) 17567c478bd9Sstevel@tonic-gate return NULL; 17577c478bd9Sstevel@tonic-gate if (bitset(MF_MATCHONLY, map->map_mflags)) 17587c478bd9Sstevel@tonic-gate return map_rewrite(map, name, strlen(name), NULL); 17597c478bd9Sstevel@tonic-gate else 17607c478bd9Sstevel@tonic-gate return map_rewrite(map, val.dptr, val.dsize, av); 17617c478bd9Sstevel@tonic-gate } 17627c478bd9Sstevel@tonic-gate 17637c478bd9Sstevel@tonic-gate 17647c478bd9Sstevel@tonic-gate /* 17657c478bd9Sstevel@tonic-gate ** NDBM_MAP_STORE -- store a datum in the database 17667c478bd9Sstevel@tonic-gate */ 17677c478bd9Sstevel@tonic-gate 17687c478bd9Sstevel@tonic-gate void 17697c478bd9Sstevel@tonic-gate ndbm_map_store(map, lhs, rhs) 17707c478bd9Sstevel@tonic-gate register MAP *map; 17717c478bd9Sstevel@tonic-gate char *lhs; 17727c478bd9Sstevel@tonic-gate char *rhs; 17737c478bd9Sstevel@tonic-gate { 17747c478bd9Sstevel@tonic-gate datum key; 17757c478bd9Sstevel@tonic-gate datum data; 17767c478bd9Sstevel@tonic-gate int status; 17777c478bd9Sstevel@tonic-gate char keybuf[MAXNAME + 1]; 17787c478bd9Sstevel@tonic-gate 17797c478bd9Sstevel@tonic-gate if (tTd(38, 12)) 17807c478bd9Sstevel@tonic-gate sm_dprintf("ndbm_map_store(%s, %s, %s)\n", 17817c478bd9Sstevel@tonic-gate map->map_mname, lhs, rhs); 17827c478bd9Sstevel@tonic-gate 17837c478bd9Sstevel@tonic-gate key.dsize = strlen(lhs); 17847c478bd9Sstevel@tonic-gate key.dptr = lhs; 17857c478bd9Sstevel@tonic-gate if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 17867c478bd9Sstevel@tonic-gate { 1787058561cbSjbeck if (key.dsize > sizeof(keybuf) - 1) 1788058561cbSjbeck key.dsize = sizeof(keybuf) - 1; 17897c478bd9Sstevel@tonic-gate memmove(keybuf, key.dptr, key.dsize); 17907c478bd9Sstevel@tonic-gate keybuf[key.dsize] = '\0'; 17917c478bd9Sstevel@tonic-gate makelower(keybuf); 17927c478bd9Sstevel@tonic-gate key.dptr = keybuf; 17937c478bd9Sstevel@tonic-gate } 17947c478bd9Sstevel@tonic-gate 17957c478bd9Sstevel@tonic-gate data.dsize = strlen(rhs); 17967c478bd9Sstevel@tonic-gate data.dptr = rhs; 17977c478bd9Sstevel@tonic-gate 17987c478bd9Sstevel@tonic-gate if (bitset(MF_INCLNULL, map->map_mflags)) 17997c478bd9Sstevel@tonic-gate { 18007c478bd9Sstevel@tonic-gate key.dsize++; 18017c478bd9Sstevel@tonic-gate data.dsize++; 18027c478bd9Sstevel@tonic-gate } 18037c478bd9Sstevel@tonic-gate 18047c478bd9Sstevel@tonic-gate status = dbm_store((DBM *) map->map_db1, key, data, DBM_INSERT); 18057c478bd9Sstevel@tonic-gate if (status > 0) 18067c478bd9Sstevel@tonic-gate { 18077c478bd9Sstevel@tonic-gate if (!bitset(MF_APPEND, map->map_mflags)) 18087c478bd9Sstevel@tonic-gate message("050 Warning: duplicate alias name %s", lhs); 18097c478bd9Sstevel@tonic-gate else 18107c478bd9Sstevel@tonic-gate { 18117c478bd9Sstevel@tonic-gate static char *buf = NULL; 18127c478bd9Sstevel@tonic-gate static int bufsiz = 0; 18137c478bd9Sstevel@tonic-gate auto int xstat; 18147c478bd9Sstevel@tonic-gate datum old; 18157c478bd9Sstevel@tonic-gate 18167c478bd9Sstevel@tonic-gate old.dptr = ndbm_map_lookup(map, key.dptr, 18177c478bd9Sstevel@tonic-gate (char **) NULL, &xstat); 18187c478bd9Sstevel@tonic-gate if (old.dptr != NULL && *(char *) old.dptr != '\0') 18197c478bd9Sstevel@tonic-gate { 18207c478bd9Sstevel@tonic-gate old.dsize = strlen(old.dptr); 18217c478bd9Sstevel@tonic-gate if (data.dsize + old.dsize + 2 > bufsiz) 18227c478bd9Sstevel@tonic-gate { 18237c478bd9Sstevel@tonic-gate if (buf != NULL) 18247c478bd9Sstevel@tonic-gate (void) sm_free(buf); 18257c478bd9Sstevel@tonic-gate bufsiz = data.dsize + old.dsize + 2; 18267c478bd9Sstevel@tonic-gate buf = sm_pmalloc_x(bufsiz); 18277c478bd9Sstevel@tonic-gate } 18287c478bd9Sstevel@tonic-gate (void) sm_strlcpyn(buf, bufsiz, 3, 18297c478bd9Sstevel@tonic-gate data.dptr, ",", old.dptr); 18307c478bd9Sstevel@tonic-gate data.dsize = data.dsize + old.dsize + 1; 18317c478bd9Sstevel@tonic-gate data.dptr = buf; 18327c478bd9Sstevel@tonic-gate if (tTd(38, 9)) 18337c478bd9Sstevel@tonic-gate sm_dprintf("ndbm_map_store append=%s\n", 18347c478bd9Sstevel@tonic-gate data.dptr); 18357c478bd9Sstevel@tonic-gate } 18367c478bd9Sstevel@tonic-gate } 18377c478bd9Sstevel@tonic-gate status = dbm_store((DBM *) map->map_db1, 18387c478bd9Sstevel@tonic-gate key, data, DBM_REPLACE); 18397c478bd9Sstevel@tonic-gate } 18407c478bd9Sstevel@tonic-gate if (status != 0) 18417c478bd9Sstevel@tonic-gate syserr("readaliases: dbm put (%s): %d", lhs, status); 18427c478bd9Sstevel@tonic-gate } 18437c478bd9Sstevel@tonic-gate 18447c478bd9Sstevel@tonic-gate 18457c478bd9Sstevel@tonic-gate /* 18467c478bd9Sstevel@tonic-gate ** NDBM_MAP_CLOSE -- close the database 18477c478bd9Sstevel@tonic-gate */ 18487c478bd9Sstevel@tonic-gate 18497c478bd9Sstevel@tonic-gate void 18507c478bd9Sstevel@tonic-gate ndbm_map_close(map) 18517c478bd9Sstevel@tonic-gate register MAP *map; 18527c478bd9Sstevel@tonic-gate { 18537c478bd9Sstevel@tonic-gate if (tTd(38, 9)) 18547c478bd9Sstevel@tonic-gate sm_dprintf("ndbm_map_close(%s, %s, %lx)\n", 18557c478bd9Sstevel@tonic-gate map->map_mname, map->map_file, map->map_mflags); 18567c478bd9Sstevel@tonic-gate 18577c478bd9Sstevel@tonic-gate if (bitset(MF_WRITABLE, map->map_mflags)) 18587c478bd9Sstevel@tonic-gate { 18597c478bd9Sstevel@tonic-gate # ifdef NDBM_YP_COMPAT 18607c478bd9Sstevel@tonic-gate bool inclnull; 18617c478bd9Sstevel@tonic-gate char buf[MAXHOSTNAMELEN]; 18627c478bd9Sstevel@tonic-gate 18637c478bd9Sstevel@tonic-gate inclnull = bitset(MF_INCLNULL, map->map_mflags); 18647c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_INCLNULL; 18657c478bd9Sstevel@tonic-gate 18667c478bd9Sstevel@tonic-gate if (strstr(map->map_file, "/yp/") != NULL) 18677c478bd9Sstevel@tonic-gate { 18687c478bd9Sstevel@tonic-gate long save_mflags = map->map_mflags; 18697c478bd9Sstevel@tonic-gate 18707c478bd9Sstevel@tonic-gate map->map_mflags |= MF_NOFOLDCASE; 18717c478bd9Sstevel@tonic-gate 1872058561cbSjbeck (void) sm_snprintf(buf, sizeof(buf), "%010ld", curtime()); 18737c478bd9Sstevel@tonic-gate ndbm_map_store(map, "YP_LAST_MODIFIED", buf); 18747c478bd9Sstevel@tonic-gate 1875058561cbSjbeck (void) gethostname(buf, sizeof(buf)); 18767c478bd9Sstevel@tonic-gate ndbm_map_store(map, "YP_MASTER_NAME", buf); 18777c478bd9Sstevel@tonic-gate 18787c478bd9Sstevel@tonic-gate map->map_mflags = save_mflags; 18797c478bd9Sstevel@tonic-gate } 18807c478bd9Sstevel@tonic-gate 18817c478bd9Sstevel@tonic-gate if (inclnull) 18827c478bd9Sstevel@tonic-gate map->map_mflags |= MF_INCLNULL; 18837c478bd9Sstevel@tonic-gate # endif /* NDBM_YP_COMPAT */ 18847c478bd9Sstevel@tonic-gate 18857c478bd9Sstevel@tonic-gate /* write out the distinguished alias */ 18867c478bd9Sstevel@tonic-gate ndbm_map_store(map, "@", "@"); 18877c478bd9Sstevel@tonic-gate } 18887c478bd9Sstevel@tonic-gate dbm_close((DBM *) map->map_db1); 18897c478bd9Sstevel@tonic-gate 18907c478bd9Sstevel@tonic-gate /* release lock (if needed) */ 18917c478bd9Sstevel@tonic-gate # if !LOCK_ON_OPEN 18927c478bd9Sstevel@tonic-gate if (map->map_lockfd >= 0) 18937c478bd9Sstevel@tonic-gate (void) close(map->map_lockfd); 18947c478bd9Sstevel@tonic-gate # endif /* !LOCK_ON_OPEN */ 18957c478bd9Sstevel@tonic-gate } 18967c478bd9Sstevel@tonic-gate 18977c478bd9Sstevel@tonic-gate #endif /* NDBM */ 18987c478bd9Sstevel@tonic-gate /* 18997c478bd9Sstevel@tonic-gate ** NEWDB (Hash and BTree) Modules 19007c478bd9Sstevel@tonic-gate */ 19017c478bd9Sstevel@tonic-gate 19027c478bd9Sstevel@tonic-gate #if NEWDB 19037c478bd9Sstevel@tonic-gate 19047c478bd9Sstevel@tonic-gate /* 19057c478bd9Sstevel@tonic-gate ** BT_MAP_OPEN, HASH_MAP_OPEN -- database open primitives. 19067c478bd9Sstevel@tonic-gate ** 19077c478bd9Sstevel@tonic-gate ** These do rather bizarre locking. If you can lock on open, 19087c478bd9Sstevel@tonic-gate ** do that to avoid the condition of opening a database that 19097c478bd9Sstevel@tonic-gate ** is being rebuilt. If you don't, we'll try to fake it, but 19107c478bd9Sstevel@tonic-gate ** there will be a race condition. If opening for read-only, 19117c478bd9Sstevel@tonic-gate ** we immediately release the lock to avoid freezing things up. 19127c478bd9Sstevel@tonic-gate ** We really ought to hold the lock, but guarantee that we won't 19137c478bd9Sstevel@tonic-gate ** be pokey about it. That's hard to do. 19147c478bd9Sstevel@tonic-gate */ 19157c478bd9Sstevel@tonic-gate 19167c478bd9Sstevel@tonic-gate /* these should be K line arguments */ 19177c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR < 2 19187c478bd9Sstevel@tonic-gate # define db_cachesize cachesize 19197c478bd9Sstevel@tonic-gate # define h_nelem nelem 19207c478bd9Sstevel@tonic-gate # ifndef DB_CACHE_SIZE 19217c478bd9Sstevel@tonic-gate # define DB_CACHE_SIZE (1024 * 1024) /* database memory cache size */ 19227c478bd9Sstevel@tonic-gate # endif /* ! DB_CACHE_SIZE */ 19237c478bd9Sstevel@tonic-gate # ifndef DB_HASH_NELEM 19247c478bd9Sstevel@tonic-gate # define DB_HASH_NELEM 4096 /* (starting) size of hash table */ 19257c478bd9Sstevel@tonic-gate # endif /* ! DB_HASH_NELEM */ 19267c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR < 2 */ 19277c478bd9Sstevel@tonic-gate 19287c478bd9Sstevel@tonic-gate bool 19297c478bd9Sstevel@tonic-gate bt_map_open(map, mode) 19307c478bd9Sstevel@tonic-gate MAP *map; 19317c478bd9Sstevel@tonic-gate int mode; 19327c478bd9Sstevel@tonic-gate { 19337c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR < 2 19347c478bd9Sstevel@tonic-gate BTREEINFO btinfo; 19357c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR < 2 */ 19367c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR == 2 19377c478bd9Sstevel@tonic-gate DB_INFO btinfo; 19387c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR == 2 */ 19397c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR > 2 19407c478bd9Sstevel@tonic-gate void *btinfo = NULL; 19417c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR > 2 */ 19427c478bd9Sstevel@tonic-gate 19437c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 19447c478bd9Sstevel@tonic-gate sm_dprintf("bt_map_open(%s, %s, %d)\n", 19457c478bd9Sstevel@tonic-gate map->map_mname, map->map_file, mode); 19467c478bd9Sstevel@tonic-gate 19477c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR < 3 1948058561cbSjbeck memset(&btinfo, '\0', sizeof(btinfo)); 19497c478bd9Sstevel@tonic-gate # ifdef DB_CACHE_SIZE 19507c478bd9Sstevel@tonic-gate btinfo.db_cachesize = DB_CACHE_SIZE; 19517c478bd9Sstevel@tonic-gate # endif /* DB_CACHE_SIZE */ 19527c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR < 3 */ 19537c478bd9Sstevel@tonic-gate 19547c478bd9Sstevel@tonic-gate return db_map_open(map, mode, "btree", DB_BTREE, &btinfo); 19557c478bd9Sstevel@tonic-gate } 19567c478bd9Sstevel@tonic-gate 19577c478bd9Sstevel@tonic-gate bool 19587c478bd9Sstevel@tonic-gate hash_map_open(map, mode) 19597c478bd9Sstevel@tonic-gate MAP *map; 19607c478bd9Sstevel@tonic-gate int mode; 19617c478bd9Sstevel@tonic-gate { 19627c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR < 2 19637c478bd9Sstevel@tonic-gate HASHINFO hinfo; 19647c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR < 2 */ 19657c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR == 2 19667c478bd9Sstevel@tonic-gate DB_INFO hinfo; 19677c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR == 2 */ 19687c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR > 2 19697c478bd9Sstevel@tonic-gate void *hinfo = NULL; 19707c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR > 2 */ 19717c478bd9Sstevel@tonic-gate 19727c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 19737c478bd9Sstevel@tonic-gate sm_dprintf("hash_map_open(%s, %s, %d)\n", 19747c478bd9Sstevel@tonic-gate map->map_mname, map->map_file, mode); 19757c478bd9Sstevel@tonic-gate 19767c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR < 3 1977058561cbSjbeck memset(&hinfo, '\0', sizeof(hinfo)); 19787c478bd9Sstevel@tonic-gate # ifdef DB_HASH_NELEM 19797c478bd9Sstevel@tonic-gate hinfo.h_nelem = DB_HASH_NELEM; 19807c478bd9Sstevel@tonic-gate # endif /* DB_HASH_NELEM */ 19817c478bd9Sstevel@tonic-gate # ifdef DB_CACHE_SIZE 19827c478bd9Sstevel@tonic-gate hinfo.db_cachesize = DB_CACHE_SIZE; 19837c478bd9Sstevel@tonic-gate # endif /* DB_CACHE_SIZE */ 19847c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR < 3 */ 19857c478bd9Sstevel@tonic-gate 19867c478bd9Sstevel@tonic-gate return db_map_open(map, mode, "hash", DB_HASH, &hinfo); 19877c478bd9Sstevel@tonic-gate } 19887c478bd9Sstevel@tonic-gate 19897c478bd9Sstevel@tonic-gate static bool 19907c478bd9Sstevel@tonic-gate db_map_open(map, mode, mapclassname, dbtype, openinfo) 19917c478bd9Sstevel@tonic-gate MAP *map; 19927c478bd9Sstevel@tonic-gate int mode; 19937c478bd9Sstevel@tonic-gate char *mapclassname; 19947c478bd9Sstevel@tonic-gate DBTYPE dbtype; 19957c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR < 2 19967c478bd9Sstevel@tonic-gate const void *openinfo; 19977c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR < 2 */ 19987c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR == 2 19997c478bd9Sstevel@tonic-gate DB_INFO *openinfo; 20007c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR == 2 */ 20017c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR > 2 20027c478bd9Sstevel@tonic-gate void **openinfo; 20037c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR > 2 */ 20047c478bd9Sstevel@tonic-gate { 20057c478bd9Sstevel@tonic-gate DB *db = NULL; 20067c478bd9Sstevel@tonic-gate int i; 20077c478bd9Sstevel@tonic-gate int omode; 20087c478bd9Sstevel@tonic-gate int smode = S_IREAD; 20097c478bd9Sstevel@tonic-gate int fd; 20107c478bd9Sstevel@tonic-gate long sff; 20117c478bd9Sstevel@tonic-gate int save_errno; 20127c478bd9Sstevel@tonic-gate struct stat st; 20137c478bd9Sstevel@tonic-gate char buf[MAXPATHLEN]; 20147c478bd9Sstevel@tonic-gate 20157c478bd9Sstevel@tonic-gate /* do initial file and directory checks */ 2016058561cbSjbeck if (sm_strlcpy(buf, map->map_file, sizeof(buf)) >= sizeof(buf)) 20177c478bd9Sstevel@tonic-gate { 20187c478bd9Sstevel@tonic-gate errno = 0; 20197c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 20207c478bd9Sstevel@tonic-gate syserr("map \"%s\": map file %s name too long", 20217c478bd9Sstevel@tonic-gate map->map_mname, map->map_file); 20227c478bd9Sstevel@tonic-gate return false; 20237c478bd9Sstevel@tonic-gate } 20247c478bd9Sstevel@tonic-gate i = strlen(buf); 20257c478bd9Sstevel@tonic-gate if (i < 3 || strcmp(&buf[i - 3], ".db") != 0) 20267c478bd9Sstevel@tonic-gate { 2027058561cbSjbeck if (sm_strlcat(buf, ".db", sizeof(buf)) >= sizeof(buf)) 20287c478bd9Sstevel@tonic-gate { 20297c478bd9Sstevel@tonic-gate errno = 0; 20307c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 20317c478bd9Sstevel@tonic-gate syserr("map \"%s\": map file %s name too long", 20327c478bd9Sstevel@tonic-gate map->map_mname, map->map_file); 20337c478bd9Sstevel@tonic-gate return false; 20347c478bd9Sstevel@tonic-gate } 20357c478bd9Sstevel@tonic-gate } 20367c478bd9Sstevel@tonic-gate 20377c478bd9Sstevel@tonic-gate mode &= O_ACCMODE; 20387c478bd9Sstevel@tonic-gate omode = mode; 20397c478bd9Sstevel@tonic-gate 20407c478bd9Sstevel@tonic-gate sff = SFF_ROOTOK|SFF_REGONLY; 20417c478bd9Sstevel@tonic-gate if (mode == O_RDWR) 20427c478bd9Sstevel@tonic-gate { 20437c478bd9Sstevel@tonic-gate sff |= SFF_CREAT; 20447c478bd9Sstevel@tonic-gate if (!bitnset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail)) 20457c478bd9Sstevel@tonic-gate sff |= SFF_NOSLINK; 20467c478bd9Sstevel@tonic-gate if (!bitnset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail)) 20477c478bd9Sstevel@tonic-gate sff |= SFF_NOHLINK; 20487c478bd9Sstevel@tonic-gate smode = S_IWRITE; 20497c478bd9Sstevel@tonic-gate } 20507c478bd9Sstevel@tonic-gate else 20517c478bd9Sstevel@tonic-gate { 20527c478bd9Sstevel@tonic-gate if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail)) 20537c478bd9Sstevel@tonic-gate sff |= SFF_NOWLINK; 20547c478bd9Sstevel@tonic-gate } 20557c478bd9Sstevel@tonic-gate if (!bitnset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail)) 20567c478bd9Sstevel@tonic-gate sff |= SFF_SAFEDIRPATH; 20577c478bd9Sstevel@tonic-gate i = safefile(buf, RunAsUid, RunAsGid, RunAsUserName, sff, smode, &st); 20587c478bd9Sstevel@tonic-gate 20597c478bd9Sstevel@tonic-gate if (i != 0) 20607c478bd9Sstevel@tonic-gate { 20617c478bd9Sstevel@tonic-gate char *prob = "unsafe"; 20627c478bd9Sstevel@tonic-gate 20637c478bd9Sstevel@tonic-gate /* cannot open this map */ 20647c478bd9Sstevel@tonic-gate if (i == ENOENT) 20657c478bd9Sstevel@tonic-gate prob = "missing"; 20667c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 20677c478bd9Sstevel@tonic-gate sm_dprintf("\t%s map file: %s\n", prob, sm_errstring(i)); 20687c478bd9Sstevel@tonic-gate errno = i; 20697c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 20707c478bd9Sstevel@tonic-gate syserr("%s map \"%s\": %s map file %s", 20717c478bd9Sstevel@tonic-gate mapclassname, map->map_mname, prob, buf); 20727c478bd9Sstevel@tonic-gate return false; 20737c478bd9Sstevel@tonic-gate } 20747c478bd9Sstevel@tonic-gate if (st.st_mode == ST_MODE_NOFILE) 20757c478bd9Sstevel@tonic-gate omode |= O_CREAT|O_EXCL; 20767c478bd9Sstevel@tonic-gate 20777c478bd9Sstevel@tonic-gate map->map_lockfd = -1; 20787c478bd9Sstevel@tonic-gate 20797c478bd9Sstevel@tonic-gate # if LOCK_ON_OPEN 20807c478bd9Sstevel@tonic-gate if (mode == O_RDWR) 20817c478bd9Sstevel@tonic-gate omode |= O_TRUNC|O_EXLOCK; 20827c478bd9Sstevel@tonic-gate else 20837c478bd9Sstevel@tonic-gate omode |= O_SHLOCK; 20847c478bd9Sstevel@tonic-gate # else /* LOCK_ON_OPEN */ 20857c478bd9Sstevel@tonic-gate /* 20867c478bd9Sstevel@tonic-gate ** Pre-lock the file to avoid race conditions. In particular, 20877c478bd9Sstevel@tonic-gate ** since dbopen returns NULL if the file is zero length, we 20887c478bd9Sstevel@tonic-gate ** must have a locked instance around the dbopen. 20897c478bd9Sstevel@tonic-gate */ 20907c478bd9Sstevel@tonic-gate 20917c478bd9Sstevel@tonic-gate fd = open(buf, omode, DBMMODE); 20927c478bd9Sstevel@tonic-gate if (fd < 0) 20937c478bd9Sstevel@tonic-gate { 20947c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 20957c478bd9Sstevel@tonic-gate syserr("db_map_open: cannot pre-open database %s", buf); 20967c478bd9Sstevel@tonic-gate return false; 20977c478bd9Sstevel@tonic-gate } 20987c478bd9Sstevel@tonic-gate 20997c478bd9Sstevel@tonic-gate /* make sure no baddies slipped in just before the open... */ 21007c478bd9Sstevel@tonic-gate if (filechanged(buf, fd, &st)) 21017c478bd9Sstevel@tonic-gate { 21027c478bd9Sstevel@tonic-gate save_errno = errno; 21037c478bd9Sstevel@tonic-gate (void) close(fd); 21047c478bd9Sstevel@tonic-gate errno = save_errno; 21057c478bd9Sstevel@tonic-gate syserr("db_map_open(%s): file changed after pre-open", buf); 21067c478bd9Sstevel@tonic-gate return false; 21077c478bd9Sstevel@tonic-gate } 21087c478bd9Sstevel@tonic-gate 21097c478bd9Sstevel@tonic-gate /* if new file, get the "before" bits for later filechanged check */ 21107c478bd9Sstevel@tonic-gate if (st.st_mode == ST_MODE_NOFILE && fstat(fd, &st) < 0) 21117c478bd9Sstevel@tonic-gate { 21127c478bd9Sstevel@tonic-gate save_errno = errno; 21137c478bd9Sstevel@tonic-gate (void) close(fd); 21147c478bd9Sstevel@tonic-gate errno = save_errno; 21157c478bd9Sstevel@tonic-gate syserr("db_map_open(%s): cannot fstat pre-opened file", 21167c478bd9Sstevel@tonic-gate buf); 21177c478bd9Sstevel@tonic-gate return false; 21187c478bd9Sstevel@tonic-gate } 21197c478bd9Sstevel@tonic-gate 21207c478bd9Sstevel@tonic-gate /* actually lock the pre-opened file */ 21217c478bd9Sstevel@tonic-gate if (!lockfile(fd, buf, NULL, mode == O_RDONLY ? LOCK_SH : LOCK_EX)) 21227c478bd9Sstevel@tonic-gate syserr("db_map_open: cannot lock %s", buf); 21237c478bd9Sstevel@tonic-gate 21247c478bd9Sstevel@tonic-gate /* set up mode bits for dbopen */ 21257c478bd9Sstevel@tonic-gate if (mode == O_RDWR) 21267c478bd9Sstevel@tonic-gate omode |= O_TRUNC; 21277c478bd9Sstevel@tonic-gate omode &= ~(O_EXCL|O_CREAT); 21287c478bd9Sstevel@tonic-gate # endif /* LOCK_ON_OPEN */ 21297c478bd9Sstevel@tonic-gate 21307c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR < 2 21317c478bd9Sstevel@tonic-gate db = dbopen(buf, omode, DBMMODE, dbtype, openinfo); 21327c478bd9Sstevel@tonic-gate # else /* DB_VERSION_MAJOR < 2 */ 21337c478bd9Sstevel@tonic-gate { 21347c478bd9Sstevel@tonic-gate int flags = 0; 21357c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR > 2 21367c478bd9Sstevel@tonic-gate int ret; 21377c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR > 2 */ 21387c478bd9Sstevel@tonic-gate 21397c478bd9Sstevel@tonic-gate if (mode == O_RDONLY) 21407c478bd9Sstevel@tonic-gate flags |= DB_RDONLY; 21417c478bd9Sstevel@tonic-gate if (bitset(O_CREAT, omode)) 21427c478bd9Sstevel@tonic-gate flags |= DB_CREATE; 21437c478bd9Sstevel@tonic-gate if (bitset(O_TRUNC, omode)) 21447c478bd9Sstevel@tonic-gate flags |= DB_TRUNCATE; 21457c478bd9Sstevel@tonic-gate SM_DB_FLAG_ADD(flags); 21467c478bd9Sstevel@tonic-gate 21477c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR > 2 21487c478bd9Sstevel@tonic-gate ret = db_create(&db, NULL, 0); 21497c478bd9Sstevel@tonic-gate # ifdef DB_CACHE_SIZE 21507c478bd9Sstevel@tonic-gate if (ret == 0 && db != NULL) 21517c478bd9Sstevel@tonic-gate { 21527c478bd9Sstevel@tonic-gate ret = db->set_cachesize(db, 0, DB_CACHE_SIZE, 0); 21537c478bd9Sstevel@tonic-gate if (ret != 0) 21547c478bd9Sstevel@tonic-gate { 21557c478bd9Sstevel@tonic-gate (void) db->close(db, 0); 21567c478bd9Sstevel@tonic-gate db = NULL; 21577c478bd9Sstevel@tonic-gate } 21587c478bd9Sstevel@tonic-gate } 21597c478bd9Sstevel@tonic-gate # endif /* DB_CACHE_SIZE */ 21607c478bd9Sstevel@tonic-gate # ifdef DB_HASH_NELEM 21617c478bd9Sstevel@tonic-gate if (dbtype == DB_HASH && ret == 0 && db != NULL) 21627c478bd9Sstevel@tonic-gate { 21637c478bd9Sstevel@tonic-gate ret = db->set_h_nelem(db, DB_HASH_NELEM); 21647c478bd9Sstevel@tonic-gate if (ret != 0) 21657c478bd9Sstevel@tonic-gate { 21667c478bd9Sstevel@tonic-gate (void) db->close(db, 0); 21677c478bd9Sstevel@tonic-gate db = NULL; 21687c478bd9Sstevel@tonic-gate } 21697c478bd9Sstevel@tonic-gate } 21707c478bd9Sstevel@tonic-gate # endif /* DB_HASH_NELEM */ 21717c478bd9Sstevel@tonic-gate if (ret == 0 && db != NULL) 21727c478bd9Sstevel@tonic-gate { 21737c478bd9Sstevel@tonic-gate ret = db->open(db, 21747c478bd9Sstevel@tonic-gate DBTXN /* transaction for DB 4.1 */ 21757c478bd9Sstevel@tonic-gate buf, NULL, dbtype, flags, DBMMODE); 21767c478bd9Sstevel@tonic-gate if (ret != 0) 21777c478bd9Sstevel@tonic-gate { 21787c478bd9Sstevel@tonic-gate #ifdef DB_OLD_VERSION 21797c478bd9Sstevel@tonic-gate if (ret == DB_OLD_VERSION) 21807c478bd9Sstevel@tonic-gate ret = EINVAL; 21817c478bd9Sstevel@tonic-gate #endif /* DB_OLD_VERSION */ 21827c478bd9Sstevel@tonic-gate (void) db->close(db, 0); 21837c478bd9Sstevel@tonic-gate db = NULL; 21847c478bd9Sstevel@tonic-gate } 21857c478bd9Sstevel@tonic-gate } 21867c478bd9Sstevel@tonic-gate errno = ret; 21877c478bd9Sstevel@tonic-gate # else /* DB_VERSION_MAJOR > 2 */ 21887c478bd9Sstevel@tonic-gate errno = db_open(buf, dbtype, flags, DBMMODE, 21897c478bd9Sstevel@tonic-gate NULL, openinfo, &db); 21907c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR > 2 */ 21917c478bd9Sstevel@tonic-gate } 21927c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR < 2 */ 21937c478bd9Sstevel@tonic-gate save_errno = errno; 21947c478bd9Sstevel@tonic-gate 21957c478bd9Sstevel@tonic-gate # if !LOCK_ON_OPEN 21967c478bd9Sstevel@tonic-gate if (mode == O_RDWR) 21977c478bd9Sstevel@tonic-gate map->map_lockfd = fd; 21987c478bd9Sstevel@tonic-gate else 21997c478bd9Sstevel@tonic-gate (void) close(fd); 22007c478bd9Sstevel@tonic-gate # endif /* !LOCK_ON_OPEN */ 22017c478bd9Sstevel@tonic-gate 22027c478bd9Sstevel@tonic-gate if (db == NULL) 22037c478bd9Sstevel@tonic-gate { 22047c478bd9Sstevel@tonic-gate if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) && 22057c478bd9Sstevel@tonic-gate aliaswait(map, ".db", false)) 22067c478bd9Sstevel@tonic-gate return true; 22077c478bd9Sstevel@tonic-gate # if !LOCK_ON_OPEN 22087c478bd9Sstevel@tonic-gate if (map->map_lockfd >= 0) 22097c478bd9Sstevel@tonic-gate (void) close(map->map_lockfd); 22107c478bd9Sstevel@tonic-gate # endif /* !LOCK_ON_OPEN */ 22117c478bd9Sstevel@tonic-gate errno = save_errno; 22127c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 22137c478bd9Sstevel@tonic-gate syserr("Cannot open %s database %s", 22147c478bd9Sstevel@tonic-gate mapclassname, buf); 22157c478bd9Sstevel@tonic-gate return false; 22167c478bd9Sstevel@tonic-gate } 22177c478bd9Sstevel@tonic-gate 22187c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR < 2 22197c478bd9Sstevel@tonic-gate fd = db->fd(db); 22207c478bd9Sstevel@tonic-gate # else /* DB_VERSION_MAJOR < 2 */ 22217c478bd9Sstevel@tonic-gate fd = -1; 22227c478bd9Sstevel@tonic-gate errno = db->fd(db, &fd); 22237c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR < 2 */ 22247c478bd9Sstevel@tonic-gate if (filechanged(buf, fd, &st)) 22257c478bd9Sstevel@tonic-gate { 22267c478bd9Sstevel@tonic-gate save_errno = errno; 22277c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR < 2 22287c478bd9Sstevel@tonic-gate (void) db->close(db); 22297c478bd9Sstevel@tonic-gate # else /* DB_VERSION_MAJOR < 2 */ 22307c478bd9Sstevel@tonic-gate errno = db->close(db, 0); 22317c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR < 2 */ 22327c478bd9Sstevel@tonic-gate # if !LOCK_ON_OPEN 22337c478bd9Sstevel@tonic-gate if (map->map_lockfd >= 0) 22347c478bd9Sstevel@tonic-gate (void) close(map->map_lockfd); 22357c478bd9Sstevel@tonic-gate # endif /* !LOCK_ON_OPEN */ 22367c478bd9Sstevel@tonic-gate errno = save_errno; 22377c478bd9Sstevel@tonic-gate syserr("db_map_open(%s): file changed after open", buf); 22387c478bd9Sstevel@tonic-gate return false; 22397c478bd9Sstevel@tonic-gate } 22407c478bd9Sstevel@tonic-gate 22417c478bd9Sstevel@tonic-gate if (mode == O_RDWR) 22427c478bd9Sstevel@tonic-gate map->map_mflags |= MF_LOCKED; 22437c478bd9Sstevel@tonic-gate # if LOCK_ON_OPEN 22447c478bd9Sstevel@tonic-gate if (fd >= 0 && mode == O_RDONLY) 22457c478bd9Sstevel@tonic-gate { 22467c478bd9Sstevel@tonic-gate (void) lockfile(fd, buf, NULL, LOCK_UN); 22477c478bd9Sstevel@tonic-gate } 22487c478bd9Sstevel@tonic-gate # endif /* LOCK_ON_OPEN */ 22497c478bd9Sstevel@tonic-gate 22507c478bd9Sstevel@tonic-gate /* try to make sure that at least the database header is on disk */ 22517c478bd9Sstevel@tonic-gate if (mode == O_RDWR) 22527c478bd9Sstevel@tonic-gate { 22537c478bd9Sstevel@tonic-gate (void) db->sync(db, 0); 22547c478bd9Sstevel@tonic-gate if (geteuid() == 0 && TrustedUid != 0) 22557c478bd9Sstevel@tonic-gate { 22567c478bd9Sstevel@tonic-gate # if HASFCHOWN 22577c478bd9Sstevel@tonic-gate if (fchown(fd, TrustedUid, -1) < 0) 22587c478bd9Sstevel@tonic-gate { 22597c478bd9Sstevel@tonic-gate int err = errno; 22607c478bd9Sstevel@tonic-gate 22617c478bd9Sstevel@tonic-gate sm_syslog(LOG_ALERT, NOQID, 22627c478bd9Sstevel@tonic-gate "ownership change on %s failed: %s", 22637c478bd9Sstevel@tonic-gate buf, sm_errstring(err)); 22647c478bd9Sstevel@tonic-gate message("050 ownership change on %s failed: %s", 22657c478bd9Sstevel@tonic-gate buf, sm_errstring(err)); 22667c478bd9Sstevel@tonic-gate } 22677c478bd9Sstevel@tonic-gate # else /* HASFCHOWN */ 22687c478bd9Sstevel@tonic-gate sm_syslog(LOG_ALERT, NOQID, 22697c478bd9Sstevel@tonic-gate "no fchown(): cannot change ownership on %s", 22707c478bd9Sstevel@tonic-gate map->map_file); 22717c478bd9Sstevel@tonic-gate message("050 no fchown(): cannot change ownership on %s", 22727c478bd9Sstevel@tonic-gate map->map_file); 22737c478bd9Sstevel@tonic-gate # endif /* HASFCHOWN */ 22747c478bd9Sstevel@tonic-gate } 22757c478bd9Sstevel@tonic-gate } 22767c478bd9Sstevel@tonic-gate 22777c478bd9Sstevel@tonic-gate map->map_db2 = (ARBPTR_T) db; 22787c478bd9Sstevel@tonic-gate 22797c478bd9Sstevel@tonic-gate /* 22807c478bd9Sstevel@tonic-gate ** Need to set map_mtime before the call to aliaswait() 22817c478bd9Sstevel@tonic-gate ** as aliaswait() will call map_lookup() which requires 22827c478bd9Sstevel@tonic-gate ** map_mtime to be set 22837c478bd9Sstevel@tonic-gate */ 22847c478bd9Sstevel@tonic-gate 22857c478bd9Sstevel@tonic-gate if (fd >= 0 && fstat(fd, &st) >= 0) 22867c478bd9Sstevel@tonic-gate map->map_mtime = st.st_mtime; 22877c478bd9Sstevel@tonic-gate 22887c478bd9Sstevel@tonic-gate if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) && 22897c478bd9Sstevel@tonic-gate !aliaswait(map, ".db", true)) 22907c478bd9Sstevel@tonic-gate return false; 22917c478bd9Sstevel@tonic-gate return true; 22927c478bd9Sstevel@tonic-gate } 22937c478bd9Sstevel@tonic-gate 22947c478bd9Sstevel@tonic-gate 22957c478bd9Sstevel@tonic-gate /* 22967c478bd9Sstevel@tonic-gate ** DB_MAP_LOOKUP -- look up a datum in a BTREE- or HASH-type map 22977c478bd9Sstevel@tonic-gate */ 22987c478bd9Sstevel@tonic-gate 22997c478bd9Sstevel@tonic-gate char * 23007c478bd9Sstevel@tonic-gate db_map_lookup(map, name, av, statp) 23017c478bd9Sstevel@tonic-gate MAP *map; 23027c478bd9Sstevel@tonic-gate char *name; 23037c478bd9Sstevel@tonic-gate char **av; 23047c478bd9Sstevel@tonic-gate int *statp; 23057c478bd9Sstevel@tonic-gate { 23067c478bd9Sstevel@tonic-gate DBT key, val; 23077c478bd9Sstevel@tonic-gate register DB *db = (DB *) map->map_db2; 23087c478bd9Sstevel@tonic-gate int i; 23097c478bd9Sstevel@tonic-gate int st; 23107c478bd9Sstevel@tonic-gate int save_errno; 23117c478bd9Sstevel@tonic-gate int fd; 23127c478bd9Sstevel@tonic-gate struct stat stbuf; 23137c478bd9Sstevel@tonic-gate char keybuf[MAXNAME + 1]; 23147c478bd9Sstevel@tonic-gate char buf[MAXPATHLEN]; 23157c478bd9Sstevel@tonic-gate 2316058561cbSjbeck memset(&key, '\0', sizeof(key)); 2317058561cbSjbeck memset(&val, '\0', sizeof(val)); 23187c478bd9Sstevel@tonic-gate 23197c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 23207c478bd9Sstevel@tonic-gate sm_dprintf("db_map_lookup(%s, %s)\n", 23217c478bd9Sstevel@tonic-gate map->map_mname, name); 23227c478bd9Sstevel@tonic-gate 2323058561cbSjbeck if (sm_strlcpy(buf, map->map_file, sizeof(buf)) >= sizeof(buf)) 23247c478bd9Sstevel@tonic-gate { 23257c478bd9Sstevel@tonic-gate errno = 0; 23267c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 23277c478bd9Sstevel@tonic-gate syserr("map \"%s\": map file %s name too long", 23287c478bd9Sstevel@tonic-gate map->map_mname, map->map_file); 23297c478bd9Sstevel@tonic-gate return NULL; 23307c478bd9Sstevel@tonic-gate } 23317c478bd9Sstevel@tonic-gate i = strlen(buf); 23327c478bd9Sstevel@tonic-gate if (i > 3 && strcmp(&buf[i - 3], ".db") == 0) 23337c478bd9Sstevel@tonic-gate buf[i - 3] = '\0'; 23347c478bd9Sstevel@tonic-gate 23357c478bd9Sstevel@tonic-gate key.size = strlen(name); 2336058561cbSjbeck if (key.size > sizeof(keybuf) - 1) 2337058561cbSjbeck key.size = sizeof(keybuf) - 1; 23387c478bd9Sstevel@tonic-gate key.data = keybuf; 23397c478bd9Sstevel@tonic-gate memmove(keybuf, name, key.size); 23407c478bd9Sstevel@tonic-gate keybuf[key.size] = '\0'; 23417c478bd9Sstevel@tonic-gate if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 23427c478bd9Sstevel@tonic-gate makelower(keybuf); 23437c478bd9Sstevel@tonic-gate lockdb: 23447c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR < 2 23457c478bd9Sstevel@tonic-gate fd = db->fd(db); 23467c478bd9Sstevel@tonic-gate # else /* DB_VERSION_MAJOR < 2 */ 23477c478bd9Sstevel@tonic-gate fd = -1; 23487c478bd9Sstevel@tonic-gate errno = db->fd(db, &fd); 23497c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR < 2 */ 23507c478bd9Sstevel@tonic-gate if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags)) 23517c478bd9Sstevel@tonic-gate (void) lockfile(fd, buf, ".db", LOCK_SH); 23527c478bd9Sstevel@tonic-gate if (fd < 0 || fstat(fd, &stbuf) < 0 || stbuf.st_mtime > map->map_mtime) 23537c478bd9Sstevel@tonic-gate { 23547c478bd9Sstevel@tonic-gate /* Reopen the database to sync the cache */ 23557c478bd9Sstevel@tonic-gate int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR 23567c478bd9Sstevel@tonic-gate : O_RDONLY; 23577c478bd9Sstevel@tonic-gate 23587c478bd9Sstevel@tonic-gate if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags)) 23597c478bd9Sstevel@tonic-gate (void) lockfile(fd, buf, ".db", LOCK_UN); 23607c478bd9Sstevel@tonic-gate map->map_mflags |= MF_CLOSING; 23617c478bd9Sstevel@tonic-gate map->map_class->map_close(map); 23627c478bd9Sstevel@tonic-gate map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING); 23637c478bd9Sstevel@tonic-gate if (map->map_class->map_open(map, omode)) 23647c478bd9Sstevel@tonic-gate { 23657c478bd9Sstevel@tonic-gate map->map_mflags |= MF_OPEN; 23667c478bd9Sstevel@tonic-gate map->map_pid = CurrentPid; 2367*e9af4bc0SJohn Beck if ((omode & O_ACCMODE) == O_RDWR) 23687c478bd9Sstevel@tonic-gate map->map_mflags |= MF_WRITABLE; 23697c478bd9Sstevel@tonic-gate db = (DB *) map->map_db2; 23707c478bd9Sstevel@tonic-gate goto lockdb; 23717c478bd9Sstevel@tonic-gate } 23727c478bd9Sstevel@tonic-gate else 23737c478bd9Sstevel@tonic-gate { 23747c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 23757c478bd9Sstevel@tonic-gate { 23767c478bd9Sstevel@tonic-gate extern MAPCLASS BogusMapClass; 23777c478bd9Sstevel@tonic-gate 23787c478bd9Sstevel@tonic-gate *statp = EX_TEMPFAIL; 23797c478bd9Sstevel@tonic-gate map->map_orgclass = map->map_class; 23807c478bd9Sstevel@tonic-gate map->map_class = &BogusMapClass; 23817c478bd9Sstevel@tonic-gate map->map_mflags |= MF_OPEN; 23827c478bd9Sstevel@tonic-gate map->map_pid = CurrentPid; 23837c478bd9Sstevel@tonic-gate syserr("Cannot reopen DB database %s", 23847c478bd9Sstevel@tonic-gate map->map_file); 23857c478bd9Sstevel@tonic-gate } 23867c478bd9Sstevel@tonic-gate return NULL; 23877c478bd9Sstevel@tonic-gate } 23887c478bd9Sstevel@tonic-gate } 23897c478bd9Sstevel@tonic-gate 23907c478bd9Sstevel@tonic-gate st = 1; 23917c478bd9Sstevel@tonic-gate if (bitset(MF_TRY0NULL, map->map_mflags)) 23927c478bd9Sstevel@tonic-gate { 23937c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR < 2 23947c478bd9Sstevel@tonic-gate st = db->get(db, &key, &val, 0); 23957c478bd9Sstevel@tonic-gate # else /* DB_VERSION_MAJOR < 2 */ 23967c478bd9Sstevel@tonic-gate errno = db->get(db, NULL, &key, &val, 0); 23977c478bd9Sstevel@tonic-gate switch (errno) 23987c478bd9Sstevel@tonic-gate { 23997c478bd9Sstevel@tonic-gate case DB_NOTFOUND: 24007c478bd9Sstevel@tonic-gate case DB_KEYEMPTY: 24017c478bd9Sstevel@tonic-gate st = 1; 24027c478bd9Sstevel@tonic-gate break; 24037c478bd9Sstevel@tonic-gate 24047c478bd9Sstevel@tonic-gate case 0: 24057c478bd9Sstevel@tonic-gate st = 0; 24067c478bd9Sstevel@tonic-gate break; 24077c478bd9Sstevel@tonic-gate 24087c478bd9Sstevel@tonic-gate default: 24097c478bd9Sstevel@tonic-gate st = -1; 24107c478bd9Sstevel@tonic-gate break; 24117c478bd9Sstevel@tonic-gate } 24127c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR < 2 */ 24137c478bd9Sstevel@tonic-gate if (st == 0) 24147c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_TRY1NULL; 24157c478bd9Sstevel@tonic-gate } 24167c478bd9Sstevel@tonic-gate if (st != 0 && bitset(MF_TRY1NULL, map->map_mflags)) 24177c478bd9Sstevel@tonic-gate { 24187c478bd9Sstevel@tonic-gate key.size++; 24197c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR < 2 24207c478bd9Sstevel@tonic-gate st = db->get(db, &key, &val, 0); 24217c478bd9Sstevel@tonic-gate # else /* DB_VERSION_MAJOR < 2 */ 24227c478bd9Sstevel@tonic-gate errno = db->get(db, NULL, &key, &val, 0); 24237c478bd9Sstevel@tonic-gate switch (errno) 24247c478bd9Sstevel@tonic-gate { 24257c478bd9Sstevel@tonic-gate case DB_NOTFOUND: 24267c478bd9Sstevel@tonic-gate case DB_KEYEMPTY: 24277c478bd9Sstevel@tonic-gate st = 1; 24287c478bd9Sstevel@tonic-gate break; 24297c478bd9Sstevel@tonic-gate 24307c478bd9Sstevel@tonic-gate case 0: 24317c478bd9Sstevel@tonic-gate st = 0; 24327c478bd9Sstevel@tonic-gate break; 24337c478bd9Sstevel@tonic-gate 24347c478bd9Sstevel@tonic-gate default: 24357c478bd9Sstevel@tonic-gate st = -1; 24367c478bd9Sstevel@tonic-gate break; 24377c478bd9Sstevel@tonic-gate } 24387c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR < 2 */ 24397c478bd9Sstevel@tonic-gate if (st == 0) 24407c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_TRY0NULL; 24417c478bd9Sstevel@tonic-gate } 24427c478bd9Sstevel@tonic-gate save_errno = errno; 24437c478bd9Sstevel@tonic-gate if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags)) 24447c478bd9Sstevel@tonic-gate (void) lockfile(fd, buf, ".db", LOCK_UN); 24457c478bd9Sstevel@tonic-gate if (st != 0) 24467c478bd9Sstevel@tonic-gate { 24477c478bd9Sstevel@tonic-gate errno = save_errno; 24487c478bd9Sstevel@tonic-gate if (st < 0) 24497c478bd9Sstevel@tonic-gate syserr("db_map_lookup: get (%s)", name); 24507c478bd9Sstevel@tonic-gate return NULL; 24517c478bd9Sstevel@tonic-gate } 24527c478bd9Sstevel@tonic-gate if (bitset(MF_MATCHONLY, map->map_mflags)) 24537c478bd9Sstevel@tonic-gate return map_rewrite(map, name, strlen(name), NULL); 24547c478bd9Sstevel@tonic-gate else 24557c478bd9Sstevel@tonic-gate return map_rewrite(map, val.data, val.size, av); 24567c478bd9Sstevel@tonic-gate } 24577c478bd9Sstevel@tonic-gate 24587c478bd9Sstevel@tonic-gate 24597c478bd9Sstevel@tonic-gate /* 24607c478bd9Sstevel@tonic-gate ** DB_MAP_STORE -- store a datum in the NEWDB database 24617c478bd9Sstevel@tonic-gate */ 24627c478bd9Sstevel@tonic-gate 24637c478bd9Sstevel@tonic-gate void 24647c478bd9Sstevel@tonic-gate db_map_store(map, lhs, rhs) 24657c478bd9Sstevel@tonic-gate register MAP *map; 24667c478bd9Sstevel@tonic-gate char *lhs; 24677c478bd9Sstevel@tonic-gate char *rhs; 24687c478bd9Sstevel@tonic-gate { 24697c478bd9Sstevel@tonic-gate int status; 24707c478bd9Sstevel@tonic-gate DBT key; 24717c478bd9Sstevel@tonic-gate DBT data; 24727c478bd9Sstevel@tonic-gate register DB *db = map->map_db2; 24737c478bd9Sstevel@tonic-gate char keybuf[MAXNAME + 1]; 24747c478bd9Sstevel@tonic-gate 2475058561cbSjbeck memset(&key, '\0', sizeof(key)); 2476058561cbSjbeck memset(&data, '\0', sizeof(data)); 24777c478bd9Sstevel@tonic-gate 24787c478bd9Sstevel@tonic-gate if (tTd(38, 12)) 24797c478bd9Sstevel@tonic-gate sm_dprintf("db_map_store(%s, %s, %s)\n", 24807c478bd9Sstevel@tonic-gate map->map_mname, lhs, rhs); 24817c478bd9Sstevel@tonic-gate 24827c478bd9Sstevel@tonic-gate key.size = strlen(lhs); 24837c478bd9Sstevel@tonic-gate key.data = lhs; 24847c478bd9Sstevel@tonic-gate if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 24857c478bd9Sstevel@tonic-gate { 2486058561cbSjbeck if (key.size > sizeof(keybuf) - 1) 2487058561cbSjbeck key.size = sizeof(keybuf) - 1; 24887c478bd9Sstevel@tonic-gate memmove(keybuf, key.data, key.size); 24897c478bd9Sstevel@tonic-gate keybuf[key.size] = '\0'; 24907c478bd9Sstevel@tonic-gate makelower(keybuf); 24917c478bd9Sstevel@tonic-gate key.data = keybuf; 24927c478bd9Sstevel@tonic-gate } 24937c478bd9Sstevel@tonic-gate 24947c478bd9Sstevel@tonic-gate data.size = strlen(rhs); 24957c478bd9Sstevel@tonic-gate data.data = rhs; 24967c478bd9Sstevel@tonic-gate 24977c478bd9Sstevel@tonic-gate if (bitset(MF_INCLNULL, map->map_mflags)) 24987c478bd9Sstevel@tonic-gate { 24997c478bd9Sstevel@tonic-gate key.size++; 25007c478bd9Sstevel@tonic-gate data.size++; 25017c478bd9Sstevel@tonic-gate } 25027c478bd9Sstevel@tonic-gate 25037c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR < 2 25047c478bd9Sstevel@tonic-gate status = db->put(db, &key, &data, R_NOOVERWRITE); 25057c478bd9Sstevel@tonic-gate # else /* DB_VERSION_MAJOR < 2 */ 25067c478bd9Sstevel@tonic-gate errno = db->put(db, NULL, &key, &data, DB_NOOVERWRITE); 25077c478bd9Sstevel@tonic-gate switch (errno) 25087c478bd9Sstevel@tonic-gate { 25097c478bd9Sstevel@tonic-gate case DB_KEYEXIST: 25107c478bd9Sstevel@tonic-gate status = 1; 25117c478bd9Sstevel@tonic-gate break; 25127c478bd9Sstevel@tonic-gate 25137c478bd9Sstevel@tonic-gate case 0: 25147c478bd9Sstevel@tonic-gate status = 0; 25157c478bd9Sstevel@tonic-gate break; 25167c478bd9Sstevel@tonic-gate 25177c478bd9Sstevel@tonic-gate default: 25187c478bd9Sstevel@tonic-gate status = -1; 25197c478bd9Sstevel@tonic-gate break; 25207c478bd9Sstevel@tonic-gate } 25217c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR < 2 */ 25227c478bd9Sstevel@tonic-gate if (status > 0) 25237c478bd9Sstevel@tonic-gate { 25247c478bd9Sstevel@tonic-gate if (!bitset(MF_APPEND, map->map_mflags)) 25257c478bd9Sstevel@tonic-gate message("050 Warning: duplicate alias name %s", lhs); 25267c478bd9Sstevel@tonic-gate else 25277c478bd9Sstevel@tonic-gate { 25287c478bd9Sstevel@tonic-gate static char *buf = NULL; 25297c478bd9Sstevel@tonic-gate static int bufsiz = 0; 25307c478bd9Sstevel@tonic-gate DBT old; 25317c478bd9Sstevel@tonic-gate 2532058561cbSjbeck memset(&old, '\0', sizeof(old)); 25337c478bd9Sstevel@tonic-gate 25347c478bd9Sstevel@tonic-gate old.data = db_map_lookup(map, key.data, 25357c478bd9Sstevel@tonic-gate (char **) NULL, &status); 25367c478bd9Sstevel@tonic-gate if (old.data != NULL) 25377c478bd9Sstevel@tonic-gate { 25387c478bd9Sstevel@tonic-gate old.size = strlen(old.data); 25397c478bd9Sstevel@tonic-gate if (data.size + old.size + 2 > (size_t) bufsiz) 25407c478bd9Sstevel@tonic-gate { 25417c478bd9Sstevel@tonic-gate if (buf != NULL) 25427c478bd9Sstevel@tonic-gate sm_free(buf); 25437c478bd9Sstevel@tonic-gate bufsiz = data.size + old.size + 2; 25447c478bd9Sstevel@tonic-gate buf = sm_pmalloc_x(bufsiz); 25457c478bd9Sstevel@tonic-gate } 25467c478bd9Sstevel@tonic-gate (void) sm_strlcpyn(buf, bufsiz, 3, 25477c478bd9Sstevel@tonic-gate (char *) data.data, ",", 25487c478bd9Sstevel@tonic-gate (char *) old.data); 25497c478bd9Sstevel@tonic-gate data.size = data.size + old.size + 1; 25507c478bd9Sstevel@tonic-gate data.data = buf; 25517c478bd9Sstevel@tonic-gate if (tTd(38, 9)) 25527c478bd9Sstevel@tonic-gate sm_dprintf("db_map_store append=%s\n", 25537c478bd9Sstevel@tonic-gate (char *) data.data); 25547c478bd9Sstevel@tonic-gate } 25557c478bd9Sstevel@tonic-gate } 25567c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR < 2 25577c478bd9Sstevel@tonic-gate status = db->put(db, &key, &data, 0); 25587c478bd9Sstevel@tonic-gate # else /* DB_VERSION_MAJOR < 2 */ 25597c478bd9Sstevel@tonic-gate status = errno = db->put(db, NULL, &key, &data, 0); 25607c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR < 2 */ 25617c478bd9Sstevel@tonic-gate } 25627c478bd9Sstevel@tonic-gate if (status != 0) 25637c478bd9Sstevel@tonic-gate syserr("readaliases: db put (%s)", lhs); 25647c478bd9Sstevel@tonic-gate } 25657c478bd9Sstevel@tonic-gate 25667c478bd9Sstevel@tonic-gate 25677c478bd9Sstevel@tonic-gate /* 25687c478bd9Sstevel@tonic-gate ** DB_MAP_CLOSE -- add distinguished entries and close the database 25697c478bd9Sstevel@tonic-gate */ 25707c478bd9Sstevel@tonic-gate 25717c478bd9Sstevel@tonic-gate void 25727c478bd9Sstevel@tonic-gate db_map_close(map) 25737c478bd9Sstevel@tonic-gate MAP *map; 25747c478bd9Sstevel@tonic-gate { 25757c478bd9Sstevel@tonic-gate register DB *db = map->map_db2; 25767c478bd9Sstevel@tonic-gate 25777c478bd9Sstevel@tonic-gate if (tTd(38, 9)) 25787c478bd9Sstevel@tonic-gate sm_dprintf("db_map_close(%s, %s, %lx)\n", 25797c478bd9Sstevel@tonic-gate map->map_mname, map->map_file, map->map_mflags); 25807c478bd9Sstevel@tonic-gate 25817c478bd9Sstevel@tonic-gate if (bitset(MF_WRITABLE, map->map_mflags)) 25827c478bd9Sstevel@tonic-gate { 25837c478bd9Sstevel@tonic-gate /* write out the distinguished alias */ 25847c478bd9Sstevel@tonic-gate db_map_store(map, "@", "@"); 25857c478bd9Sstevel@tonic-gate } 25867c478bd9Sstevel@tonic-gate 25877c478bd9Sstevel@tonic-gate (void) db->sync(db, 0); 25887c478bd9Sstevel@tonic-gate 25897c478bd9Sstevel@tonic-gate # if !LOCK_ON_OPEN 25907c478bd9Sstevel@tonic-gate if (map->map_lockfd >= 0) 25917c478bd9Sstevel@tonic-gate (void) close(map->map_lockfd); 25927c478bd9Sstevel@tonic-gate # endif /* !LOCK_ON_OPEN */ 25937c478bd9Sstevel@tonic-gate 25947c478bd9Sstevel@tonic-gate # if DB_VERSION_MAJOR < 2 25957c478bd9Sstevel@tonic-gate if (db->close(db) != 0) 25967c478bd9Sstevel@tonic-gate # else /* DB_VERSION_MAJOR < 2 */ 25977c478bd9Sstevel@tonic-gate /* 25987c478bd9Sstevel@tonic-gate ** Berkeley DB can use internal shared memory 25997c478bd9Sstevel@tonic-gate ** locking for its memory pool. Closing a map 26007c478bd9Sstevel@tonic-gate ** opened by another process will interfere 26017c478bd9Sstevel@tonic-gate ** with the shared memory and locks of the parent 26027c478bd9Sstevel@tonic-gate ** process leaving things in a bad state. 26037c478bd9Sstevel@tonic-gate */ 26047c478bd9Sstevel@tonic-gate 26057c478bd9Sstevel@tonic-gate /* 26067c478bd9Sstevel@tonic-gate ** If this map was not opened by the current 26077c478bd9Sstevel@tonic-gate ** process, do not close the map but recover 26087c478bd9Sstevel@tonic-gate ** the file descriptor. 26097c478bd9Sstevel@tonic-gate */ 26107c478bd9Sstevel@tonic-gate 26117c478bd9Sstevel@tonic-gate if (map->map_pid != CurrentPid) 26127c478bd9Sstevel@tonic-gate { 26137c478bd9Sstevel@tonic-gate int fd = -1; 26147c478bd9Sstevel@tonic-gate 26157c478bd9Sstevel@tonic-gate errno = db->fd(db, &fd); 26167c478bd9Sstevel@tonic-gate if (fd >= 0) 26177c478bd9Sstevel@tonic-gate (void) close(fd); 26187c478bd9Sstevel@tonic-gate return; 26197c478bd9Sstevel@tonic-gate } 26207c478bd9Sstevel@tonic-gate 26217c478bd9Sstevel@tonic-gate if ((errno = db->close(db, 0)) != 0) 26227c478bd9Sstevel@tonic-gate # endif /* DB_VERSION_MAJOR < 2 */ 26237c478bd9Sstevel@tonic-gate syserr("db_map_close(%s, %s, %lx): db close failure", 26247c478bd9Sstevel@tonic-gate map->map_mname, map->map_file, map->map_mflags); 26257c478bd9Sstevel@tonic-gate } 26267c478bd9Sstevel@tonic-gate #endif /* NEWDB */ 26277c478bd9Sstevel@tonic-gate /* 26287c478bd9Sstevel@tonic-gate ** NIS Modules 26297c478bd9Sstevel@tonic-gate */ 26307c478bd9Sstevel@tonic-gate 26317c478bd9Sstevel@tonic-gate #if NIS 26327c478bd9Sstevel@tonic-gate 26337c478bd9Sstevel@tonic-gate # ifndef YPERR_BUSY 26347c478bd9Sstevel@tonic-gate # define YPERR_BUSY 16 26357c478bd9Sstevel@tonic-gate # endif /* ! YPERR_BUSY */ 26367c478bd9Sstevel@tonic-gate 26377c478bd9Sstevel@tonic-gate /* 26387c478bd9Sstevel@tonic-gate ** NIS_MAP_OPEN -- open DBM map 26397c478bd9Sstevel@tonic-gate */ 26407c478bd9Sstevel@tonic-gate 26417c478bd9Sstevel@tonic-gate bool 26427c478bd9Sstevel@tonic-gate nis_map_open(map, mode) 26437c478bd9Sstevel@tonic-gate MAP *map; 26447c478bd9Sstevel@tonic-gate int mode; 26457c478bd9Sstevel@tonic-gate { 26467c478bd9Sstevel@tonic-gate int yperr; 26477c478bd9Sstevel@tonic-gate register char *p; 26487c478bd9Sstevel@tonic-gate auto char *vp; 26497c478bd9Sstevel@tonic-gate auto int vsize; 26507c478bd9Sstevel@tonic-gate 26517c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 26527c478bd9Sstevel@tonic-gate sm_dprintf("nis_map_open(%s, %s, %d)\n", 26537c478bd9Sstevel@tonic-gate map->map_mname, map->map_file, mode); 26547c478bd9Sstevel@tonic-gate 26557c478bd9Sstevel@tonic-gate mode &= O_ACCMODE; 26567c478bd9Sstevel@tonic-gate if (mode != O_RDONLY) 26577c478bd9Sstevel@tonic-gate { 26587c478bd9Sstevel@tonic-gate /* issue a pseudo-error message */ 26597c478bd9Sstevel@tonic-gate errno = SM_EMAPCANTWRITE; 26607c478bd9Sstevel@tonic-gate return false; 26617c478bd9Sstevel@tonic-gate } 26627c478bd9Sstevel@tonic-gate 26637c478bd9Sstevel@tonic-gate p = strchr(map->map_file, '@'); 26647c478bd9Sstevel@tonic-gate if (p != NULL) 26657c478bd9Sstevel@tonic-gate { 26667c478bd9Sstevel@tonic-gate *p++ = '\0'; 26677c478bd9Sstevel@tonic-gate if (*p != '\0') 26687c478bd9Sstevel@tonic-gate map->map_domain = p; 26697c478bd9Sstevel@tonic-gate } 26707c478bd9Sstevel@tonic-gate 26717c478bd9Sstevel@tonic-gate if (*map->map_file == '\0') 26727c478bd9Sstevel@tonic-gate map->map_file = "mail.aliases"; 26737c478bd9Sstevel@tonic-gate 26747c478bd9Sstevel@tonic-gate if (map->map_domain == NULL) 26757c478bd9Sstevel@tonic-gate { 26767c478bd9Sstevel@tonic-gate yperr = yp_get_default_domain(&map->map_domain); 26777c478bd9Sstevel@tonic-gate if (yperr != 0) 26787c478bd9Sstevel@tonic-gate { 26797c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 26807c478bd9Sstevel@tonic-gate syserr("451 4.3.5 NIS map %s specified, but NIS not running", 26817c478bd9Sstevel@tonic-gate map->map_file); 26827c478bd9Sstevel@tonic-gate return false; 26837c478bd9Sstevel@tonic-gate } 26847c478bd9Sstevel@tonic-gate } 26857c478bd9Sstevel@tonic-gate 26867c478bd9Sstevel@tonic-gate /* check to see if this map actually exists */ 26877c478bd9Sstevel@tonic-gate vp = NULL; 26887c478bd9Sstevel@tonic-gate yperr = yp_match(map->map_domain, map->map_file, "@", 1, 26897c478bd9Sstevel@tonic-gate &vp, &vsize); 26907c478bd9Sstevel@tonic-gate if (tTd(38, 10)) 26917c478bd9Sstevel@tonic-gate sm_dprintf("nis_map_open: yp_match(@, %s, %s) => %s\n", 26927c478bd9Sstevel@tonic-gate map->map_domain, map->map_file, yperr_string(yperr)); 26937c478bd9Sstevel@tonic-gate if (vp != NULL) 26947c478bd9Sstevel@tonic-gate sm_free(vp); 26957c478bd9Sstevel@tonic-gate 26967c478bd9Sstevel@tonic-gate if (yperr == 0 || yperr == YPERR_KEY || yperr == YPERR_BUSY) 26977c478bd9Sstevel@tonic-gate { 26987c478bd9Sstevel@tonic-gate /* 26997c478bd9Sstevel@tonic-gate ** We ought to be calling aliaswait() here if this is an 27007c478bd9Sstevel@tonic-gate ** alias file, but powerful HP-UX NIS servers apparently 27017c478bd9Sstevel@tonic-gate ** don't insert the @:@ token into the alias map when it 27027c478bd9Sstevel@tonic-gate ** is rebuilt, so aliaswait() just hangs. I hate HP-UX. 27037c478bd9Sstevel@tonic-gate */ 27047c478bd9Sstevel@tonic-gate 27057c478bd9Sstevel@tonic-gate # if 0 27067c478bd9Sstevel@tonic-gate if (!bitset(MF_ALIAS, map->map_mflags) || 27077c478bd9Sstevel@tonic-gate aliaswait(map, NULL, true)) 27087c478bd9Sstevel@tonic-gate # endif /* 0 */ 27097c478bd9Sstevel@tonic-gate return true; 27107c478bd9Sstevel@tonic-gate } 27117c478bd9Sstevel@tonic-gate 27127c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 27137c478bd9Sstevel@tonic-gate { 27147c478bd9Sstevel@tonic-gate syserr("451 4.3.5 Cannot bind to map %s in domain %s: %s", 27157c478bd9Sstevel@tonic-gate map->map_file, map->map_domain, yperr_string(yperr)); 27167c478bd9Sstevel@tonic-gate } 27177c478bd9Sstevel@tonic-gate 27187c478bd9Sstevel@tonic-gate return false; 27197c478bd9Sstevel@tonic-gate } 27207c478bd9Sstevel@tonic-gate 27217c478bd9Sstevel@tonic-gate 27227c478bd9Sstevel@tonic-gate /* 27237c478bd9Sstevel@tonic-gate ** NIS_MAP_LOOKUP -- look up a datum in a NIS map 27247c478bd9Sstevel@tonic-gate */ 27257c478bd9Sstevel@tonic-gate 27267c478bd9Sstevel@tonic-gate /* ARGSUSED3 */ 27277c478bd9Sstevel@tonic-gate char * 27287c478bd9Sstevel@tonic-gate nis_map_lookup(map, name, av, statp) 27297c478bd9Sstevel@tonic-gate MAP *map; 27307c478bd9Sstevel@tonic-gate char *name; 27317c478bd9Sstevel@tonic-gate char **av; 27327c478bd9Sstevel@tonic-gate int *statp; 27337c478bd9Sstevel@tonic-gate { 27347c478bd9Sstevel@tonic-gate char *vp; 27357c478bd9Sstevel@tonic-gate auto int vsize; 27367c478bd9Sstevel@tonic-gate int buflen; 27377c478bd9Sstevel@tonic-gate int yperr; 27387c478bd9Sstevel@tonic-gate char keybuf[MAXNAME + 1]; 27397c478bd9Sstevel@tonic-gate char *SM_NONVOLATILE result = NULL; 27407c478bd9Sstevel@tonic-gate 27417c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 27427c478bd9Sstevel@tonic-gate sm_dprintf("nis_map_lookup(%s, %s)\n", 27437c478bd9Sstevel@tonic-gate map->map_mname, name); 27447c478bd9Sstevel@tonic-gate 27457c478bd9Sstevel@tonic-gate buflen = strlen(name); 2746058561cbSjbeck if (buflen > sizeof(keybuf) - 1) 2747058561cbSjbeck buflen = sizeof(keybuf) - 1; 27487c478bd9Sstevel@tonic-gate memmove(keybuf, name, buflen); 27497c478bd9Sstevel@tonic-gate keybuf[buflen] = '\0'; 27507c478bd9Sstevel@tonic-gate if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 27517c478bd9Sstevel@tonic-gate makelower(keybuf); 27527c478bd9Sstevel@tonic-gate yperr = YPERR_KEY; 27537c478bd9Sstevel@tonic-gate vp = NULL; 27547c478bd9Sstevel@tonic-gate if (bitset(MF_TRY0NULL, map->map_mflags)) 27557c478bd9Sstevel@tonic-gate { 27567c478bd9Sstevel@tonic-gate yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen, 27577c478bd9Sstevel@tonic-gate &vp, &vsize); 27587c478bd9Sstevel@tonic-gate if (yperr == 0) 27597c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_TRY1NULL; 27607c478bd9Sstevel@tonic-gate } 27617c478bd9Sstevel@tonic-gate if (yperr == YPERR_KEY && bitset(MF_TRY1NULL, map->map_mflags)) 27627c478bd9Sstevel@tonic-gate { 27637c478bd9Sstevel@tonic-gate SM_FREE_CLR(vp); 27647c478bd9Sstevel@tonic-gate buflen++; 27657c478bd9Sstevel@tonic-gate yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen, 27667c478bd9Sstevel@tonic-gate &vp, &vsize); 27677c478bd9Sstevel@tonic-gate if (yperr == 0) 27687c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_TRY0NULL; 27697c478bd9Sstevel@tonic-gate } 27707c478bd9Sstevel@tonic-gate if (yperr != 0) 27717c478bd9Sstevel@tonic-gate { 27727c478bd9Sstevel@tonic-gate if (yperr != YPERR_KEY && yperr != YPERR_BUSY) 27737c478bd9Sstevel@tonic-gate map->map_mflags &= ~(MF_VALID|MF_OPEN); 27747c478bd9Sstevel@tonic-gate if (vp != NULL) 27757c478bd9Sstevel@tonic-gate sm_free(vp); 27767c478bd9Sstevel@tonic-gate return NULL; 27777c478bd9Sstevel@tonic-gate } 27787c478bd9Sstevel@tonic-gate SM_TRY 27797c478bd9Sstevel@tonic-gate if (bitset(MF_MATCHONLY, map->map_mflags)) 27807c478bd9Sstevel@tonic-gate result = map_rewrite(map, name, strlen(name), NULL); 27817c478bd9Sstevel@tonic-gate else 27827c478bd9Sstevel@tonic-gate result = map_rewrite(map, vp, vsize, av); 27837c478bd9Sstevel@tonic-gate SM_FINALLY 27847c478bd9Sstevel@tonic-gate if (vp != NULL) 27857c478bd9Sstevel@tonic-gate sm_free(vp); 27867c478bd9Sstevel@tonic-gate SM_END_TRY 27877c478bd9Sstevel@tonic-gate return result; 27887c478bd9Sstevel@tonic-gate } 27897c478bd9Sstevel@tonic-gate 27907c478bd9Sstevel@tonic-gate 27917c478bd9Sstevel@tonic-gate /* 27927c478bd9Sstevel@tonic-gate ** NIS_GETCANONNAME -- look up canonical name in NIS 27937c478bd9Sstevel@tonic-gate */ 27947c478bd9Sstevel@tonic-gate 27957c478bd9Sstevel@tonic-gate static bool 27967c478bd9Sstevel@tonic-gate nis_getcanonname(name, hbsize, statp) 27977c478bd9Sstevel@tonic-gate char *name; 27987c478bd9Sstevel@tonic-gate int hbsize; 27997c478bd9Sstevel@tonic-gate int *statp; 28007c478bd9Sstevel@tonic-gate { 28017c478bd9Sstevel@tonic-gate char *vp; 28027c478bd9Sstevel@tonic-gate auto int vsize; 28037c478bd9Sstevel@tonic-gate int keylen; 28047c478bd9Sstevel@tonic-gate int yperr; 28057c478bd9Sstevel@tonic-gate static bool try0null = true; 28067c478bd9Sstevel@tonic-gate static bool try1null = true; 28077c478bd9Sstevel@tonic-gate static char *yp_domain = NULL; 28087c478bd9Sstevel@tonic-gate char host_record[MAXLINE]; 28097c478bd9Sstevel@tonic-gate char cbuf[MAXNAME]; 28107c478bd9Sstevel@tonic-gate char nbuf[MAXNAME + 1]; 28117c478bd9Sstevel@tonic-gate 28127c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 28137c478bd9Sstevel@tonic-gate sm_dprintf("nis_getcanonname(%s)\n", name); 28147c478bd9Sstevel@tonic-gate 2815058561cbSjbeck if (sm_strlcpy(nbuf, name, sizeof(nbuf)) >= sizeof(nbuf)) 28167c478bd9Sstevel@tonic-gate { 28177c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 28187c478bd9Sstevel@tonic-gate return false; 28197c478bd9Sstevel@tonic-gate } 28207c478bd9Sstevel@tonic-gate (void) shorten_hostname(nbuf); 28217c478bd9Sstevel@tonic-gate keylen = strlen(nbuf); 28227c478bd9Sstevel@tonic-gate 28237c478bd9Sstevel@tonic-gate if (yp_domain == NULL) 28247c478bd9Sstevel@tonic-gate (void) yp_get_default_domain(&yp_domain); 28257c478bd9Sstevel@tonic-gate makelower(nbuf); 28267c478bd9Sstevel@tonic-gate yperr = YPERR_KEY; 28277c478bd9Sstevel@tonic-gate vp = NULL; 28287c478bd9Sstevel@tonic-gate if (try0null) 28297c478bd9Sstevel@tonic-gate { 28307c478bd9Sstevel@tonic-gate yperr = yp_match(yp_domain, "hosts.byname", nbuf, keylen, 28317c478bd9Sstevel@tonic-gate &vp, &vsize); 28327c478bd9Sstevel@tonic-gate if (yperr == 0) 28337c478bd9Sstevel@tonic-gate try1null = false; 28347c478bd9Sstevel@tonic-gate } 28357c478bd9Sstevel@tonic-gate if (yperr == YPERR_KEY && try1null) 28367c478bd9Sstevel@tonic-gate { 28377c478bd9Sstevel@tonic-gate SM_FREE_CLR(vp); 28387c478bd9Sstevel@tonic-gate keylen++; 28397c478bd9Sstevel@tonic-gate yperr = yp_match(yp_domain, "hosts.byname", nbuf, keylen, 28407c478bd9Sstevel@tonic-gate &vp, &vsize); 28417c478bd9Sstevel@tonic-gate if (yperr == 0) 28427c478bd9Sstevel@tonic-gate try0null = false; 28437c478bd9Sstevel@tonic-gate } 28447c478bd9Sstevel@tonic-gate if (yperr != 0) 28457c478bd9Sstevel@tonic-gate { 28467c478bd9Sstevel@tonic-gate if (yperr == YPERR_KEY) 28477c478bd9Sstevel@tonic-gate *statp = EX_NOHOST; 28487c478bd9Sstevel@tonic-gate else if (yperr == YPERR_BUSY) 28497c478bd9Sstevel@tonic-gate *statp = EX_TEMPFAIL; 28507c478bd9Sstevel@tonic-gate else 28517c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 28527c478bd9Sstevel@tonic-gate if (vp != NULL) 28537c478bd9Sstevel@tonic-gate sm_free(vp); 28547c478bd9Sstevel@tonic-gate return false; 28557c478bd9Sstevel@tonic-gate } 2856058561cbSjbeck (void) sm_strlcpy(host_record, vp, sizeof(host_record)); 28577c478bd9Sstevel@tonic-gate sm_free(vp); 28587c478bd9Sstevel@tonic-gate if (tTd(38, 44)) 28597c478bd9Sstevel@tonic-gate sm_dprintf("got record `%s'\n", host_record); 28607c478bd9Sstevel@tonic-gate vp = strpbrk(host_record, "#\n"); 28617c478bd9Sstevel@tonic-gate if (vp != NULL) 28627c478bd9Sstevel@tonic-gate *vp = '\0'; 2863058561cbSjbeck if (!extract_canonname(nbuf, NULL, host_record, cbuf, sizeof(cbuf))) 28647c478bd9Sstevel@tonic-gate { 28657c478bd9Sstevel@tonic-gate /* this should not happen, but.... */ 28667c478bd9Sstevel@tonic-gate *statp = EX_NOHOST; 28677c478bd9Sstevel@tonic-gate return false; 28687c478bd9Sstevel@tonic-gate } 28697c478bd9Sstevel@tonic-gate if (sm_strlcpy(name, cbuf, hbsize) >= hbsize) 28707c478bd9Sstevel@tonic-gate { 28717c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 28727c478bd9Sstevel@tonic-gate return false; 28737c478bd9Sstevel@tonic-gate } 28747c478bd9Sstevel@tonic-gate *statp = EX_OK; 28757c478bd9Sstevel@tonic-gate return true; 28767c478bd9Sstevel@tonic-gate } 28777c478bd9Sstevel@tonic-gate 28787c478bd9Sstevel@tonic-gate #endif /* NIS */ 28797c478bd9Sstevel@tonic-gate /* 28807c478bd9Sstevel@tonic-gate ** NISPLUS Modules 28817c478bd9Sstevel@tonic-gate ** 28827c478bd9Sstevel@tonic-gate ** This code donated by Sun Microsystems. 28837c478bd9Sstevel@tonic-gate */ 28847c478bd9Sstevel@tonic-gate 28857c478bd9Sstevel@tonic-gate #if NISPLUS 28867c478bd9Sstevel@tonic-gate 28877c478bd9Sstevel@tonic-gate # undef NIS /* symbol conflict in nis.h */ 28887c478bd9Sstevel@tonic-gate # undef T_UNSPEC /* symbol conflict in nis.h -> ... -> sys/tiuser.h */ 28897c478bd9Sstevel@tonic-gate # include <rpcsvc/nis.h> 28907c478bd9Sstevel@tonic-gate # include <rpcsvc/nislib.h> 28917c478bd9Sstevel@tonic-gate 28927c478bd9Sstevel@tonic-gate # define EN_col(col) zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val 28937c478bd9Sstevel@tonic-gate # define COL_NAME(res,i) ((res->objects.objects_val)->TA_data.ta_cols.ta_cols_val)[i].tc_name 28947c478bd9Sstevel@tonic-gate # define COL_MAX(res) ((res->objects.objects_val)->TA_data.ta_cols.ta_cols_len) 28957c478bd9Sstevel@tonic-gate # define PARTIAL_NAME(x) ((x)[strlen(x) - 1] != '.') 28967c478bd9Sstevel@tonic-gate 28977c478bd9Sstevel@tonic-gate /* 28987c478bd9Sstevel@tonic-gate ** NISPLUS_MAP_OPEN -- open nisplus table 28997c478bd9Sstevel@tonic-gate */ 29007c478bd9Sstevel@tonic-gate 29017c478bd9Sstevel@tonic-gate bool 29027c478bd9Sstevel@tonic-gate nisplus_map_open(map, mode) 29037c478bd9Sstevel@tonic-gate MAP *map; 29047c478bd9Sstevel@tonic-gate int mode; 29057c478bd9Sstevel@tonic-gate { 29067c478bd9Sstevel@tonic-gate nis_result *res = NULL; 29077c478bd9Sstevel@tonic-gate int retry_cnt, max_col, i; 29087c478bd9Sstevel@tonic-gate char qbuf[MAXLINE + NIS_MAXNAMELEN]; 29097c478bd9Sstevel@tonic-gate 29107c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 29117c478bd9Sstevel@tonic-gate sm_dprintf("nisplus_map_open(%s, %s, %d)\n", 29127c478bd9Sstevel@tonic-gate map->map_mname, map->map_file, mode); 29137c478bd9Sstevel@tonic-gate 29147c478bd9Sstevel@tonic-gate mode &= O_ACCMODE; 29157c478bd9Sstevel@tonic-gate if (mode != O_RDONLY) 29167c478bd9Sstevel@tonic-gate { 29177c478bd9Sstevel@tonic-gate errno = EPERM; 29187c478bd9Sstevel@tonic-gate return false; 29197c478bd9Sstevel@tonic-gate } 29207c478bd9Sstevel@tonic-gate 29217c478bd9Sstevel@tonic-gate if (*map->map_file == '\0') 29227c478bd9Sstevel@tonic-gate map->map_file = "mail_aliases.org_dir"; 29237c478bd9Sstevel@tonic-gate 29247c478bd9Sstevel@tonic-gate if (PARTIAL_NAME(map->map_file) && map->map_domain == NULL) 29257c478bd9Sstevel@tonic-gate { 29267c478bd9Sstevel@tonic-gate /* set default NISPLUS Domain to $m */ 29277c478bd9Sstevel@tonic-gate map->map_domain = newstr(nisplus_default_domain()); 29287c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 29297c478bd9Sstevel@tonic-gate sm_dprintf("nisplus_map_open(%s): using domain %s\n", 29307c478bd9Sstevel@tonic-gate map->map_file, map->map_domain); 29317c478bd9Sstevel@tonic-gate } 29327c478bd9Sstevel@tonic-gate if (!PARTIAL_NAME(map->map_file)) 29337c478bd9Sstevel@tonic-gate { 29347c478bd9Sstevel@tonic-gate map->map_domain = newstr(""); 2935058561cbSjbeck (void) sm_strlcpy(qbuf, map->map_file, sizeof(qbuf)); 29367c478bd9Sstevel@tonic-gate } 29377c478bd9Sstevel@tonic-gate else 29387c478bd9Sstevel@tonic-gate { 29397c478bd9Sstevel@tonic-gate /* check to see if this map actually exists */ 2940058561cbSjbeck (void) sm_strlcpyn(qbuf, sizeof(qbuf), 3, 29417c478bd9Sstevel@tonic-gate map->map_file, ".", map->map_domain); 29427c478bd9Sstevel@tonic-gate } 29437c478bd9Sstevel@tonic-gate 29447c478bd9Sstevel@tonic-gate retry_cnt = 0; 29457c478bd9Sstevel@tonic-gate while (res == NULL || res->status != NIS_SUCCESS) 29467c478bd9Sstevel@tonic-gate { 29477c478bd9Sstevel@tonic-gate res = nis_lookup(qbuf, FOLLOW_LINKS); 29487c478bd9Sstevel@tonic-gate switch (res->status) 29497c478bd9Sstevel@tonic-gate { 29507c478bd9Sstevel@tonic-gate case NIS_SUCCESS: 29517c478bd9Sstevel@tonic-gate break; 29527c478bd9Sstevel@tonic-gate 29537c478bd9Sstevel@tonic-gate case NIS_TRYAGAIN: 29547c478bd9Sstevel@tonic-gate case NIS_RPCERROR: 29557c478bd9Sstevel@tonic-gate case NIS_NAMEUNREACHABLE: 29567c478bd9Sstevel@tonic-gate if (retry_cnt++ > 4) 29577c478bd9Sstevel@tonic-gate { 29587c478bd9Sstevel@tonic-gate errno = EAGAIN; 29597c478bd9Sstevel@tonic-gate return false; 29607c478bd9Sstevel@tonic-gate } 29617c478bd9Sstevel@tonic-gate /* try not to overwhelm hosed server */ 29627c478bd9Sstevel@tonic-gate sleep(2); 29637c478bd9Sstevel@tonic-gate break; 29647c478bd9Sstevel@tonic-gate 29657c478bd9Sstevel@tonic-gate default: /* all other nisplus errors */ 29667c478bd9Sstevel@tonic-gate # if 0 29677c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 29687c478bd9Sstevel@tonic-gate syserr("451 4.3.5 Cannot find table %s.%s: %s", 29697c478bd9Sstevel@tonic-gate map->map_file, map->map_domain, 29707c478bd9Sstevel@tonic-gate nis_sperrno(res->status)); 29717c478bd9Sstevel@tonic-gate # endif /* 0 */ 29727c478bd9Sstevel@tonic-gate errno = EAGAIN; 29737c478bd9Sstevel@tonic-gate return false; 29747c478bd9Sstevel@tonic-gate } 29757c478bd9Sstevel@tonic-gate } 29767c478bd9Sstevel@tonic-gate 29777c478bd9Sstevel@tonic-gate if (NIS_RES_NUMOBJ(res) != 1 || 29787c478bd9Sstevel@tonic-gate (NIS_RES_OBJECT(res)->zo_data.zo_type != TABLE_OBJ)) 29797c478bd9Sstevel@tonic-gate { 29807c478bd9Sstevel@tonic-gate if (tTd(38, 10)) 29817c478bd9Sstevel@tonic-gate sm_dprintf("nisplus_map_open: %s is not a table\n", qbuf); 29827c478bd9Sstevel@tonic-gate # if 0 29837c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 29847c478bd9Sstevel@tonic-gate syserr("451 4.3.5 %s.%s: %s is not a table", 29857c478bd9Sstevel@tonic-gate map->map_file, map->map_domain, 29867c478bd9Sstevel@tonic-gate nis_sperrno(res->status)); 29877c478bd9Sstevel@tonic-gate # endif /* 0 */ 29887c478bd9Sstevel@tonic-gate errno = EBADF; 29897c478bd9Sstevel@tonic-gate return false; 29907c478bd9Sstevel@tonic-gate } 29917c478bd9Sstevel@tonic-gate /* default key column is column 0 */ 29927c478bd9Sstevel@tonic-gate if (map->map_keycolnm == NULL) 29937c478bd9Sstevel@tonic-gate map->map_keycolnm = newstr(COL_NAME(res,0)); 29947c478bd9Sstevel@tonic-gate 29957c478bd9Sstevel@tonic-gate max_col = COL_MAX(res); 29967c478bd9Sstevel@tonic-gate 29977c478bd9Sstevel@tonic-gate /* verify the key column exist */ 29987c478bd9Sstevel@tonic-gate for (i = 0; i < max_col; i++) 29997c478bd9Sstevel@tonic-gate { 30007c478bd9Sstevel@tonic-gate if (strcmp(map->map_keycolnm, COL_NAME(res,i)) == 0) 30017c478bd9Sstevel@tonic-gate break; 30027c478bd9Sstevel@tonic-gate } 30037c478bd9Sstevel@tonic-gate if (i == max_col) 30047c478bd9Sstevel@tonic-gate { 30057c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 30067c478bd9Sstevel@tonic-gate sm_dprintf("nisplus_map_open(%s): can not find key column %s\n", 30077c478bd9Sstevel@tonic-gate map->map_file, map->map_keycolnm); 30087c478bd9Sstevel@tonic-gate errno = ENOENT; 30097c478bd9Sstevel@tonic-gate return false; 30107c478bd9Sstevel@tonic-gate } 30117c478bd9Sstevel@tonic-gate 30127c478bd9Sstevel@tonic-gate /* default value column is the last column */ 30137c478bd9Sstevel@tonic-gate if (map->map_valcolnm == NULL) 30147c478bd9Sstevel@tonic-gate { 30157c478bd9Sstevel@tonic-gate map->map_valcolno = max_col - 1; 30167c478bd9Sstevel@tonic-gate return true; 30177c478bd9Sstevel@tonic-gate } 30187c478bd9Sstevel@tonic-gate 30197c478bd9Sstevel@tonic-gate for (i = 0; i< max_col; i++) 30207c478bd9Sstevel@tonic-gate { 30217c478bd9Sstevel@tonic-gate if (strcmp(map->map_valcolnm, COL_NAME(res,i)) == 0) 30227c478bd9Sstevel@tonic-gate { 30237c478bd9Sstevel@tonic-gate map->map_valcolno = i; 30247c478bd9Sstevel@tonic-gate return true; 30257c478bd9Sstevel@tonic-gate } 30267c478bd9Sstevel@tonic-gate } 30277c478bd9Sstevel@tonic-gate 30287c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 30297c478bd9Sstevel@tonic-gate sm_dprintf("nisplus_map_open(%s): can not find column %s\n", 30307c478bd9Sstevel@tonic-gate map->map_file, map->map_keycolnm); 30317c478bd9Sstevel@tonic-gate errno = ENOENT; 30327c478bd9Sstevel@tonic-gate return false; 30337c478bd9Sstevel@tonic-gate } 30347c478bd9Sstevel@tonic-gate 30357c478bd9Sstevel@tonic-gate 30367c478bd9Sstevel@tonic-gate /* 30377c478bd9Sstevel@tonic-gate ** NISPLUS_MAP_LOOKUP -- look up a datum in a NISPLUS table 30387c478bd9Sstevel@tonic-gate */ 30397c478bd9Sstevel@tonic-gate 30407c478bd9Sstevel@tonic-gate char * 30417c478bd9Sstevel@tonic-gate nisplus_map_lookup(map, name, av, statp) 30427c478bd9Sstevel@tonic-gate MAP *map; 30437c478bd9Sstevel@tonic-gate char *name; 30447c478bd9Sstevel@tonic-gate char **av; 30457c478bd9Sstevel@tonic-gate int *statp; 30467c478bd9Sstevel@tonic-gate { 30477c478bd9Sstevel@tonic-gate char *p; 30487c478bd9Sstevel@tonic-gate auto int vsize; 30497c478bd9Sstevel@tonic-gate char *skp; 30507c478bd9Sstevel@tonic-gate int skleft; 30517c478bd9Sstevel@tonic-gate char search_key[MAXNAME + 4]; 30527c478bd9Sstevel@tonic-gate char qbuf[MAXLINE + NIS_MAXNAMELEN]; 30537c478bd9Sstevel@tonic-gate nis_result *result; 30547c478bd9Sstevel@tonic-gate 30557c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 30567c478bd9Sstevel@tonic-gate sm_dprintf("nisplus_map_lookup(%s, %s)\n", 30577c478bd9Sstevel@tonic-gate map->map_mname, name); 30587c478bd9Sstevel@tonic-gate 30597c478bd9Sstevel@tonic-gate if (!bitset(MF_OPEN, map->map_mflags)) 30607c478bd9Sstevel@tonic-gate { 30617c478bd9Sstevel@tonic-gate if (nisplus_map_open(map, O_RDONLY)) 30627c478bd9Sstevel@tonic-gate { 30637c478bd9Sstevel@tonic-gate map->map_mflags |= MF_OPEN; 30647c478bd9Sstevel@tonic-gate map->map_pid = CurrentPid; 30657c478bd9Sstevel@tonic-gate } 30667c478bd9Sstevel@tonic-gate else 30677c478bd9Sstevel@tonic-gate { 30687c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 30697c478bd9Sstevel@tonic-gate return NULL; 30707c478bd9Sstevel@tonic-gate } 30717c478bd9Sstevel@tonic-gate } 30727c478bd9Sstevel@tonic-gate 30737c478bd9Sstevel@tonic-gate /* 30747c478bd9Sstevel@tonic-gate ** Copy the name to the key buffer, escaping double quote characters 30757c478bd9Sstevel@tonic-gate ** by doubling them and quoting "]" and "," to avoid having the 30767c478bd9Sstevel@tonic-gate ** NIS+ parser choke on them. 30777c478bd9Sstevel@tonic-gate */ 30787c478bd9Sstevel@tonic-gate 3079058561cbSjbeck skleft = sizeof(search_key) - 4; 30807c478bd9Sstevel@tonic-gate skp = search_key; 30817c478bd9Sstevel@tonic-gate for (p = name; *p != '\0' && skleft > 0; p++) 30827c478bd9Sstevel@tonic-gate { 30837c478bd9Sstevel@tonic-gate switch (*p) 30847c478bd9Sstevel@tonic-gate { 30857c478bd9Sstevel@tonic-gate case ']': 30867c478bd9Sstevel@tonic-gate case ',': 30877c478bd9Sstevel@tonic-gate /* quote the character */ 30887c478bd9Sstevel@tonic-gate *skp++ = '"'; 30897c478bd9Sstevel@tonic-gate *skp++ = *p; 30907c478bd9Sstevel@tonic-gate *skp++ = '"'; 30917c478bd9Sstevel@tonic-gate skleft -= 3; 30927c478bd9Sstevel@tonic-gate break; 30937c478bd9Sstevel@tonic-gate 30947c478bd9Sstevel@tonic-gate case '"': 30957c478bd9Sstevel@tonic-gate /* double the quote */ 30967c478bd9Sstevel@tonic-gate *skp++ = '"'; 30977c478bd9Sstevel@tonic-gate skleft--; 30987c478bd9Sstevel@tonic-gate /* FALLTHROUGH */ 30997c478bd9Sstevel@tonic-gate 31007c478bd9Sstevel@tonic-gate default: 31017c478bd9Sstevel@tonic-gate *skp++ = *p; 31027c478bd9Sstevel@tonic-gate skleft--; 31037c478bd9Sstevel@tonic-gate break; 31047c478bd9Sstevel@tonic-gate } 31057c478bd9Sstevel@tonic-gate } 31067c478bd9Sstevel@tonic-gate *skp = '\0'; 31077c478bd9Sstevel@tonic-gate if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 31087c478bd9Sstevel@tonic-gate makelower(search_key); 31097c478bd9Sstevel@tonic-gate 31107c478bd9Sstevel@tonic-gate /* construct the query */ 31117c478bd9Sstevel@tonic-gate if (PARTIAL_NAME(map->map_file)) 3112058561cbSjbeck (void) sm_snprintf(qbuf, sizeof(qbuf), "[%s=%s],%s.%s", 31137c478bd9Sstevel@tonic-gate map->map_keycolnm, search_key, map->map_file, 31147c478bd9Sstevel@tonic-gate map->map_domain); 31157c478bd9Sstevel@tonic-gate else 3116058561cbSjbeck (void) sm_snprintf(qbuf, sizeof(qbuf), "[%s=%s],%s", 31177c478bd9Sstevel@tonic-gate map->map_keycolnm, search_key, map->map_file); 31187c478bd9Sstevel@tonic-gate 31197c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 31207c478bd9Sstevel@tonic-gate sm_dprintf("qbuf=%s\n", qbuf); 31217c478bd9Sstevel@tonic-gate result = nis_list(qbuf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL); 31227c478bd9Sstevel@tonic-gate if (result->status == NIS_SUCCESS) 31237c478bd9Sstevel@tonic-gate { 31247c478bd9Sstevel@tonic-gate int count; 31257c478bd9Sstevel@tonic-gate char *str; 31267c478bd9Sstevel@tonic-gate 31277c478bd9Sstevel@tonic-gate if ((count = NIS_RES_NUMOBJ(result)) != 1) 31287c478bd9Sstevel@tonic-gate { 31297c478bd9Sstevel@tonic-gate if (LogLevel > 10) 31307c478bd9Sstevel@tonic-gate sm_syslog(LOG_WARNING, CurEnv->e_id, 31317c478bd9Sstevel@tonic-gate "%s: lookup error, expected 1 entry, got %d", 31327c478bd9Sstevel@tonic-gate map->map_file, count); 31337c478bd9Sstevel@tonic-gate 31347c478bd9Sstevel@tonic-gate /* ignore second entry */ 31357c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 31367c478bd9Sstevel@tonic-gate sm_dprintf("nisplus_map_lookup(%s), got %d entries, additional entries ignored\n", 31377c478bd9Sstevel@tonic-gate name, count); 31387c478bd9Sstevel@tonic-gate } 31397c478bd9Sstevel@tonic-gate 31407c478bd9Sstevel@tonic-gate p = ((NIS_RES_OBJECT(result))->EN_col(map->map_valcolno)); 31417c478bd9Sstevel@tonic-gate /* set the length of the result */ 31427c478bd9Sstevel@tonic-gate if (p == NULL) 31437c478bd9Sstevel@tonic-gate p = ""; 31447c478bd9Sstevel@tonic-gate vsize = strlen(p); 31457c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 31467c478bd9Sstevel@tonic-gate sm_dprintf("nisplus_map_lookup(%s), found %s\n", 31477c478bd9Sstevel@tonic-gate name, p); 31487c478bd9Sstevel@tonic-gate if (bitset(MF_MATCHONLY, map->map_mflags)) 31497c478bd9Sstevel@tonic-gate str = map_rewrite(map, name, strlen(name), NULL); 31507c478bd9Sstevel@tonic-gate else 31517c478bd9Sstevel@tonic-gate str = map_rewrite(map, p, vsize, av); 31527c478bd9Sstevel@tonic-gate nis_freeresult(result); 31537c478bd9Sstevel@tonic-gate *statp = EX_OK; 31547c478bd9Sstevel@tonic-gate return str; 31557c478bd9Sstevel@tonic-gate } 31567c478bd9Sstevel@tonic-gate else 31577c478bd9Sstevel@tonic-gate { 31587c478bd9Sstevel@tonic-gate if (result->status == NIS_NOTFOUND) 31597c478bd9Sstevel@tonic-gate *statp = EX_NOTFOUND; 31607c478bd9Sstevel@tonic-gate else if (result->status == NIS_TRYAGAIN) 31617c478bd9Sstevel@tonic-gate *statp = EX_TEMPFAIL; 31627c478bd9Sstevel@tonic-gate else 31637c478bd9Sstevel@tonic-gate { 31647c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 31657c478bd9Sstevel@tonic-gate map->map_mflags &= ~(MF_VALID|MF_OPEN); 31667c478bd9Sstevel@tonic-gate } 31677c478bd9Sstevel@tonic-gate } 31687c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 31697c478bd9Sstevel@tonic-gate sm_dprintf("nisplus_map_lookup(%s), failed\n", name); 31707c478bd9Sstevel@tonic-gate nis_freeresult(result); 31717c478bd9Sstevel@tonic-gate return NULL; 31727c478bd9Sstevel@tonic-gate } 31737c478bd9Sstevel@tonic-gate 31747c478bd9Sstevel@tonic-gate 31757c478bd9Sstevel@tonic-gate 31767c478bd9Sstevel@tonic-gate /* 31777c478bd9Sstevel@tonic-gate ** NISPLUS_GETCANONNAME -- look up canonical name in NIS+ 31787c478bd9Sstevel@tonic-gate */ 31797c478bd9Sstevel@tonic-gate 31807c478bd9Sstevel@tonic-gate static bool 31817c478bd9Sstevel@tonic-gate nisplus_getcanonname(name, hbsize, statp) 31827c478bd9Sstevel@tonic-gate char *name; 31837c478bd9Sstevel@tonic-gate int hbsize; 31847c478bd9Sstevel@tonic-gate int *statp; 31857c478bd9Sstevel@tonic-gate { 31867c478bd9Sstevel@tonic-gate char *vp; 31877c478bd9Sstevel@tonic-gate auto int vsize; 31887c478bd9Sstevel@tonic-gate nis_result *result; 31897c478bd9Sstevel@tonic-gate char *p; 31907c478bd9Sstevel@tonic-gate char nbuf[MAXNAME + 1]; 31917c478bd9Sstevel@tonic-gate char qbuf[MAXLINE + NIS_MAXNAMELEN]; 31927c478bd9Sstevel@tonic-gate 3193058561cbSjbeck if (sm_strlcpy(nbuf, name, sizeof(nbuf)) >= sizeof(nbuf)) 31947c478bd9Sstevel@tonic-gate { 31957c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 31967c478bd9Sstevel@tonic-gate return false; 31977c478bd9Sstevel@tonic-gate } 31987c478bd9Sstevel@tonic-gate (void) shorten_hostname(nbuf); 31997c478bd9Sstevel@tonic-gate 32007c478bd9Sstevel@tonic-gate p = strchr(nbuf, '.'); 32017c478bd9Sstevel@tonic-gate if (p == NULL) 32027c478bd9Sstevel@tonic-gate { 32037c478bd9Sstevel@tonic-gate /* single token */ 3204058561cbSjbeck (void) sm_snprintf(qbuf, sizeof(qbuf), 32057c478bd9Sstevel@tonic-gate "[name=%s],hosts.org_dir", nbuf); 32067c478bd9Sstevel@tonic-gate } 32077c478bd9Sstevel@tonic-gate else if (p[1] != '\0') 32087c478bd9Sstevel@tonic-gate { 32097c478bd9Sstevel@tonic-gate /* multi token -- take only first token in nbuf */ 32107c478bd9Sstevel@tonic-gate *p = '\0'; 3211058561cbSjbeck (void) sm_snprintf(qbuf, sizeof(qbuf), 32127c478bd9Sstevel@tonic-gate "[name=%s],hosts.org_dir.%s", nbuf, &p[1]); 32137c478bd9Sstevel@tonic-gate } 32147c478bd9Sstevel@tonic-gate else 32157c478bd9Sstevel@tonic-gate { 32167c478bd9Sstevel@tonic-gate *statp = EX_NOHOST; 32177c478bd9Sstevel@tonic-gate return false; 32187c478bd9Sstevel@tonic-gate } 32197c478bd9Sstevel@tonic-gate 32207c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 32217c478bd9Sstevel@tonic-gate sm_dprintf("\nnisplus_getcanonname(%s), qbuf=%s\n", 32227c478bd9Sstevel@tonic-gate name, qbuf); 32237c478bd9Sstevel@tonic-gate 32247c478bd9Sstevel@tonic-gate result = nis_list(qbuf, EXPAND_NAME|FOLLOW_LINKS|FOLLOW_PATH, 32257c478bd9Sstevel@tonic-gate NULL, NULL); 32267c478bd9Sstevel@tonic-gate 32277c478bd9Sstevel@tonic-gate if (result->status == NIS_SUCCESS) 32287c478bd9Sstevel@tonic-gate { 32297c478bd9Sstevel@tonic-gate int count; 32307c478bd9Sstevel@tonic-gate char *domain; 32317c478bd9Sstevel@tonic-gate 32327c478bd9Sstevel@tonic-gate if ((count = NIS_RES_NUMOBJ(result)) != 1) 32337c478bd9Sstevel@tonic-gate { 32347c478bd9Sstevel@tonic-gate if (LogLevel > 10) 32357c478bd9Sstevel@tonic-gate sm_syslog(LOG_WARNING, CurEnv->e_id, 32367c478bd9Sstevel@tonic-gate "nisplus_getcanonname: lookup error, expected 1 entry, got %d", 32377c478bd9Sstevel@tonic-gate count); 32387c478bd9Sstevel@tonic-gate 32397c478bd9Sstevel@tonic-gate /* ignore second entry */ 32407c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 32417c478bd9Sstevel@tonic-gate sm_dprintf("nisplus_getcanonname(%s), got %d entries, all but first ignored\n", 32427c478bd9Sstevel@tonic-gate name, count); 32437c478bd9Sstevel@tonic-gate } 32447c478bd9Sstevel@tonic-gate 32457c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 32467c478bd9Sstevel@tonic-gate sm_dprintf("nisplus_getcanonname(%s), found in directory \"%s\"\n", 32477c478bd9Sstevel@tonic-gate name, (NIS_RES_OBJECT(result))->zo_domain); 32487c478bd9Sstevel@tonic-gate 32497c478bd9Sstevel@tonic-gate 32507c478bd9Sstevel@tonic-gate vp = ((NIS_RES_OBJECT(result))->EN_col(0)); 32517c478bd9Sstevel@tonic-gate vsize = strlen(vp); 32527c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 32537c478bd9Sstevel@tonic-gate sm_dprintf("nisplus_getcanonname(%s), found %s\n", 32547c478bd9Sstevel@tonic-gate name, vp); 32557c478bd9Sstevel@tonic-gate if (strchr(vp, '.') != NULL) 32567c478bd9Sstevel@tonic-gate { 32577c478bd9Sstevel@tonic-gate domain = ""; 32587c478bd9Sstevel@tonic-gate } 32597c478bd9Sstevel@tonic-gate else 32607c478bd9Sstevel@tonic-gate { 32617c478bd9Sstevel@tonic-gate domain = macvalue('m', CurEnv); 32627c478bd9Sstevel@tonic-gate if (domain == NULL) 32637c478bd9Sstevel@tonic-gate domain = ""; 32647c478bd9Sstevel@tonic-gate } 32657c478bd9Sstevel@tonic-gate if (hbsize > vsize + (int) strlen(domain) + 1) 32667c478bd9Sstevel@tonic-gate { 32677c478bd9Sstevel@tonic-gate if (domain[0] == '\0') 32687c478bd9Sstevel@tonic-gate (void) sm_strlcpy(name, vp, hbsize); 32697c478bd9Sstevel@tonic-gate else 32707c478bd9Sstevel@tonic-gate (void) sm_snprintf(name, hbsize, 32717c478bd9Sstevel@tonic-gate "%s.%s", vp, domain); 32727c478bd9Sstevel@tonic-gate *statp = EX_OK; 32737c478bd9Sstevel@tonic-gate } 32747c478bd9Sstevel@tonic-gate else 32757c478bd9Sstevel@tonic-gate *statp = EX_NOHOST; 32767c478bd9Sstevel@tonic-gate nis_freeresult(result); 32777c478bd9Sstevel@tonic-gate return true; 32787c478bd9Sstevel@tonic-gate } 32797c478bd9Sstevel@tonic-gate else 32807c478bd9Sstevel@tonic-gate { 32817c478bd9Sstevel@tonic-gate if (result->status == NIS_NOTFOUND) 32827c478bd9Sstevel@tonic-gate *statp = EX_NOHOST; 32837c478bd9Sstevel@tonic-gate else if (result->status == NIS_TRYAGAIN) 32847c478bd9Sstevel@tonic-gate *statp = EX_TEMPFAIL; 32857c478bd9Sstevel@tonic-gate else 32867c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 32877c478bd9Sstevel@tonic-gate } 32887c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 32897c478bd9Sstevel@tonic-gate sm_dprintf("nisplus_getcanonname(%s), failed, status=%d, nsw_stat=%d\n", 32907c478bd9Sstevel@tonic-gate name, result->status, *statp); 32917c478bd9Sstevel@tonic-gate nis_freeresult(result); 32927c478bd9Sstevel@tonic-gate return false; 32937c478bd9Sstevel@tonic-gate } 32947c478bd9Sstevel@tonic-gate 32957c478bd9Sstevel@tonic-gate char * 32967c478bd9Sstevel@tonic-gate nisplus_default_domain() 32977c478bd9Sstevel@tonic-gate { 32987c478bd9Sstevel@tonic-gate static char default_domain[MAXNAME + 1] = ""; 32997c478bd9Sstevel@tonic-gate char *p; 33007c478bd9Sstevel@tonic-gate 33017c478bd9Sstevel@tonic-gate if (default_domain[0] != '\0') 33027c478bd9Sstevel@tonic-gate return default_domain; 33037c478bd9Sstevel@tonic-gate 33047c478bd9Sstevel@tonic-gate p = nis_local_directory(); 3305058561cbSjbeck (void) sm_strlcpy(default_domain, p, sizeof(default_domain)); 33067c478bd9Sstevel@tonic-gate return default_domain; 33077c478bd9Sstevel@tonic-gate } 33087c478bd9Sstevel@tonic-gate 33097c478bd9Sstevel@tonic-gate #endif /* NISPLUS */ 33107c478bd9Sstevel@tonic-gate /* 33117c478bd9Sstevel@tonic-gate ** LDAP Modules 33127c478bd9Sstevel@tonic-gate */ 33137c478bd9Sstevel@tonic-gate 33147c478bd9Sstevel@tonic-gate /* 33157c478bd9Sstevel@tonic-gate ** LDAPMAP_DEQUOTE - helper routine for ldapmap_parseargs 33167c478bd9Sstevel@tonic-gate */ 33177c478bd9Sstevel@tonic-gate 33187c478bd9Sstevel@tonic-gate #if defined(LDAPMAP) || defined(PH_MAP) 33197c478bd9Sstevel@tonic-gate 33207c478bd9Sstevel@tonic-gate # if PH_MAP 33217c478bd9Sstevel@tonic-gate # define ph_map_dequote ldapmap_dequote 33227c478bd9Sstevel@tonic-gate # endif /* PH_MAP */ 33237c478bd9Sstevel@tonic-gate 33247c478bd9Sstevel@tonic-gate static char *ldapmap_dequote __P((char *)); 33257c478bd9Sstevel@tonic-gate 33267c478bd9Sstevel@tonic-gate static char * 33277c478bd9Sstevel@tonic-gate ldapmap_dequote(str) 33287c478bd9Sstevel@tonic-gate char *str; 33297c478bd9Sstevel@tonic-gate { 33307c478bd9Sstevel@tonic-gate char *p; 33317c478bd9Sstevel@tonic-gate char *start; 33327c478bd9Sstevel@tonic-gate 33337c478bd9Sstevel@tonic-gate if (str == NULL) 33347c478bd9Sstevel@tonic-gate return NULL; 33357c478bd9Sstevel@tonic-gate 33367c478bd9Sstevel@tonic-gate p = str; 33377c478bd9Sstevel@tonic-gate if (*p == '"') 33387c478bd9Sstevel@tonic-gate { 33397c478bd9Sstevel@tonic-gate /* Should probably swallow initial whitespace here */ 33407c478bd9Sstevel@tonic-gate start = ++p; 33417c478bd9Sstevel@tonic-gate } 33427c478bd9Sstevel@tonic-gate else 33437c478bd9Sstevel@tonic-gate return str; 33447c478bd9Sstevel@tonic-gate while (*p != '"' && *p != '\0') 33457c478bd9Sstevel@tonic-gate p++; 33467c478bd9Sstevel@tonic-gate if (*p != '\0') 33477c478bd9Sstevel@tonic-gate *p = '\0'; 33487c478bd9Sstevel@tonic-gate return start; 33497c478bd9Sstevel@tonic-gate } 33507c478bd9Sstevel@tonic-gate #endif /* defined(LDAPMAP) || defined(PH_MAP) */ 33517c478bd9Sstevel@tonic-gate 33527c478bd9Sstevel@tonic-gate #if LDAPMAP 33537c478bd9Sstevel@tonic-gate 33547c478bd9Sstevel@tonic-gate static SM_LDAP_STRUCT *LDAPDefaults = NULL; 33557c478bd9Sstevel@tonic-gate 33567c478bd9Sstevel@tonic-gate /* 33577c478bd9Sstevel@tonic-gate ** LDAPMAP_OPEN -- open LDAP map 33587c478bd9Sstevel@tonic-gate ** 33597c478bd9Sstevel@tonic-gate ** Connect to the LDAP server. Re-use existing connections since a 33607c478bd9Sstevel@tonic-gate ** single server connection to a host (with the same host, port, 33617c478bd9Sstevel@tonic-gate ** bind DN, and secret) can answer queries for multiple maps. 33627c478bd9Sstevel@tonic-gate */ 33637c478bd9Sstevel@tonic-gate 33647c478bd9Sstevel@tonic-gate bool 33657c478bd9Sstevel@tonic-gate ldapmap_open(map, mode) 33667c478bd9Sstevel@tonic-gate MAP *map; 33677c478bd9Sstevel@tonic-gate int mode; 33687c478bd9Sstevel@tonic-gate { 33697c478bd9Sstevel@tonic-gate SM_LDAP_STRUCT *lmap; 33707c478bd9Sstevel@tonic-gate STAB *s; 33717c478bd9Sstevel@tonic-gate char *id; 33727c478bd9Sstevel@tonic-gate 33737c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 33747c478bd9Sstevel@tonic-gate sm_dprintf("ldapmap_open(%s, %d): ", map->map_mname, mode); 33757c478bd9Sstevel@tonic-gate 33767c478bd9Sstevel@tonic-gate #if defined(SUN_EXTENSIONS) && defined(SUN_SIMPLIFIED_LDAP) && \ 3377d25d47eeSjbeck HASLDAPGETALIASBYNAME 33787c478bd9Sstevel@tonic-gate if (VendorCode == VENDOR_SUN && 33797c478bd9Sstevel@tonic-gate strcmp(map->map_mname, "aliases.ldap") == 0) 33807c478bd9Sstevel@tonic-gate { 33817c478bd9Sstevel@tonic-gate return true; 33827c478bd9Sstevel@tonic-gate } 3383d25d47eeSjbeck #endif /* defined(SUN_EXTENSIONS) && defined(SUN_SIMPLIFIED_LDAP) && ... */ 33847c478bd9Sstevel@tonic-gate 33857c478bd9Sstevel@tonic-gate mode &= O_ACCMODE; 33867c478bd9Sstevel@tonic-gate 33877c478bd9Sstevel@tonic-gate /* sendmail doesn't have the ability to write to LDAP (yet) */ 33887c478bd9Sstevel@tonic-gate if (mode != O_RDONLY) 33897c478bd9Sstevel@tonic-gate { 33907c478bd9Sstevel@tonic-gate /* issue a pseudo-error message */ 33917c478bd9Sstevel@tonic-gate errno = SM_EMAPCANTWRITE; 33927c478bd9Sstevel@tonic-gate return false; 33937c478bd9Sstevel@tonic-gate } 33947c478bd9Sstevel@tonic-gate 33957c478bd9Sstevel@tonic-gate lmap = (SM_LDAP_STRUCT *) map->map_db1; 33967c478bd9Sstevel@tonic-gate 33977c478bd9Sstevel@tonic-gate s = ldapmap_findconn(lmap); 33987c478bd9Sstevel@tonic-gate if (s->s_lmap != NULL) 33997c478bd9Sstevel@tonic-gate { 34007c478bd9Sstevel@tonic-gate /* Already have a connection open to this LDAP server */ 34017c478bd9Sstevel@tonic-gate lmap->ldap_ld = ((SM_LDAP_STRUCT *)s->s_lmap->map_db1)->ldap_ld; 34027c478bd9Sstevel@tonic-gate lmap->ldap_pid = ((SM_LDAP_STRUCT *)s->s_lmap->map_db1)->ldap_pid; 34037c478bd9Sstevel@tonic-gate 34047c478bd9Sstevel@tonic-gate /* Add this map as head of linked list */ 34057c478bd9Sstevel@tonic-gate lmap->ldap_next = s->s_lmap; 34067c478bd9Sstevel@tonic-gate s->s_lmap = map; 34077c478bd9Sstevel@tonic-gate 34087c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 34097c478bd9Sstevel@tonic-gate sm_dprintf("using cached connection\n"); 34107c478bd9Sstevel@tonic-gate return true; 34117c478bd9Sstevel@tonic-gate } 34127c478bd9Sstevel@tonic-gate 34137c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 34147c478bd9Sstevel@tonic-gate sm_dprintf("opening new connection\n"); 34157c478bd9Sstevel@tonic-gate 34167c478bd9Sstevel@tonic-gate if (lmap->ldap_host != NULL) 34177c478bd9Sstevel@tonic-gate id = lmap->ldap_host; 34187c478bd9Sstevel@tonic-gate else if (lmap->ldap_uri != NULL) 34197c478bd9Sstevel@tonic-gate id = lmap->ldap_uri; 34207c478bd9Sstevel@tonic-gate else 34217c478bd9Sstevel@tonic-gate id = "localhost"; 34227c478bd9Sstevel@tonic-gate 3423*e9af4bc0SJohn Beck if (tTd(74, 104)) 3424*e9af4bc0SJohn Beck { 3425*e9af4bc0SJohn Beck extern MAPCLASS NullMapClass; 3426*e9af4bc0SJohn Beck 3427*e9af4bc0SJohn Beck /* debug mode: don't actually open an LDAP connection */ 3428*e9af4bc0SJohn Beck map->map_orgclass = map->map_class; 3429*e9af4bc0SJohn Beck map->map_class = &NullMapClass; 3430*e9af4bc0SJohn Beck map->map_mflags |= MF_OPEN; 3431*e9af4bc0SJohn Beck map->map_pid = CurrentPid; 3432*e9af4bc0SJohn Beck return true; 3433*e9af4bc0SJohn Beck } 3434*e9af4bc0SJohn Beck 34357c478bd9Sstevel@tonic-gate /* No connection yet, connect */ 34367c478bd9Sstevel@tonic-gate if (!sm_ldap_start(map->map_mname, lmap)) 34377c478bd9Sstevel@tonic-gate { 34387c478bd9Sstevel@tonic-gate if (errno == ETIMEDOUT) 34397c478bd9Sstevel@tonic-gate { 34407c478bd9Sstevel@tonic-gate if (LogLevel > 1) 34417c478bd9Sstevel@tonic-gate sm_syslog(LOG_NOTICE, CurEnv->e_id, 34427c478bd9Sstevel@tonic-gate "timeout conning to LDAP server %.100s", 34437c478bd9Sstevel@tonic-gate id); 34447c478bd9Sstevel@tonic-gate } 34457c478bd9Sstevel@tonic-gate 34467c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 34477c478bd9Sstevel@tonic-gate { 34487c478bd9Sstevel@tonic-gate if (bitset(MF_NODEFER, map->map_mflags)) 34497c478bd9Sstevel@tonic-gate { 34507c478bd9Sstevel@tonic-gate syserr("%s failed to %s in map %s", 34517c478bd9Sstevel@tonic-gate # if USE_LDAP_INIT 34527c478bd9Sstevel@tonic-gate "ldap_init/ldap_bind", 34537c478bd9Sstevel@tonic-gate # else /* USE_LDAP_INIT */ 34547c478bd9Sstevel@tonic-gate "ldap_open", 34557c478bd9Sstevel@tonic-gate # endif /* USE_LDAP_INIT */ 34567c478bd9Sstevel@tonic-gate id, map->map_mname); 34577c478bd9Sstevel@tonic-gate } 34587c478bd9Sstevel@tonic-gate else 34597c478bd9Sstevel@tonic-gate { 34607c478bd9Sstevel@tonic-gate syserr("451 4.3.5 %s failed to %s in map %s", 34617c478bd9Sstevel@tonic-gate # if USE_LDAP_INIT 34627c478bd9Sstevel@tonic-gate "ldap_init/ldap_bind", 34637c478bd9Sstevel@tonic-gate # else /* USE_LDAP_INIT */ 34647c478bd9Sstevel@tonic-gate "ldap_open", 34657c478bd9Sstevel@tonic-gate # endif /* USE_LDAP_INIT */ 34667c478bd9Sstevel@tonic-gate id, map->map_mname); 34677c478bd9Sstevel@tonic-gate } 34687c478bd9Sstevel@tonic-gate } 34697c478bd9Sstevel@tonic-gate return false; 34707c478bd9Sstevel@tonic-gate } 34717c478bd9Sstevel@tonic-gate 34727c478bd9Sstevel@tonic-gate /* Save connection for reuse */ 34737c478bd9Sstevel@tonic-gate s->s_lmap = map; 34747c478bd9Sstevel@tonic-gate return true; 34757c478bd9Sstevel@tonic-gate } 34767c478bd9Sstevel@tonic-gate 34777c478bd9Sstevel@tonic-gate /* 34787c478bd9Sstevel@tonic-gate ** LDAPMAP_CLOSE -- close ldap map 34797c478bd9Sstevel@tonic-gate */ 34807c478bd9Sstevel@tonic-gate 34817c478bd9Sstevel@tonic-gate void 34827c478bd9Sstevel@tonic-gate ldapmap_close(map) 34837c478bd9Sstevel@tonic-gate MAP *map; 34847c478bd9Sstevel@tonic-gate { 34857c478bd9Sstevel@tonic-gate SM_LDAP_STRUCT *lmap; 34867c478bd9Sstevel@tonic-gate STAB *s; 34877c478bd9Sstevel@tonic-gate 34887c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 34897c478bd9Sstevel@tonic-gate sm_dprintf("ldapmap_close(%s)\n", map->map_mname); 34907c478bd9Sstevel@tonic-gate 34917c478bd9Sstevel@tonic-gate lmap = (SM_LDAP_STRUCT *) map->map_db1; 34927c478bd9Sstevel@tonic-gate 34937c478bd9Sstevel@tonic-gate /* Check if already closed */ 34947c478bd9Sstevel@tonic-gate if (lmap->ldap_ld == NULL) 34957c478bd9Sstevel@tonic-gate return; 34967c478bd9Sstevel@tonic-gate 34977c478bd9Sstevel@tonic-gate /* Close the LDAP connection */ 34987c478bd9Sstevel@tonic-gate sm_ldap_close(lmap); 34997c478bd9Sstevel@tonic-gate 35007c478bd9Sstevel@tonic-gate /* Mark all the maps that share the connection as closed */ 35017c478bd9Sstevel@tonic-gate s = ldapmap_findconn(lmap); 35027c478bd9Sstevel@tonic-gate 35037c478bd9Sstevel@tonic-gate while (s->s_lmap != NULL) 35047c478bd9Sstevel@tonic-gate { 35057c478bd9Sstevel@tonic-gate MAP *smap = s->s_lmap; 35067c478bd9Sstevel@tonic-gate 35077c478bd9Sstevel@tonic-gate if (tTd(38, 2) && smap != map) 35087c478bd9Sstevel@tonic-gate sm_dprintf("ldapmap_close(%s): closed %s (shared LDAP connection)\n", 35097c478bd9Sstevel@tonic-gate map->map_mname, smap->map_mname); 35107c478bd9Sstevel@tonic-gate smap->map_mflags &= ~(MF_OPEN|MF_WRITABLE); 35117c478bd9Sstevel@tonic-gate lmap = (SM_LDAP_STRUCT *) smap->map_db1; 35127c478bd9Sstevel@tonic-gate lmap->ldap_ld = NULL; 35137c478bd9Sstevel@tonic-gate s->s_lmap = lmap->ldap_next; 35147c478bd9Sstevel@tonic-gate lmap->ldap_next = NULL; 35157c478bd9Sstevel@tonic-gate } 35167c478bd9Sstevel@tonic-gate } 35177c478bd9Sstevel@tonic-gate 35187c478bd9Sstevel@tonic-gate # ifdef SUNET_ID 35197c478bd9Sstevel@tonic-gate /* 35207c478bd9Sstevel@tonic-gate ** SUNET_ID_HASH -- Convert a string to its Sunet_id canonical form 35217c478bd9Sstevel@tonic-gate ** This only makes sense at Stanford University. 35227c478bd9Sstevel@tonic-gate */ 35237c478bd9Sstevel@tonic-gate 35247c478bd9Sstevel@tonic-gate static char * 35257c478bd9Sstevel@tonic-gate sunet_id_hash(str) 35267c478bd9Sstevel@tonic-gate char *str; 35277c478bd9Sstevel@tonic-gate { 35287c478bd9Sstevel@tonic-gate char *p, *p_last; 35297c478bd9Sstevel@tonic-gate 35307c478bd9Sstevel@tonic-gate p = str; 35317c478bd9Sstevel@tonic-gate p_last = p; 35327c478bd9Sstevel@tonic-gate while (*p != '\0') 35337c478bd9Sstevel@tonic-gate { 3534*e9af4bc0SJohn Beck if (isascii(*p) && (islower(*p) || isdigit(*p))) 35357c478bd9Sstevel@tonic-gate { 35367c478bd9Sstevel@tonic-gate *p_last = *p; 35377c478bd9Sstevel@tonic-gate p_last++; 35387c478bd9Sstevel@tonic-gate } 3539*e9af4bc0SJohn Beck else if (isascii(*p) && isupper(*p)) 35407c478bd9Sstevel@tonic-gate { 35417c478bd9Sstevel@tonic-gate *p_last = tolower(*p); 35427c478bd9Sstevel@tonic-gate p_last++; 35437c478bd9Sstevel@tonic-gate } 35447c478bd9Sstevel@tonic-gate ++p; 35457c478bd9Sstevel@tonic-gate } 35467c478bd9Sstevel@tonic-gate if (*p_last != '\0') 35477c478bd9Sstevel@tonic-gate *p_last = '\0'; 35487c478bd9Sstevel@tonic-gate return str; 35497c478bd9Sstevel@tonic-gate } 3550058561cbSjbeck # define SM_CONVERT_ID(str) sunet_id_hash(str) 3551058561cbSjbeck # else /* SUNET_ID */ 3552058561cbSjbeck # define SM_CONVERT_ID(str) makelower(str) 35537c478bd9Sstevel@tonic-gate # endif /* SUNET_ID */ 35547c478bd9Sstevel@tonic-gate 35557c478bd9Sstevel@tonic-gate /* 35567c478bd9Sstevel@tonic-gate ** LDAPMAP_LOOKUP -- look up a datum in a LDAP map 35577c478bd9Sstevel@tonic-gate */ 35587c478bd9Sstevel@tonic-gate 35597c478bd9Sstevel@tonic-gate char * 35607c478bd9Sstevel@tonic-gate ldapmap_lookup(map, name, av, statp) 35617c478bd9Sstevel@tonic-gate MAP *map; 35627c478bd9Sstevel@tonic-gate char *name; 35637c478bd9Sstevel@tonic-gate char **av; 35647c478bd9Sstevel@tonic-gate int *statp; 35657c478bd9Sstevel@tonic-gate { 35667c478bd9Sstevel@tonic-gate int flags; 3567058561cbSjbeck int i; 35687c478bd9Sstevel@tonic-gate int plen = 0; 35697c478bd9Sstevel@tonic-gate int psize = 0; 35707c478bd9Sstevel@tonic-gate int msgid; 35717c478bd9Sstevel@tonic-gate int save_errno; 35727c478bd9Sstevel@tonic-gate char *vp, *p; 35737c478bd9Sstevel@tonic-gate char *result = NULL; 35747c478bd9Sstevel@tonic-gate SM_RPOOL_T *rpool; 35757c478bd9Sstevel@tonic-gate SM_LDAP_STRUCT *lmap = NULL; 3576058561cbSjbeck char *argv[SM_LDAP_ARGS]; 3577445f2479Sjbeck char keybuf[MAXKEY]; 3578058561cbSjbeck #if SM_LDAP_ARGS != MAX_MAP_ARGS 3579058561cbSjbeck # ERROR _SM_LDAP_ARGS must be the same as _MAX_MAP_ARGS 3580058561cbSjbeck #endif /* SM_LDAP_ARGS != MAX_MAP_ARGS */ 35817c478bd9Sstevel@tonic-gate 35827c478bd9Sstevel@tonic-gate #if defined(SUN_EXTENSIONS) && defined(SUN_SIMPLIFIED_LDAP) && \ 3583d25d47eeSjbeck HASLDAPGETALIASBYNAME 35847c478bd9Sstevel@tonic-gate if (VendorCode == VENDOR_SUN && 35857c478bd9Sstevel@tonic-gate strcmp(map->map_mname, "aliases.ldap") == 0) 35867c478bd9Sstevel@tonic-gate { 35877c478bd9Sstevel@tonic-gate int rc; 35887800901eSjbeck #if defined(GETLDAPALIASBYNAME_VERSION) && (GETLDAPALIASBYNAME_VERSION >= 2) 35897800901eSjbeck extern char *__getldapaliasbyname(); 35907800901eSjbeck char *answer; 35917800901eSjbeck 35927800901eSjbeck answer = __getldapaliasbyname(name, &rc); 35937800901eSjbeck #else 35947800901eSjbeck char answer[MAXNAME + 1]; 35957c478bd9Sstevel@tonic-gate 35967c478bd9Sstevel@tonic-gate rc = __getldapaliasbyname(name, answer, sizeof(answer)); 35977800901eSjbeck #endif 35987c478bd9Sstevel@tonic-gate if (rc != 0) 35997c478bd9Sstevel@tonic-gate { 36007c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 36017c478bd9Sstevel@tonic-gate sm_dprintf("getldapaliasbyname(%.100s) failed, errno=%d\n", 36027c478bd9Sstevel@tonic-gate name, errno); 36037c478bd9Sstevel@tonic-gate *statp = EX_NOTFOUND; 36047c478bd9Sstevel@tonic-gate return NULL; 36057c478bd9Sstevel@tonic-gate } 36067c478bd9Sstevel@tonic-gate *statp = EX_OK; 36077c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 36087c478bd9Sstevel@tonic-gate sm_dprintf("getldapaliasbyname(%.100s) => %s\n", name, 36097c478bd9Sstevel@tonic-gate answer); 36107c478bd9Sstevel@tonic-gate if (bitset(MF_MATCHONLY, map->map_mflags)) 36117c478bd9Sstevel@tonic-gate result = map_rewrite(map, name, strlen(name), NULL); 36127c478bd9Sstevel@tonic-gate else 36137c478bd9Sstevel@tonic-gate result = map_rewrite(map, answer, strlen(answer), av); 36147800901eSjbeck #if defined(GETLDAPALIASBYNAME_VERSION) && (GETLDAPALIASBYNAME_VERSION >= 2) 36157800901eSjbeck free(answer); 36167800901eSjbeck #endif 36177c478bd9Sstevel@tonic-gate return result; 36187c478bd9Sstevel@tonic-gate } 3619d25d47eeSjbeck #endif /* defined(SUN_EXTENSIONS) && defined(SUN_SIMPLIFIED_LDAP) && ... */ 36207c478bd9Sstevel@tonic-gate 36217c478bd9Sstevel@tonic-gate /* Get ldap struct pointer from map */ 36227c478bd9Sstevel@tonic-gate lmap = (SM_LDAP_STRUCT *) map->map_db1; 36237c478bd9Sstevel@tonic-gate sm_ldap_setopts(lmap->ldap_ld, lmap); 36247c478bd9Sstevel@tonic-gate 3625058561cbSjbeck if (lmap->ldap_multi_args) 36267c478bd9Sstevel@tonic-gate { 3627058561cbSjbeck SM_REQUIRE(av != NULL); 3628058561cbSjbeck memset(argv, '\0', sizeof(argv)); 3629058561cbSjbeck for (i = 0; i < SM_LDAP_ARGS && av[i] != NULL; i++) 3630058561cbSjbeck { 3631058561cbSjbeck argv[i] = sm_strdup(av[i]); 3632058561cbSjbeck if (argv[i] == NULL) 3633058561cbSjbeck { 3634058561cbSjbeck int save_errno, j; 3635058561cbSjbeck 3636058561cbSjbeck save_errno = errno; 3637058561cbSjbeck for (j = 0; j < i && argv[j] != NULL; j++) 3638058561cbSjbeck SM_FREE(argv[j]); 3639058561cbSjbeck *statp = EX_TEMPFAIL; 3640058561cbSjbeck errno = save_errno; 3641058561cbSjbeck return NULL; 36427c478bd9Sstevel@tonic-gate } 36437c478bd9Sstevel@tonic-gate 3644058561cbSjbeck if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 3645058561cbSjbeck SM_CONVERT_ID(av[i]); 3646058561cbSjbeck } 3647058561cbSjbeck } 3648058561cbSjbeck else 3649058561cbSjbeck { 3650058561cbSjbeck (void) sm_strlcpy(keybuf, name, sizeof(keybuf)); 3651058561cbSjbeck 3652058561cbSjbeck if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 3653058561cbSjbeck SM_CONVERT_ID(keybuf); 3654058561cbSjbeck } 3655058561cbSjbeck 3656058561cbSjbeck if (tTd(38, 20)) 3657058561cbSjbeck { 3658058561cbSjbeck if (lmap->ldap_multi_args) 3659058561cbSjbeck { 3660058561cbSjbeck sm_dprintf("ldapmap_lookup(%s, argv)\n", 3661058561cbSjbeck map->map_mname); 3662058561cbSjbeck for (i = 0; i < SM_LDAP_ARGS; i++) 3663058561cbSjbeck { 3664058561cbSjbeck sm_dprintf(" argv[%d] = %s\n", i, 3665058561cbSjbeck argv[i] == NULL ? "NULL" : argv[i]); 3666058561cbSjbeck } 3667058561cbSjbeck } 3668058561cbSjbeck else 3669058561cbSjbeck { 3670058561cbSjbeck sm_dprintf("ldapmap_lookup(%s, %s)\n", 3671058561cbSjbeck map->map_mname, name); 3672058561cbSjbeck } 3673058561cbSjbeck } 3674058561cbSjbeck 3675058561cbSjbeck if (lmap->ldap_multi_args) 3676058561cbSjbeck { 3677058561cbSjbeck msgid = sm_ldap_search_m(lmap, argv); 3678058561cbSjbeck 3679058561cbSjbeck /* free the argv array and its content, no longer needed */ 3680058561cbSjbeck for (i = 0; i < SM_LDAP_ARGS && argv[i] != NULL; i++) 3681058561cbSjbeck SM_FREE(argv[i]); 3682058561cbSjbeck } 3683058561cbSjbeck else 36847c478bd9Sstevel@tonic-gate msgid = sm_ldap_search(lmap, keybuf); 3685058561cbSjbeck if (msgid == SM_LDAP_ERR) 36867c478bd9Sstevel@tonic-gate { 36877c478bd9Sstevel@tonic-gate errno = sm_ldap_geterrno(lmap->ldap_ld) + E_LDAPBASE; 36887c478bd9Sstevel@tonic-gate save_errno = errno; 36897c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 36907c478bd9Sstevel@tonic-gate { 3691058561cbSjbeck /* 3692058561cbSjbeck ** Do not include keybuf as this error may be shown 3693058561cbSjbeck ** to outsiders. 3694058561cbSjbeck */ 3695058561cbSjbeck 36967c478bd9Sstevel@tonic-gate if (bitset(MF_NODEFER, map->map_mflags)) 3697058561cbSjbeck syserr("Error in ldap_search in map %s", 3698058561cbSjbeck map->map_mname); 36997c478bd9Sstevel@tonic-gate else 3700058561cbSjbeck syserr("451 4.3.5 Error in ldap_search in map %s", 3701058561cbSjbeck map->map_mname); 37027c478bd9Sstevel@tonic-gate } 37037c478bd9Sstevel@tonic-gate *statp = EX_TEMPFAIL; 37047c478bd9Sstevel@tonic-gate switch (save_errno - E_LDAPBASE) 37057c478bd9Sstevel@tonic-gate { 37067c478bd9Sstevel@tonic-gate # ifdef LDAP_SERVER_DOWN 37077c478bd9Sstevel@tonic-gate case LDAP_SERVER_DOWN: 37087c478bd9Sstevel@tonic-gate # endif /* LDAP_SERVER_DOWN */ 37097c478bd9Sstevel@tonic-gate case LDAP_TIMEOUT: 37107c478bd9Sstevel@tonic-gate case LDAP_UNAVAILABLE: 37117c478bd9Sstevel@tonic-gate /* server disappeared, try reopen on next search */ 37127c478bd9Sstevel@tonic-gate ldapmap_close(map); 37137c478bd9Sstevel@tonic-gate break; 37147c478bd9Sstevel@tonic-gate } 37157c478bd9Sstevel@tonic-gate errno = save_errno; 37167c478bd9Sstevel@tonic-gate return NULL; 37177c478bd9Sstevel@tonic-gate } 3718058561cbSjbeck #if SM_LDAP_ERROR_ON_MISSING_ARGS 3719058561cbSjbeck else if (msgid == SM_LDAP_ERR_ARG_MISS) 3720058561cbSjbeck { 3721058561cbSjbeck if (bitset(MF_NODEFER, map->map_mflags)) 3722058561cbSjbeck syserr("Error in ldap_search in map %s, too few arguments", 3723058561cbSjbeck map->map_mname); 3724058561cbSjbeck else 3725058561cbSjbeck syserr("554 5.3.5 Error in ldap_search in map %s, too few arguments", 3726058561cbSjbeck map->map_mname); 3727058561cbSjbeck *statp = EX_CONFIG; 3728058561cbSjbeck return NULL; 3729058561cbSjbeck } 3730058561cbSjbeck #endif /* SM_LDAP_ERROR_ON_MISSING_ARGS */ 37317c478bd9Sstevel@tonic-gate 37327c478bd9Sstevel@tonic-gate *statp = EX_NOTFOUND; 37337c478bd9Sstevel@tonic-gate vp = NULL; 37347c478bd9Sstevel@tonic-gate 37357c478bd9Sstevel@tonic-gate flags = 0; 37367c478bd9Sstevel@tonic-gate if (bitset(MF_SINGLEMATCH, map->map_mflags)) 37377c478bd9Sstevel@tonic-gate flags |= SM_LDAP_SINGLEMATCH; 37387c478bd9Sstevel@tonic-gate if (bitset(MF_MATCHONLY, map->map_mflags)) 37397c478bd9Sstevel@tonic-gate flags |= SM_LDAP_MATCHONLY; 374049218d4fSjbeck # if _FFR_LDAP_SINGLEDN 374149218d4fSjbeck if (bitset(MF_SINGLEDN, map->map_mflags)) 374249218d4fSjbeck flags |= SM_LDAP_SINGLEDN; 374349218d4fSjbeck # endif /* _FFR_LDAP_SINGLEDN */ 37447c478bd9Sstevel@tonic-gate 37457c478bd9Sstevel@tonic-gate /* Create an rpool for search related memory usage */ 37467c478bd9Sstevel@tonic-gate rpool = sm_rpool_new_x(NULL); 37477c478bd9Sstevel@tonic-gate 37487c478bd9Sstevel@tonic-gate p = NULL; 37497c478bd9Sstevel@tonic-gate *statp = sm_ldap_results(lmap, msgid, flags, map->map_coldelim, 37507c478bd9Sstevel@tonic-gate rpool, &p, &plen, &psize, NULL); 37517c478bd9Sstevel@tonic-gate save_errno = errno; 37527c478bd9Sstevel@tonic-gate 37537c478bd9Sstevel@tonic-gate /* Copy result so rpool can be freed */ 37547c478bd9Sstevel@tonic-gate if (*statp == EX_OK && p != NULL) 37557c478bd9Sstevel@tonic-gate vp = newstr(p); 37567c478bd9Sstevel@tonic-gate sm_rpool_free(rpool); 37577c478bd9Sstevel@tonic-gate 37587c478bd9Sstevel@tonic-gate /* need to restart LDAP connection? */ 37597c478bd9Sstevel@tonic-gate if (*statp == EX_RESTART) 37607c478bd9Sstevel@tonic-gate { 37617c478bd9Sstevel@tonic-gate *statp = EX_TEMPFAIL; 37627c478bd9Sstevel@tonic-gate ldapmap_close(map); 37637c478bd9Sstevel@tonic-gate } 37647c478bd9Sstevel@tonic-gate 37657c478bd9Sstevel@tonic-gate errno = save_errno; 37667c478bd9Sstevel@tonic-gate if (*statp != EX_OK && *statp != EX_NOTFOUND) 37677c478bd9Sstevel@tonic-gate { 37687c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 37697c478bd9Sstevel@tonic-gate { 37707c478bd9Sstevel@tonic-gate if (bitset(MF_NODEFER, map->map_mflags)) 37717c478bd9Sstevel@tonic-gate syserr("Error getting LDAP results in map %s", 37727c478bd9Sstevel@tonic-gate map->map_mname); 37737c478bd9Sstevel@tonic-gate else 37747c478bd9Sstevel@tonic-gate syserr("451 4.3.5 Error getting LDAP results in map %s", 37757c478bd9Sstevel@tonic-gate map->map_mname); 37767c478bd9Sstevel@tonic-gate } 37777c478bd9Sstevel@tonic-gate errno = save_errno; 37787c478bd9Sstevel@tonic-gate return NULL; 37797c478bd9Sstevel@tonic-gate } 37807c478bd9Sstevel@tonic-gate 37817c478bd9Sstevel@tonic-gate /* Did we match anything? */ 37827c478bd9Sstevel@tonic-gate if (vp == NULL && !bitset(MF_MATCHONLY, map->map_mflags)) 37837c478bd9Sstevel@tonic-gate return NULL; 37847c478bd9Sstevel@tonic-gate 37857c478bd9Sstevel@tonic-gate if (*statp == EX_OK) 37867c478bd9Sstevel@tonic-gate { 37877c478bd9Sstevel@tonic-gate if (LogLevel > 9) 37887c478bd9Sstevel@tonic-gate sm_syslog(LOG_INFO, CurEnv->e_id, 37897c478bd9Sstevel@tonic-gate "ldap %.100s => %s", name, 37907c478bd9Sstevel@tonic-gate vp == NULL ? "<NULL>" : vp); 37917c478bd9Sstevel@tonic-gate if (bitset(MF_MATCHONLY, map->map_mflags)) 37927c478bd9Sstevel@tonic-gate result = map_rewrite(map, name, strlen(name), NULL); 37937c478bd9Sstevel@tonic-gate else 37947c478bd9Sstevel@tonic-gate { 37957c478bd9Sstevel@tonic-gate /* vp != NULL according to test above */ 37967c478bd9Sstevel@tonic-gate result = map_rewrite(map, vp, strlen(vp), av); 37977c478bd9Sstevel@tonic-gate } 37987c478bd9Sstevel@tonic-gate if (vp != NULL) 37997c478bd9Sstevel@tonic-gate sm_free(vp); /* XXX */ 38007c478bd9Sstevel@tonic-gate } 38017c478bd9Sstevel@tonic-gate return result; 38027c478bd9Sstevel@tonic-gate } 38037c478bd9Sstevel@tonic-gate 38047c478bd9Sstevel@tonic-gate /* 38057c478bd9Sstevel@tonic-gate ** LDAPMAP_FINDCONN -- find an LDAP connection to the server 38067c478bd9Sstevel@tonic-gate ** 38077c478bd9Sstevel@tonic-gate ** Cache LDAP connections based on the host, port, bind DN, 38087c478bd9Sstevel@tonic-gate ** secret, and PID so we don't have multiple connections open to 38097c478bd9Sstevel@tonic-gate ** the same server for different maps. Need a separate connection 38107c478bd9Sstevel@tonic-gate ** per PID since a parent process may close the map before the 38117c478bd9Sstevel@tonic-gate ** child is done with it. 38127c478bd9Sstevel@tonic-gate ** 38137c478bd9Sstevel@tonic-gate ** Parameters: 38147c478bd9Sstevel@tonic-gate ** lmap -- LDAP map information 38157c478bd9Sstevel@tonic-gate ** 38167c478bd9Sstevel@tonic-gate ** Returns: 38177c478bd9Sstevel@tonic-gate ** Symbol table entry for the LDAP connection. 38187c478bd9Sstevel@tonic-gate */ 38197c478bd9Sstevel@tonic-gate 38207c478bd9Sstevel@tonic-gate static STAB * 38217c478bd9Sstevel@tonic-gate ldapmap_findconn(lmap) 38227c478bd9Sstevel@tonic-gate SM_LDAP_STRUCT *lmap; 38237c478bd9Sstevel@tonic-gate { 38247c478bd9Sstevel@tonic-gate char *format; 38257c478bd9Sstevel@tonic-gate char *nbuf; 38267c478bd9Sstevel@tonic-gate char *id; 38277c478bd9Sstevel@tonic-gate STAB *SM_NONVOLATILE s = NULL; 38287c478bd9Sstevel@tonic-gate 38297c478bd9Sstevel@tonic-gate if (lmap->ldap_host != NULL) 38307c478bd9Sstevel@tonic-gate id = lmap->ldap_host; 38317c478bd9Sstevel@tonic-gate else if (lmap->ldap_uri != NULL) 38327c478bd9Sstevel@tonic-gate id = lmap->ldap_uri; 38337c478bd9Sstevel@tonic-gate else 38347c478bd9Sstevel@tonic-gate id = "localhost"; 38357c478bd9Sstevel@tonic-gate 38367c478bd9Sstevel@tonic-gate format = "%s%c%d%c%d%c%s%c%s%d"; 38377c478bd9Sstevel@tonic-gate nbuf = sm_stringf_x(format, 38387c478bd9Sstevel@tonic-gate id, 38397c478bd9Sstevel@tonic-gate CONDELSE, 38407c478bd9Sstevel@tonic-gate lmap->ldap_port, 38417c478bd9Sstevel@tonic-gate CONDELSE, 38427c478bd9Sstevel@tonic-gate lmap->ldap_version, 38437c478bd9Sstevel@tonic-gate CONDELSE, 38447c478bd9Sstevel@tonic-gate (lmap->ldap_binddn == NULL ? "" 38457c478bd9Sstevel@tonic-gate : lmap->ldap_binddn), 38467c478bd9Sstevel@tonic-gate CONDELSE, 38477c478bd9Sstevel@tonic-gate (lmap->ldap_secret == NULL ? "" 38487c478bd9Sstevel@tonic-gate : lmap->ldap_secret), 38497c478bd9Sstevel@tonic-gate (int) CurrentPid); 38507c478bd9Sstevel@tonic-gate SM_TRY 38517c478bd9Sstevel@tonic-gate s = stab(nbuf, ST_LMAP, ST_ENTER); 38527c478bd9Sstevel@tonic-gate SM_FINALLY 38537c478bd9Sstevel@tonic-gate sm_free(nbuf); 38547c478bd9Sstevel@tonic-gate SM_END_TRY 38557c478bd9Sstevel@tonic-gate return s; 38567c478bd9Sstevel@tonic-gate } 38577c478bd9Sstevel@tonic-gate /* 38587c478bd9Sstevel@tonic-gate ** LDAPMAP_PARSEARGS -- parse ldap map definition args. 38597c478bd9Sstevel@tonic-gate */ 38607c478bd9Sstevel@tonic-gate 38617c478bd9Sstevel@tonic-gate static struct lamvalues LDAPAuthMethods[] = 38627c478bd9Sstevel@tonic-gate { 38637c478bd9Sstevel@tonic-gate { "none", LDAP_AUTH_NONE }, 38647c478bd9Sstevel@tonic-gate { "simple", LDAP_AUTH_SIMPLE }, 38657c478bd9Sstevel@tonic-gate # ifdef LDAP_AUTH_KRBV4 38667c478bd9Sstevel@tonic-gate { "krbv4", LDAP_AUTH_KRBV4 }, 38677c478bd9Sstevel@tonic-gate # endif /* LDAP_AUTH_KRBV4 */ 38687c478bd9Sstevel@tonic-gate { NULL, 0 } 38697c478bd9Sstevel@tonic-gate }; 38707c478bd9Sstevel@tonic-gate 38717c478bd9Sstevel@tonic-gate static struct ladvalues LDAPAliasDereference[] = 38727c478bd9Sstevel@tonic-gate { 38737c478bd9Sstevel@tonic-gate { "never", LDAP_DEREF_NEVER }, 38747c478bd9Sstevel@tonic-gate { "always", LDAP_DEREF_ALWAYS }, 38757c478bd9Sstevel@tonic-gate { "search", LDAP_DEREF_SEARCHING }, 38767c478bd9Sstevel@tonic-gate { "find", LDAP_DEREF_FINDING }, 38777c478bd9Sstevel@tonic-gate { NULL, 0 } 38787c478bd9Sstevel@tonic-gate }; 38797c478bd9Sstevel@tonic-gate 38807c478bd9Sstevel@tonic-gate static struct lssvalues LDAPSearchScope[] = 38817c478bd9Sstevel@tonic-gate { 38827c478bd9Sstevel@tonic-gate { "base", LDAP_SCOPE_BASE }, 38837c478bd9Sstevel@tonic-gate { "one", LDAP_SCOPE_ONELEVEL }, 38847c478bd9Sstevel@tonic-gate { "sub", LDAP_SCOPE_SUBTREE }, 38857c478bd9Sstevel@tonic-gate { NULL, 0 } 38867c478bd9Sstevel@tonic-gate }; 38877c478bd9Sstevel@tonic-gate 38887c478bd9Sstevel@tonic-gate bool 38897c478bd9Sstevel@tonic-gate ldapmap_parseargs(map, args) 38907c478bd9Sstevel@tonic-gate MAP *map; 38917c478bd9Sstevel@tonic-gate char *args; 38927c478bd9Sstevel@tonic-gate { 38937c478bd9Sstevel@tonic-gate bool secretread = true; 38947c478bd9Sstevel@tonic-gate bool attrssetup = false; 38957c478bd9Sstevel@tonic-gate int i; 38967c478bd9Sstevel@tonic-gate register char *p = args; 38977c478bd9Sstevel@tonic-gate SM_LDAP_STRUCT *lmap; 38987c478bd9Sstevel@tonic-gate struct lamvalues *lam; 38997c478bd9Sstevel@tonic-gate struct ladvalues *lad; 39007c478bd9Sstevel@tonic-gate struct lssvalues *lss; 39017c478bd9Sstevel@tonic-gate char ldapfilt[MAXLINE]; 39027c478bd9Sstevel@tonic-gate char m_tmp[MAXPATHLEN + LDAPMAP_MAX_PASSWD]; 39037c478bd9Sstevel@tonic-gate 39047c478bd9Sstevel@tonic-gate /* Get ldap struct pointer from map */ 39057c478bd9Sstevel@tonic-gate lmap = (SM_LDAP_STRUCT *) map->map_db1; 39067c478bd9Sstevel@tonic-gate 39077c478bd9Sstevel@tonic-gate /* Check if setting the initial LDAP defaults */ 39087c478bd9Sstevel@tonic-gate if (lmap == NULL || lmap != LDAPDefaults) 39097c478bd9Sstevel@tonic-gate { 39107c478bd9Sstevel@tonic-gate /* We need to alloc an SM_LDAP_STRUCT struct */ 3911058561cbSjbeck lmap = (SM_LDAP_STRUCT *) xalloc(sizeof(*lmap)); 39127c478bd9Sstevel@tonic-gate if (LDAPDefaults == NULL) 39137c478bd9Sstevel@tonic-gate sm_ldap_clear(lmap); 39147c478bd9Sstevel@tonic-gate else 39157c478bd9Sstevel@tonic-gate STRUCTCOPY(*LDAPDefaults, *lmap); 39167c478bd9Sstevel@tonic-gate } 39177c478bd9Sstevel@tonic-gate 39187c478bd9Sstevel@tonic-gate /* there is no check whether there is really an argument */ 39197c478bd9Sstevel@tonic-gate map->map_mflags |= MF_TRY0NULL|MF_TRY1NULL; 39207c478bd9Sstevel@tonic-gate map->map_spacesub = SpaceSub; /* default value */ 39217c478bd9Sstevel@tonic-gate 39227c478bd9Sstevel@tonic-gate /* Check if setting up an alias or file class LDAP map */ 39237c478bd9Sstevel@tonic-gate if (bitset(MF_ALIAS, map->map_mflags)) 39247c478bd9Sstevel@tonic-gate { 39257c478bd9Sstevel@tonic-gate /* Comma separate if used as an alias file */ 39267c478bd9Sstevel@tonic-gate map->map_coldelim = ','; 39277c478bd9Sstevel@tonic-gate if (*args == '\0') 39287c478bd9Sstevel@tonic-gate { 39297c478bd9Sstevel@tonic-gate int n; 39307c478bd9Sstevel@tonic-gate char *lc; 39317c478bd9Sstevel@tonic-gate char jbuf[MAXHOSTNAMELEN]; 39327c478bd9Sstevel@tonic-gate char lcbuf[MAXLINE]; 39337c478bd9Sstevel@tonic-gate 39347c478bd9Sstevel@tonic-gate /* Get $j */ 3935058561cbSjbeck expand("\201j", jbuf, sizeof(jbuf), &BlankEnvelope); 39367c478bd9Sstevel@tonic-gate if (jbuf[0] == '\0') 39377c478bd9Sstevel@tonic-gate { 39387c478bd9Sstevel@tonic-gate (void) sm_strlcpy(jbuf, "localhost", 3939058561cbSjbeck sizeof(jbuf)); 39407c478bd9Sstevel@tonic-gate } 39417c478bd9Sstevel@tonic-gate 39427c478bd9Sstevel@tonic-gate lc = macvalue(macid("{sendmailMTACluster}"), CurEnv); 39437c478bd9Sstevel@tonic-gate if (lc == NULL) 39447c478bd9Sstevel@tonic-gate lc = ""; 39457c478bd9Sstevel@tonic-gate else 39467c478bd9Sstevel@tonic-gate { 3947058561cbSjbeck expand(lc, lcbuf, sizeof(lcbuf), CurEnv); 39487c478bd9Sstevel@tonic-gate lc = lcbuf; 39497c478bd9Sstevel@tonic-gate } 39507c478bd9Sstevel@tonic-gate 3951058561cbSjbeck n = sm_snprintf(ldapfilt, sizeof(ldapfilt), 39527c478bd9Sstevel@tonic-gate "(&(objectClass=sendmailMTAAliasObject)(sendmailMTAAliasGrouping=aliases)(|(sendmailMTACluster=%s)(sendmailMTAHost=%s))(sendmailMTAKey=%%0))", 39537c478bd9Sstevel@tonic-gate lc, jbuf); 3954058561cbSjbeck if (n >= sizeof(ldapfilt)) 39557c478bd9Sstevel@tonic-gate { 39567c478bd9Sstevel@tonic-gate syserr("%s: Default LDAP string too long", 39577c478bd9Sstevel@tonic-gate map->map_mname); 39587c478bd9Sstevel@tonic-gate return false; 39597c478bd9Sstevel@tonic-gate } 39607c478bd9Sstevel@tonic-gate 39617c478bd9Sstevel@tonic-gate /* default args for an alias LDAP entry */ 39627c478bd9Sstevel@tonic-gate lmap->ldap_filter = ldapfilt; 39637c478bd9Sstevel@tonic-gate lmap->ldap_attr[0] = "objectClass"; 39647c478bd9Sstevel@tonic-gate lmap->ldap_attr_type[0] = SM_LDAP_ATTR_OBJCLASS; 39657c478bd9Sstevel@tonic-gate lmap->ldap_attr_needobjclass[0] = NULL; 39667c478bd9Sstevel@tonic-gate lmap->ldap_attr[1] = "sendmailMTAAliasValue"; 39677c478bd9Sstevel@tonic-gate lmap->ldap_attr_type[1] = SM_LDAP_ATTR_NORMAL; 39687c478bd9Sstevel@tonic-gate lmap->ldap_attr_needobjclass[1] = NULL; 39697c478bd9Sstevel@tonic-gate lmap->ldap_attr[2] = "sendmailMTAAliasSearch"; 39707c478bd9Sstevel@tonic-gate lmap->ldap_attr_type[2] = SM_LDAP_ATTR_FILTER; 39717c478bd9Sstevel@tonic-gate lmap->ldap_attr_needobjclass[2] = "sendmailMTAMapObject"; 39727c478bd9Sstevel@tonic-gate lmap->ldap_attr[3] = "sendmailMTAAliasURL"; 39737c478bd9Sstevel@tonic-gate lmap->ldap_attr_type[3] = SM_LDAP_ATTR_URL; 39747c478bd9Sstevel@tonic-gate lmap->ldap_attr_needobjclass[3] = "sendmailMTAMapObject"; 39757c478bd9Sstevel@tonic-gate lmap->ldap_attr[4] = NULL; 39767c478bd9Sstevel@tonic-gate lmap->ldap_attr_type[4] = SM_LDAP_ATTR_NONE; 39777c478bd9Sstevel@tonic-gate lmap->ldap_attr_needobjclass[4] = NULL; 39787c478bd9Sstevel@tonic-gate attrssetup = true; 39797c478bd9Sstevel@tonic-gate } 39807c478bd9Sstevel@tonic-gate } 39817c478bd9Sstevel@tonic-gate else if (bitset(MF_FILECLASS, map->map_mflags)) 39827c478bd9Sstevel@tonic-gate { 39837c478bd9Sstevel@tonic-gate /* Space separate if used as a file class file */ 39847c478bd9Sstevel@tonic-gate map->map_coldelim = ' '; 39857c478bd9Sstevel@tonic-gate } 39867c478bd9Sstevel@tonic-gate 3987*e9af4bc0SJohn Beck # if _FFR_LDAP_NETWORK_TIMEOUT 3988*e9af4bc0SJohn Beck lmap->ldap_networktmo = 120; 3989*e9af4bc0SJohn Beck # endif /* _FFR_LDAP_NETWORK_TIMEOUT */ 3990*e9af4bc0SJohn Beck 39917c478bd9Sstevel@tonic-gate for (;;) 39927c478bd9Sstevel@tonic-gate { 39937c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 39947c478bd9Sstevel@tonic-gate p++; 39957c478bd9Sstevel@tonic-gate if (*p != '-') 39967c478bd9Sstevel@tonic-gate break; 39977c478bd9Sstevel@tonic-gate switch (*++p) 39987c478bd9Sstevel@tonic-gate { 39997800901eSjbeck case 'A': 40007800901eSjbeck map->map_mflags |= MF_APPEND; 40017800901eSjbeck break; 40027800901eSjbeck 40037800901eSjbeck case 'a': 40047800901eSjbeck map->map_app = ++p; 40057800901eSjbeck break; 40067800901eSjbeck 40077800901eSjbeck case 'D': 40087800901eSjbeck map->map_mflags |= MF_DEFER; 40097800901eSjbeck break; 40107800901eSjbeck 40117800901eSjbeck case 'f': 40127800901eSjbeck map->map_mflags |= MF_NOFOLDCASE; 40137800901eSjbeck break; 40147800901eSjbeck 40157800901eSjbeck case 'm': 40167800901eSjbeck map->map_mflags |= MF_MATCHONLY; 40177800901eSjbeck break; 40187800901eSjbeck 40197c478bd9Sstevel@tonic-gate case 'N': 40207c478bd9Sstevel@tonic-gate map->map_mflags |= MF_INCLNULL; 40217c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_TRY0NULL; 40227c478bd9Sstevel@tonic-gate break; 40237c478bd9Sstevel@tonic-gate 40247c478bd9Sstevel@tonic-gate case 'O': 40257c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_TRY1NULL; 40267c478bd9Sstevel@tonic-gate break; 40277c478bd9Sstevel@tonic-gate 40287c478bd9Sstevel@tonic-gate case 'o': 40297c478bd9Sstevel@tonic-gate map->map_mflags |= MF_OPTIONAL; 40307c478bd9Sstevel@tonic-gate break; 40317c478bd9Sstevel@tonic-gate 40327c478bd9Sstevel@tonic-gate case 'q': 40337c478bd9Sstevel@tonic-gate map->map_mflags |= MF_KEEPQUOTES; 40347c478bd9Sstevel@tonic-gate break; 40357c478bd9Sstevel@tonic-gate 40367800901eSjbeck case 'S': 40377800901eSjbeck map->map_spacesub = *++p; 40387c478bd9Sstevel@tonic-gate break; 40397c478bd9Sstevel@tonic-gate 40407c478bd9Sstevel@tonic-gate case 'T': 40417c478bd9Sstevel@tonic-gate map->map_tapp = ++p; 40427c478bd9Sstevel@tonic-gate break; 40437c478bd9Sstevel@tonic-gate 40447c478bd9Sstevel@tonic-gate case 't': 40457c478bd9Sstevel@tonic-gate map->map_mflags |= MF_NODEFER; 40467c478bd9Sstevel@tonic-gate break; 40477c478bd9Sstevel@tonic-gate 40487c478bd9Sstevel@tonic-gate case 'z': 40497c478bd9Sstevel@tonic-gate if (*++p != '\\') 40507c478bd9Sstevel@tonic-gate map->map_coldelim = *p; 40517c478bd9Sstevel@tonic-gate else 40527c478bd9Sstevel@tonic-gate { 40537c478bd9Sstevel@tonic-gate switch (*++p) 40547c478bd9Sstevel@tonic-gate { 40557c478bd9Sstevel@tonic-gate case 'n': 40567c478bd9Sstevel@tonic-gate map->map_coldelim = '\n'; 40577c478bd9Sstevel@tonic-gate break; 40587c478bd9Sstevel@tonic-gate 40597c478bd9Sstevel@tonic-gate case 't': 40607c478bd9Sstevel@tonic-gate map->map_coldelim = '\t'; 40617c478bd9Sstevel@tonic-gate break; 40627c478bd9Sstevel@tonic-gate 40637c478bd9Sstevel@tonic-gate default: 40647c478bd9Sstevel@tonic-gate map->map_coldelim = '\\'; 40657c478bd9Sstevel@tonic-gate } 40667c478bd9Sstevel@tonic-gate } 40677c478bd9Sstevel@tonic-gate break; 40687c478bd9Sstevel@tonic-gate 40697c478bd9Sstevel@tonic-gate /* Start of ldapmap specific args */ 40707c478bd9Sstevel@tonic-gate case '1': 40717c478bd9Sstevel@tonic-gate map->map_mflags |= MF_SINGLEMATCH; 40727c478bd9Sstevel@tonic-gate break; 40737c478bd9Sstevel@tonic-gate 407449218d4fSjbeck # if _FFR_LDAP_SINGLEDN 407549218d4fSjbeck case '2': 407649218d4fSjbeck map->map_mflags |= MF_SINGLEDN; 407749218d4fSjbeck break; 407849218d4fSjbeck # endif /* _FFR_LDAP_SINGLEDN */ 407949218d4fSjbeck 40807800901eSjbeck case 'b': /* search base */ 40817800901eSjbeck while (isascii(*++p) && isspace(*p)) 40827800901eSjbeck continue; 40837800901eSjbeck lmap->ldap_base = p; 40847800901eSjbeck break; 40857800901eSjbeck 40867800901eSjbeck # if _FFR_LDAP_NETWORK_TIMEOUT 40877800901eSjbeck case 'c': /* network (connect) timeout */ 40887800901eSjbeck while (isascii(*++p) && isspace(*p)) 40897800901eSjbeck continue; 4090*e9af4bc0SJohn Beck lmap->ldap_networktmo = atoi(p); 40917800901eSjbeck break; 40927800901eSjbeck # endif /* _FFR_LDAP_NETWORK_TIMEOUT */ 40937800901eSjbeck 40947800901eSjbeck case 'd': /* Dn to bind to server as */ 40957800901eSjbeck while (isascii(*++p) && isspace(*p)) 40967800901eSjbeck continue; 40977800901eSjbeck lmap->ldap_binddn = p; 40987800901eSjbeck break; 40997800901eSjbeck 41007800901eSjbeck case 'H': /* Use LDAP URI */ 41017800901eSjbeck # if !USE_LDAP_INIT 41027800901eSjbeck syserr("Must compile with -DUSE_LDAP_INIT to use LDAP URIs (-H) in map %s", 41037800901eSjbeck map->map_mname); 41047800901eSjbeck return false; 41057800901eSjbeck # else /* !USE_LDAP_INIT */ 41067800901eSjbeck if (lmap->ldap_host != NULL) 41077800901eSjbeck { 41087800901eSjbeck syserr("Can not specify both an LDAP host and an LDAP URI in map %s", 41097800901eSjbeck map->map_mname); 41107800901eSjbeck return false; 41117800901eSjbeck } 41127800901eSjbeck while (isascii(*++p) && isspace(*p)) 41137800901eSjbeck continue; 41147800901eSjbeck lmap->ldap_uri = p; 41157800901eSjbeck break; 41167800901eSjbeck # endif /* !USE_LDAP_INIT */ 41177800901eSjbeck 41187800901eSjbeck case 'h': /* ldap host */ 41197800901eSjbeck while (isascii(*++p) && isspace(*p)) 41207800901eSjbeck continue; 41217800901eSjbeck if (lmap->ldap_uri != NULL) 41227800901eSjbeck { 41237800901eSjbeck syserr("Can not specify both an LDAP host and an LDAP URI in map %s", 41247800901eSjbeck map->map_mname); 41257800901eSjbeck return false; 41267800901eSjbeck } 41277800901eSjbeck lmap->ldap_host = p; 41287800901eSjbeck break; 41297800901eSjbeck 41307800901eSjbeck case 'K': 41317800901eSjbeck lmap->ldap_multi_args = true; 41327800901eSjbeck break; 41337800901eSjbeck 41347800901eSjbeck case 'k': /* search field */ 41357800901eSjbeck while (isascii(*++p) && isspace(*p)) 41367800901eSjbeck continue; 41377800901eSjbeck lmap->ldap_filter = p; 41387800901eSjbeck break; 41397800901eSjbeck 41407800901eSjbeck case 'l': /* time limit */ 41417800901eSjbeck while (isascii(*++p) && isspace(*p)) 41427800901eSjbeck continue; 41437800901eSjbeck lmap->ldap_timelimit = atoi(p); 41447800901eSjbeck lmap->ldap_timeout.tv_sec = lmap->ldap_timelimit; 41457800901eSjbeck break; 41467800901eSjbeck 41477800901eSjbeck case 'M': /* Method for binding */ 41487800901eSjbeck while (isascii(*++p) && isspace(*p)) 41497800901eSjbeck continue; 41507800901eSjbeck 41517800901eSjbeck if (sm_strncasecmp(p, "LDAP_AUTH_", 10) == 0) 41527800901eSjbeck p += 10; 41537800901eSjbeck 41547800901eSjbeck for (lam = LDAPAuthMethods; 41557800901eSjbeck lam != NULL && lam->lam_name != NULL; lam++) 41567800901eSjbeck { 41577800901eSjbeck if (sm_strncasecmp(p, lam->lam_name, 41587800901eSjbeck strlen(lam->lam_name)) == 0) 41597800901eSjbeck break; 41607800901eSjbeck } 41617800901eSjbeck if (lam->lam_name != NULL) 41627800901eSjbeck lmap->ldap_method = lam->lam_code; 41637800901eSjbeck else 41647800901eSjbeck { 41657800901eSjbeck /* bad config line */ 41667800901eSjbeck if (!bitset(MCF_OPTFILE, 41677800901eSjbeck map->map_class->map_cflags)) 41687800901eSjbeck { 41697800901eSjbeck char *ptr; 41707800901eSjbeck 41717800901eSjbeck if ((ptr = strchr(p, ' ')) != NULL) 41727800901eSjbeck *ptr = '\0'; 41737800901eSjbeck syserr("Method for binding must be [none|simple|krbv4] (not %s) in map %s", 41747800901eSjbeck p, map->map_mname); 41757800901eSjbeck if (ptr != NULL) 41767800901eSjbeck *ptr = ' '; 41777800901eSjbeck return false; 41787800901eSjbeck } 41797800901eSjbeck } 41807800901eSjbeck break; 41817800901eSjbeck 41827800901eSjbeck case 'n': /* retrieve attribute names only */ 41837800901eSjbeck lmap->ldap_attrsonly = LDAPMAP_TRUE; 41847800901eSjbeck break; 41857800901eSjbeck 41867800901eSjbeck /* 41877800901eSjbeck ** This is a string that is dependent on the 41887800901eSjbeck ** method used defined by 'M'. 41897800901eSjbeck */ 41907800901eSjbeck 41917800901eSjbeck case 'P': /* Secret password for binding */ 41927800901eSjbeck while (isascii(*++p) && isspace(*p)) 41937800901eSjbeck continue; 41947800901eSjbeck lmap->ldap_secret = p; 41957800901eSjbeck secretread = false; 41967800901eSjbeck break; 41977800901eSjbeck 41987800901eSjbeck case 'p': /* ldap port */ 41997800901eSjbeck while (isascii(*++p) && isspace(*p)) 42007800901eSjbeck continue; 42017800901eSjbeck lmap->ldap_port = atoi(p); 42027800901eSjbeck break; 42037800901eSjbeck 42047c478bd9Sstevel@tonic-gate /* args stolen from ldapsearch.c */ 42057c478bd9Sstevel@tonic-gate case 'R': /* don't auto chase referrals */ 42067c478bd9Sstevel@tonic-gate # ifdef LDAP_REFERRALS 42077c478bd9Sstevel@tonic-gate lmap->ldap_options &= ~LDAP_OPT_REFERRALS; 42087c478bd9Sstevel@tonic-gate # else /* LDAP_REFERRALS */ 42097c478bd9Sstevel@tonic-gate syserr("compile with -DLDAP_REFERRALS for referral support"); 42107c478bd9Sstevel@tonic-gate # endif /* LDAP_REFERRALS */ 42117c478bd9Sstevel@tonic-gate break; 42127c478bd9Sstevel@tonic-gate 42137c478bd9Sstevel@tonic-gate case 'r': /* alias dereferencing */ 42147c478bd9Sstevel@tonic-gate while (isascii(*++p) && isspace(*p)) 42157c478bd9Sstevel@tonic-gate continue; 42167c478bd9Sstevel@tonic-gate 42177c478bd9Sstevel@tonic-gate if (sm_strncasecmp(p, "LDAP_DEREF_", 11) == 0) 42187c478bd9Sstevel@tonic-gate p += 11; 42197c478bd9Sstevel@tonic-gate 42207c478bd9Sstevel@tonic-gate for (lad = LDAPAliasDereference; 42217c478bd9Sstevel@tonic-gate lad != NULL && lad->lad_name != NULL; lad++) 42227c478bd9Sstevel@tonic-gate { 42237c478bd9Sstevel@tonic-gate if (sm_strncasecmp(p, lad->lad_name, 42247c478bd9Sstevel@tonic-gate strlen(lad->lad_name)) == 0) 42257c478bd9Sstevel@tonic-gate break; 42267c478bd9Sstevel@tonic-gate } 42277c478bd9Sstevel@tonic-gate if (lad->lad_name != NULL) 42287c478bd9Sstevel@tonic-gate lmap->ldap_deref = lad->lad_code; 42297c478bd9Sstevel@tonic-gate else 42307c478bd9Sstevel@tonic-gate { 42317c478bd9Sstevel@tonic-gate /* bad config line */ 42327c478bd9Sstevel@tonic-gate if (!bitset(MCF_OPTFILE, 42337c478bd9Sstevel@tonic-gate map->map_class->map_cflags)) 42347c478bd9Sstevel@tonic-gate { 42357c478bd9Sstevel@tonic-gate char *ptr; 42367c478bd9Sstevel@tonic-gate 42377c478bd9Sstevel@tonic-gate if ((ptr = strchr(p, ' ')) != NULL) 42387c478bd9Sstevel@tonic-gate *ptr = '\0'; 42397c478bd9Sstevel@tonic-gate syserr("Deref must be [never|always|search|find] (not %s) in map %s", 42407c478bd9Sstevel@tonic-gate p, map->map_mname); 42417c478bd9Sstevel@tonic-gate if (ptr != NULL) 42427c478bd9Sstevel@tonic-gate *ptr = ' '; 42437c478bd9Sstevel@tonic-gate return false; 42447c478bd9Sstevel@tonic-gate } 42457c478bd9Sstevel@tonic-gate } 42467c478bd9Sstevel@tonic-gate break; 42477c478bd9Sstevel@tonic-gate 42487c478bd9Sstevel@tonic-gate case 's': /* search scope */ 42497c478bd9Sstevel@tonic-gate while (isascii(*++p) && isspace(*p)) 42507c478bd9Sstevel@tonic-gate continue; 42517c478bd9Sstevel@tonic-gate 42527c478bd9Sstevel@tonic-gate if (sm_strncasecmp(p, "LDAP_SCOPE_", 11) == 0) 42537c478bd9Sstevel@tonic-gate p += 11; 42547c478bd9Sstevel@tonic-gate 42557c478bd9Sstevel@tonic-gate for (lss = LDAPSearchScope; 42567c478bd9Sstevel@tonic-gate lss != NULL && lss->lss_name != NULL; lss++) 42577c478bd9Sstevel@tonic-gate { 42587c478bd9Sstevel@tonic-gate if (sm_strncasecmp(p, lss->lss_name, 42597c478bd9Sstevel@tonic-gate strlen(lss->lss_name)) == 0) 42607c478bd9Sstevel@tonic-gate break; 42617c478bd9Sstevel@tonic-gate } 42627c478bd9Sstevel@tonic-gate if (lss->lss_name != NULL) 42637c478bd9Sstevel@tonic-gate lmap->ldap_scope = lss->lss_code; 42647c478bd9Sstevel@tonic-gate else 42657c478bd9Sstevel@tonic-gate { 42667c478bd9Sstevel@tonic-gate /* bad config line */ 42677c478bd9Sstevel@tonic-gate if (!bitset(MCF_OPTFILE, 42687c478bd9Sstevel@tonic-gate map->map_class->map_cflags)) 42697c478bd9Sstevel@tonic-gate { 42707c478bd9Sstevel@tonic-gate char *ptr; 42717c478bd9Sstevel@tonic-gate 42727c478bd9Sstevel@tonic-gate if ((ptr = strchr(p, ' ')) != NULL) 42737c478bd9Sstevel@tonic-gate *ptr = '\0'; 42747c478bd9Sstevel@tonic-gate syserr("Scope must be [base|one|sub] (not %s) in map %s", 42757c478bd9Sstevel@tonic-gate p, map->map_mname); 42767c478bd9Sstevel@tonic-gate if (ptr != NULL) 42777c478bd9Sstevel@tonic-gate *ptr = ' '; 42787c478bd9Sstevel@tonic-gate return false; 42797c478bd9Sstevel@tonic-gate } 42807c478bd9Sstevel@tonic-gate } 42817c478bd9Sstevel@tonic-gate break; 42827c478bd9Sstevel@tonic-gate 42837800901eSjbeck case 'V': 42847800901eSjbeck if (*++p != '\\') 42857800901eSjbeck lmap->ldap_attrsep = *p; 42867c478bd9Sstevel@tonic-gate else 42877c478bd9Sstevel@tonic-gate { 42887800901eSjbeck switch (*++p) 42897c478bd9Sstevel@tonic-gate { 42907800901eSjbeck case 'n': 42917800901eSjbeck lmap->ldap_attrsep = '\n'; 42927c478bd9Sstevel@tonic-gate break; 42937c478bd9Sstevel@tonic-gate 42947800901eSjbeck case 't': 42957800901eSjbeck lmap->ldap_attrsep = '\t'; 42967800901eSjbeck break; 42977c478bd9Sstevel@tonic-gate 42987800901eSjbeck default: 42997800901eSjbeck lmap->ldap_attrsep = '\\'; 43007800901eSjbeck } 43017800901eSjbeck } 43027800901eSjbeck break; 43037800901eSjbeck 43047800901eSjbeck case 'v': /* attr to return */ 43057c478bd9Sstevel@tonic-gate while (isascii(*++p) && isspace(*p)) 43067c478bd9Sstevel@tonic-gate continue; 43077800901eSjbeck lmap->ldap_attr[0] = p; 43087800901eSjbeck lmap->ldap_attr[1] = NULL; 43097c478bd9Sstevel@tonic-gate break; 43107c478bd9Sstevel@tonic-gate 43117c478bd9Sstevel@tonic-gate case 'w': 43127c478bd9Sstevel@tonic-gate /* -w should be for passwd, -P should be for version */ 43137c478bd9Sstevel@tonic-gate while (isascii(*++p) && isspace(*p)) 43147c478bd9Sstevel@tonic-gate continue; 43157c478bd9Sstevel@tonic-gate lmap->ldap_version = atoi(p); 43167c478bd9Sstevel@tonic-gate # ifdef LDAP_VERSION_MAX 43177c478bd9Sstevel@tonic-gate if (lmap->ldap_version > LDAP_VERSION_MAX) 43187c478bd9Sstevel@tonic-gate { 43197c478bd9Sstevel@tonic-gate syserr("LDAP version %d exceeds max of %d in map %s", 43207c478bd9Sstevel@tonic-gate lmap->ldap_version, LDAP_VERSION_MAX, 43217c478bd9Sstevel@tonic-gate map->map_mname); 43227c478bd9Sstevel@tonic-gate return false; 43237c478bd9Sstevel@tonic-gate } 43247c478bd9Sstevel@tonic-gate # endif /* LDAP_VERSION_MAX */ 43257c478bd9Sstevel@tonic-gate # ifdef LDAP_VERSION_MIN 43267c478bd9Sstevel@tonic-gate if (lmap->ldap_version < LDAP_VERSION_MIN) 43277c478bd9Sstevel@tonic-gate { 43287c478bd9Sstevel@tonic-gate syserr("LDAP version %d is lower than min of %d in map %s", 43297c478bd9Sstevel@tonic-gate lmap->ldap_version, LDAP_VERSION_MIN, 43307c478bd9Sstevel@tonic-gate map->map_mname); 43317c478bd9Sstevel@tonic-gate return false; 43327c478bd9Sstevel@tonic-gate } 43337c478bd9Sstevel@tonic-gate # endif /* LDAP_VERSION_MIN */ 43347c478bd9Sstevel@tonic-gate break; 43357c478bd9Sstevel@tonic-gate 43367800901eSjbeck case 'Z': 43377800901eSjbeck while (isascii(*++p) && isspace(*p)) 43387800901eSjbeck continue; 43397800901eSjbeck lmap->ldap_sizelimit = atoi(p); 4340058561cbSjbeck break; 4341058561cbSjbeck 43427c478bd9Sstevel@tonic-gate default: 43437c478bd9Sstevel@tonic-gate syserr("Illegal option %c map %s", *p, map->map_mname); 43447c478bd9Sstevel@tonic-gate break; 43457c478bd9Sstevel@tonic-gate } 43467c478bd9Sstevel@tonic-gate 43477c478bd9Sstevel@tonic-gate /* need to account for quoted strings here */ 43487c478bd9Sstevel@tonic-gate while (*p != '\0' && !(isascii(*p) && isspace(*p))) 43497c478bd9Sstevel@tonic-gate { 43507c478bd9Sstevel@tonic-gate if (*p == '"') 43517c478bd9Sstevel@tonic-gate { 43527c478bd9Sstevel@tonic-gate while (*++p != '"' && *p != '\0') 43537c478bd9Sstevel@tonic-gate continue; 43547c478bd9Sstevel@tonic-gate if (*p != '\0') 43557c478bd9Sstevel@tonic-gate p++; 43567c478bd9Sstevel@tonic-gate } 43577c478bd9Sstevel@tonic-gate else 43587c478bd9Sstevel@tonic-gate p++; 43597c478bd9Sstevel@tonic-gate } 43607c478bd9Sstevel@tonic-gate 43617c478bd9Sstevel@tonic-gate if (*p != '\0') 43627c478bd9Sstevel@tonic-gate *p++ = '\0'; 43637c478bd9Sstevel@tonic-gate } 43647c478bd9Sstevel@tonic-gate 43657c478bd9Sstevel@tonic-gate if (map->map_app != NULL) 43667c478bd9Sstevel@tonic-gate map->map_app = newstr(ldapmap_dequote(map->map_app)); 43677c478bd9Sstevel@tonic-gate if (map->map_tapp != NULL) 43687c478bd9Sstevel@tonic-gate map->map_tapp = newstr(ldapmap_dequote(map->map_tapp)); 43697c478bd9Sstevel@tonic-gate 43707c478bd9Sstevel@tonic-gate /* 43717c478bd9Sstevel@tonic-gate ** We need to swallow up all the stuff into a struct 43727c478bd9Sstevel@tonic-gate ** and dump it into map->map_dbptr1 43737c478bd9Sstevel@tonic-gate */ 43747c478bd9Sstevel@tonic-gate 43757c478bd9Sstevel@tonic-gate if (lmap->ldap_host != NULL && 43767c478bd9Sstevel@tonic-gate (LDAPDefaults == NULL || 43777c478bd9Sstevel@tonic-gate LDAPDefaults == lmap || 43787c478bd9Sstevel@tonic-gate LDAPDefaults->ldap_host != lmap->ldap_host)) 43797c478bd9Sstevel@tonic-gate lmap->ldap_host = newstr(ldapmap_dequote(lmap->ldap_host)); 43807c478bd9Sstevel@tonic-gate map->map_domain = lmap->ldap_host; 43817c478bd9Sstevel@tonic-gate 43827c478bd9Sstevel@tonic-gate if (lmap->ldap_uri != NULL && 43837c478bd9Sstevel@tonic-gate (LDAPDefaults == NULL || 43847c478bd9Sstevel@tonic-gate LDAPDefaults == lmap || 43857c478bd9Sstevel@tonic-gate LDAPDefaults->ldap_uri != lmap->ldap_uri)) 43867c478bd9Sstevel@tonic-gate lmap->ldap_uri = newstr(ldapmap_dequote(lmap->ldap_uri)); 43877c478bd9Sstevel@tonic-gate map->map_domain = lmap->ldap_uri; 43887c478bd9Sstevel@tonic-gate 43897c478bd9Sstevel@tonic-gate if (lmap->ldap_binddn != NULL && 43907c478bd9Sstevel@tonic-gate (LDAPDefaults == NULL || 43917c478bd9Sstevel@tonic-gate LDAPDefaults == lmap || 43927c478bd9Sstevel@tonic-gate LDAPDefaults->ldap_binddn != lmap->ldap_binddn)) 43937c478bd9Sstevel@tonic-gate lmap->ldap_binddn = newstr(ldapmap_dequote(lmap->ldap_binddn)); 43947c478bd9Sstevel@tonic-gate 43957c478bd9Sstevel@tonic-gate if (lmap->ldap_secret != NULL && 43967c478bd9Sstevel@tonic-gate (LDAPDefaults == NULL || 43977c478bd9Sstevel@tonic-gate LDAPDefaults == lmap || 43987c478bd9Sstevel@tonic-gate LDAPDefaults->ldap_secret != lmap->ldap_secret)) 43997c478bd9Sstevel@tonic-gate { 44007c478bd9Sstevel@tonic-gate SM_FILE_T *sfd; 44017c478bd9Sstevel@tonic-gate long sff = SFF_OPENASROOT|SFF_ROOTOK|SFF_NOWLINK|SFF_NOWWFILES|SFF_NOGWFILES; 44027c478bd9Sstevel@tonic-gate 44037c478bd9Sstevel@tonic-gate if (DontLockReadFiles) 44047c478bd9Sstevel@tonic-gate sff |= SFF_NOLOCK; 44057c478bd9Sstevel@tonic-gate 44067c478bd9Sstevel@tonic-gate /* need to use method to map secret to passwd string */ 44077c478bd9Sstevel@tonic-gate switch (lmap->ldap_method) 44087c478bd9Sstevel@tonic-gate { 44097c478bd9Sstevel@tonic-gate case LDAP_AUTH_NONE: 44107c478bd9Sstevel@tonic-gate /* Do nothing */ 44117c478bd9Sstevel@tonic-gate break; 44127c478bd9Sstevel@tonic-gate 44137c478bd9Sstevel@tonic-gate case LDAP_AUTH_SIMPLE: 44147c478bd9Sstevel@tonic-gate 44157c478bd9Sstevel@tonic-gate /* 44167c478bd9Sstevel@tonic-gate ** Secret is the name of a file with 44177c478bd9Sstevel@tonic-gate ** the first line as the password. 44187c478bd9Sstevel@tonic-gate */ 44197c478bd9Sstevel@tonic-gate 44207c478bd9Sstevel@tonic-gate /* Already read in the secret? */ 44217c478bd9Sstevel@tonic-gate if (secretread) 44227c478bd9Sstevel@tonic-gate break; 44237c478bd9Sstevel@tonic-gate 44247c478bd9Sstevel@tonic-gate sfd = safefopen(ldapmap_dequote(lmap->ldap_secret), 44257c478bd9Sstevel@tonic-gate O_RDONLY, 0, sff); 44267c478bd9Sstevel@tonic-gate if (sfd == NULL) 44277c478bd9Sstevel@tonic-gate { 44287c478bd9Sstevel@tonic-gate syserr("LDAP map: cannot open secret %s", 44297c478bd9Sstevel@tonic-gate ldapmap_dequote(lmap->ldap_secret)); 44307c478bd9Sstevel@tonic-gate return false; 44317c478bd9Sstevel@tonic-gate } 4432058561cbSjbeck lmap->ldap_secret = sfgets(m_tmp, sizeof(m_tmp), 44337c478bd9Sstevel@tonic-gate sfd, TimeOuts.to_fileopen, 44347c478bd9Sstevel@tonic-gate "ldapmap_parseargs"); 44357c478bd9Sstevel@tonic-gate (void) sm_io_close(sfd, SM_TIME_DEFAULT); 44367c478bd9Sstevel@tonic-gate if (strlen(m_tmp) > LDAPMAP_MAX_PASSWD) 44377c478bd9Sstevel@tonic-gate { 44387c478bd9Sstevel@tonic-gate syserr("LDAP map: secret in %s too long", 44397c478bd9Sstevel@tonic-gate ldapmap_dequote(lmap->ldap_secret)); 44407c478bd9Sstevel@tonic-gate return false; 44417c478bd9Sstevel@tonic-gate } 44427c478bd9Sstevel@tonic-gate if (lmap->ldap_secret != NULL && 44437c478bd9Sstevel@tonic-gate strlen(m_tmp) > 0) 44447c478bd9Sstevel@tonic-gate { 44457c478bd9Sstevel@tonic-gate /* chomp newline */ 44467c478bd9Sstevel@tonic-gate if (m_tmp[strlen(m_tmp) - 1] == '\n') 44477c478bd9Sstevel@tonic-gate m_tmp[strlen(m_tmp) - 1] = '\0'; 44487c478bd9Sstevel@tonic-gate 44497c478bd9Sstevel@tonic-gate lmap->ldap_secret = m_tmp; 44507c478bd9Sstevel@tonic-gate } 44517c478bd9Sstevel@tonic-gate break; 44527c478bd9Sstevel@tonic-gate 44537c478bd9Sstevel@tonic-gate # ifdef LDAP_AUTH_KRBV4 44547c478bd9Sstevel@tonic-gate case LDAP_AUTH_KRBV4: 44557c478bd9Sstevel@tonic-gate 44567c478bd9Sstevel@tonic-gate /* 44577c478bd9Sstevel@tonic-gate ** Secret is where the ticket file is 44587c478bd9Sstevel@tonic-gate ** stashed 44597c478bd9Sstevel@tonic-gate */ 44607c478bd9Sstevel@tonic-gate 4461058561cbSjbeck (void) sm_snprintf(m_tmp, sizeof(m_tmp), 44627c478bd9Sstevel@tonic-gate "KRBTKFILE=%s", 44637c478bd9Sstevel@tonic-gate ldapmap_dequote(lmap->ldap_secret)); 44647c478bd9Sstevel@tonic-gate lmap->ldap_secret = m_tmp; 44657c478bd9Sstevel@tonic-gate break; 44667c478bd9Sstevel@tonic-gate # endif /* LDAP_AUTH_KRBV4 */ 44677c478bd9Sstevel@tonic-gate 44687c478bd9Sstevel@tonic-gate default: /* Should NEVER get here */ 44697c478bd9Sstevel@tonic-gate syserr("LDAP map: Illegal value in lmap method"); 44707c478bd9Sstevel@tonic-gate return false; 44717c478bd9Sstevel@tonic-gate /* NOTREACHED */ 44727c478bd9Sstevel@tonic-gate break; 44737c478bd9Sstevel@tonic-gate } 44747c478bd9Sstevel@tonic-gate } 44757c478bd9Sstevel@tonic-gate 44767c478bd9Sstevel@tonic-gate if (lmap->ldap_secret != NULL && 44777c478bd9Sstevel@tonic-gate (LDAPDefaults == NULL || 44787c478bd9Sstevel@tonic-gate LDAPDefaults == lmap || 44797c478bd9Sstevel@tonic-gate LDAPDefaults->ldap_secret != lmap->ldap_secret)) 44807c478bd9Sstevel@tonic-gate lmap->ldap_secret = newstr(ldapmap_dequote(lmap->ldap_secret)); 44817c478bd9Sstevel@tonic-gate 44827c478bd9Sstevel@tonic-gate if (lmap->ldap_base != NULL && 44837c478bd9Sstevel@tonic-gate (LDAPDefaults == NULL || 44847c478bd9Sstevel@tonic-gate LDAPDefaults == lmap || 44857c478bd9Sstevel@tonic-gate LDAPDefaults->ldap_base != lmap->ldap_base)) 44867c478bd9Sstevel@tonic-gate lmap->ldap_base = newstr(ldapmap_dequote(lmap->ldap_base)); 44877c478bd9Sstevel@tonic-gate 44887c478bd9Sstevel@tonic-gate /* 44897c478bd9Sstevel@tonic-gate ** Save the server from extra work. If request is for a single 44907c478bd9Sstevel@tonic-gate ** match, tell the server to only return enough records to 44917c478bd9Sstevel@tonic-gate ** determine if there is a single match or not. This can not 44927c478bd9Sstevel@tonic-gate ** be one since the server would only return one and we wouldn't 44937c478bd9Sstevel@tonic-gate ** know if there were others available. 44947c478bd9Sstevel@tonic-gate */ 44957c478bd9Sstevel@tonic-gate 44967c478bd9Sstevel@tonic-gate if (bitset(MF_SINGLEMATCH, map->map_mflags)) 44977c478bd9Sstevel@tonic-gate lmap->ldap_sizelimit = 2; 44987c478bd9Sstevel@tonic-gate 44997c478bd9Sstevel@tonic-gate /* If setting defaults, don't process ldap_filter and ldap_attr */ 45007c478bd9Sstevel@tonic-gate if (lmap == LDAPDefaults) 45017c478bd9Sstevel@tonic-gate return true; 45027c478bd9Sstevel@tonic-gate 45037c478bd9Sstevel@tonic-gate if (lmap->ldap_filter != NULL) 45047c478bd9Sstevel@tonic-gate lmap->ldap_filter = newstr(ldapmap_dequote(lmap->ldap_filter)); 45057c478bd9Sstevel@tonic-gate else 45067c478bd9Sstevel@tonic-gate { 45077c478bd9Sstevel@tonic-gate if (!bitset(MCF_OPTFILE, map->map_class->map_cflags)) 45087c478bd9Sstevel@tonic-gate { 45097c478bd9Sstevel@tonic-gate syserr("No filter given in map %s", map->map_mname); 45107c478bd9Sstevel@tonic-gate return false; 45117c478bd9Sstevel@tonic-gate } 45127c478bd9Sstevel@tonic-gate } 45137c478bd9Sstevel@tonic-gate 45147c478bd9Sstevel@tonic-gate if (!attrssetup && lmap->ldap_attr[0] != NULL) 45157c478bd9Sstevel@tonic-gate { 45167c478bd9Sstevel@tonic-gate bool recurse = false; 45177c478bd9Sstevel@tonic-gate bool normalseen = false; 45187c478bd9Sstevel@tonic-gate 45197c478bd9Sstevel@tonic-gate i = 0; 45207c478bd9Sstevel@tonic-gate p = ldapmap_dequote(lmap->ldap_attr[0]); 45217c478bd9Sstevel@tonic-gate lmap->ldap_attr[0] = NULL; 45227c478bd9Sstevel@tonic-gate 45237c478bd9Sstevel@tonic-gate /* Prime the attr list with the objectClass attribute */ 45247c478bd9Sstevel@tonic-gate lmap->ldap_attr[i] = "objectClass"; 45257c478bd9Sstevel@tonic-gate lmap->ldap_attr_type[i] = SM_LDAP_ATTR_OBJCLASS; 45267c478bd9Sstevel@tonic-gate lmap->ldap_attr_needobjclass[i] = NULL; 45277c478bd9Sstevel@tonic-gate i++; 45287c478bd9Sstevel@tonic-gate 45297c478bd9Sstevel@tonic-gate while (p != NULL) 45307c478bd9Sstevel@tonic-gate { 45317c478bd9Sstevel@tonic-gate char *v; 45327c478bd9Sstevel@tonic-gate 45337c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 45347c478bd9Sstevel@tonic-gate p++; 45357c478bd9Sstevel@tonic-gate if (*p == '\0') 45367c478bd9Sstevel@tonic-gate break; 45377c478bd9Sstevel@tonic-gate v = p; 45387c478bd9Sstevel@tonic-gate p = strchr(v, ','); 45397c478bd9Sstevel@tonic-gate if (p != NULL) 45407c478bd9Sstevel@tonic-gate *p++ = '\0'; 45417c478bd9Sstevel@tonic-gate 45427c478bd9Sstevel@tonic-gate if (i >= LDAPMAP_MAX_ATTR) 45437c478bd9Sstevel@tonic-gate { 45447c478bd9Sstevel@tonic-gate syserr("Too many return attributes in %s (max %d)", 45457c478bd9Sstevel@tonic-gate map->map_mname, LDAPMAP_MAX_ATTR); 45467c478bd9Sstevel@tonic-gate return false; 45477c478bd9Sstevel@tonic-gate } 45487c478bd9Sstevel@tonic-gate if (*v != '\0') 45497c478bd9Sstevel@tonic-gate { 45507c478bd9Sstevel@tonic-gate int j; 45517c478bd9Sstevel@tonic-gate int use; 45527c478bd9Sstevel@tonic-gate char *type; 45537c478bd9Sstevel@tonic-gate char *needobjclass; 45547c478bd9Sstevel@tonic-gate 45557c478bd9Sstevel@tonic-gate type = strchr(v, ':'); 45567c478bd9Sstevel@tonic-gate if (type != NULL) 45577c478bd9Sstevel@tonic-gate { 45587c478bd9Sstevel@tonic-gate *type++ = '\0'; 45597c478bd9Sstevel@tonic-gate needobjclass = strchr(type, ':'); 45607c478bd9Sstevel@tonic-gate if (needobjclass != NULL) 45617c478bd9Sstevel@tonic-gate *needobjclass++ = '\0'; 45627c478bd9Sstevel@tonic-gate } 45637c478bd9Sstevel@tonic-gate else 45647c478bd9Sstevel@tonic-gate { 45657c478bd9Sstevel@tonic-gate needobjclass = NULL; 45667c478bd9Sstevel@tonic-gate } 45677c478bd9Sstevel@tonic-gate 45687c478bd9Sstevel@tonic-gate use = i; 45697c478bd9Sstevel@tonic-gate 45707c478bd9Sstevel@tonic-gate /* allow override on "objectClass" type */ 45717c478bd9Sstevel@tonic-gate if (sm_strcasecmp(v, "objectClass") == 0 && 45727c478bd9Sstevel@tonic-gate lmap->ldap_attr_type[0] == SM_LDAP_ATTR_OBJCLASS) 45737c478bd9Sstevel@tonic-gate { 45747c478bd9Sstevel@tonic-gate use = 0; 45757c478bd9Sstevel@tonic-gate } 45767c478bd9Sstevel@tonic-gate else 45777c478bd9Sstevel@tonic-gate { 45787c478bd9Sstevel@tonic-gate /* 45797c478bd9Sstevel@tonic-gate ** Don't add something to attribute 45807c478bd9Sstevel@tonic-gate ** list twice. 45817c478bd9Sstevel@tonic-gate */ 45827c478bd9Sstevel@tonic-gate 45837c478bd9Sstevel@tonic-gate for (j = 1; j < i; j++) 45847c478bd9Sstevel@tonic-gate { 45857c478bd9Sstevel@tonic-gate if (sm_strcasecmp(v, lmap->ldap_attr[j]) == 0) 45867c478bd9Sstevel@tonic-gate { 45877c478bd9Sstevel@tonic-gate syserr("Duplicate attribute (%s) in %s", 45887c478bd9Sstevel@tonic-gate v, map->map_mname); 45897c478bd9Sstevel@tonic-gate return false; 45907c478bd9Sstevel@tonic-gate } 45917c478bd9Sstevel@tonic-gate } 45927c478bd9Sstevel@tonic-gate 45937c478bd9Sstevel@tonic-gate lmap->ldap_attr[use] = newstr(v); 45947c478bd9Sstevel@tonic-gate if (needobjclass != NULL && 45957c478bd9Sstevel@tonic-gate *needobjclass != '\0' && 45967c478bd9Sstevel@tonic-gate *needobjclass != '*') 45977c478bd9Sstevel@tonic-gate { 45987c478bd9Sstevel@tonic-gate lmap->ldap_attr_needobjclass[use] = newstr(needobjclass); 45997c478bd9Sstevel@tonic-gate } 46007c478bd9Sstevel@tonic-gate else 46017c478bd9Sstevel@tonic-gate { 46027c478bd9Sstevel@tonic-gate lmap->ldap_attr_needobjclass[use] = NULL; 46037c478bd9Sstevel@tonic-gate } 46047c478bd9Sstevel@tonic-gate 46057c478bd9Sstevel@tonic-gate } 46067c478bd9Sstevel@tonic-gate 46077c478bd9Sstevel@tonic-gate if (type != NULL && *type != '\0') 46087c478bd9Sstevel@tonic-gate { 46097c478bd9Sstevel@tonic-gate if (sm_strcasecmp(type, "dn") == 0) 46107c478bd9Sstevel@tonic-gate { 46117c478bd9Sstevel@tonic-gate recurse = true; 46127c478bd9Sstevel@tonic-gate lmap->ldap_attr_type[use] = SM_LDAP_ATTR_DN; 46137c478bd9Sstevel@tonic-gate } 46147c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(type, "filter") == 0) 46157c478bd9Sstevel@tonic-gate { 46167c478bd9Sstevel@tonic-gate recurse = true; 46177c478bd9Sstevel@tonic-gate lmap->ldap_attr_type[use] = SM_LDAP_ATTR_FILTER; 46187c478bd9Sstevel@tonic-gate } 46197c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(type, "url") == 0) 46207c478bd9Sstevel@tonic-gate { 46217c478bd9Sstevel@tonic-gate recurse = true; 46227c478bd9Sstevel@tonic-gate lmap->ldap_attr_type[use] = SM_LDAP_ATTR_URL; 46237c478bd9Sstevel@tonic-gate } 46247c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(type, "normal") == 0) 46257c478bd9Sstevel@tonic-gate { 46267c478bd9Sstevel@tonic-gate lmap->ldap_attr_type[use] = SM_LDAP_ATTR_NORMAL; 46277c478bd9Sstevel@tonic-gate normalseen = true; 46287c478bd9Sstevel@tonic-gate } 46297c478bd9Sstevel@tonic-gate else 46307c478bd9Sstevel@tonic-gate { 46317c478bd9Sstevel@tonic-gate syserr("Unknown attribute type (%s) in %s", 46327c478bd9Sstevel@tonic-gate type, map->map_mname); 46337c478bd9Sstevel@tonic-gate return false; 46347c478bd9Sstevel@tonic-gate } 46357c478bd9Sstevel@tonic-gate } 46367c478bd9Sstevel@tonic-gate else 46377c478bd9Sstevel@tonic-gate { 46387c478bd9Sstevel@tonic-gate lmap->ldap_attr_type[use] = SM_LDAP_ATTR_NORMAL; 46397c478bd9Sstevel@tonic-gate normalseen = true; 46407c478bd9Sstevel@tonic-gate } 46417c478bd9Sstevel@tonic-gate i++; 46427c478bd9Sstevel@tonic-gate } 46437c478bd9Sstevel@tonic-gate } 46447c478bd9Sstevel@tonic-gate lmap->ldap_attr[i] = NULL; 46457c478bd9Sstevel@tonic-gate 46467c478bd9Sstevel@tonic-gate /* Set in case needed in future code */ 46477c478bd9Sstevel@tonic-gate attrssetup = true; 46487c478bd9Sstevel@tonic-gate 46497c478bd9Sstevel@tonic-gate if (recurse && !normalseen) 46507c478bd9Sstevel@tonic-gate { 46517c478bd9Sstevel@tonic-gate syserr("LDAP recursion requested in %s but no returnable attribute given", 46527c478bd9Sstevel@tonic-gate map->map_mname); 46537c478bd9Sstevel@tonic-gate return false; 46547c478bd9Sstevel@tonic-gate } 46557c478bd9Sstevel@tonic-gate if (recurse && lmap->ldap_attrsonly == LDAPMAP_TRUE) 46567c478bd9Sstevel@tonic-gate { 46577c478bd9Sstevel@tonic-gate syserr("LDAP recursion requested in %s can not be used with -n", 46587c478bd9Sstevel@tonic-gate map->map_mname); 46597c478bd9Sstevel@tonic-gate return false; 46607c478bd9Sstevel@tonic-gate } 46617c478bd9Sstevel@tonic-gate } 46627c478bd9Sstevel@tonic-gate map->map_db1 = (ARBPTR_T) lmap; 46637c478bd9Sstevel@tonic-gate return true; 46647c478bd9Sstevel@tonic-gate } 46657c478bd9Sstevel@tonic-gate 46667c478bd9Sstevel@tonic-gate /* 46677c478bd9Sstevel@tonic-gate ** LDAPMAP_SET_DEFAULTS -- Read default map spec from LDAPDefaults in .cf 46687c478bd9Sstevel@tonic-gate ** 46697c478bd9Sstevel@tonic-gate ** Parameters: 46707c478bd9Sstevel@tonic-gate ** spec -- map argument string from LDAPDefaults option 46717c478bd9Sstevel@tonic-gate ** 46727c478bd9Sstevel@tonic-gate ** Returns: 46737c478bd9Sstevel@tonic-gate ** None. 46747c478bd9Sstevel@tonic-gate */ 46757c478bd9Sstevel@tonic-gate 46767c478bd9Sstevel@tonic-gate void 46777c478bd9Sstevel@tonic-gate ldapmap_set_defaults(spec) 46787c478bd9Sstevel@tonic-gate char *spec; 46797c478bd9Sstevel@tonic-gate { 46807c478bd9Sstevel@tonic-gate STAB *class; 46817c478bd9Sstevel@tonic-gate MAP map; 46827c478bd9Sstevel@tonic-gate 46837c478bd9Sstevel@tonic-gate /* Allocate and set the default values */ 46847c478bd9Sstevel@tonic-gate if (LDAPDefaults == NULL) 4685058561cbSjbeck LDAPDefaults = (SM_LDAP_STRUCT *) xalloc(sizeof(*LDAPDefaults)); 46867c478bd9Sstevel@tonic-gate sm_ldap_clear(LDAPDefaults); 46877c478bd9Sstevel@tonic-gate 4688058561cbSjbeck memset(&map, '\0', sizeof(map)); 46897c478bd9Sstevel@tonic-gate 46907c478bd9Sstevel@tonic-gate /* look up the class */ 46917c478bd9Sstevel@tonic-gate class = stab("ldap", ST_MAPCLASS, ST_FIND); 46927c478bd9Sstevel@tonic-gate if (class == NULL) 46937c478bd9Sstevel@tonic-gate { 46947c478bd9Sstevel@tonic-gate syserr("readcf: LDAPDefaultSpec: class ldap not available"); 46957c478bd9Sstevel@tonic-gate return; 46967c478bd9Sstevel@tonic-gate } 46977c478bd9Sstevel@tonic-gate map.map_class = &class->s_mapclass; 46987c478bd9Sstevel@tonic-gate map.map_db1 = (ARBPTR_T) LDAPDefaults; 46997c478bd9Sstevel@tonic-gate map.map_mname = "O LDAPDefaultSpec"; 47007c478bd9Sstevel@tonic-gate 47017c478bd9Sstevel@tonic-gate (void) ldapmap_parseargs(&map, spec); 47027c478bd9Sstevel@tonic-gate 47037c478bd9Sstevel@tonic-gate /* These should never be set in LDAPDefaults */ 47047c478bd9Sstevel@tonic-gate if (map.map_mflags != (MF_TRY0NULL|MF_TRY1NULL) || 47057c478bd9Sstevel@tonic-gate map.map_spacesub != SpaceSub || 47067c478bd9Sstevel@tonic-gate map.map_app != NULL || 47077c478bd9Sstevel@tonic-gate map.map_tapp != NULL) 47087c478bd9Sstevel@tonic-gate { 47097c478bd9Sstevel@tonic-gate syserr("readcf: option LDAPDefaultSpec: Do not set non-LDAP specific flags"); 47107c478bd9Sstevel@tonic-gate SM_FREE_CLR(map.map_app); 47117c478bd9Sstevel@tonic-gate SM_FREE_CLR(map.map_tapp); 47127c478bd9Sstevel@tonic-gate } 47137c478bd9Sstevel@tonic-gate 47147c478bd9Sstevel@tonic-gate if (LDAPDefaults->ldap_filter != NULL) 47157c478bd9Sstevel@tonic-gate { 47167c478bd9Sstevel@tonic-gate syserr("readcf: option LDAPDefaultSpec: Do not set the LDAP search filter"); 47177c478bd9Sstevel@tonic-gate 47187c478bd9Sstevel@tonic-gate /* don't free, it isn't malloc'ed in parseargs */ 47197c478bd9Sstevel@tonic-gate LDAPDefaults->ldap_filter = NULL; 47207c478bd9Sstevel@tonic-gate } 47217c478bd9Sstevel@tonic-gate 47227c478bd9Sstevel@tonic-gate if (LDAPDefaults->ldap_attr[0] != NULL) 47237c478bd9Sstevel@tonic-gate { 47247c478bd9Sstevel@tonic-gate syserr("readcf: option LDAPDefaultSpec: Do not set the requested LDAP attributes"); 47257c478bd9Sstevel@tonic-gate /* don't free, they aren't malloc'ed in parseargs */ 47267c478bd9Sstevel@tonic-gate LDAPDefaults->ldap_attr[0] = NULL; 47277c478bd9Sstevel@tonic-gate } 47287c478bd9Sstevel@tonic-gate } 47297c478bd9Sstevel@tonic-gate #endif /* LDAPMAP */ 47307c478bd9Sstevel@tonic-gate /* 47317c478bd9Sstevel@tonic-gate ** PH map 47327c478bd9Sstevel@tonic-gate */ 47337c478bd9Sstevel@tonic-gate 47347c478bd9Sstevel@tonic-gate #if PH_MAP 47357c478bd9Sstevel@tonic-gate 47367c478bd9Sstevel@tonic-gate /* 47377c478bd9Sstevel@tonic-gate ** Support for the CCSO Nameserver (ph/qi). 47387c478bd9Sstevel@tonic-gate ** This code is intended to replace the so-called "ph mailer". 47394aac33d3Sjbeck ** Contributed by Mark D. Roth. Contact him for support. 47407c478bd9Sstevel@tonic-gate */ 47417c478bd9Sstevel@tonic-gate 47427c478bd9Sstevel@tonic-gate /* what version of the ph map code we're running */ 47437c478bd9Sstevel@tonic-gate static char phmap_id[128]; 47447c478bd9Sstevel@tonic-gate 47457c478bd9Sstevel@tonic-gate /* sendmail version for phmap id string */ 47467c478bd9Sstevel@tonic-gate extern const char Version[]; 47477c478bd9Sstevel@tonic-gate 47487c478bd9Sstevel@tonic-gate /* assume we're using nph-1.2.x if not specified */ 47497c478bd9Sstevel@tonic-gate # ifndef NPH_VERSION 47507c478bd9Sstevel@tonic-gate # define NPH_VERSION 10200 47517c478bd9Sstevel@tonic-gate # endif 47527c478bd9Sstevel@tonic-gate 47537c478bd9Sstevel@tonic-gate /* compatibility for versions older than nph-1.2.0 */ 47547c478bd9Sstevel@tonic-gate # if NPH_VERSION < 10200 47557c478bd9Sstevel@tonic-gate # define PH_OPEN_ROUNDROBIN PH_ROUNDROBIN 47567c478bd9Sstevel@tonic-gate # define PH_OPEN_DONTID PH_DONTID 47577c478bd9Sstevel@tonic-gate # define PH_CLOSE_FAST PH_FASTCLOSE 47587c478bd9Sstevel@tonic-gate # define PH_ERR_DATAERR PH_DATAERR 47597c478bd9Sstevel@tonic-gate # define PH_ERR_NOMATCH PH_NOMATCH 47607c478bd9Sstevel@tonic-gate # endif /* NPH_VERSION < 10200 */ 47617c478bd9Sstevel@tonic-gate 47627c478bd9Sstevel@tonic-gate /* 47637c478bd9Sstevel@tonic-gate ** PH_MAP_PARSEARGS -- parse ph map definition args. 47647c478bd9Sstevel@tonic-gate */ 47657c478bd9Sstevel@tonic-gate 47667c478bd9Sstevel@tonic-gate bool 47677c478bd9Sstevel@tonic-gate ph_map_parseargs(map, args) 47687c478bd9Sstevel@tonic-gate MAP *map; 47697c478bd9Sstevel@tonic-gate char *args; 47707c478bd9Sstevel@tonic-gate { 47717c478bd9Sstevel@tonic-gate register bool done; 47727c478bd9Sstevel@tonic-gate register char *p = args; 47737c478bd9Sstevel@tonic-gate PH_MAP_STRUCT *pmap = NULL; 47747c478bd9Sstevel@tonic-gate 47757c478bd9Sstevel@tonic-gate /* initialize version string */ 4776058561cbSjbeck (void) sm_snprintf(phmap_id, sizeof(phmap_id), 47777c478bd9Sstevel@tonic-gate "sendmail-%s phmap-20010529 libphclient-%s", 47787c478bd9Sstevel@tonic-gate Version, libphclient_version); 47797c478bd9Sstevel@tonic-gate 4780058561cbSjbeck pmap = (PH_MAP_STRUCT *) xalloc(sizeof(*pmap)); 47817c478bd9Sstevel@tonic-gate 47827c478bd9Sstevel@tonic-gate /* defaults */ 47837c478bd9Sstevel@tonic-gate pmap->ph_servers = NULL; 47847c478bd9Sstevel@tonic-gate pmap->ph_field_list = NULL; 47857c478bd9Sstevel@tonic-gate pmap->ph = NULL; 47867c478bd9Sstevel@tonic-gate pmap->ph_timeout = 0; 47877c478bd9Sstevel@tonic-gate pmap->ph_fastclose = 0; 47887c478bd9Sstevel@tonic-gate 47897c478bd9Sstevel@tonic-gate map->map_mflags |= MF_TRY0NULL|MF_TRY1NULL; 47907c478bd9Sstevel@tonic-gate for (;;) 47917c478bd9Sstevel@tonic-gate { 47927c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 47937c478bd9Sstevel@tonic-gate p++; 47947c478bd9Sstevel@tonic-gate if (*p != '-') 47957c478bd9Sstevel@tonic-gate break; 47967c478bd9Sstevel@tonic-gate switch (*++p) 47977c478bd9Sstevel@tonic-gate { 47987c478bd9Sstevel@tonic-gate case 'N': 47997c478bd9Sstevel@tonic-gate map->map_mflags |= MF_INCLNULL; 48007c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_TRY0NULL; 48017c478bd9Sstevel@tonic-gate break; 48027c478bd9Sstevel@tonic-gate 48037c478bd9Sstevel@tonic-gate case 'O': 48047c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_TRY1NULL; 48057c478bd9Sstevel@tonic-gate break; 48067c478bd9Sstevel@tonic-gate 48077c478bd9Sstevel@tonic-gate case 'o': 48087c478bd9Sstevel@tonic-gate map->map_mflags |= MF_OPTIONAL; 48097c478bd9Sstevel@tonic-gate break; 48107c478bd9Sstevel@tonic-gate 48117c478bd9Sstevel@tonic-gate case 'f': 48127c478bd9Sstevel@tonic-gate map->map_mflags |= MF_NOFOLDCASE; 48137c478bd9Sstevel@tonic-gate break; 48147c478bd9Sstevel@tonic-gate 48157c478bd9Sstevel@tonic-gate case 'm': 48167c478bd9Sstevel@tonic-gate map->map_mflags |= MF_MATCHONLY; 48177c478bd9Sstevel@tonic-gate break; 48187c478bd9Sstevel@tonic-gate 48197c478bd9Sstevel@tonic-gate case 'A': 48207c478bd9Sstevel@tonic-gate map->map_mflags |= MF_APPEND; 48217c478bd9Sstevel@tonic-gate break; 48227c478bd9Sstevel@tonic-gate 48237c478bd9Sstevel@tonic-gate case 'q': 48247c478bd9Sstevel@tonic-gate map->map_mflags |= MF_KEEPQUOTES; 48257c478bd9Sstevel@tonic-gate break; 48267c478bd9Sstevel@tonic-gate 48277c478bd9Sstevel@tonic-gate case 't': 48287c478bd9Sstevel@tonic-gate map->map_mflags |= MF_NODEFER; 48297c478bd9Sstevel@tonic-gate break; 48307c478bd9Sstevel@tonic-gate 48317c478bd9Sstevel@tonic-gate case 'a': 48327c478bd9Sstevel@tonic-gate map->map_app = ++p; 48337c478bd9Sstevel@tonic-gate break; 48347c478bd9Sstevel@tonic-gate 48357c478bd9Sstevel@tonic-gate case 'T': 48367c478bd9Sstevel@tonic-gate map->map_tapp = ++p; 48377c478bd9Sstevel@tonic-gate break; 48387c478bd9Sstevel@tonic-gate 48397c478bd9Sstevel@tonic-gate case 'l': 48407c478bd9Sstevel@tonic-gate while (isascii(*++p) && isspace(*p)) 48417c478bd9Sstevel@tonic-gate continue; 48427c478bd9Sstevel@tonic-gate pmap->ph_timeout = atoi(p); 48437c478bd9Sstevel@tonic-gate break; 48447c478bd9Sstevel@tonic-gate 48457c478bd9Sstevel@tonic-gate case 'S': 48467c478bd9Sstevel@tonic-gate map->map_spacesub = *++p; 48477c478bd9Sstevel@tonic-gate break; 48487c478bd9Sstevel@tonic-gate 48497c478bd9Sstevel@tonic-gate case 'D': 48507c478bd9Sstevel@tonic-gate map->map_mflags |= MF_DEFER; 48517c478bd9Sstevel@tonic-gate break; 48527c478bd9Sstevel@tonic-gate 48537c478bd9Sstevel@tonic-gate case 'h': /* PH server list */ 48547c478bd9Sstevel@tonic-gate while (isascii(*++p) && isspace(*p)) 48557c478bd9Sstevel@tonic-gate continue; 48567c478bd9Sstevel@tonic-gate pmap->ph_servers = p; 48577c478bd9Sstevel@tonic-gate break; 48587c478bd9Sstevel@tonic-gate 48597c478bd9Sstevel@tonic-gate case 'k': /* fields to search for */ 48607c478bd9Sstevel@tonic-gate while (isascii(*++p) && isspace(*p)) 48617c478bd9Sstevel@tonic-gate continue; 48627c478bd9Sstevel@tonic-gate pmap->ph_field_list = p; 48637c478bd9Sstevel@tonic-gate break; 48647c478bd9Sstevel@tonic-gate 48657c478bd9Sstevel@tonic-gate default: 48667c478bd9Sstevel@tonic-gate syserr("ph_map_parseargs: unknown option -%c", *p); 48677c478bd9Sstevel@tonic-gate } 48687c478bd9Sstevel@tonic-gate 48697c478bd9Sstevel@tonic-gate /* try to account for quoted strings */ 48707c478bd9Sstevel@tonic-gate done = isascii(*p) && isspace(*p); 48717c478bd9Sstevel@tonic-gate while (*p != '\0' && !done) 48727c478bd9Sstevel@tonic-gate { 48737c478bd9Sstevel@tonic-gate if (*p == '"') 48747c478bd9Sstevel@tonic-gate { 48757c478bd9Sstevel@tonic-gate while (*++p != '"' && *p != '\0') 48767c478bd9Sstevel@tonic-gate continue; 48777c478bd9Sstevel@tonic-gate if (*p != '\0') 48787c478bd9Sstevel@tonic-gate p++; 48797c478bd9Sstevel@tonic-gate } 48807c478bd9Sstevel@tonic-gate else 48817c478bd9Sstevel@tonic-gate p++; 48827c478bd9Sstevel@tonic-gate done = isascii(*p) && isspace(*p); 48837c478bd9Sstevel@tonic-gate } 48847c478bd9Sstevel@tonic-gate 48857c478bd9Sstevel@tonic-gate if (*p != '\0') 48867c478bd9Sstevel@tonic-gate *p++ = '\0'; 48877c478bd9Sstevel@tonic-gate } 48887c478bd9Sstevel@tonic-gate 48897c478bd9Sstevel@tonic-gate if (map->map_app != NULL) 48907c478bd9Sstevel@tonic-gate map->map_app = newstr(ph_map_dequote(map->map_app)); 48917c478bd9Sstevel@tonic-gate if (map->map_tapp != NULL) 48927c478bd9Sstevel@tonic-gate map->map_tapp = newstr(ph_map_dequote(map->map_tapp)); 48937c478bd9Sstevel@tonic-gate 48947c478bd9Sstevel@tonic-gate if (pmap->ph_field_list != NULL) 48957c478bd9Sstevel@tonic-gate pmap->ph_field_list = newstr(ph_map_dequote(pmap->ph_field_list)); 48967c478bd9Sstevel@tonic-gate 48977c478bd9Sstevel@tonic-gate if (pmap->ph_servers != NULL) 48987c478bd9Sstevel@tonic-gate pmap->ph_servers = newstr(ph_map_dequote(pmap->ph_servers)); 48997c478bd9Sstevel@tonic-gate else 49007c478bd9Sstevel@tonic-gate { 49017c478bd9Sstevel@tonic-gate syserr("ph_map_parseargs: -h flag is required"); 49027c478bd9Sstevel@tonic-gate return false; 49037c478bd9Sstevel@tonic-gate } 49047c478bd9Sstevel@tonic-gate 49057c478bd9Sstevel@tonic-gate map->map_db1 = (ARBPTR_T) pmap; 49067c478bd9Sstevel@tonic-gate return true; 49077c478bd9Sstevel@tonic-gate } 49087c478bd9Sstevel@tonic-gate 49097c478bd9Sstevel@tonic-gate /* 49107c478bd9Sstevel@tonic-gate ** PH_MAP_CLOSE -- close the connection to the ph server 49117c478bd9Sstevel@tonic-gate */ 49127c478bd9Sstevel@tonic-gate 49137c478bd9Sstevel@tonic-gate void 49147c478bd9Sstevel@tonic-gate ph_map_close(map) 49157c478bd9Sstevel@tonic-gate MAP *map; 49167c478bd9Sstevel@tonic-gate { 49177c478bd9Sstevel@tonic-gate PH_MAP_STRUCT *pmap; 49187c478bd9Sstevel@tonic-gate 49197c478bd9Sstevel@tonic-gate pmap = (PH_MAP_STRUCT *)map->map_db1; 49207c478bd9Sstevel@tonic-gate if (tTd(38, 9)) 49217c478bd9Sstevel@tonic-gate sm_dprintf("ph_map_close(%s): pmap->ph_fastclose=%d\n", 49227c478bd9Sstevel@tonic-gate map->map_mname, pmap->ph_fastclose); 49237c478bd9Sstevel@tonic-gate 49247c478bd9Sstevel@tonic-gate 49257c478bd9Sstevel@tonic-gate if (pmap->ph != NULL) 49267c478bd9Sstevel@tonic-gate { 49277c478bd9Sstevel@tonic-gate ph_set_sendhook(pmap->ph, NULL); 49287c478bd9Sstevel@tonic-gate ph_set_recvhook(pmap->ph, NULL); 49297c478bd9Sstevel@tonic-gate ph_close(pmap->ph, pmap->ph_fastclose); 49307c478bd9Sstevel@tonic-gate } 49317c478bd9Sstevel@tonic-gate 49327c478bd9Sstevel@tonic-gate map->map_mflags &= ~(MF_OPEN|MF_WRITABLE); 49337c478bd9Sstevel@tonic-gate } 49347c478bd9Sstevel@tonic-gate 49357c478bd9Sstevel@tonic-gate static jmp_buf PHTimeout; 49367c478bd9Sstevel@tonic-gate 49377c478bd9Sstevel@tonic-gate /* ARGSUSED */ 49387c478bd9Sstevel@tonic-gate static void 49397c478bd9Sstevel@tonic-gate ph_timeout(unused) 49407c478bd9Sstevel@tonic-gate int unused; 49417c478bd9Sstevel@tonic-gate { 49427c478bd9Sstevel@tonic-gate /* 49437c478bd9Sstevel@tonic-gate ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD 49447c478bd9Sstevel@tonic-gate ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE 49457c478bd9Sstevel@tonic-gate ** DOING. 49467c478bd9Sstevel@tonic-gate */ 49477c478bd9Sstevel@tonic-gate 49487c478bd9Sstevel@tonic-gate errno = ETIMEDOUT; 49497c478bd9Sstevel@tonic-gate longjmp(PHTimeout, 1); 49507c478bd9Sstevel@tonic-gate } 49517c478bd9Sstevel@tonic-gate 49527c478bd9Sstevel@tonic-gate static void 49537c478bd9Sstevel@tonic-gate #if NPH_VERSION >= 10200 49547c478bd9Sstevel@tonic-gate ph_map_send_debug(appdata, text) 49557c478bd9Sstevel@tonic-gate void *appdata; 49567c478bd9Sstevel@tonic-gate #else 49577c478bd9Sstevel@tonic-gate ph_map_send_debug(text) 49587c478bd9Sstevel@tonic-gate #endif 49597c478bd9Sstevel@tonic-gate char *text; 49607c478bd9Sstevel@tonic-gate { 49617c478bd9Sstevel@tonic-gate if (LogLevel > 9) 49627c478bd9Sstevel@tonic-gate sm_syslog(LOG_NOTICE, CurEnv->e_id, 49637c478bd9Sstevel@tonic-gate "ph_map_send_debug: ==> %s", text); 49647c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 49657c478bd9Sstevel@tonic-gate sm_dprintf("ph_map_send_debug: ==> %s\n", text); 49667c478bd9Sstevel@tonic-gate } 49677c478bd9Sstevel@tonic-gate 49687c478bd9Sstevel@tonic-gate static void 49697c478bd9Sstevel@tonic-gate #if NPH_VERSION >= 10200 49707c478bd9Sstevel@tonic-gate ph_map_recv_debug(appdata, text) 49717c478bd9Sstevel@tonic-gate void *appdata; 49727c478bd9Sstevel@tonic-gate #else 49737c478bd9Sstevel@tonic-gate ph_map_recv_debug(text) 49747c478bd9Sstevel@tonic-gate #endif 49757c478bd9Sstevel@tonic-gate char *text; 49767c478bd9Sstevel@tonic-gate { 49777c478bd9Sstevel@tonic-gate if (LogLevel > 10) 49787c478bd9Sstevel@tonic-gate sm_syslog(LOG_NOTICE, CurEnv->e_id, 49797c478bd9Sstevel@tonic-gate "ph_map_recv_debug: <== %s", text); 49807c478bd9Sstevel@tonic-gate if (tTd(38, 21)) 49817c478bd9Sstevel@tonic-gate sm_dprintf("ph_map_recv_debug: <== %s\n", text); 49827c478bd9Sstevel@tonic-gate } 49837c478bd9Sstevel@tonic-gate 49847c478bd9Sstevel@tonic-gate /* 49857c478bd9Sstevel@tonic-gate ** PH_MAP_OPEN -- sub for opening PH map 49867c478bd9Sstevel@tonic-gate */ 49877c478bd9Sstevel@tonic-gate bool 49887c478bd9Sstevel@tonic-gate ph_map_open(map, mode) 49897c478bd9Sstevel@tonic-gate MAP *map; 49907c478bd9Sstevel@tonic-gate int mode; 49917c478bd9Sstevel@tonic-gate { 49927c478bd9Sstevel@tonic-gate PH_MAP_STRUCT *pmap; 49937c478bd9Sstevel@tonic-gate register SM_EVENT *ev = NULL; 49947c478bd9Sstevel@tonic-gate int save_errno = 0; 49957c478bd9Sstevel@tonic-gate char *hostlist, *host; 49967c478bd9Sstevel@tonic-gate 49977c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 49987c478bd9Sstevel@tonic-gate sm_dprintf("ph_map_open(%s)\n", map->map_mname); 49997c478bd9Sstevel@tonic-gate 50007c478bd9Sstevel@tonic-gate mode &= O_ACCMODE; 50017c478bd9Sstevel@tonic-gate if (mode != O_RDONLY) 50027c478bd9Sstevel@tonic-gate { 50037c478bd9Sstevel@tonic-gate /* issue a pseudo-error message */ 50047c478bd9Sstevel@tonic-gate errno = SM_EMAPCANTWRITE; 50057c478bd9Sstevel@tonic-gate return false; 50067c478bd9Sstevel@tonic-gate } 50077c478bd9Sstevel@tonic-gate 50087c478bd9Sstevel@tonic-gate if (CurEnv != NULL && CurEnv->e_sendmode == SM_DEFER && 50097c478bd9Sstevel@tonic-gate bitset(MF_DEFER, map->map_mflags)) 50107c478bd9Sstevel@tonic-gate { 50117c478bd9Sstevel@tonic-gate if (tTd(9, 1)) 50127c478bd9Sstevel@tonic-gate sm_dprintf("ph_map_open(%s) => DEFERRED\n", 50137c478bd9Sstevel@tonic-gate map->map_mname); 50147c478bd9Sstevel@tonic-gate 50157c478bd9Sstevel@tonic-gate /* 50167c478bd9Sstevel@tonic-gate ** Unset MF_DEFER here so that map_lookup() returns 50177c478bd9Sstevel@tonic-gate ** a temporary failure using the bogus map and 50187c478bd9Sstevel@tonic-gate ** map->map_tapp instead of the default permanent error. 50197c478bd9Sstevel@tonic-gate */ 50207c478bd9Sstevel@tonic-gate 50217c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_DEFER; 50227c478bd9Sstevel@tonic-gate return false; 50237c478bd9Sstevel@tonic-gate } 50247c478bd9Sstevel@tonic-gate 50257c478bd9Sstevel@tonic-gate pmap = (PH_MAP_STRUCT *)map->map_db1; 50267c478bd9Sstevel@tonic-gate pmap->ph_fastclose = 0; /* refresh field for reopen */ 50277c478bd9Sstevel@tonic-gate 50287c478bd9Sstevel@tonic-gate /* try each host in the list */ 50297c478bd9Sstevel@tonic-gate hostlist = newstr(pmap->ph_servers); 50307c478bd9Sstevel@tonic-gate for (host = strtok(hostlist, " "); 50317c478bd9Sstevel@tonic-gate host != NULL; 50327c478bd9Sstevel@tonic-gate host = strtok(NULL, " ")) 50337c478bd9Sstevel@tonic-gate { 50347c478bd9Sstevel@tonic-gate /* set timeout */ 50357c478bd9Sstevel@tonic-gate if (pmap->ph_timeout != 0) 50367c478bd9Sstevel@tonic-gate { 50377c478bd9Sstevel@tonic-gate if (setjmp(PHTimeout) != 0) 50387c478bd9Sstevel@tonic-gate { 50397c478bd9Sstevel@tonic-gate ev = NULL; 50407c478bd9Sstevel@tonic-gate if (LogLevel > 1) 50417c478bd9Sstevel@tonic-gate sm_syslog(LOG_NOTICE, CurEnv->e_id, 50427c478bd9Sstevel@tonic-gate "timeout connecting to PH server %.100s", 50437c478bd9Sstevel@tonic-gate host); 50447c478bd9Sstevel@tonic-gate errno = ETIMEDOUT; 50457c478bd9Sstevel@tonic-gate goto ph_map_open_abort; 50467c478bd9Sstevel@tonic-gate } 50477c478bd9Sstevel@tonic-gate ev = sm_setevent(pmap->ph_timeout, ph_timeout, 0); 50487c478bd9Sstevel@tonic-gate } 50497c478bd9Sstevel@tonic-gate 50507c478bd9Sstevel@tonic-gate /* open connection to server */ 50517c478bd9Sstevel@tonic-gate if (ph_open(&(pmap->ph), host, 50527c478bd9Sstevel@tonic-gate PH_OPEN_ROUNDROBIN|PH_OPEN_DONTID, 50537c478bd9Sstevel@tonic-gate ph_map_send_debug, ph_map_recv_debug 50547c478bd9Sstevel@tonic-gate #if NPH_VERSION >= 10200 50557c478bd9Sstevel@tonic-gate , NULL 50567c478bd9Sstevel@tonic-gate #endif 50577c478bd9Sstevel@tonic-gate ) == 0 50587c478bd9Sstevel@tonic-gate && ph_id(pmap->ph, phmap_id) == 0) 50597c478bd9Sstevel@tonic-gate { 50607c478bd9Sstevel@tonic-gate if (ev != NULL) 50617c478bd9Sstevel@tonic-gate sm_clrevent(ev); 50627c478bd9Sstevel@tonic-gate sm_free(hostlist); /* XXX */ 50637c478bd9Sstevel@tonic-gate return true; 50647c478bd9Sstevel@tonic-gate } 50657c478bd9Sstevel@tonic-gate 50667c478bd9Sstevel@tonic-gate ph_map_open_abort: 50677c478bd9Sstevel@tonic-gate save_errno = errno; 50687c478bd9Sstevel@tonic-gate if (ev != NULL) 50697c478bd9Sstevel@tonic-gate sm_clrevent(ev); 50707c478bd9Sstevel@tonic-gate pmap->ph_fastclose = PH_CLOSE_FAST; 50717c478bd9Sstevel@tonic-gate ph_map_close(map); 50727c478bd9Sstevel@tonic-gate errno = save_errno; 50737c478bd9Sstevel@tonic-gate } 50747c478bd9Sstevel@tonic-gate 50757c478bd9Sstevel@tonic-gate if (bitset(MF_NODEFER, map->map_mflags)) 50767c478bd9Sstevel@tonic-gate { 50777c478bd9Sstevel@tonic-gate if (errno == 0) 50787c478bd9Sstevel@tonic-gate errno = EAGAIN; 50797c478bd9Sstevel@tonic-gate syserr("ph_map_open: %s: cannot connect to PH server", 50807c478bd9Sstevel@tonic-gate map->map_mname); 50817c478bd9Sstevel@tonic-gate } 50827c478bd9Sstevel@tonic-gate else if (!bitset(MF_OPTIONAL, map->map_mflags) && LogLevel > 1) 50837c478bd9Sstevel@tonic-gate sm_syslog(LOG_NOTICE, CurEnv->e_id, 50847c478bd9Sstevel@tonic-gate "ph_map_open: %s: cannot connect to PH server", 50857c478bd9Sstevel@tonic-gate map->map_mname); 50867c478bd9Sstevel@tonic-gate sm_free(hostlist); /* XXX */ 50877c478bd9Sstevel@tonic-gate return false; 50887c478bd9Sstevel@tonic-gate } 50897c478bd9Sstevel@tonic-gate 50907c478bd9Sstevel@tonic-gate /* 50917c478bd9Sstevel@tonic-gate ** PH_MAP_LOOKUP -- look up key from ph server 50927c478bd9Sstevel@tonic-gate */ 50937c478bd9Sstevel@tonic-gate 50947c478bd9Sstevel@tonic-gate char * 50957c478bd9Sstevel@tonic-gate ph_map_lookup(map, key, args, pstat) 50967c478bd9Sstevel@tonic-gate MAP *map; 50977c478bd9Sstevel@tonic-gate char *key; 50987c478bd9Sstevel@tonic-gate char **args; 50997c478bd9Sstevel@tonic-gate int *pstat; 51007c478bd9Sstevel@tonic-gate { 51017c478bd9Sstevel@tonic-gate int i, save_errno = 0; 51027c478bd9Sstevel@tonic-gate register SM_EVENT *ev = NULL; 51037c478bd9Sstevel@tonic-gate PH_MAP_STRUCT *pmap; 51047c478bd9Sstevel@tonic-gate char *value = NULL; 51057c478bd9Sstevel@tonic-gate 51067c478bd9Sstevel@tonic-gate pmap = (PH_MAP_STRUCT *)map->map_db1; 51077c478bd9Sstevel@tonic-gate 51087c478bd9Sstevel@tonic-gate *pstat = EX_OK; 51097c478bd9Sstevel@tonic-gate 51107c478bd9Sstevel@tonic-gate /* set timeout */ 51117c478bd9Sstevel@tonic-gate if (pmap->ph_timeout != 0) 51127c478bd9Sstevel@tonic-gate { 51137c478bd9Sstevel@tonic-gate if (setjmp(PHTimeout) != 0) 51147c478bd9Sstevel@tonic-gate { 51157c478bd9Sstevel@tonic-gate ev = NULL; 51167c478bd9Sstevel@tonic-gate if (LogLevel > 1) 51177c478bd9Sstevel@tonic-gate sm_syslog(LOG_NOTICE, CurEnv->e_id, 51187c478bd9Sstevel@tonic-gate "timeout during PH lookup of %.100s", 51197c478bd9Sstevel@tonic-gate key); 51207c478bd9Sstevel@tonic-gate errno = ETIMEDOUT; 51217c478bd9Sstevel@tonic-gate *pstat = EX_TEMPFAIL; 51227c478bd9Sstevel@tonic-gate goto ph_map_lookup_abort; 51237c478bd9Sstevel@tonic-gate } 51247c478bd9Sstevel@tonic-gate ev = sm_setevent(pmap->ph_timeout, ph_timeout, 0); 51257c478bd9Sstevel@tonic-gate } 51267c478bd9Sstevel@tonic-gate 51277c478bd9Sstevel@tonic-gate /* perform lookup */ 51287c478bd9Sstevel@tonic-gate i = ph_email_resolve(pmap->ph, key, pmap->ph_field_list, &value); 51297c478bd9Sstevel@tonic-gate if (i == -1) 51307c478bd9Sstevel@tonic-gate *pstat = EX_TEMPFAIL; 51317c478bd9Sstevel@tonic-gate else if (i == PH_ERR_NOMATCH || i == PH_ERR_DATAERR) 51327c478bd9Sstevel@tonic-gate *pstat = EX_UNAVAILABLE; 51337c478bd9Sstevel@tonic-gate 51347c478bd9Sstevel@tonic-gate ph_map_lookup_abort: 51357c478bd9Sstevel@tonic-gate if (ev != NULL) 51367c478bd9Sstevel@tonic-gate sm_clrevent(ev); 51377c478bd9Sstevel@tonic-gate 51387c478bd9Sstevel@tonic-gate /* 51397c478bd9Sstevel@tonic-gate ** Close the connection if the timer popped 51407c478bd9Sstevel@tonic-gate ** or we got a temporary PH error 51417c478bd9Sstevel@tonic-gate */ 51427c478bd9Sstevel@tonic-gate 51437c478bd9Sstevel@tonic-gate if (*pstat == EX_TEMPFAIL) 51447c478bd9Sstevel@tonic-gate { 51457c478bd9Sstevel@tonic-gate save_errno = errno; 51467c478bd9Sstevel@tonic-gate pmap->ph_fastclose = PH_CLOSE_FAST; 51477c478bd9Sstevel@tonic-gate ph_map_close(map); 51487c478bd9Sstevel@tonic-gate errno = save_errno; 51497c478bd9Sstevel@tonic-gate } 51507c478bd9Sstevel@tonic-gate 51517c478bd9Sstevel@tonic-gate if (*pstat == EX_OK) 51527c478bd9Sstevel@tonic-gate { 51537c478bd9Sstevel@tonic-gate if (tTd(38,20)) 51547c478bd9Sstevel@tonic-gate sm_dprintf("ph_map_lookup: %s => %s\n", key, value); 51557c478bd9Sstevel@tonic-gate 51567c478bd9Sstevel@tonic-gate if (bitset(MF_MATCHONLY, map->map_mflags)) 51577c478bd9Sstevel@tonic-gate return map_rewrite(map, key, strlen(key), NULL); 51587c478bd9Sstevel@tonic-gate else 51597c478bd9Sstevel@tonic-gate return map_rewrite(map, value, strlen(value), args); 51607c478bd9Sstevel@tonic-gate } 51617c478bd9Sstevel@tonic-gate 51627c478bd9Sstevel@tonic-gate return NULL; 51637c478bd9Sstevel@tonic-gate } 51647c478bd9Sstevel@tonic-gate #endif /* PH_MAP */ 5165058561cbSjbeck 51667c478bd9Sstevel@tonic-gate /* 51677c478bd9Sstevel@tonic-gate ** syslog map 51687c478bd9Sstevel@tonic-gate */ 51697c478bd9Sstevel@tonic-gate 51707c478bd9Sstevel@tonic-gate #define map_prio map_lockfd /* overload field */ 51717c478bd9Sstevel@tonic-gate 51727c478bd9Sstevel@tonic-gate /* 51737c478bd9Sstevel@tonic-gate ** SYSLOG_MAP_PARSEARGS -- check for priority level to syslog messages. 51747c478bd9Sstevel@tonic-gate */ 51757c478bd9Sstevel@tonic-gate 51767c478bd9Sstevel@tonic-gate bool 51777c478bd9Sstevel@tonic-gate syslog_map_parseargs(map, args) 51787c478bd9Sstevel@tonic-gate MAP *map; 51797c478bd9Sstevel@tonic-gate char *args; 51807c478bd9Sstevel@tonic-gate { 51817c478bd9Sstevel@tonic-gate char *p = args; 51827c478bd9Sstevel@tonic-gate char *priority = NULL; 51837c478bd9Sstevel@tonic-gate 51847c478bd9Sstevel@tonic-gate /* there is no check whether there is really an argument */ 51857c478bd9Sstevel@tonic-gate while (*p != '\0') 51867c478bd9Sstevel@tonic-gate { 51877c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 51887c478bd9Sstevel@tonic-gate p++; 51897c478bd9Sstevel@tonic-gate if (*p != '-') 51907c478bd9Sstevel@tonic-gate break; 51917c478bd9Sstevel@tonic-gate ++p; 51927c478bd9Sstevel@tonic-gate if (*p == 'D') 51937c478bd9Sstevel@tonic-gate { 51947c478bd9Sstevel@tonic-gate map->map_mflags |= MF_DEFER; 51957c478bd9Sstevel@tonic-gate ++p; 51967c478bd9Sstevel@tonic-gate } 51977c478bd9Sstevel@tonic-gate else if (*p == 'S') 51987c478bd9Sstevel@tonic-gate { 51997c478bd9Sstevel@tonic-gate map->map_spacesub = *++p; 52007c478bd9Sstevel@tonic-gate if (*p != '\0') 52017c478bd9Sstevel@tonic-gate p++; 52027c478bd9Sstevel@tonic-gate } 52037c478bd9Sstevel@tonic-gate else if (*p == 'L') 52047c478bd9Sstevel@tonic-gate { 52057c478bd9Sstevel@tonic-gate while (*++p != '\0' && isascii(*p) && isspace(*p)) 52067c478bd9Sstevel@tonic-gate continue; 52077c478bd9Sstevel@tonic-gate if (*p == '\0') 52087c478bd9Sstevel@tonic-gate break; 52097c478bd9Sstevel@tonic-gate priority = p; 52107c478bd9Sstevel@tonic-gate while (*p != '\0' && !(isascii(*p) && isspace(*p))) 52117c478bd9Sstevel@tonic-gate p++; 52127c478bd9Sstevel@tonic-gate if (*p != '\0') 52137c478bd9Sstevel@tonic-gate *p++ = '\0'; 52147c478bd9Sstevel@tonic-gate } 52157c478bd9Sstevel@tonic-gate else 52167c478bd9Sstevel@tonic-gate { 52177c478bd9Sstevel@tonic-gate syserr("Illegal option %c map syslog", *p); 52187c478bd9Sstevel@tonic-gate ++p; 52197c478bd9Sstevel@tonic-gate } 52207c478bd9Sstevel@tonic-gate } 52217c478bd9Sstevel@tonic-gate 52227c478bd9Sstevel@tonic-gate if (priority == NULL) 52237c478bd9Sstevel@tonic-gate map->map_prio = LOG_INFO; 52247c478bd9Sstevel@tonic-gate else 52257c478bd9Sstevel@tonic-gate { 52267c478bd9Sstevel@tonic-gate if (sm_strncasecmp("LOG_", priority, 4) == 0) 52277c478bd9Sstevel@tonic-gate priority += 4; 52287c478bd9Sstevel@tonic-gate 52297c478bd9Sstevel@tonic-gate #ifdef LOG_EMERG 52307c478bd9Sstevel@tonic-gate if (sm_strcasecmp("EMERG", priority) == 0) 52317c478bd9Sstevel@tonic-gate map->map_prio = LOG_EMERG; 52327c478bd9Sstevel@tonic-gate else 52337c478bd9Sstevel@tonic-gate #endif /* LOG_EMERG */ 52347c478bd9Sstevel@tonic-gate #ifdef LOG_ALERT 52357c478bd9Sstevel@tonic-gate if (sm_strcasecmp("ALERT", priority) == 0) 52367c478bd9Sstevel@tonic-gate map->map_prio = LOG_ALERT; 52377c478bd9Sstevel@tonic-gate else 52387c478bd9Sstevel@tonic-gate #endif /* LOG_ALERT */ 52397c478bd9Sstevel@tonic-gate #ifdef LOG_CRIT 52407c478bd9Sstevel@tonic-gate if (sm_strcasecmp("CRIT", priority) == 0) 52417c478bd9Sstevel@tonic-gate map->map_prio = LOG_CRIT; 52427c478bd9Sstevel@tonic-gate else 52437c478bd9Sstevel@tonic-gate #endif /* LOG_CRIT */ 52447c478bd9Sstevel@tonic-gate #ifdef LOG_ERR 52457c478bd9Sstevel@tonic-gate if (sm_strcasecmp("ERR", priority) == 0) 52467c478bd9Sstevel@tonic-gate map->map_prio = LOG_ERR; 52477c478bd9Sstevel@tonic-gate else 52487c478bd9Sstevel@tonic-gate #endif /* LOG_ERR */ 52497c478bd9Sstevel@tonic-gate #ifdef LOG_WARNING 52507c478bd9Sstevel@tonic-gate if (sm_strcasecmp("WARNING", priority) == 0) 52517c478bd9Sstevel@tonic-gate map->map_prio = LOG_WARNING; 52527c478bd9Sstevel@tonic-gate else 52537c478bd9Sstevel@tonic-gate #endif /* LOG_WARNING */ 52547c478bd9Sstevel@tonic-gate #ifdef LOG_NOTICE 52557c478bd9Sstevel@tonic-gate if (sm_strcasecmp("NOTICE", priority) == 0) 52567c478bd9Sstevel@tonic-gate map->map_prio = LOG_NOTICE; 52577c478bd9Sstevel@tonic-gate else 52587c478bd9Sstevel@tonic-gate #endif /* LOG_NOTICE */ 52597c478bd9Sstevel@tonic-gate #ifdef LOG_INFO 52607c478bd9Sstevel@tonic-gate if (sm_strcasecmp("INFO", priority) == 0) 52617c478bd9Sstevel@tonic-gate map->map_prio = LOG_INFO; 52627c478bd9Sstevel@tonic-gate else 52637c478bd9Sstevel@tonic-gate #endif /* LOG_INFO */ 52647c478bd9Sstevel@tonic-gate #ifdef LOG_DEBUG 52657c478bd9Sstevel@tonic-gate if (sm_strcasecmp("DEBUG", priority) == 0) 52667c478bd9Sstevel@tonic-gate map->map_prio = LOG_DEBUG; 52677c478bd9Sstevel@tonic-gate else 52687c478bd9Sstevel@tonic-gate #endif /* LOG_DEBUG */ 52697c478bd9Sstevel@tonic-gate { 52707c478bd9Sstevel@tonic-gate syserr("syslog_map_parseargs: Unknown priority %s", 52717c478bd9Sstevel@tonic-gate priority); 52727c478bd9Sstevel@tonic-gate return false; 52737c478bd9Sstevel@tonic-gate } 52747c478bd9Sstevel@tonic-gate } 52757c478bd9Sstevel@tonic-gate return true; 52767c478bd9Sstevel@tonic-gate } 52777c478bd9Sstevel@tonic-gate 52787c478bd9Sstevel@tonic-gate /* 52797c478bd9Sstevel@tonic-gate ** SYSLOG_MAP_LOOKUP -- rewrite and syslog message. Always return empty string 52807c478bd9Sstevel@tonic-gate */ 52817c478bd9Sstevel@tonic-gate 52827c478bd9Sstevel@tonic-gate char * 52837c478bd9Sstevel@tonic-gate syslog_map_lookup(map, string, args, statp) 52847c478bd9Sstevel@tonic-gate MAP *map; 52857c478bd9Sstevel@tonic-gate char *string; 52867c478bd9Sstevel@tonic-gate char **args; 52877c478bd9Sstevel@tonic-gate int *statp; 52887c478bd9Sstevel@tonic-gate { 52897c478bd9Sstevel@tonic-gate char *ptr = map_rewrite(map, string, strlen(string), args); 52907c478bd9Sstevel@tonic-gate 52917c478bd9Sstevel@tonic-gate if (ptr != NULL) 52927c478bd9Sstevel@tonic-gate { 52937c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 52947c478bd9Sstevel@tonic-gate sm_dprintf("syslog_map_lookup(%s (priority %d): %s\n", 52957c478bd9Sstevel@tonic-gate map->map_mname, map->map_prio, ptr); 52967c478bd9Sstevel@tonic-gate 52977c478bd9Sstevel@tonic-gate sm_syslog(map->map_prio, CurEnv->e_id, "%s", ptr); 52987c478bd9Sstevel@tonic-gate } 52997c478bd9Sstevel@tonic-gate 53007c478bd9Sstevel@tonic-gate *statp = EX_OK; 53017c478bd9Sstevel@tonic-gate return ""; 53027c478bd9Sstevel@tonic-gate } 53037c478bd9Sstevel@tonic-gate 5304058561cbSjbeck #if _FFR_DPRINTF_MAP 5305058561cbSjbeck /* 5306058561cbSjbeck ** dprintf map 5307058561cbSjbeck */ 5308058561cbSjbeck 5309058561cbSjbeck #define map_dbg_level map_lockfd /* overload field */ 5310058561cbSjbeck 5311058561cbSjbeck /* 5312058561cbSjbeck ** DPRINTF_MAP_PARSEARGS -- check for priority level to dprintf messages. 5313058561cbSjbeck */ 5314058561cbSjbeck 5315058561cbSjbeck bool 5316058561cbSjbeck dprintf_map_parseargs(map, args) 5317058561cbSjbeck MAP *map; 5318058561cbSjbeck char *args; 5319058561cbSjbeck { 5320058561cbSjbeck char *p = args; 5321058561cbSjbeck char *dbg_level = NULL; 5322058561cbSjbeck 5323058561cbSjbeck /* there is no check whether there is really an argument */ 5324058561cbSjbeck while (*p != '\0') 5325058561cbSjbeck { 5326058561cbSjbeck while (isascii(*p) && isspace(*p)) 5327058561cbSjbeck p++; 5328058561cbSjbeck if (*p != '-') 5329058561cbSjbeck break; 5330058561cbSjbeck ++p; 5331058561cbSjbeck if (*p == 'D') 5332058561cbSjbeck { 5333058561cbSjbeck map->map_mflags |= MF_DEFER; 5334058561cbSjbeck ++p; 5335058561cbSjbeck } 5336058561cbSjbeck else if (*p == 'S') 5337058561cbSjbeck { 5338058561cbSjbeck map->map_spacesub = *++p; 5339058561cbSjbeck if (*p != '\0') 5340058561cbSjbeck p++; 5341058561cbSjbeck } 5342058561cbSjbeck else if (*p == 'd') 5343058561cbSjbeck { 5344058561cbSjbeck while (*++p != '\0' && isascii(*p) && isspace(*p)) 5345058561cbSjbeck continue; 5346058561cbSjbeck if (*p == '\0') 5347058561cbSjbeck break; 5348058561cbSjbeck dbg_level = p; 5349058561cbSjbeck while (*p != '\0' && !(isascii(*p) && isspace(*p))) 5350058561cbSjbeck p++; 5351058561cbSjbeck if (*p != '\0') 5352058561cbSjbeck *p++ = '\0'; 5353058561cbSjbeck } 5354058561cbSjbeck else 5355058561cbSjbeck { 5356058561cbSjbeck syserr("Illegal option %c map dprintf", *p); 5357058561cbSjbeck ++p; 5358058561cbSjbeck } 5359058561cbSjbeck } 5360058561cbSjbeck 5361058561cbSjbeck if (dbg_level == NULL) 5362058561cbSjbeck map->map_dbg_level = 0; 5363058561cbSjbeck else 5364058561cbSjbeck { 5365058561cbSjbeck if (!(isascii(*dbg_level) && isdigit(*dbg_level))) 5366058561cbSjbeck { 5367058561cbSjbeck syserr("dprintf map \"%s\", file %s: -d should specify a number, not %s", 5368058561cbSjbeck map->map_mname, map->map_file, 5369058561cbSjbeck dbg_level); 5370058561cbSjbeck return false; 5371058561cbSjbeck } 5372058561cbSjbeck map->map_dbg_level = atoi(dbg_level); 5373058561cbSjbeck } 5374058561cbSjbeck return true; 5375058561cbSjbeck } 5376058561cbSjbeck 5377058561cbSjbeck /* 5378058561cbSjbeck ** DPRINTF_MAP_LOOKUP -- rewrite and print message. Always return empty string 5379058561cbSjbeck */ 5380058561cbSjbeck 5381058561cbSjbeck char * 5382058561cbSjbeck dprintf_map_lookup(map, string, args, statp) 5383058561cbSjbeck MAP *map; 5384058561cbSjbeck char *string; 5385058561cbSjbeck char **args; 5386058561cbSjbeck int *statp; 5387058561cbSjbeck { 5388058561cbSjbeck char *ptr = map_rewrite(map, string, strlen(string), args); 5389058561cbSjbeck 5390058561cbSjbeck if (ptr != NULL && tTd(85, map->map_dbg_level)) 5391058561cbSjbeck sm_dprintf("%s\n", ptr); 5392058561cbSjbeck *statp = EX_OK; 5393058561cbSjbeck return ""; 5394058561cbSjbeck } 5395058561cbSjbeck #endif /* _FFR_DPRINTF_MAP */ 5396058561cbSjbeck 53977c478bd9Sstevel@tonic-gate /* 53987c478bd9Sstevel@tonic-gate ** HESIOD Modules 53997c478bd9Sstevel@tonic-gate */ 54007c478bd9Sstevel@tonic-gate 54017c478bd9Sstevel@tonic-gate #if HESIOD 54027c478bd9Sstevel@tonic-gate 54037c478bd9Sstevel@tonic-gate bool 54047c478bd9Sstevel@tonic-gate hes_map_open(map, mode) 54057c478bd9Sstevel@tonic-gate MAP *map; 54067c478bd9Sstevel@tonic-gate int mode; 54077c478bd9Sstevel@tonic-gate { 54087c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 54097c478bd9Sstevel@tonic-gate sm_dprintf("hes_map_open(%s, %s, %d)\n", 54107c478bd9Sstevel@tonic-gate map->map_mname, map->map_file, mode); 54117c478bd9Sstevel@tonic-gate 54127c478bd9Sstevel@tonic-gate if (mode != O_RDONLY) 54137c478bd9Sstevel@tonic-gate { 54147c478bd9Sstevel@tonic-gate /* issue a pseudo-error message */ 54157c478bd9Sstevel@tonic-gate errno = SM_EMAPCANTWRITE; 54167c478bd9Sstevel@tonic-gate return false; 54177c478bd9Sstevel@tonic-gate } 54187c478bd9Sstevel@tonic-gate 54197c478bd9Sstevel@tonic-gate # ifdef HESIOD_INIT 54207c478bd9Sstevel@tonic-gate if (HesiodContext != NULL || hesiod_init(&HesiodContext) == 0) 54217c478bd9Sstevel@tonic-gate return true; 54227c478bd9Sstevel@tonic-gate 54237c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 54247c478bd9Sstevel@tonic-gate syserr("451 4.3.5 cannot initialize Hesiod map (%s)", 54257c478bd9Sstevel@tonic-gate sm_errstring(errno)); 54267c478bd9Sstevel@tonic-gate return false; 54277c478bd9Sstevel@tonic-gate # else /* HESIOD_INIT */ 54287c478bd9Sstevel@tonic-gate if (hes_error() == HES_ER_UNINIT) 54297c478bd9Sstevel@tonic-gate hes_init(); 54307c478bd9Sstevel@tonic-gate switch (hes_error()) 54317c478bd9Sstevel@tonic-gate { 54327c478bd9Sstevel@tonic-gate case HES_ER_OK: 54337c478bd9Sstevel@tonic-gate case HES_ER_NOTFOUND: 54347c478bd9Sstevel@tonic-gate return true; 54357c478bd9Sstevel@tonic-gate } 54367c478bd9Sstevel@tonic-gate 54377c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 54387c478bd9Sstevel@tonic-gate syserr("451 4.3.5 cannot initialize Hesiod map (%d)", hes_error()); 54397c478bd9Sstevel@tonic-gate 54407c478bd9Sstevel@tonic-gate return false; 54417c478bd9Sstevel@tonic-gate # endif /* HESIOD_INIT */ 54427c478bd9Sstevel@tonic-gate } 54437c478bd9Sstevel@tonic-gate 54447c478bd9Sstevel@tonic-gate char * 54457c478bd9Sstevel@tonic-gate hes_map_lookup(map, name, av, statp) 54467c478bd9Sstevel@tonic-gate MAP *map; 54477c478bd9Sstevel@tonic-gate char *name; 54487c478bd9Sstevel@tonic-gate char **av; 54497c478bd9Sstevel@tonic-gate int *statp; 54507c478bd9Sstevel@tonic-gate { 54517c478bd9Sstevel@tonic-gate char **hp; 54527c478bd9Sstevel@tonic-gate 54537c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 54547c478bd9Sstevel@tonic-gate sm_dprintf("hes_map_lookup(%s, %s)\n", map->map_file, name); 54557c478bd9Sstevel@tonic-gate 54567c478bd9Sstevel@tonic-gate if (name[0] == '\\') 54577c478bd9Sstevel@tonic-gate { 54587c478bd9Sstevel@tonic-gate char *np; 54597c478bd9Sstevel@tonic-gate int nl; 54607c478bd9Sstevel@tonic-gate int save_errno; 54617c478bd9Sstevel@tonic-gate char nbuf[MAXNAME]; 54627c478bd9Sstevel@tonic-gate 54637c478bd9Sstevel@tonic-gate nl = strlen(name); 5464058561cbSjbeck if (nl < sizeof(nbuf) - 1) 54657c478bd9Sstevel@tonic-gate np = nbuf; 54667c478bd9Sstevel@tonic-gate else 54677c478bd9Sstevel@tonic-gate np = xalloc(strlen(name) + 2); 54687c478bd9Sstevel@tonic-gate np[0] = '\\'; 5469058561cbSjbeck (void) sm_strlcpy(&np[1], name, (sizeof(nbuf)) - 1); 54707c478bd9Sstevel@tonic-gate # ifdef HESIOD_INIT 54717c478bd9Sstevel@tonic-gate hp = hesiod_resolve(HesiodContext, np, map->map_file); 54727c478bd9Sstevel@tonic-gate # else /* HESIOD_INIT */ 54737c478bd9Sstevel@tonic-gate hp = hes_resolve(np, map->map_file); 54747c478bd9Sstevel@tonic-gate # endif /* HESIOD_INIT */ 54757c478bd9Sstevel@tonic-gate save_errno = errno; 54767c478bd9Sstevel@tonic-gate if (np != nbuf) 54777c478bd9Sstevel@tonic-gate sm_free(np); /* XXX */ 54787c478bd9Sstevel@tonic-gate errno = save_errno; 54797c478bd9Sstevel@tonic-gate } 54807c478bd9Sstevel@tonic-gate else 54817c478bd9Sstevel@tonic-gate { 54827c478bd9Sstevel@tonic-gate # ifdef HESIOD_INIT 54837c478bd9Sstevel@tonic-gate hp = hesiod_resolve(HesiodContext, name, map->map_file); 54847c478bd9Sstevel@tonic-gate # else /* HESIOD_INIT */ 54857c478bd9Sstevel@tonic-gate hp = hes_resolve(name, map->map_file); 54867c478bd9Sstevel@tonic-gate # endif /* HESIOD_INIT */ 54877c478bd9Sstevel@tonic-gate } 54887c478bd9Sstevel@tonic-gate # ifdef HESIOD_INIT 54897c478bd9Sstevel@tonic-gate if (hp == NULL || *hp == NULL) 54907c478bd9Sstevel@tonic-gate { 54917c478bd9Sstevel@tonic-gate switch (errno) 54927c478bd9Sstevel@tonic-gate { 54937c478bd9Sstevel@tonic-gate case ENOENT: 54947c478bd9Sstevel@tonic-gate *statp = EX_NOTFOUND; 54957c478bd9Sstevel@tonic-gate break; 54967c478bd9Sstevel@tonic-gate case ECONNREFUSED: 54977c478bd9Sstevel@tonic-gate *statp = EX_TEMPFAIL; 54987c478bd9Sstevel@tonic-gate break; 54997c478bd9Sstevel@tonic-gate case EMSGSIZE: 55007c478bd9Sstevel@tonic-gate case ENOMEM: 55017c478bd9Sstevel@tonic-gate default: 55027c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 55037c478bd9Sstevel@tonic-gate break; 55047c478bd9Sstevel@tonic-gate } 55057c478bd9Sstevel@tonic-gate if (hp != NULL) 55067c478bd9Sstevel@tonic-gate hesiod_free_list(HesiodContext, hp); 55077c478bd9Sstevel@tonic-gate return NULL; 55087c478bd9Sstevel@tonic-gate } 55097c478bd9Sstevel@tonic-gate # else /* HESIOD_INIT */ 55107c478bd9Sstevel@tonic-gate if (hp == NULL || hp[0] == NULL) 55117c478bd9Sstevel@tonic-gate { 55127c478bd9Sstevel@tonic-gate switch (hes_error()) 55137c478bd9Sstevel@tonic-gate { 55147c478bd9Sstevel@tonic-gate case HES_ER_OK: 55157c478bd9Sstevel@tonic-gate *statp = EX_OK; 55167c478bd9Sstevel@tonic-gate break; 55177c478bd9Sstevel@tonic-gate 55187c478bd9Sstevel@tonic-gate case HES_ER_NOTFOUND: 55197c478bd9Sstevel@tonic-gate *statp = EX_NOTFOUND; 55207c478bd9Sstevel@tonic-gate break; 55217c478bd9Sstevel@tonic-gate 55227c478bd9Sstevel@tonic-gate case HES_ER_CONFIG: 55237c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 55247c478bd9Sstevel@tonic-gate break; 55257c478bd9Sstevel@tonic-gate 55267c478bd9Sstevel@tonic-gate case HES_ER_NET: 55277c478bd9Sstevel@tonic-gate *statp = EX_TEMPFAIL; 55287c478bd9Sstevel@tonic-gate break; 55297c478bd9Sstevel@tonic-gate } 55307c478bd9Sstevel@tonic-gate return NULL; 55317c478bd9Sstevel@tonic-gate } 55327c478bd9Sstevel@tonic-gate # endif /* HESIOD_INIT */ 55337c478bd9Sstevel@tonic-gate 55347c478bd9Sstevel@tonic-gate if (bitset(MF_MATCHONLY, map->map_mflags)) 55357c478bd9Sstevel@tonic-gate return map_rewrite(map, name, strlen(name), NULL); 55367c478bd9Sstevel@tonic-gate else 55377c478bd9Sstevel@tonic-gate return map_rewrite(map, hp[0], strlen(hp[0]), av); 55387c478bd9Sstevel@tonic-gate } 55397c478bd9Sstevel@tonic-gate 55407c478bd9Sstevel@tonic-gate /* 55417c478bd9Sstevel@tonic-gate ** HES_MAP_CLOSE -- free the Hesiod context 55427c478bd9Sstevel@tonic-gate */ 55437c478bd9Sstevel@tonic-gate 55447c478bd9Sstevel@tonic-gate void 55457c478bd9Sstevel@tonic-gate hes_map_close(map) 55467c478bd9Sstevel@tonic-gate MAP *map; 55477c478bd9Sstevel@tonic-gate { 55487c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 55497c478bd9Sstevel@tonic-gate sm_dprintf("hes_map_close(%s)\n", map->map_file); 55507c478bd9Sstevel@tonic-gate 55517c478bd9Sstevel@tonic-gate # ifdef HESIOD_INIT 55527c478bd9Sstevel@tonic-gate /* Free the hesiod context */ 55537c478bd9Sstevel@tonic-gate if (HesiodContext != NULL) 55547c478bd9Sstevel@tonic-gate { 55557c478bd9Sstevel@tonic-gate hesiod_end(HesiodContext); 55567c478bd9Sstevel@tonic-gate HesiodContext = NULL; 55577c478bd9Sstevel@tonic-gate } 55587c478bd9Sstevel@tonic-gate # endif /* HESIOD_INIT */ 55597c478bd9Sstevel@tonic-gate } 55607c478bd9Sstevel@tonic-gate 55617c478bd9Sstevel@tonic-gate #endif /* HESIOD */ 55627c478bd9Sstevel@tonic-gate /* 55637c478bd9Sstevel@tonic-gate ** NeXT NETINFO Modules 55647c478bd9Sstevel@tonic-gate */ 55657c478bd9Sstevel@tonic-gate 55667c478bd9Sstevel@tonic-gate #if NETINFO 55677c478bd9Sstevel@tonic-gate 55687c478bd9Sstevel@tonic-gate # define NETINFO_DEFAULT_DIR "/aliases" 55697c478bd9Sstevel@tonic-gate # define NETINFO_DEFAULT_PROPERTY "members" 55707c478bd9Sstevel@tonic-gate 55717c478bd9Sstevel@tonic-gate /* 55727c478bd9Sstevel@tonic-gate ** NI_MAP_OPEN -- open NetInfo Aliases 55737c478bd9Sstevel@tonic-gate */ 55747c478bd9Sstevel@tonic-gate 55757c478bd9Sstevel@tonic-gate bool 55767c478bd9Sstevel@tonic-gate ni_map_open(map, mode) 55777c478bd9Sstevel@tonic-gate MAP *map; 55787c478bd9Sstevel@tonic-gate int mode; 55797c478bd9Sstevel@tonic-gate { 55807c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 55817c478bd9Sstevel@tonic-gate sm_dprintf("ni_map_open(%s, %s, %d)\n", 55827c478bd9Sstevel@tonic-gate map->map_mname, map->map_file, mode); 55837c478bd9Sstevel@tonic-gate mode &= O_ACCMODE; 55847c478bd9Sstevel@tonic-gate 55857c478bd9Sstevel@tonic-gate if (*map->map_file == '\0') 55867c478bd9Sstevel@tonic-gate map->map_file = NETINFO_DEFAULT_DIR; 55877c478bd9Sstevel@tonic-gate 55887c478bd9Sstevel@tonic-gate if (map->map_valcolnm == NULL) 55897c478bd9Sstevel@tonic-gate map->map_valcolnm = NETINFO_DEFAULT_PROPERTY; 55907c478bd9Sstevel@tonic-gate 55917c478bd9Sstevel@tonic-gate if (map->map_coldelim == '\0') 55927c478bd9Sstevel@tonic-gate { 55937c478bd9Sstevel@tonic-gate if (bitset(MF_ALIAS, map->map_mflags)) 55947c478bd9Sstevel@tonic-gate map->map_coldelim = ','; 55957c478bd9Sstevel@tonic-gate else if (bitset(MF_FILECLASS, map->map_mflags)) 55967c478bd9Sstevel@tonic-gate map->map_coldelim = ' '; 55977c478bd9Sstevel@tonic-gate } 55987c478bd9Sstevel@tonic-gate return true; 55997c478bd9Sstevel@tonic-gate } 56007c478bd9Sstevel@tonic-gate 56017c478bd9Sstevel@tonic-gate 56027c478bd9Sstevel@tonic-gate /* 56037c478bd9Sstevel@tonic-gate ** NI_MAP_LOOKUP -- look up a datum in NetInfo 56047c478bd9Sstevel@tonic-gate */ 56057c478bd9Sstevel@tonic-gate 56067c478bd9Sstevel@tonic-gate char * 56077c478bd9Sstevel@tonic-gate ni_map_lookup(map, name, av, statp) 56087c478bd9Sstevel@tonic-gate MAP *map; 56097c478bd9Sstevel@tonic-gate char *name; 56107c478bd9Sstevel@tonic-gate char **av; 56117c478bd9Sstevel@tonic-gate int *statp; 56127c478bd9Sstevel@tonic-gate { 56137c478bd9Sstevel@tonic-gate char *res; 56147c478bd9Sstevel@tonic-gate char *propval; 56157c478bd9Sstevel@tonic-gate 56167c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 56177c478bd9Sstevel@tonic-gate sm_dprintf("ni_map_lookup(%s, %s)\n", map->map_mname, name); 56187c478bd9Sstevel@tonic-gate 56197c478bd9Sstevel@tonic-gate propval = ni_propval(map->map_file, map->map_keycolnm, name, 56207c478bd9Sstevel@tonic-gate map->map_valcolnm, map->map_coldelim); 56217c478bd9Sstevel@tonic-gate 56227c478bd9Sstevel@tonic-gate if (propval == NULL) 56237c478bd9Sstevel@tonic-gate return NULL; 56247c478bd9Sstevel@tonic-gate 56257c478bd9Sstevel@tonic-gate SM_TRY 56267c478bd9Sstevel@tonic-gate if (bitset(MF_MATCHONLY, map->map_mflags)) 56277c478bd9Sstevel@tonic-gate res = map_rewrite(map, name, strlen(name), NULL); 56287c478bd9Sstevel@tonic-gate else 56297c478bd9Sstevel@tonic-gate res = map_rewrite(map, propval, strlen(propval), av); 56307c478bd9Sstevel@tonic-gate SM_FINALLY 56317c478bd9Sstevel@tonic-gate sm_free(propval); 56327c478bd9Sstevel@tonic-gate SM_END_TRY 56337c478bd9Sstevel@tonic-gate return res; 56347c478bd9Sstevel@tonic-gate } 56357c478bd9Sstevel@tonic-gate 56367c478bd9Sstevel@tonic-gate 56377c478bd9Sstevel@tonic-gate static bool 56387c478bd9Sstevel@tonic-gate ni_getcanonname(name, hbsize, statp) 56397c478bd9Sstevel@tonic-gate char *name; 56407c478bd9Sstevel@tonic-gate int hbsize; 56417c478bd9Sstevel@tonic-gate int *statp; 56427c478bd9Sstevel@tonic-gate { 56437c478bd9Sstevel@tonic-gate char *vptr; 56447c478bd9Sstevel@tonic-gate char *ptr; 56457c478bd9Sstevel@tonic-gate char nbuf[MAXNAME + 1]; 56467c478bd9Sstevel@tonic-gate 56477c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 56487c478bd9Sstevel@tonic-gate sm_dprintf("ni_getcanonname(%s)\n", name); 56497c478bd9Sstevel@tonic-gate 5650058561cbSjbeck if (sm_strlcpy(nbuf, name, sizeof(nbuf)) >= sizeof(nbuf)) 56517c478bd9Sstevel@tonic-gate { 56527c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 56537c478bd9Sstevel@tonic-gate return false; 56547c478bd9Sstevel@tonic-gate } 56557c478bd9Sstevel@tonic-gate (void) shorten_hostname(nbuf); 56567c478bd9Sstevel@tonic-gate 56577c478bd9Sstevel@tonic-gate /* we only accept single token search key */ 56587c478bd9Sstevel@tonic-gate if (strchr(nbuf, '.')) 56597c478bd9Sstevel@tonic-gate { 56607c478bd9Sstevel@tonic-gate *statp = EX_NOHOST; 56617c478bd9Sstevel@tonic-gate return false; 56627c478bd9Sstevel@tonic-gate } 56637c478bd9Sstevel@tonic-gate 56647c478bd9Sstevel@tonic-gate /* Do the search */ 56657c478bd9Sstevel@tonic-gate vptr = ni_propval("/machines", NULL, nbuf, "name", '\n'); 56667c478bd9Sstevel@tonic-gate 56677c478bd9Sstevel@tonic-gate if (vptr == NULL) 56687c478bd9Sstevel@tonic-gate { 56697c478bd9Sstevel@tonic-gate *statp = EX_NOHOST; 56707c478bd9Sstevel@tonic-gate return false; 56717c478bd9Sstevel@tonic-gate } 56727c478bd9Sstevel@tonic-gate 56737c478bd9Sstevel@tonic-gate /* Only want the first machine name */ 56747c478bd9Sstevel@tonic-gate if ((ptr = strchr(vptr, '\n')) != NULL) 56757c478bd9Sstevel@tonic-gate *ptr = '\0'; 56767c478bd9Sstevel@tonic-gate 56777c478bd9Sstevel@tonic-gate if (sm_strlcpy(name, vptr, hbsize) >= hbsize) 56787c478bd9Sstevel@tonic-gate { 56797c478bd9Sstevel@tonic-gate sm_free(vptr); 56807c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 56817c478bd9Sstevel@tonic-gate return true; 56827c478bd9Sstevel@tonic-gate } 56837c478bd9Sstevel@tonic-gate sm_free(vptr); 56847c478bd9Sstevel@tonic-gate *statp = EX_OK; 56857c478bd9Sstevel@tonic-gate return false; 56867c478bd9Sstevel@tonic-gate } 56877c478bd9Sstevel@tonic-gate #endif /* NETINFO */ 56887c478bd9Sstevel@tonic-gate /* 56897c478bd9Sstevel@tonic-gate ** TEXT (unindexed text file) Modules 56907c478bd9Sstevel@tonic-gate ** 56917c478bd9Sstevel@tonic-gate ** This code donated by Sun Microsystems. 56927c478bd9Sstevel@tonic-gate */ 56937c478bd9Sstevel@tonic-gate 56947c478bd9Sstevel@tonic-gate #define map_sff map_lockfd /* overload field */ 56957c478bd9Sstevel@tonic-gate 56967c478bd9Sstevel@tonic-gate 56977c478bd9Sstevel@tonic-gate /* 56987c478bd9Sstevel@tonic-gate ** TEXT_MAP_OPEN -- open text table 56997c478bd9Sstevel@tonic-gate */ 57007c478bd9Sstevel@tonic-gate 57017c478bd9Sstevel@tonic-gate bool 57027c478bd9Sstevel@tonic-gate text_map_open(map, mode) 57037c478bd9Sstevel@tonic-gate MAP *map; 57047c478bd9Sstevel@tonic-gate int mode; 57057c478bd9Sstevel@tonic-gate { 57067c478bd9Sstevel@tonic-gate long sff; 57077c478bd9Sstevel@tonic-gate int i; 57087c478bd9Sstevel@tonic-gate 57097c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 57107c478bd9Sstevel@tonic-gate sm_dprintf("text_map_open(%s, %s, %d)\n", 57117c478bd9Sstevel@tonic-gate map->map_mname, map->map_file, mode); 57127c478bd9Sstevel@tonic-gate 57137c478bd9Sstevel@tonic-gate mode &= O_ACCMODE; 57147c478bd9Sstevel@tonic-gate if (mode != O_RDONLY) 57157c478bd9Sstevel@tonic-gate { 57167c478bd9Sstevel@tonic-gate errno = EPERM; 57177c478bd9Sstevel@tonic-gate return false; 57187c478bd9Sstevel@tonic-gate } 57197c478bd9Sstevel@tonic-gate 57207c478bd9Sstevel@tonic-gate if (*map->map_file == '\0') 57217c478bd9Sstevel@tonic-gate { 57227c478bd9Sstevel@tonic-gate syserr("text map \"%s\": file name required", 57237c478bd9Sstevel@tonic-gate map->map_mname); 57247c478bd9Sstevel@tonic-gate return false; 57257c478bd9Sstevel@tonic-gate } 57267c478bd9Sstevel@tonic-gate 57277c478bd9Sstevel@tonic-gate if (map->map_file[0] != '/') 57287c478bd9Sstevel@tonic-gate { 57297c478bd9Sstevel@tonic-gate syserr("text map \"%s\": file name must be fully qualified", 57307c478bd9Sstevel@tonic-gate map->map_mname); 57317c478bd9Sstevel@tonic-gate return false; 57327c478bd9Sstevel@tonic-gate } 57337c478bd9Sstevel@tonic-gate 57347c478bd9Sstevel@tonic-gate sff = SFF_ROOTOK|SFF_REGONLY; 57357c478bd9Sstevel@tonic-gate if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail)) 57367c478bd9Sstevel@tonic-gate sff |= SFF_NOWLINK; 57377c478bd9Sstevel@tonic-gate if (!bitnset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail)) 57387c478bd9Sstevel@tonic-gate sff |= SFF_SAFEDIRPATH; 57397c478bd9Sstevel@tonic-gate if ((i = safefile(map->map_file, RunAsUid, RunAsGid, RunAsUserName, 57407c478bd9Sstevel@tonic-gate sff, S_IRUSR, NULL)) != 0) 57417c478bd9Sstevel@tonic-gate { 57427c478bd9Sstevel@tonic-gate int save_errno = errno; 57437c478bd9Sstevel@tonic-gate 57447c478bd9Sstevel@tonic-gate /* cannot open this map */ 57457c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 57467c478bd9Sstevel@tonic-gate sm_dprintf("\tunsafe map file: %d\n", i); 57477c478bd9Sstevel@tonic-gate errno = save_errno; 57487c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 57497c478bd9Sstevel@tonic-gate syserr("text map \"%s\": unsafe map file %s", 57507c478bd9Sstevel@tonic-gate map->map_mname, map->map_file); 57517c478bd9Sstevel@tonic-gate return false; 57527c478bd9Sstevel@tonic-gate } 57537c478bd9Sstevel@tonic-gate 57547c478bd9Sstevel@tonic-gate if (map->map_keycolnm == NULL) 57557c478bd9Sstevel@tonic-gate map->map_keycolno = 0; 57567c478bd9Sstevel@tonic-gate else 57577c478bd9Sstevel@tonic-gate { 57587c478bd9Sstevel@tonic-gate if (!(isascii(*map->map_keycolnm) && isdigit(*map->map_keycolnm))) 57597c478bd9Sstevel@tonic-gate { 57607c478bd9Sstevel@tonic-gate syserr("text map \"%s\", file %s: -k should specify a number, not %s", 57617c478bd9Sstevel@tonic-gate map->map_mname, map->map_file, 57627c478bd9Sstevel@tonic-gate map->map_keycolnm); 57637c478bd9Sstevel@tonic-gate return false; 57647c478bd9Sstevel@tonic-gate } 57657c478bd9Sstevel@tonic-gate map->map_keycolno = atoi(map->map_keycolnm); 57667c478bd9Sstevel@tonic-gate } 57677c478bd9Sstevel@tonic-gate 57687c478bd9Sstevel@tonic-gate if (map->map_valcolnm == NULL) 57697c478bd9Sstevel@tonic-gate map->map_valcolno = 0; 57707c478bd9Sstevel@tonic-gate else 57717c478bd9Sstevel@tonic-gate { 57727c478bd9Sstevel@tonic-gate if (!(isascii(*map->map_valcolnm) && isdigit(*map->map_valcolnm))) 57737c478bd9Sstevel@tonic-gate { 57747c478bd9Sstevel@tonic-gate syserr("text map \"%s\", file %s: -v should specify a number, not %s", 57757c478bd9Sstevel@tonic-gate map->map_mname, map->map_file, 57767c478bd9Sstevel@tonic-gate map->map_valcolnm); 57777c478bd9Sstevel@tonic-gate return false; 57787c478bd9Sstevel@tonic-gate } 57797c478bd9Sstevel@tonic-gate map->map_valcolno = atoi(map->map_valcolnm); 57807c478bd9Sstevel@tonic-gate } 57817c478bd9Sstevel@tonic-gate 57827c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 57837c478bd9Sstevel@tonic-gate { 57847c478bd9Sstevel@tonic-gate sm_dprintf("text_map_open(%s, %s): delimiter = ", 57857c478bd9Sstevel@tonic-gate map->map_mname, map->map_file); 57867c478bd9Sstevel@tonic-gate if (map->map_coldelim == '\0') 57877c478bd9Sstevel@tonic-gate sm_dprintf("(white space)\n"); 57887c478bd9Sstevel@tonic-gate else 57897c478bd9Sstevel@tonic-gate sm_dprintf("%c\n", map->map_coldelim); 57907c478bd9Sstevel@tonic-gate } 57917c478bd9Sstevel@tonic-gate 57927c478bd9Sstevel@tonic-gate map->map_sff = sff; 57937c478bd9Sstevel@tonic-gate return true; 57947c478bd9Sstevel@tonic-gate } 57957c478bd9Sstevel@tonic-gate 57967c478bd9Sstevel@tonic-gate 57977c478bd9Sstevel@tonic-gate /* 57987c478bd9Sstevel@tonic-gate ** TEXT_MAP_LOOKUP -- look up a datum in a TEXT table 57997c478bd9Sstevel@tonic-gate */ 58007c478bd9Sstevel@tonic-gate 58017c478bd9Sstevel@tonic-gate char * 58027c478bd9Sstevel@tonic-gate text_map_lookup(map, name, av, statp) 58037c478bd9Sstevel@tonic-gate MAP *map; 58047c478bd9Sstevel@tonic-gate char *name; 58057c478bd9Sstevel@tonic-gate char **av; 58067c478bd9Sstevel@tonic-gate int *statp; 58077c478bd9Sstevel@tonic-gate { 58087c478bd9Sstevel@tonic-gate char *vp; 58097c478bd9Sstevel@tonic-gate auto int vsize; 58107c478bd9Sstevel@tonic-gate int buflen; 58117c478bd9Sstevel@tonic-gate SM_FILE_T *f; 58127c478bd9Sstevel@tonic-gate char delim; 58137c478bd9Sstevel@tonic-gate int key_idx; 58147c478bd9Sstevel@tonic-gate bool found_it; 58157c478bd9Sstevel@tonic-gate long sff = map->map_sff; 58167c478bd9Sstevel@tonic-gate char search_key[MAXNAME + 1]; 58177c478bd9Sstevel@tonic-gate char linebuf[MAXLINE]; 58187c478bd9Sstevel@tonic-gate char buf[MAXNAME + 1]; 58197c478bd9Sstevel@tonic-gate 58207c478bd9Sstevel@tonic-gate found_it = false; 58217c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 58227c478bd9Sstevel@tonic-gate sm_dprintf("text_map_lookup(%s, %s)\n", map->map_mname, name); 58237c478bd9Sstevel@tonic-gate 58247c478bd9Sstevel@tonic-gate buflen = strlen(name); 5825058561cbSjbeck if (buflen > sizeof(search_key) - 1) 5826058561cbSjbeck buflen = sizeof(search_key) - 1; /* XXX just cut if off? */ 58277c478bd9Sstevel@tonic-gate memmove(search_key, name, buflen); 58287c478bd9Sstevel@tonic-gate search_key[buflen] = '\0'; 58297c478bd9Sstevel@tonic-gate if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 58307c478bd9Sstevel@tonic-gate makelower(search_key); 58317c478bd9Sstevel@tonic-gate 58327c478bd9Sstevel@tonic-gate f = safefopen(map->map_file, O_RDONLY, FileMode, sff); 58337c478bd9Sstevel@tonic-gate if (f == NULL) 58347c478bd9Sstevel@tonic-gate { 58357c478bd9Sstevel@tonic-gate map->map_mflags &= ~(MF_VALID|MF_OPEN); 58367c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 58377c478bd9Sstevel@tonic-gate return NULL; 58387c478bd9Sstevel@tonic-gate } 58397c478bd9Sstevel@tonic-gate key_idx = map->map_keycolno; 58407c478bd9Sstevel@tonic-gate delim = map->map_coldelim; 58417c478bd9Sstevel@tonic-gate while (sm_io_fgets(f, SM_TIME_DEFAULT, 5842058561cbSjbeck linebuf, sizeof(linebuf)) != NULL) 58437c478bd9Sstevel@tonic-gate { 58447c478bd9Sstevel@tonic-gate char *p; 58457c478bd9Sstevel@tonic-gate 58467c478bd9Sstevel@tonic-gate /* skip comment line */ 58477c478bd9Sstevel@tonic-gate if (linebuf[0] == '#') 58487c478bd9Sstevel@tonic-gate continue; 58497c478bd9Sstevel@tonic-gate p = strchr(linebuf, '\n'); 58507c478bd9Sstevel@tonic-gate if (p != NULL) 58517c478bd9Sstevel@tonic-gate *p = '\0'; 5852058561cbSjbeck p = get_column(linebuf, key_idx, delim, buf, sizeof(buf)); 58537c478bd9Sstevel@tonic-gate if (p != NULL && sm_strcasecmp(search_key, p) == 0) 58547c478bd9Sstevel@tonic-gate { 58557c478bd9Sstevel@tonic-gate found_it = true; 58567c478bd9Sstevel@tonic-gate break; 58577c478bd9Sstevel@tonic-gate } 58587c478bd9Sstevel@tonic-gate } 58597c478bd9Sstevel@tonic-gate (void) sm_io_close(f, SM_TIME_DEFAULT); 58607c478bd9Sstevel@tonic-gate if (!found_it) 58617c478bd9Sstevel@tonic-gate { 58627c478bd9Sstevel@tonic-gate *statp = EX_NOTFOUND; 58637c478bd9Sstevel@tonic-gate return NULL; 58647c478bd9Sstevel@tonic-gate } 5865058561cbSjbeck vp = get_column(linebuf, map->map_valcolno, delim, buf, sizeof(buf)); 58667c478bd9Sstevel@tonic-gate if (vp == NULL) 58677c478bd9Sstevel@tonic-gate { 58687c478bd9Sstevel@tonic-gate *statp = EX_NOTFOUND; 58697c478bd9Sstevel@tonic-gate return NULL; 58707c478bd9Sstevel@tonic-gate } 58717c478bd9Sstevel@tonic-gate vsize = strlen(vp); 58727c478bd9Sstevel@tonic-gate *statp = EX_OK; 58737c478bd9Sstevel@tonic-gate if (bitset(MF_MATCHONLY, map->map_mflags)) 58747c478bd9Sstevel@tonic-gate return map_rewrite(map, name, strlen(name), NULL); 58757c478bd9Sstevel@tonic-gate else 58767c478bd9Sstevel@tonic-gate return map_rewrite(map, vp, vsize, av); 58777c478bd9Sstevel@tonic-gate } 58787c478bd9Sstevel@tonic-gate 58797c478bd9Sstevel@tonic-gate /* 58807c478bd9Sstevel@tonic-gate ** TEXT_GETCANONNAME -- look up canonical name in hosts file 58817c478bd9Sstevel@tonic-gate */ 58827c478bd9Sstevel@tonic-gate 58837c478bd9Sstevel@tonic-gate static bool 58847c478bd9Sstevel@tonic-gate text_getcanonname(name, hbsize, statp) 58857c478bd9Sstevel@tonic-gate char *name; 58867c478bd9Sstevel@tonic-gate int hbsize; 58877c478bd9Sstevel@tonic-gate int *statp; 58887c478bd9Sstevel@tonic-gate { 58897c478bd9Sstevel@tonic-gate bool found; 58907c478bd9Sstevel@tonic-gate char *dot; 58917c478bd9Sstevel@tonic-gate SM_FILE_T *f; 58927c478bd9Sstevel@tonic-gate char linebuf[MAXLINE]; 58937c478bd9Sstevel@tonic-gate char cbuf[MAXNAME + 1]; 58947c478bd9Sstevel@tonic-gate char nbuf[MAXNAME + 1]; 58957c478bd9Sstevel@tonic-gate 58967c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 58977c478bd9Sstevel@tonic-gate sm_dprintf("text_getcanonname(%s)\n", name); 58987c478bd9Sstevel@tonic-gate 5899058561cbSjbeck if (sm_strlcpy(nbuf, name, sizeof(nbuf)) >= sizeof(nbuf)) 59007c478bd9Sstevel@tonic-gate { 59017c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 59027c478bd9Sstevel@tonic-gate return false; 59037c478bd9Sstevel@tonic-gate } 59047c478bd9Sstevel@tonic-gate dot = shorten_hostname(nbuf); 59057c478bd9Sstevel@tonic-gate 59067c478bd9Sstevel@tonic-gate f = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, HostsFile, SM_IO_RDONLY, 59077c478bd9Sstevel@tonic-gate NULL); 59087c478bd9Sstevel@tonic-gate if (f == NULL) 59097c478bd9Sstevel@tonic-gate { 59107c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 59117c478bd9Sstevel@tonic-gate return false; 59127c478bd9Sstevel@tonic-gate } 59137c478bd9Sstevel@tonic-gate found = false; 59147c478bd9Sstevel@tonic-gate while (!found && 59157c478bd9Sstevel@tonic-gate sm_io_fgets(f, SM_TIME_DEFAULT, 5916058561cbSjbeck linebuf, sizeof(linebuf)) != NULL) 59177c478bd9Sstevel@tonic-gate { 59187c478bd9Sstevel@tonic-gate char *p = strpbrk(linebuf, "#\n"); 59197c478bd9Sstevel@tonic-gate 59207c478bd9Sstevel@tonic-gate if (p != NULL) 59217c478bd9Sstevel@tonic-gate *p = '\0'; 59227c478bd9Sstevel@tonic-gate if (linebuf[0] != '\0') 59237c478bd9Sstevel@tonic-gate found = extract_canonname(nbuf, dot, linebuf, 5924058561cbSjbeck cbuf, sizeof(cbuf)); 59257c478bd9Sstevel@tonic-gate } 59267c478bd9Sstevel@tonic-gate (void) sm_io_close(f, SM_TIME_DEFAULT); 59277c478bd9Sstevel@tonic-gate if (!found) 59287c478bd9Sstevel@tonic-gate { 59297c478bd9Sstevel@tonic-gate *statp = EX_NOHOST; 59307c478bd9Sstevel@tonic-gate return false; 59317c478bd9Sstevel@tonic-gate } 59327c478bd9Sstevel@tonic-gate 59337c478bd9Sstevel@tonic-gate if (sm_strlcpy(name, cbuf, hbsize) >= hbsize) 59347c478bd9Sstevel@tonic-gate { 59357c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 59367c478bd9Sstevel@tonic-gate return false; 59377c478bd9Sstevel@tonic-gate } 59387c478bd9Sstevel@tonic-gate *statp = EX_OK; 59397c478bd9Sstevel@tonic-gate return true; 59407c478bd9Sstevel@tonic-gate } 59417c478bd9Sstevel@tonic-gate /* 59427c478bd9Sstevel@tonic-gate ** STAB (Symbol Table) Modules 59437c478bd9Sstevel@tonic-gate */ 59447c478bd9Sstevel@tonic-gate 59457c478bd9Sstevel@tonic-gate 59467c478bd9Sstevel@tonic-gate /* 59477c478bd9Sstevel@tonic-gate ** STAB_MAP_LOOKUP -- look up alias in symbol table 59487c478bd9Sstevel@tonic-gate */ 59497c478bd9Sstevel@tonic-gate 59507c478bd9Sstevel@tonic-gate /* ARGSUSED2 */ 59517c478bd9Sstevel@tonic-gate char * 59527c478bd9Sstevel@tonic-gate stab_map_lookup(map, name, av, pstat) 59537c478bd9Sstevel@tonic-gate register MAP *map; 59547c478bd9Sstevel@tonic-gate char *name; 59557c478bd9Sstevel@tonic-gate char **av; 59567c478bd9Sstevel@tonic-gate int *pstat; 59577c478bd9Sstevel@tonic-gate { 59587c478bd9Sstevel@tonic-gate register STAB *s; 59597c478bd9Sstevel@tonic-gate 59607c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 59617c478bd9Sstevel@tonic-gate sm_dprintf("stab_lookup(%s, %s)\n", 59627c478bd9Sstevel@tonic-gate map->map_mname, name); 59637c478bd9Sstevel@tonic-gate 59647c478bd9Sstevel@tonic-gate s = stab(name, ST_ALIAS, ST_FIND); 59657c478bd9Sstevel@tonic-gate if (s == NULL) 59667c478bd9Sstevel@tonic-gate return NULL; 59677c478bd9Sstevel@tonic-gate if (bitset(MF_MATCHONLY, map->map_mflags)) 59687c478bd9Sstevel@tonic-gate return map_rewrite(map, name, strlen(name), NULL); 59697c478bd9Sstevel@tonic-gate else 59707c478bd9Sstevel@tonic-gate return map_rewrite(map, s->s_alias, strlen(s->s_alias), av); 59717c478bd9Sstevel@tonic-gate } 59727c478bd9Sstevel@tonic-gate 59737c478bd9Sstevel@tonic-gate /* 59747c478bd9Sstevel@tonic-gate ** STAB_MAP_STORE -- store in symtab (actually using during init, not rebuild) 59757c478bd9Sstevel@tonic-gate */ 59767c478bd9Sstevel@tonic-gate 59777c478bd9Sstevel@tonic-gate void 59787c478bd9Sstevel@tonic-gate stab_map_store(map, lhs, rhs) 59797c478bd9Sstevel@tonic-gate register MAP *map; 59807c478bd9Sstevel@tonic-gate char *lhs; 59817c478bd9Sstevel@tonic-gate char *rhs; 59827c478bd9Sstevel@tonic-gate { 59837c478bd9Sstevel@tonic-gate register STAB *s; 59847c478bd9Sstevel@tonic-gate 59857c478bd9Sstevel@tonic-gate s = stab(lhs, ST_ALIAS, ST_ENTER); 59867c478bd9Sstevel@tonic-gate s->s_alias = newstr(rhs); 59877c478bd9Sstevel@tonic-gate } 59887c478bd9Sstevel@tonic-gate 59897c478bd9Sstevel@tonic-gate 59907c478bd9Sstevel@tonic-gate /* 59917c478bd9Sstevel@tonic-gate ** STAB_MAP_OPEN -- initialize (reads data file) 59927c478bd9Sstevel@tonic-gate ** 59937c478bd9Sstevel@tonic-gate ** This is a wierd case -- it is only intended as a fallback for 59947c478bd9Sstevel@tonic-gate ** aliases. For this reason, opens for write (only during a 59957c478bd9Sstevel@tonic-gate ** "newaliases") always fails, and opens for read open the 59967c478bd9Sstevel@tonic-gate ** actual underlying text file instead of the database. 59977c478bd9Sstevel@tonic-gate */ 59987c478bd9Sstevel@tonic-gate 59997c478bd9Sstevel@tonic-gate bool 60007c478bd9Sstevel@tonic-gate stab_map_open(map, mode) 60017c478bd9Sstevel@tonic-gate register MAP *map; 60027c478bd9Sstevel@tonic-gate int mode; 60037c478bd9Sstevel@tonic-gate { 60047c478bd9Sstevel@tonic-gate SM_FILE_T *af; 60057c478bd9Sstevel@tonic-gate long sff; 60067c478bd9Sstevel@tonic-gate struct stat st; 60077c478bd9Sstevel@tonic-gate 60087c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 60097c478bd9Sstevel@tonic-gate sm_dprintf("stab_map_open(%s, %s, %d)\n", 60107c478bd9Sstevel@tonic-gate map->map_mname, map->map_file, mode); 60117c478bd9Sstevel@tonic-gate 60127c478bd9Sstevel@tonic-gate mode &= O_ACCMODE; 60137c478bd9Sstevel@tonic-gate if (mode != O_RDONLY) 60147c478bd9Sstevel@tonic-gate { 60157c478bd9Sstevel@tonic-gate errno = EPERM; 60167c478bd9Sstevel@tonic-gate return false; 60177c478bd9Sstevel@tonic-gate } 60187c478bd9Sstevel@tonic-gate 60197c478bd9Sstevel@tonic-gate sff = SFF_ROOTOK|SFF_REGONLY; 60207c478bd9Sstevel@tonic-gate if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail)) 60217c478bd9Sstevel@tonic-gate sff |= SFF_NOWLINK; 60227c478bd9Sstevel@tonic-gate if (!bitnset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail)) 60237c478bd9Sstevel@tonic-gate sff |= SFF_SAFEDIRPATH; 60247c478bd9Sstevel@tonic-gate af = safefopen(map->map_file, O_RDONLY, 0444, sff); 60257c478bd9Sstevel@tonic-gate if (af == NULL) 60267c478bd9Sstevel@tonic-gate return false; 60277c478bd9Sstevel@tonic-gate readaliases(map, af, false, false); 60287c478bd9Sstevel@tonic-gate 60297c478bd9Sstevel@tonic-gate if (fstat(sm_io_getinfo(af, SM_IO_WHAT_FD, NULL), &st) >= 0) 60307c478bd9Sstevel@tonic-gate map->map_mtime = st.st_mtime; 60317c478bd9Sstevel@tonic-gate (void) sm_io_close(af, SM_TIME_DEFAULT); 60327c478bd9Sstevel@tonic-gate 60337c478bd9Sstevel@tonic-gate return true; 60347c478bd9Sstevel@tonic-gate } 60357c478bd9Sstevel@tonic-gate /* 60367c478bd9Sstevel@tonic-gate ** Implicit Modules 60377c478bd9Sstevel@tonic-gate ** 60387c478bd9Sstevel@tonic-gate ** Tries several types. For back compatibility of aliases. 60397c478bd9Sstevel@tonic-gate */ 60407c478bd9Sstevel@tonic-gate 60417c478bd9Sstevel@tonic-gate 60427c478bd9Sstevel@tonic-gate /* 60437c478bd9Sstevel@tonic-gate ** IMPL_MAP_LOOKUP -- lookup in best open database 60447c478bd9Sstevel@tonic-gate */ 60457c478bd9Sstevel@tonic-gate 60467c478bd9Sstevel@tonic-gate char * 60477c478bd9Sstevel@tonic-gate impl_map_lookup(map, name, av, pstat) 60487c478bd9Sstevel@tonic-gate MAP *map; 60497c478bd9Sstevel@tonic-gate char *name; 60507c478bd9Sstevel@tonic-gate char **av; 60517c478bd9Sstevel@tonic-gate int *pstat; 60527c478bd9Sstevel@tonic-gate { 60537c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 60547c478bd9Sstevel@tonic-gate sm_dprintf("impl_map_lookup(%s, %s)\n", 60557c478bd9Sstevel@tonic-gate map->map_mname, name); 60567c478bd9Sstevel@tonic-gate 60577c478bd9Sstevel@tonic-gate #if NEWDB 60587c478bd9Sstevel@tonic-gate if (bitset(MF_IMPL_HASH, map->map_mflags)) 60597c478bd9Sstevel@tonic-gate return db_map_lookup(map, name, av, pstat); 60607c478bd9Sstevel@tonic-gate #endif /* NEWDB */ 60617c478bd9Sstevel@tonic-gate #if NDBM 60627c478bd9Sstevel@tonic-gate if (bitset(MF_IMPL_NDBM, map->map_mflags)) 60637c478bd9Sstevel@tonic-gate return ndbm_map_lookup(map, name, av, pstat); 60647c478bd9Sstevel@tonic-gate #endif /* NDBM */ 60657c478bd9Sstevel@tonic-gate return stab_map_lookup(map, name, av, pstat); 60667c478bd9Sstevel@tonic-gate } 60677c478bd9Sstevel@tonic-gate 60687c478bd9Sstevel@tonic-gate /* 60697c478bd9Sstevel@tonic-gate ** IMPL_MAP_STORE -- store in open databases 60707c478bd9Sstevel@tonic-gate */ 60717c478bd9Sstevel@tonic-gate 60727c478bd9Sstevel@tonic-gate void 60737c478bd9Sstevel@tonic-gate impl_map_store(map, lhs, rhs) 60747c478bd9Sstevel@tonic-gate MAP *map; 60757c478bd9Sstevel@tonic-gate char *lhs; 60767c478bd9Sstevel@tonic-gate char *rhs; 60777c478bd9Sstevel@tonic-gate { 60787c478bd9Sstevel@tonic-gate if (tTd(38, 12)) 60797c478bd9Sstevel@tonic-gate sm_dprintf("impl_map_store(%s, %s, %s)\n", 60807c478bd9Sstevel@tonic-gate map->map_mname, lhs, rhs); 60817c478bd9Sstevel@tonic-gate #if NEWDB 60827c478bd9Sstevel@tonic-gate if (bitset(MF_IMPL_HASH, map->map_mflags)) 60837c478bd9Sstevel@tonic-gate db_map_store(map, lhs, rhs); 60847c478bd9Sstevel@tonic-gate #endif /* NEWDB */ 60857c478bd9Sstevel@tonic-gate #if NDBM 60867c478bd9Sstevel@tonic-gate if (bitset(MF_IMPL_NDBM, map->map_mflags)) 60877c478bd9Sstevel@tonic-gate ndbm_map_store(map, lhs, rhs); 60887c478bd9Sstevel@tonic-gate #endif /* NDBM */ 60897c478bd9Sstevel@tonic-gate stab_map_store(map, lhs, rhs); 60907c478bd9Sstevel@tonic-gate } 60917c478bd9Sstevel@tonic-gate 60927c478bd9Sstevel@tonic-gate /* 60937c478bd9Sstevel@tonic-gate ** IMPL_MAP_OPEN -- implicit database open 60947c478bd9Sstevel@tonic-gate */ 60957c478bd9Sstevel@tonic-gate 60967c478bd9Sstevel@tonic-gate bool 60977c478bd9Sstevel@tonic-gate impl_map_open(map, mode) 60987c478bd9Sstevel@tonic-gate MAP *map; 60997c478bd9Sstevel@tonic-gate int mode; 61007c478bd9Sstevel@tonic-gate { 61017c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 61027c478bd9Sstevel@tonic-gate sm_dprintf("impl_map_open(%s, %s, %d)\n", 61037c478bd9Sstevel@tonic-gate map->map_mname, map->map_file, mode); 61047c478bd9Sstevel@tonic-gate 61057c478bd9Sstevel@tonic-gate mode &= O_ACCMODE; 61067c478bd9Sstevel@tonic-gate #if NEWDB 61077c478bd9Sstevel@tonic-gate map->map_mflags |= MF_IMPL_HASH; 61087c478bd9Sstevel@tonic-gate if (hash_map_open(map, mode)) 61097c478bd9Sstevel@tonic-gate { 61107c478bd9Sstevel@tonic-gate # ifdef NDBM_YP_COMPAT 61117c478bd9Sstevel@tonic-gate if (mode == O_RDONLY || strstr(map->map_file, "/yp/") == NULL) 61127c478bd9Sstevel@tonic-gate # endif /* NDBM_YP_COMPAT */ 61137c478bd9Sstevel@tonic-gate return true; 61147c478bd9Sstevel@tonic-gate } 61157c478bd9Sstevel@tonic-gate else 61167c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_IMPL_HASH; 61177c478bd9Sstevel@tonic-gate #endif /* NEWDB */ 61187c478bd9Sstevel@tonic-gate #if NDBM 61197c478bd9Sstevel@tonic-gate map->map_mflags |= MF_IMPL_NDBM; 61207c478bd9Sstevel@tonic-gate if (ndbm_map_open(map, mode)) 61217c478bd9Sstevel@tonic-gate { 61227c478bd9Sstevel@tonic-gate return true; 61237c478bd9Sstevel@tonic-gate } 61247c478bd9Sstevel@tonic-gate else 61257c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_IMPL_NDBM; 61267c478bd9Sstevel@tonic-gate #endif /* NDBM */ 61277c478bd9Sstevel@tonic-gate 61287c478bd9Sstevel@tonic-gate #if defined(NEWDB) || defined(NDBM) 61297c478bd9Sstevel@tonic-gate if (Verbose) 61307c478bd9Sstevel@tonic-gate message("WARNING: cannot open alias database %s%s", 61317c478bd9Sstevel@tonic-gate map->map_file, 61327c478bd9Sstevel@tonic-gate mode == O_RDONLY ? "; reading text version" : ""); 61337c478bd9Sstevel@tonic-gate #else /* defined(NEWDB) || defined(NDBM) */ 61347c478bd9Sstevel@tonic-gate if (mode != O_RDONLY) 61357c478bd9Sstevel@tonic-gate usrerr("Cannot rebuild aliases: no database format defined"); 61367c478bd9Sstevel@tonic-gate #endif /* defined(NEWDB) || defined(NDBM) */ 61377c478bd9Sstevel@tonic-gate 61387c478bd9Sstevel@tonic-gate if (mode == O_RDONLY) 61397c478bd9Sstevel@tonic-gate return stab_map_open(map, mode); 61407c478bd9Sstevel@tonic-gate else 61417c478bd9Sstevel@tonic-gate return false; 61427c478bd9Sstevel@tonic-gate } 61437c478bd9Sstevel@tonic-gate 61447c478bd9Sstevel@tonic-gate 61457c478bd9Sstevel@tonic-gate /* 61467c478bd9Sstevel@tonic-gate ** IMPL_MAP_CLOSE -- close any open database(s) 61477c478bd9Sstevel@tonic-gate */ 61487c478bd9Sstevel@tonic-gate 61497c478bd9Sstevel@tonic-gate void 61507c478bd9Sstevel@tonic-gate impl_map_close(map) 61517c478bd9Sstevel@tonic-gate MAP *map; 61527c478bd9Sstevel@tonic-gate { 61537c478bd9Sstevel@tonic-gate if (tTd(38, 9)) 61547c478bd9Sstevel@tonic-gate sm_dprintf("impl_map_close(%s, %s, %lx)\n", 61557c478bd9Sstevel@tonic-gate map->map_mname, map->map_file, map->map_mflags); 61567c478bd9Sstevel@tonic-gate #if NEWDB 61577c478bd9Sstevel@tonic-gate if (bitset(MF_IMPL_HASH, map->map_mflags)) 61587c478bd9Sstevel@tonic-gate { 61597c478bd9Sstevel@tonic-gate db_map_close(map); 61607c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_IMPL_HASH; 61617c478bd9Sstevel@tonic-gate } 61627c478bd9Sstevel@tonic-gate #endif /* NEWDB */ 61637c478bd9Sstevel@tonic-gate 61647c478bd9Sstevel@tonic-gate #if NDBM 61657c478bd9Sstevel@tonic-gate if (bitset(MF_IMPL_NDBM, map->map_mflags)) 61667c478bd9Sstevel@tonic-gate { 61677c478bd9Sstevel@tonic-gate ndbm_map_close(map); 61687c478bd9Sstevel@tonic-gate map->map_mflags &= ~MF_IMPL_NDBM; 61697c478bd9Sstevel@tonic-gate } 61707c478bd9Sstevel@tonic-gate #endif /* NDBM */ 61717c478bd9Sstevel@tonic-gate } 61727c478bd9Sstevel@tonic-gate /* 61737c478bd9Sstevel@tonic-gate ** User map class. 61747c478bd9Sstevel@tonic-gate ** 61757c478bd9Sstevel@tonic-gate ** Provides access to the system password file. 61767c478bd9Sstevel@tonic-gate */ 61777c478bd9Sstevel@tonic-gate 61787c478bd9Sstevel@tonic-gate /* 61797c478bd9Sstevel@tonic-gate ** USER_MAP_OPEN -- open user map 61807c478bd9Sstevel@tonic-gate ** 61817c478bd9Sstevel@tonic-gate ** Really just binds field names to field numbers. 61827c478bd9Sstevel@tonic-gate */ 61837c478bd9Sstevel@tonic-gate 61847c478bd9Sstevel@tonic-gate bool 61857c478bd9Sstevel@tonic-gate user_map_open(map, mode) 61867c478bd9Sstevel@tonic-gate MAP *map; 61877c478bd9Sstevel@tonic-gate int mode; 61887c478bd9Sstevel@tonic-gate { 61897c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 61907c478bd9Sstevel@tonic-gate sm_dprintf("user_map_open(%s, %d)\n", 61917c478bd9Sstevel@tonic-gate map->map_mname, mode); 61927c478bd9Sstevel@tonic-gate 61937c478bd9Sstevel@tonic-gate mode &= O_ACCMODE; 61947c478bd9Sstevel@tonic-gate if (mode != O_RDONLY) 61957c478bd9Sstevel@tonic-gate { 61967c478bd9Sstevel@tonic-gate /* issue a pseudo-error message */ 61977c478bd9Sstevel@tonic-gate errno = SM_EMAPCANTWRITE; 61987c478bd9Sstevel@tonic-gate return false; 61997c478bd9Sstevel@tonic-gate } 62007c478bd9Sstevel@tonic-gate if (map->map_valcolnm == NULL) 62017c478bd9Sstevel@tonic-gate /* EMPTY */ 62027c478bd9Sstevel@tonic-gate /* nothing */ ; 62037c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(map->map_valcolnm, "name") == 0) 62047c478bd9Sstevel@tonic-gate map->map_valcolno = 1; 62057c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(map->map_valcolnm, "passwd") == 0) 62067c478bd9Sstevel@tonic-gate map->map_valcolno = 2; 62077c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(map->map_valcolnm, "uid") == 0) 62087c478bd9Sstevel@tonic-gate map->map_valcolno = 3; 62097c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(map->map_valcolnm, "gid") == 0) 62107c478bd9Sstevel@tonic-gate map->map_valcolno = 4; 62117c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(map->map_valcolnm, "gecos") == 0) 62127c478bd9Sstevel@tonic-gate map->map_valcolno = 5; 62137c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(map->map_valcolnm, "dir") == 0) 62147c478bd9Sstevel@tonic-gate map->map_valcolno = 6; 62157c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(map->map_valcolnm, "shell") == 0) 62167c478bd9Sstevel@tonic-gate map->map_valcolno = 7; 62177c478bd9Sstevel@tonic-gate else 62187c478bd9Sstevel@tonic-gate { 62197c478bd9Sstevel@tonic-gate syserr("User map %s: unknown column name %s", 62207c478bd9Sstevel@tonic-gate map->map_mname, map->map_valcolnm); 62217c478bd9Sstevel@tonic-gate return false; 62227c478bd9Sstevel@tonic-gate } 62237c478bd9Sstevel@tonic-gate return true; 62247c478bd9Sstevel@tonic-gate } 62257c478bd9Sstevel@tonic-gate 62267c478bd9Sstevel@tonic-gate 62277c478bd9Sstevel@tonic-gate /* 62287c478bd9Sstevel@tonic-gate ** USER_MAP_LOOKUP -- look up a user in the passwd file. 62297c478bd9Sstevel@tonic-gate */ 62307c478bd9Sstevel@tonic-gate 62317c478bd9Sstevel@tonic-gate /* ARGSUSED3 */ 62327c478bd9Sstevel@tonic-gate char * 62337c478bd9Sstevel@tonic-gate user_map_lookup(map, key, av, statp) 62347c478bd9Sstevel@tonic-gate MAP *map; 62357c478bd9Sstevel@tonic-gate char *key; 62367c478bd9Sstevel@tonic-gate char **av; 62377c478bd9Sstevel@tonic-gate int *statp; 62387c478bd9Sstevel@tonic-gate { 62397c478bd9Sstevel@tonic-gate auto bool fuzzy; 62407c478bd9Sstevel@tonic-gate SM_MBDB_T user; 62417c478bd9Sstevel@tonic-gate 62427c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 62437c478bd9Sstevel@tonic-gate sm_dprintf("user_map_lookup(%s, %s)\n", 62447c478bd9Sstevel@tonic-gate map->map_mname, key); 62457c478bd9Sstevel@tonic-gate 62467c478bd9Sstevel@tonic-gate *statp = finduser(key, &fuzzy, &user); 62477c478bd9Sstevel@tonic-gate if (*statp != EX_OK) 62487c478bd9Sstevel@tonic-gate return NULL; 62497c478bd9Sstevel@tonic-gate if (bitset(MF_MATCHONLY, map->map_mflags)) 62507c478bd9Sstevel@tonic-gate return map_rewrite(map, key, strlen(key), NULL); 62517c478bd9Sstevel@tonic-gate else 62527c478bd9Sstevel@tonic-gate { 62537c478bd9Sstevel@tonic-gate char *rwval = NULL; 62547c478bd9Sstevel@tonic-gate char buf[30]; 62557c478bd9Sstevel@tonic-gate 62567c478bd9Sstevel@tonic-gate switch (map->map_valcolno) 62577c478bd9Sstevel@tonic-gate { 62587c478bd9Sstevel@tonic-gate case 0: 62597c478bd9Sstevel@tonic-gate case 1: 62607c478bd9Sstevel@tonic-gate rwval = user.mbdb_name; 62617c478bd9Sstevel@tonic-gate break; 62627c478bd9Sstevel@tonic-gate 62637c478bd9Sstevel@tonic-gate case 2: 62647c478bd9Sstevel@tonic-gate rwval = "x"; /* passwd no longer supported */ 62657c478bd9Sstevel@tonic-gate break; 62667c478bd9Sstevel@tonic-gate 62677c478bd9Sstevel@tonic-gate case 3: 6268058561cbSjbeck (void) sm_snprintf(buf, sizeof(buf), "%d", 62697c478bd9Sstevel@tonic-gate (int) user.mbdb_uid); 62707c478bd9Sstevel@tonic-gate rwval = buf; 62717c478bd9Sstevel@tonic-gate break; 62727c478bd9Sstevel@tonic-gate 62737c478bd9Sstevel@tonic-gate case 4: 6274058561cbSjbeck (void) sm_snprintf(buf, sizeof(buf), "%d", 62757c478bd9Sstevel@tonic-gate (int) user.mbdb_gid); 62767c478bd9Sstevel@tonic-gate rwval = buf; 62777c478bd9Sstevel@tonic-gate break; 62787c478bd9Sstevel@tonic-gate 62797c478bd9Sstevel@tonic-gate case 5: 62807c478bd9Sstevel@tonic-gate rwval = user.mbdb_fullname; 62817c478bd9Sstevel@tonic-gate break; 62827c478bd9Sstevel@tonic-gate 62837c478bd9Sstevel@tonic-gate case 6: 62847c478bd9Sstevel@tonic-gate rwval = user.mbdb_homedir; 62857c478bd9Sstevel@tonic-gate break; 62867c478bd9Sstevel@tonic-gate 62877c478bd9Sstevel@tonic-gate case 7: 62887c478bd9Sstevel@tonic-gate rwval = user.mbdb_shell; 62897c478bd9Sstevel@tonic-gate break; 62903ee0e492Sjbeck default: 62913ee0e492Sjbeck syserr("user_map %s: bogus field %d", 62923ee0e492Sjbeck map->map_mname, map->map_valcolno); 62933ee0e492Sjbeck return NULL; 62947c478bd9Sstevel@tonic-gate } 62957c478bd9Sstevel@tonic-gate return map_rewrite(map, rwval, strlen(rwval), av); 62967c478bd9Sstevel@tonic-gate } 62977c478bd9Sstevel@tonic-gate } 62987c478bd9Sstevel@tonic-gate /* 62997c478bd9Sstevel@tonic-gate ** Program map type. 63007c478bd9Sstevel@tonic-gate ** 63017c478bd9Sstevel@tonic-gate ** This provides access to arbitrary programs. It should be used 63027c478bd9Sstevel@tonic-gate ** only very sparingly, since there is no way to bound the cost 63037c478bd9Sstevel@tonic-gate ** of invoking an arbitrary program. 63047c478bd9Sstevel@tonic-gate */ 63057c478bd9Sstevel@tonic-gate 63067c478bd9Sstevel@tonic-gate char * 63077c478bd9Sstevel@tonic-gate prog_map_lookup(map, name, av, statp) 63087c478bd9Sstevel@tonic-gate MAP *map; 63097c478bd9Sstevel@tonic-gate char *name; 63107c478bd9Sstevel@tonic-gate char **av; 63117c478bd9Sstevel@tonic-gate int *statp; 63127c478bd9Sstevel@tonic-gate { 63137c478bd9Sstevel@tonic-gate int i; 63147c478bd9Sstevel@tonic-gate int save_errno; 63157c478bd9Sstevel@tonic-gate int fd; 63167c478bd9Sstevel@tonic-gate int status; 63177c478bd9Sstevel@tonic-gate auto pid_t pid; 63187c478bd9Sstevel@tonic-gate register char *p; 63197c478bd9Sstevel@tonic-gate char *rval; 63207c478bd9Sstevel@tonic-gate char *argv[MAXPV + 1]; 63217c478bd9Sstevel@tonic-gate char buf[MAXLINE]; 63227c478bd9Sstevel@tonic-gate 63237c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 63247c478bd9Sstevel@tonic-gate sm_dprintf("prog_map_lookup(%s, %s) %s\n", 63257c478bd9Sstevel@tonic-gate map->map_mname, name, map->map_file); 63267c478bd9Sstevel@tonic-gate 63277c478bd9Sstevel@tonic-gate i = 0; 63287c478bd9Sstevel@tonic-gate argv[i++] = map->map_file; 63297c478bd9Sstevel@tonic-gate if (map->map_rebuild != NULL) 63307c478bd9Sstevel@tonic-gate { 6331058561cbSjbeck (void) sm_strlcpy(buf, map->map_rebuild, sizeof(buf)); 63327c478bd9Sstevel@tonic-gate for (p = strtok(buf, " \t"); p != NULL; p = strtok(NULL, " \t")) 63337c478bd9Sstevel@tonic-gate { 63347c478bd9Sstevel@tonic-gate if (i >= MAXPV - 1) 63357c478bd9Sstevel@tonic-gate break; 63367c478bd9Sstevel@tonic-gate argv[i++] = p; 63377c478bd9Sstevel@tonic-gate } 63387c478bd9Sstevel@tonic-gate } 63397c478bd9Sstevel@tonic-gate argv[i++] = name; 63407c478bd9Sstevel@tonic-gate argv[i] = NULL; 63417c478bd9Sstevel@tonic-gate if (tTd(38, 21)) 63427c478bd9Sstevel@tonic-gate { 63437c478bd9Sstevel@tonic-gate sm_dprintf("prog_open:"); 63447c478bd9Sstevel@tonic-gate for (i = 0; argv[i] != NULL; i++) 63457c478bd9Sstevel@tonic-gate sm_dprintf(" %s", argv[i]); 63467c478bd9Sstevel@tonic-gate sm_dprintf("\n"); 63477c478bd9Sstevel@tonic-gate } 63487c478bd9Sstevel@tonic-gate (void) sm_blocksignal(SIGCHLD); 63497c478bd9Sstevel@tonic-gate pid = prog_open(argv, &fd, CurEnv); 63507c478bd9Sstevel@tonic-gate if (pid < 0) 63517c478bd9Sstevel@tonic-gate { 63527c478bd9Sstevel@tonic-gate if (!bitset(MF_OPTIONAL, map->map_mflags)) 63537c478bd9Sstevel@tonic-gate syserr("prog_map_lookup(%s) failed (%s) -- closing", 63547c478bd9Sstevel@tonic-gate map->map_mname, sm_errstring(errno)); 63557c478bd9Sstevel@tonic-gate else if (tTd(38, 9)) 63567c478bd9Sstevel@tonic-gate sm_dprintf("prog_map_lookup(%s) failed (%s) -- closing", 63577c478bd9Sstevel@tonic-gate map->map_mname, sm_errstring(errno)); 63587c478bd9Sstevel@tonic-gate map->map_mflags &= ~(MF_VALID|MF_OPEN); 63597c478bd9Sstevel@tonic-gate *statp = EX_OSFILE; 63607c478bd9Sstevel@tonic-gate return NULL; 63617c478bd9Sstevel@tonic-gate } 6362058561cbSjbeck i = read(fd, buf, sizeof(buf) - 1); 63637c478bd9Sstevel@tonic-gate if (i < 0) 63647c478bd9Sstevel@tonic-gate { 63657c478bd9Sstevel@tonic-gate syserr("prog_map_lookup(%s): read error %s", 63667c478bd9Sstevel@tonic-gate map->map_mname, sm_errstring(errno)); 63677c478bd9Sstevel@tonic-gate rval = NULL; 63687c478bd9Sstevel@tonic-gate } 63697c478bd9Sstevel@tonic-gate else if (i == 0) 63707c478bd9Sstevel@tonic-gate { 63717c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 63727c478bd9Sstevel@tonic-gate sm_dprintf("prog_map_lookup(%s): empty answer\n", 63737c478bd9Sstevel@tonic-gate map->map_mname); 63747c478bd9Sstevel@tonic-gate rval = NULL; 63757c478bd9Sstevel@tonic-gate } 63767c478bd9Sstevel@tonic-gate else 63777c478bd9Sstevel@tonic-gate { 63787c478bd9Sstevel@tonic-gate buf[i] = '\0'; 63797c478bd9Sstevel@tonic-gate p = strchr(buf, '\n'); 63807c478bd9Sstevel@tonic-gate if (p != NULL) 63817c478bd9Sstevel@tonic-gate *p = '\0'; 63827c478bd9Sstevel@tonic-gate 63837c478bd9Sstevel@tonic-gate /* collect the return value */ 63847c478bd9Sstevel@tonic-gate if (bitset(MF_MATCHONLY, map->map_mflags)) 63857c478bd9Sstevel@tonic-gate rval = map_rewrite(map, name, strlen(name), NULL); 63867c478bd9Sstevel@tonic-gate else 63877c478bd9Sstevel@tonic-gate rval = map_rewrite(map, buf, strlen(buf), av); 63887c478bd9Sstevel@tonic-gate 63897c478bd9Sstevel@tonic-gate /* now flush any additional output */ 6390058561cbSjbeck while ((i = read(fd, buf, sizeof(buf))) > 0) 63917c478bd9Sstevel@tonic-gate continue; 63927c478bd9Sstevel@tonic-gate } 63937c478bd9Sstevel@tonic-gate 63947c478bd9Sstevel@tonic-gate /* wait for the process to terminate */ 63957c478bd9Sstevel@tonic-gate (void) close(fd); 63967c478bd9Sstevel@tonic-gate status = waitfor(pid); 63977c478bd9Sstevel@tonic-gate save_errno = errno; 63987c478bd9Sstevel@tonic-gate (void) sm_releasesignal(SIGCHLD); 63997c478bd9Sstevel@tonic-gate errno = save_errno; 64007c478bd9Sstevel@tonic-gate 64017c478bd9Sstevel@tonic-gate if (status == -1) 64027c478bd9Sstevel@tonic-gate { 64037c478bd9Sstevel@tonic-gate syserr("prog_map_lookup(%s): wait error %s", 64047c478bd9Sstevel@tonic-gate map->map_mname, sm_errstring(errno)); 64057c478bd9Sstevel@tonic-gate *statp = EX_SOFTWARE; 64067c478bd9Sstevel@tonic-gate rval = NULL; 64077c478bd9Sstevel@tonic-gate } 64087c478bd9Sstevel@tonic-gate else if (WIFEXITED(status)) 64097c478bd9Sstevel@tonic-gate { 64107c478bd9Sstevel@tonic-gate if ((*statp = WEXITSTATUS(status)) != EX_OK) 64117c478bd9Sstevel@tonic-gate rval = NULL; 64127c478bd9Sstevel@tonic-gate } 64137c478bd9Sstevel@tonic-gate else 64147c478bd9Sstevel@tonic-gate { 64157c478bd9Sstevel@tonic-gate syserr("prog_map_lookup(%s): child died on signal %d", 64167c478bd9Sstevel@tonic-gate map->map_mname, status); 64177c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 64187c478bd9Sstevel@tonic-gate rval = NULL; 64197c478bd9Sstevel@tonic-gate } 64207c478bd9Sstevel@tonic-gate return rval; 64217c478bd9Sstevel@tonic-gate } 64227c478bd9Sstevel@tonic-gate /* 64237c478bd9Sstevel@tonic-gate ** Sequenced map type. 64247c478bd9Sstevel@tonic-gate ** 64257c478bd9Sstevel@tonic-gate ** Tries each map in order until something matches, much like 64267c478bd9Sstevel@tonic-gate ** implicit. Stores go to the first map in the list that can 64277c478bd9Sstevel@tonic-gate ** support storing. 64287c478bd9Sstevel@tonic-gate ** 64297c478bd9Sstevel@tonic-gate ** This is slightly unusual in that there are two interfaces. 64307c478bd9Sstevel@tonic-gate ** The "sequence" interface lets you stack maps arbitrarily. 64317c478bd9Sstevel@tonic-gate ** The "switch" interface builds a sequence map by looking 64327c478bd9Sstevel@tonic-gate ** at a system-dependent configuration file such as 64337c478bd9Sstevel@tonic-gate ** /etc/nsswitch.conf on Solaris or /etc/svc.conf on Ultrix. 64347c478bd9Sstevel@tonic-gate ** 64357c478bd9Sstevel@tonic-gate ** We don't need an explicit open, since all maps are 64367c478bd9Sstevel@tonic-gate ** opened on demand. 64377c478bd9Sstevel@tonic-gate */ 64387c478bd9Sstevel@tonic-gate 64397c478bd9Sstevel@tonic-gate /* 64407c478bd9Sstevel@tonic-gate ** SEQ_MAP_PARSE -- Sequenced map parsing 64417c478bd9Sstevel@tonic-gate */ 64427c478bd9Sstevel@tonic-gate 64437c478bd9Sstevel@tonic-gate bool 64447c478bd9Sstevel@tonic-gate seq_map_parse(map, ap) 64457c478bd9Sstevel@tonic-gate MAP *map; 64467c478bd9Sstevel@tonic-gate char *ap; 64477c478bd9Sstevel@tonic-gate { 64487c478bd9Sstevel@tonic-gate int maxmap; 64497c478bd9Sstevel@tonic-gate 64507c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 64517c478bd9Sstevel@tonic-gate sm_dprintf("seq_map_parse(%s, %s)\n", map->map_mname, ap); 64527c478bd9Sstevel@tonic-gate maxmap = 0; 64537c478bd9Sstevel@tonic-gate while (*ap != '\0') 64547c478bd9Sstevel@tonic-gate { 64557c478bd9Sstevel@tonic-gate register char *p; 64567c478bd9Sstevel@tonic-gate STAB *s; 64577c478bd9Sstevel@tonic-gate 64587c478bd9Sstevel@tonic-gate /* find beginning of map name */ 64597c478bd9Sstevel@tonic-gate while (isascii(*ap) && isspace(*ap)) 64607c478bd9Sstevel@tonic-gate ap++; 64617c478bd9Sstevel@tonic-gate for (p = ap; 64627c478bd9Sstevel@tonic-gate (isascii(*p) && isalnum(*p)) || *p == '_' || *p == '.'; 64637c478bd9Sstevel@tonic-gate p++) 64647c478bd9Sstevel@tonic-gate continue; 64657c478bd9Sstevel@tonic-gate if (*p != '\0') 64667c478bd9Sstevel@tonic-gate *p++ = '\0'; 64677c478bd9Sstevel@tonic-gate while (*p != '\0' && (!isascii(*p) || !isalnum(*p))) 64687c478bd9Sstevel@tonic-gate p++; 64697c478bd9Sstevel@tonic-gate if (*ap == '\0') 64707c478bd9Sstevel@tonic-gate { 64717c478bd9Sstevel@tonic-gate ap = p; 64727c478bd9Sstevel@tonic-gate continue; 64737c478bd9Sstevel@tonic-gate } 64747c478bd9Sstevel@tonic-gate s = stab(ap, ST_MAP, ST_FIND); 64757c478bd9Sstevel@tonic-gate if (s == NULL) 64767c478bd9Sstevel@tonic-gate { 64777c478bd9Sstevel@tonic-gate syserr("Sequence map %s: unknown member map %s", 64787c478bd9Sstevel@tonic-gate map->map_mname, ap); 64797c478bd9Sstevel@tonic-gate } 64807c478bd9Sstevel@tonic-gate else if (maxmap >= MAXMAPSTACK) 64817c478bd9Sstevel@tonic-gate { 64827c478bd9Sstevel@tonic-gate syserr("Sequence map %s: too many member maps (%d max)", 64837c478bd9Sstevel@tonic-gate map->map_mname, MAXMAPSTACK); 64847c478bd9Sstevel@tonic-gate maxmap++; 64857c478bd9Sstevel@tonic-gate } 64867c478bd9Sstevel@tonic-gate else if (maxmap < MAXMAPSTACK) 64877c478bd9Sstevel@tonic-gate { 64887c478bd9Sstevel@tonic-gate map->map_stack[maxmap++] = &s->s_map; 64897c478bd9Sstevel@tonic-gate } 64907c478bd9Sstevel@tonic-gate ap = p; 64917c478bd9Sstevel@tonic-gate } 64927c478bd9Sstevel@tonic-gate return true; 64937c478bd9Sstevel@tonic-gate } 64947c478bd9Sstevel@tonic-gate 64957c478bd9Sstevel@tonic-gate /* 64967c478bd9Sstevel@tonic-gate ** SWITCH_MAP_OPEN -- open a switched map 64977c478bd9Sstevel@tonic-gate ** 64987c478bd9Sstevel@tonic-gate ** This looks at the system-dependent configuration and builds 64997c478bd9Sstevel@tonic-gate ** a sequence map that does the same thing. 65007c478bd9Sstevel@tonic-gate ** 65017c478bd9Sstevel@tonic-gate ** Every system must define a switch_map_find routine in conf.c 65027c478bd9Sstevel@tonic-gate ** that will return the list of service types associated with a 65037c478bd9Sstevel@tonic-gate ** given service class. 65047c478bd9Sstevel@tonic-gate */ 65057c478bd9Sstevel@tonic-gate 65067c478bd9Sstevel@tonic-gate bool 65077c478bd9Sstevel@tonic-gate switch_map_open(map, mode) 65087c478bd9Sstevel@tonic-gate MAP *map; 65097c478bd9Sstevel@tonic-gate int mode; 65107c478bd9Sstevel@tonic-gate { 65117c478bd9Sstevel@tonic-gate int mapno; 65127c478bd9Sstevel@tonic-gate int nmaps; 65137c478bd9Sstevel@tonic-gate char *maptype[MAXMAPSTACK]; 65147c478bd9Sstevel@tonic-gate 65157c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 65167c478bd9Sstevel@tonic-gate sm_dprintf("switch_map_open(%s, %s, %d)\n", 65177c478bd9Sstevel@tonic-gate map->map_mname, map->map_file, mode); 65187c478bd9Sstevel@tonic-gate 65197c478bd9Sstevel@tonic-gate mode &= O_ACCMODE; 65207c478bd9Sstevel@tonic-gate nmaps = switch_map_find(map->map_file, maptype, map->map_return); 65217c478bd9Sstevel@tonic-gate if (tTd(38, 19)) 65227c478bd9Sstevel@tonic-gate { 65237c478bd9Sstevel@tonic-gate sm_dprintf("\tswitch_map_find => %d\n", nmaps); 65247c478bd9Sstevel@tonic-gate for (mapno = 0; mapno < nmaps; mapno++) 65257c478bd9Sstevel@tonic-gate sm_dprintf("\t\t%s\n", maptype[mapno]); 65267c478bd9Sstevel@tonic-gate } 65277c478bd9Sstevel@tonic-gate if (nmaps <= 0 || nmaps > MAXMAPSTACK) 65287c478bd9Sstevel@tonic-gate return false; 65297c478bd9Sstevel@tonic-gate 65307c478bd9Sstevel@tonic-gate for (mapno = 0; mapno < nmaps; mapno++) 65317c478bd9Sstevel@tonic-gate { 65327c478bd9Sstevel@tonic-gate register STAB *s; 65337c478bd9Sstevel@tonic-gate char nbuf[MAXNAME + 1]; 65347c478bd9Sstevel@tonic-gate 65357c478bd9Sstevel@tonic-gate if (maptype[mapno] == NULL) 65367c478bd9Sstevel@tonic-gate continue; 6537058561cbSjbeck (void) sm_strlcpyn(nbuf, sizeof(nbuf), 3, 65387c478bd9Sstevel@tonic-gate map->map_mname, ".", maptype[mapno]); 65397c478bd9Sstevel@tonic-gate s = stab(nbuf, ST_MAP, ST_FIND); 65407c478bd9Sstevel@tonic-gate if (s == NULL) 65417c478bd9Sstevel@tonic-gate { 65427c478bd9Sstevel@tonic-gate syserr("Switch map %s: unknown member map %s", 65437c478bd9Sstevel@tonic-gate map->map_mname, nbuf); 65447c478bd9Sstevel@tonic-gate } 65457c478bd9Sstevel@tonic-gate else 65467c478bd9Sstevel@tonic-gate { 65477c478bd9Sstevel@tonic-gate map->map_stack[mapno] = &s->s_map; 65487c478bd9Sstevel@tonic-gate if (tTd(38, 4)) 65497c478bd9Sstevel@tonic-gate sm_dprintf("\tmap_stack[%d] = %s:%s\n", 65507c478bd9Sstevel@tonic-gate mapno, 65517c478bd9Sstevel@tonic-gate s->s_map.map_class->map_cname, 65527c478bd9Sstevel@tonic-gate nbuf); 65537c478bd9Sstevel@tonic-gate } 65547c478bd9Sstevel@tonic-gate } 65557c478bd9Sstevel@tonic-gate return true; 65567c478bd9Sstevel@tonic-gate } 65577c478bd9Sstevel@tonic-gate 65587c478bd9Sstevel@tonic-gate #if 0 65597c478bd9Sstevel@tonic-gate /* 65607c478bd9Sstevel@tonic-gate ** SEQ_MAP_CLOSE -- close all underlying maps 65617c478bd9Sstevel@tonic-gate */ 65627c478bd9Sstevel@tonic-gate 65637c478bd9Sstevel@tonic-gate void 65647c478bd9Sstevel@tonic-gate seq_map_close(map) 65657c478bd9Sstevel@tonic-gate MAP *map; 65667c478bd9Sstevel@tonic-gate { 65677c478bd9Sstevel@tonic-gate int mapno; 65687c478bd9Sstevel@tonic-gate 65697c478bd9Sstevel@tonic-gate if (tTd(38, 9)) 65707c478bd9Sstevel@tonic-gate sm_dprintf("seq_map_close(%s)\n", map->map_mname); 65717c478bd9Sstevel@tonic-gate 65727c478bd9Sstevel@tonic-gate for (mapno = 0; mapno < MAXMAPSTACK; mapno++) 65737c478bd9Sstevel@tonic-gate { 65747c478bd9Sstevel@tonic-gate MAP *mm = map->map_stack[mapno]; 65757c478bd9Sstevel@tonic-gate 65767c478bd9Sstevel@tonic-gate if (mm == NULL || !bitset(MF_OPEN, mm->map_mflags)) 65777c478bd9Sstevel@tonic-gate continue; 65787c478bd9Sstevel@tonic-gate mm->map_mflags |= MF_CLOSING; 65797c478bd9Sstevel@tonic-gate mm->map_class->map_close(mm); 65807c478bd9Sstevel@tonic-gate mm->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING); 65817c478bd9Sstevel@tonic-gate } 65827c478bd9Sstevel@tonic-gate } 65837c478bd9Sstevel@tonic-gate #endif /* 0 */ 65847c478bd9Sstevel@tonic-gate 65857c478bd9Sstevel@tonic-gate /* 65867c478bd9Sstevel@tonic-gate ** SEQ_MAP_LOOKUP -- sequenced map lookup 65877c478bd9Sstevel@tonic-gate */ 65887c478bd9Sstevel@tonic-gate 65897c478bd9Sstevel@tonic-gate char * 65907c478bd9Sstevel@tonic-gate seq_map_lookup(map, key, args, pstat) 65917c478bd9Sstevel@tonic-gate MAP *map; 65927c478bd9Sstevel@tonic-gate char *key; 65937c478bd9Sstevel@tonic-gate char **args; 65947c478bd9Sstevel@tonic-gate int *pstat; 65957c478bd9Sstevel@tonic-gate { 65967c478bd9Sstevel@tonic-gate int mapno; 65977c478bd9Sstevel@tonic-gate int mapbit = 0x01; 65987c478bd9Sstevel@tonic-gate bool tempfail = false; 65997c478bd9Sstevel@tonic-gate 66007c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 66017c478bd9Sstevel@tonic-gate sm_dprintf("seq_map_lookup(%s, %s)\n", map->map_mname, key); 66027c478bd9Sstevel@tonic-gate 66037c478bd9Sstevel@tonic-gate for (mapno = 0; mapno < MAXMAPSTACK; mapbit <<= 1, mapno++) 66047c478bd9Sstevel@tonic-gate { 66057c478bd9Sstevel@tonic-gate MAP *mm = map->map_stack[mapno]; 66067c478bd9Sstevel@tonic-gate char *rv; 66077c478bd9Sstevel@tonic-gate 66087c478bd9Sstevel@tonic-gate if (mm == NULL) 66097c478bd9Sstevel@tonic-gate continue; 66107c478bd9Sstevel@tonic-gate if (!bitset(MF_OPEN, mm->map_mflags) && 66117c478bd9Sstevel@tonic-gate !openmap(mm)) 66127c478bd9Sstevel@tonic-gate { 66137c478bd9Sstevel@tonic-gate if (bitset(mapbit, map->map_return[MA_UNAVAIL])) 66147c478bd9Sstevel@tonic-gate { 66157c478bd9Sstevel@tonic-gate *pstat = EX_UNAVAILABLE; 66167c478bd9Sstevel@tonic-gate return NULL; 66177c478bd9Sstevel@tonic-gate } 66187c478bd9Sstevel@tonic-gate continue; 66197c478bd9Sstevel@tonic-gate } 66207c478bd9Sstevel@tonic-gate *pstat = EX_OK; 66217c478bd9Sstevel@tonic-gate rv = mm->map_class->map_lookup(mm, key, args, pstat); 66227c478bd9Sstevel@tonic-gate if (rv != NULL) 66237c478bd9Sstevel@tonic-gate return rv; 66247c478bd9Sstevel@tonic-gate if (*pstat == EX_TEMPFAIL) 66257c478bd9Sstevel@tonic-gate { 66267c478bd9Sstevel@tonic-gate if (bitset(mapbit, map->map_return[MA_TRYAGAIN])) 66277c478bd9Sstevel@tonic-gate return NULL; 66287c478bd9Sstevel@tonic-gate tempfail = true; 66297c478bd9Sstevel@tonic-gate } 66307c478bd9Sstevel@tonic-gate else if (bitset(mapbit, map->map_return[MA_NOTFOUND])) 66317c478bd9Sstevel@tonic-gate break; 66327c478bd9Sstevel@tonic-gate } 66337c478bd9Sstevel@tonic-gate if (tempfail) 66347c478bd9Sstevel@tonic-gate *pstat = EX_TEMPFAIL; 66357c478bd9Sstevel@tonic-gate else if (*pstat == EX_OK) 66367c478bd9Sstevel@tonic-gate *pstat = EX_NOTFOUND; 66377c478bd9Sstevel@tonic-gate return NULL; 66387c478bd9Sstevel@tonic-gate } 66397c478bd9Sstevel@tonic-gate 66407c478bd9Sstevel@tonic-gate /* 66417c478bd9Sstevel@tonic-gate ** SEQ_MAP_STORE -- sequenced map store 66427c478bd9Sstevel@tonic-gate */ 66437c478bd9Sstevel@tonic-gate 66447c478bd9Sstevel@tonic-gate void 66457c478bd9Sstevel@tonic-gate seq_map_store(map, key, val) 66467c478bd9Sstevel@tonic-gate MAP *map; 66477c478bd9Sstevel@tonic-gate char *key; 66487c478bd9Sstevel@tonic-gate char *val; 66497c478bd9Sstevel@tonic-gate { 66507c478bd9Sstevel@tonic-gate int mapno; 66517c478bd9Sstevel@tonic-gate 66527c478bd9Sstevel@tonic-gate if (tTd(38, 12)) 66537c478bd9Sstevel@tonic-gate sm_dprintf("seq_map_store(%s, %s, %s)\n", 66547c478bd9Sstevel@tonic-gate map->map_mname, key, val); 66557c478bd9Sstevel@tonic-gate 66567c478bd9Sstevel@tonic-gate for (mapno = 0; mapno < MAXMAPSTACK; mapno++) 66577c478bd9Sstevel@tonic-gate { 66587c478bd9Sstevel@tonic-gate MAP *mm = map->map_stack[mapno]; 66597c478bd9Sstevel@tonic-gate 66607c478bd9Sstevel@tonic-gate if (mm == NULL || !bitset(MF_WRITABLE, mm->map_mflags)) 66617c478bd9Sstevel@tonic-gate continue; 66627c478bd9Sstevel@tonic-gate 66637c478bd9Sstevel@tonic-gate mm->map_class->map_store(mm, key, val); 66647c478bd9Sstevel@tonic-gate return; 66657c478bd9Sstevel@tonic-gate } 66667c478bd9Sstevel@tonic-gate syserr("seq_map_store(%s, %s, %s): no writable map", 66677c478bd9Sstevel@tonic-gate map->map_mname, key, val); 66687c478bd9Sstevel@tonic-gate } 66697c478bd9Sstevel@tonic-gate /* 66707c478bd9Sstevel@tonic-gate ** NULL stubs 66717c478bd9Sstevel@tonic-gate */ 66727c478bd9Sstevel@tonic-gate 66737c478bd9Sstevel@tonic-gate /* ARGSUSED */ 66747c478bd9Sstevel@tonic-gate bool 66757c478bd9Sstevel@tonic-gate null_map_open(map, mode) 66767c478bd9Sstevel@tonic-gate MAP *map; 66777c478bd9Sstevel@tonic-gate int mode; 66787c478bd9Sstevel@tonic-gate { 66797c478bd9Sstevel@tonic-gate return true; 66807c478bd9Sstevel@tonic-gate } 66817c478bd9Sstevel@tonic-gate 66827c478bd9Sstevel@tonic-gate /* ARGSUSED */ 66837c478bd9Sstevel@tonic-gate void 66847c478bd9Sstevel@tonic-gate null_map_close(map) 66857c478bd9Sstevel@tonic-gate MAP *map; 66867c478bd9Sstevel@tonic-gate { 66877c478bd9Sstevel@tonic-gate return; 66887c478bd9Sstevel@tonic-gate } 66897c478bd9Sstevel@tonic-gate 66907c478bd9Sstevel@tonic-gate char * 66917c478bd9Sstevel@tonic-gate null_map_lookup(map, key, args, pstat) 66927c478bd9Sstevel@tonic-gate MAP *map; 66937c478bd9Sstevel@tonic-gate char *key; 66947c478bd9Sstevel@tonic-gate char **args; 66957c478bd9Sstevel@tonic-gate int *pstat; 66967c478bd9Sstevel@tonic-gate { 66977c478bd9Sstevel@tonic-gate *pstat = EX_NOTFOUND; 66987c478bd9Sstevel@tonic-gate return NULL; 66997c478bd9Sstevel@tonic-gate } 67007c478bd9Sstevel@tonic-gate 67017c478bd9Sstevel@tonic-gate /* ARGSUSED */ 67027c478bd9Sstevel@tonic-gate void 67037c478bd9Sstevel@tonic-gate null_map_store(map, key, val) 67047c478bd9Sstevel@tonic-gate MAP *map; 67057c478bd9Sstevel@tonic-gate char *key; 67067c478bd9Sstevel@tonic-gate char *val; 67077c478bd9Sstevel@tonic-gate { 67087c478bd9Sstevel@tonic-gate return; 67097c478bd9Sstevel@tonic-gate } 67107c478bd9Sstevel@tonic-gate 6711*e9af4bc0SJohn Beck MAPCLASS NullMapClass = 6712*e9af4bc0SJohn Beck { 6713*e9af4bc0SJohn Beck "null-map", NULL, 0, 6714*e9af4bc0SJohn Beck NULL, null_map_lookup, null_map_store, 6715*e9af4bc0SJohn Beck null_map_open, null_map_close, 6716*e9af4bc0SJohn Beck }; 6717*e9af4bc0SJohn Beck 67187c478bd9Sstevel@tonic-gate /* 67197c478bd9Sstevel@tonic-gate ** BOGUS stubs 67207c478bd9Sstevel@tonic-gate */ 67217c478bd9Sstevel@tonic-gate 67227c478bd9Sstevel@tonic-gate char * 67237c478bd9Sstevel@tonic-gate bogus_map_lookup(map, key, args, pstat) 67247c478bd9Sstevel@tonic-gate MAP *map; 67257c478bd9Sstevel@tonic-gate char *key; 67267c478bd9Sstevel@tonic-gate char **args; 67277c478bd9Sstevel@tonic-gate int *pstat; 67287c478bd9Sstevel@tonic-gate { 67297c478bd9Sstevel@tonic-gate *pstat = EX_TEMPFAIL; 67307c478bd9Sstevel@tonic-gate return NULL; 67317c478bd9Sstevel@tonic-gate } 67327c478bd9Sstevel@tonic-gate 67337c478bd9Sstevel@tonic-gate MAPCLASS BogusMapClass = 67347c478bd9Sstevel@tonic-gate { 67357c478bd9Sstevel@tonic-gate "bogus-map", NULL, 0, 67367c478bd9Sstevel@tonic-gate NULL, bogus_map_lookup, null_map_store, 67377c478bd9Sstevel@tonic-gate null_map_open, null_map_close, 67387c478bd9Sstevel@tonic-gate }; 67397c478bd9Sstevel@tonic-gate /* 67407c478bd9Sstevel@tonic-gate ** MACRO modules 67417c478bd9Sstevel@tonic-gate */ 67427c478bd9Sstevel@tonic-gate 67437c478bd9Sstevel@tonic-gate char * 67447c478bd9Sstevel@tonic-gate macro_map_lookup(map, name, av, statp) 67457c478bd9Sstevel@tonic-gate MAP *map; 67467c478bd9Sstevel@tonic-gate char *name; 67477c478bd9Sstevel@tonic-gate char **av; 67487c478bd9Sstevel@tonic-gate int *statp; 67497c478bd9Sstevel@tonic-gate { 67507c478bd9Sstevel@tonic-gate int mid; 67517c478bd9Sstevel@tonic-gate 67527c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 67537c478bd9Sstevel@tonic-gate sm_dprintf("macro_map_lookup(%s, %s)\n", map->map_mname, 67547c478bd9Sstevel@tonic-gate name == NULL ? "NULL" : name); 67557c478bd9Sstevel@tonic-gate 67567c478bd9Sstevel@tonic-gate if (name == NULL || 67577c478bd9Sstevel@tonic-gate *name == '\0' || 67587c478bd9Sstevel@tonic-gate (mid = macid(name)) == 0) 67597c478bd9Sstevel@tonic-gate { 67607c478bd9Sstevel@tonic-gate *statp = EX_CONFIG; 67617c478bd9Sstevel@tonic-gate return NULL; 67627c478bd9Sstevel@tonic-gate } 67637c478bd9Sstevel@tonic-gate 67647c478bd9Sstevel@tonic-gate if (av[1] == NULL) 67657c478bd9Sstevel@tonic-gate macdefine(&CurEnv->e_macro, A_PERM, mid, NULL); 67667c478bd9Sstevel@tonic-gate else 67677c478bd9Sstevel@tonic-gate macdefine(&CurEnv->e_macro, A_TEMP, mid, av[1]); 67687c478bd9Sstevel@tonic-gate 67697c478bd9Sstevel@tonic-gate *statp = EX_OK; 67707c478bd9Sstevel@tonic-gate return ""; 67717c478bd9Sstevel@tonic-gate } 67727c478bd9Sstevel@tonic-gate /* 67737c478bd9Sstevel@tonic-gate ** REGEX modules 67747c478bd9Sstevel@tonic-gate */ 67757c478bd9Sstevel@tonic-gate 67767c478bd9Sstevel@tonic-gate #if MAP_REGEX 67777c478bd9Sstevel@tonic-gate 67787c478bd9Sstevel@tonic-gate # include <regex.h> 67797c478bd9Sstevel@tonic-gate 67807c478bd9Sstevel@tonic-gate # define DEFAULT_DELIM CONDELSE 67817c478bd9Sstevel@tonic-gate # define END_OF_FIELDS -1 67827c478bd9Sstevel@tonic-gate # define ERRBUF_SIZE 80 67837c478bd9Sstevel@tonic-gate # define MAX_MATCH 32 67847c478bd9Sstevel@tonic-gate 67857c478bd9Sstevel@tonic-gate # define xnalloc(s) memset(xalloc(s), '\0', s); 67867c478bd9Sstevel@tonic-gate 67877c478bd9Sstevel@tonic-gate struct regex_map 67887c478bd9Sstevel@tonic-gate { 67897c478bd9Sstevel@tonic-gate regex_t *regex_pattern_buf; /* xalloc it */ 67907c478bd9Sstevel@tonic-gate int *regex_subfields; /* move to type MAP */ 67917c478bd9Sstevel@tonic-gate char *regex_delim; /* move to type MAP */ 67927c478bd9Sstevel@tonic-gate }; 67937c478bd9Sstevel@tonic-gate 67947c478bd9Sstevel@tonic-gate static int parse_fields __P((char *, int *, int, int)); 67957c478bd9Sstevel@tonic-gate static char *regex_map_rewrite __P((MAP *, const char*, size_t, char **)); 67967c478bd9Sstevel@tonic-gate 67977c478bd9Sstevel@tonic-gate static int 67987c478bd9Sstevel@tonic-gate parse_fields(s, ibuf, blen, nr_substrings) 67997c478bd9Sstevel@tonic-gate char *s; 68007c478bd9Sstevel@tonic-gate int *ibuf; /* array */ 68017c478bd9Sstevel@tonic-gate int blen; /* number of elements in ibuf */ 68027c478bd9Sstevel@tonic-gate int nr_substrings; /* number of substrings in the pattern */ 68037c478bd9Sstevel@tonic-gate { 68047c478bd9Sstevel@tonic-gate register char *cp; 68057c478bd9Sstevel@tonic-gate int i = 0; 68067c478bd9Sstevel@tonic-gate bool lastone = false; 68077c478bd9Sstevel@tonic-gate 68087c478bd9Sstevel@tonic-gate blen--; /* for terminating END_OF_FIELDS */ 68097c478bd9Sstevel@tonic-gate cp = s; 68107c478bd9Sstevel@tonic-gate do 68117c478bd9Sstevel@tonic-gate { 68127c478bd9Sstevel@tonic-gate for (;; cp++) 68137c478bd9Sstevel@tonic-gate { 68147c478bd9Sstevel@tonic-gate if (*cp == ',') 68157c478bd9Sstevel@tonic-gate { 68167c478bd9Sstevel@tonic-gate *cp = '\0'; 68177c478bd9Sstevel@tonic-gate break; 68187c478bd9Sstevel@tonic-gate } 68197c478bd9Sstevel@tonic-gate if (*cp == '\0') 68207c478bd9Sstevel@tonic-gate { 68217c478bd9Sstevel@tonic-gate lastone = true; 68227c478bd9Sstevel@tonic-gate break; 68237c478bd9Sstevel@tonic-gate } 68247c478bd9Sstevel@tonic-gate } 68257c478bd9Sstevel@tonic-gate if (i < blen) 68267c478bd9Sstevel@tonic-gate { 68277c478bd9Sstevel@tonic-gate int val = atoi(s); 68287c478bd9Sstevel@tonic-gate 68297c478bd9Sstevel@tonic-gate if (val < 0 || val >= nr_substrings) 68307c478bd9Sstevel@tonic-gate { 68317c478bd9Sstevel@tonic-gate syserr("field (%d) out of range, only %d substrings in pattern", 68327c478bd9Sstevel@tonic-gate val, nr_substrings); 68337c478bd9Sstevel@tonic-gate return -1; 68347c478bd9Sstevel@tonic-gate } 68357c478bd9Sstevel@tonic-gate ibuf[i++] = val; 68367c478bd9Sstevel@tonic-gate } 68377c478bd9Sstevel@tonic-gate else 68387c478bd9Sstevel@tonic-gate { 68397c478bd9Sstevel@tonic-gate syserr("too many fields, %d max", blen); 68407c478bd9Sstevel@tonic-gate return -1; 68417c478bd9Sstevel@tonic-gate } 68427c478bd9Sstevel@tonic-gate s = ++cp; 68437c478bd9Sstevel@tonic-gate } while (!lastone); 68447c478bd9Sstevel@tonic-gate ibuf[i] = END_OF_FIELDS; 68457c478bd9Sstevel@tonic-gate return i; 68467c478bd9Sstevel@tonic-gate } 68477c478bd9Sstevel@tonic-gate 68487c478bd9Sstevel@tonic-gate bool 68497c478bd9Sstevel@tonic-gate regex_map_init(map, ap) 68507c478bd9Sstevel@tonic-gate MAP *map; 68517c478bd9Sstevel@tonic-gate char *ap; 68527c478bd9Sstevel@tonic-gate { 68537c478bd9Sstevel@tonic-gate int regerr; 68547c478bd9Sstevel@tonic-gate struct regex_map *map_p; 68557c478bd9Sstevel@tonic-gate register char *p; 68567c478bd9Sstevel@tonic-gate char *sub_param = NULL; 68577c478bd9Sstevel@tonic-gate int pflags; 68587c478bd9Sstevel@tonic-gate static char defdstr[] = { (char) DEFAULT_DELIM, '\0' }; 68597c478bd9Sstevel@tonic-gate 68607c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 68617c478bd9Sstevel@tonic-gate sm_dprintf("regex_map_init: mapname '%s', args '%s'\n", 68627c478bd9Sstevel@tonic-gate map->map_mname, ap); 68637c478bd9Sstevel@tonic-gate 68647c478bd9Sstevel@tonic-gate pflags = REG_ICASE | REG_EXTENDED | REG_NOSUB; 68657c478bd9Sstevel@tonic-gate p = ap; 6866058561cbSjbeck map_p = (struct regex_map *) xnalloc(sizeof(*map_p)); 68677c478bd9Sstevel@tonic-gate map_p->regex_pattern_buf = (regex_t *)xnalloc(sizeof(regex_t)); 68687c478bd9Sstevel@tonic-gate 68697c478bd9Sstevel@tonic-gate for (;;) 68707c478bd9Sstevel@tonic-gate { 68717c478bd9Sstevel@tonic-gate while (isascii(*p) && isspace(*p)) 68727c478bd9Sstevel@tonic-gate p++; 68737c478bd9Sstevel@tonic-gate if (*p != '-') 68747c478bd9Sstevel@tonic-gate break; 68757c478bd9Sstevel@tonic-gate switch (*++p) 68767c478bd9Sstevel@tonic-gate { 68777c478bd9Sstevel@tonic-gate case 'n': /* not */ 68787c478bd9Sstevel@tonic-gate map->map_mflags |= MF_REGEX_NOT; 68797c478bd9Sstevel@tonic-gate break; 68807c478bd9Sstevel@tonic-gate 68817c478bd9Sstevel@tonic-gate case 'f': /* case sensitive */ 68827c478bd9Sstevel@tonic-gate map->map_mflags |= MF_NOFOLDCASE; 68837c478bd9Sstevel@tonic-gate pflags &= ~REG_ICASE; 68847c478bd9Sstevel@tonic-gate break; 68857c478bd9Sstevel@tonic-gate 68867c478bd9Sstevel@tonic-gate case 'b': /* basic regular expressions */ 68877c478bd9Sstevel@tonic-gate pflags &= ~REG_EXTENDED; 68887c478bd9Sstevel@tonic-gate break; 68897c478bd9Sstevel@tonic-gate 68907c478bd9Sstevel@tonic-gate case 's': /* substring match () syntax */ 68917c478bd9Sstevel@tonic-gate sub_param = ++p; 68927c478bd9Sstevel@tonic-gate pflags &= ~REG_NOSUB; 68937c478bd9Sstevel@tonic-gate break; 68947c478bd9Sstevel@tonic-gate 68957c478bd9Sstevel@tonic-gate case 'd': /* delimiter */ 68967c478bd9Sstevel@tonic-gate map_p->regex_delim = ++p; 68977c478bd9Sstevel@tonic-gate break; 68987c478bd9Sstevel@tonic-gate 68997c478bd9Sstevel@tonic-gate case 'a': /* map append */ 69007c478bd9Sstevel@tonic-gate map->map_app = ++p; 69017c478bd9Sstevel@tonic-gate break; 69027c478bd9Sstevel@tonic-gate 69037c478bd9Sstevel@tonic-gate case 'm': /* matchonly */ 69047c478bd9Sstevel@tonic-gate map->map_mflags |= MF_MATCHONLY; 69057c478bd9Sstevel@tonic-gate break; 69067c478bd9Sstevel@tonic-gate 69077c478bd9Sstevel@tonic-gate case 'q': 69087c478bd9Sstevel@tonic-gate map->map_mflags |= MF_KEEPQUOTES; 69097c478bd9Sstevel@tonic-gate break; 69107c478bd9Sstevel@tonic-gate 69117c478bd9Sstevel@tonic-gate case 'S': 69127c478bd9Sstevel@tonic-gate map->map_spacesub = *++p; 69137c478bd9Sstevel@tonic-gate break; 69147c478bd9Sstevel@tonic-gate 69157c478bd9Sstevel@tonic-gate case 'D': 69167c478bd9Sstevel@tonic-gate map->map_mflags |= MF_DEFER; 69177c478bd9Sstevel@tonic-gate break; 69187c478bd9Sstevel@tonic-gate 69197c478bd9Sstevel@tonic-gate } 69207c478bd9Sstevel@tonic-gate while (*p != '\0' && !(isascii(*p) && isspace(*p))) 69217c478bd9Sstevel@tonic-gate p++; 69227c478bd9Sstevel@tonic-gate if (*p != '\0') 69237c478bd9Sstevel@tonic-gate *p++ = '\0'; 69247c478bd9Sstevel@tonic-gate } 69257c478bd9Sstevel@tonic-gate if (tTd(38, 3)) 69267c478bd9Sstevel@tonic-gate sm_dprintf("regex_map_init: compile '%s' 0x%x\n", p, pflags); 69277c478bd9Sstevel@tonic-gate 69287c478bd9Sstevel@tonic-gate if ((regerr = regcomp(map_p->regex_pattern_buf, p, pflags)) != 0) 69297c478bd9Sstevel@tonic-gate { 69307c478bd9Sstevel@tonic-gate /* Errorhandling */ 69317c478bd9Sstevel@tonic-gate char errbuf[ERRBUF_SIZE]; 69327c478bd9Sstevel@tonic-gate 69337c478bd9Sstevel@tonic-gate (void) regerror(regerr, map_p->regex_pattern_buf, 6934058561cbSjbeck errbuf, sizeof(errbuf)); 69357c478bd9Sstevel@tonic-gate syserr("pattern-compile-error: %s", errbuf); 69367c478bd9Sstevel@tonic-gate sm_free(map_p->regex_pattern_buf); /* XXX */ 69377c478bd9Sstevel@tonic-gate sm_free(map_p); /* XXX */ 69387c478bd9Sstevel@tonic-gate return false; 69397c478bd9Sstevel@tonic-gate } 69407c478bd9Sstevel@tonic-gate 69417c478bd9Sstevel@tonic-gate if (map->map_app != NULL) 69427c478bd9Sstevel@tonic-gate map->map_app = newstr(map->map_app); 69437c478bd9Sstevel@tonic-gate if (map_p->regex_delim != NULL) 69447c478bd9Sstevel@tonic-gate map_p->regex_delim = newstr(map_p->regex_delim); 69457c478bd9Sstevel@tonic-gate else 69467c478bd9Sstevel@tonic-gate map_p->regex_delim = defdstr; 69477c478bd9Sstevel@tonic-gate 69487c478bd9Sstevel@tonic-gate if (!bitset(REG_NOSUB, pflags)) 69497c478bd9Sstevel@tonic-gate { 69507c478bd9Sstevel@tonic-gate /* substring matching */ 69517c478bd9Sstevel@tonic-gate int substrings; 69527c478bd9Sstevel@tonic-gate int *fields = (int *) xalloc(sizeof(int) * (MAX_MATCH + 1)); 69537c478bd9Sstevel@tonic-gate 69547c478bd9Sstevel@tonic-gate substrings = map_p->regex_pattern_buf->re_nsub + 1; 69557c478bd9Sstevel@tonic-gate 69567c478bd9Sstevel@tonic-gate if (tTd(38, 3)) 69577c478bd9Sstevel@tonic-gate sm_dprintf("regex_map_init: nr of substrings %d\n", 69587c478bd9Sstevel@tonic-gate substrings); 69597c478bd9Sstevel@tonic-gate 69607c478bd9Sstevel@tonic-gate if (substrings >= MAX_MATCH) 69617c478bd9Sstevel@tonic-gate { 69627c478bd9Sstevel@tonic-gate syserr("too many substrings, %d max", MAX_MATCH); 69637c478bd9Sstevel@tonic-gate sm_free(map_p->regex_pattern_buf); /* XXX */ 69647c478bd9Sstevel@tonic-gate sm_free(map_p); /* XXX */ 69657c478bd9Sstevel@tonic-gate return false; 69667c478bd9Sstevel@tonic-gate } 69677c478bd9Sstevel@tonic-gate if (sub_param != NULL && sub_param[0] != '\0') 69687c478bd9Sstevel@tonic-gate { 69697c478bd9Sstevel@tonic-gate /* optional parameter -sfields */ 69707c478bd9Sstevel@tonic-gate if (parse_fields(sub_param, fields, 69717c478bd9Sstevel@tonic-gate MAX_MATCH + 1, substrings) == -1) 69727c478bd9Sstevel@tonic-gate return false; 69737c478bd9Sstevel@tonic-gate } 69747c478bd9Sstevel@tonic-gate else 69757c478bd9Sstevel@tonic-gate { 69767c478bd9Sstevel@tonic-gate int i; 69777c478bd9Sstevel@tonic-gate 69787c478bd9Sstevel@tonic-gate /* set default fields */ 69797c478bd9Sstevel@tonic-gate for (i = 0; i < substrings; i++) 69807c478bd9Sstevel@tonic-gate fields[i] = i; 69817c478bd9Sstevel@tonic-gate fields[i] = END_OF_FIELDS; 69827c478bd9Sstevel@tonic-gate } 69837c478bd9Sstevel@tonic-gate map_p->regex_subfields = fields; 69847c478bd9Sstevel@tonic-gate if (tTd(38, 3)) 69857c478bd9Sstevel@tonic-gate { 69867c478bd9Sstevel@tonic-gate int *ip; 69877c478bd9Sstevel@tonic-gate 69887c478bd9Sstevel@tonic-gate sm_dprintf("regex_map_init: subfields"); 69897c478bd9Sstevel@tonic-gate for (ip = fields; *ip != END_OF_FIELDS; ip++) 69907c478bd9Sstevel@tonic-gate sm_dprintf(" %d", *ip); 69917c478bd9Sstevel@tonic-gate sm_dprintf("\n"); 69927c478bd9Sstevel@tonic-gate } 69937c478bd9Sstevel@tonic-gate } 69947c478bd9Sstevel@tonic-gate map->map_db1 = (ARBPTR_T) map_p; /* dirty hack */ 69957c478bd9Sstevel@tonic-gate return true; 69967c478bd9Sstevel@tonic-gate } 69977c478bd9Sstevel@tonic-gate 69987c478bd9Sstevel@tonic-gate static char * 69997c478bd9Sstevel@tonic-gate regex_map_rewrite(map, s, slen, av) 70007c478bd9Sstevel@tonic-gate MAP *map; 70017c478bd9Sstevel@tonic-gate const char *s; 70027c478bd9Sstevel@tonic-gate size_t slen; 70037c478bd9Sstevel@tonic-gate char **av; 70047c478bd9Sstevel@tonic-gate { 70057c478bd9Sstevel@tonic-gate if (bitset(MF_MATCHONLY, map->map_mflags)) 70067c478bd9Sstevel@tonic-gate return map_rewrite(map, av[0], strlen(av[0]), NULL); 70077c478bd9Sstevel@tonic-gate else 70087c478bd9Sstevel@tonic-gate return map_rewrite(map, s, slen, av); 70097c478bd9Sstevel@tonic-gate } 70107c478bd9Sstevel@tonic-gate 70117c478bd9Sstevel@tonic-gate char * 70127c478bd9Sstevel@tonic-gate regex_map_lookup(map, name, av, statp) 70137c478bd9Sstevel@tonic-gate MAP *map; 70147c478bd9Sstevel@tonic-gate char *name; 70157c478bd9Sstevel@tonic-gate char **av; 70167c478bd9Sstevel@tonic-gate int *statp; 70177c478bd9Sstevel@tonic-gate { 70187c478bd9Sstevel@tonic-gate int reg_res; 70197c478bd9Sstevel@tonic-gate struct regex_map *map_p; 70207c478bd9Sstevel@tonic-gate regmatch_t pmatch[MAX_MATCH]; 70217c478bd9Sstevel@tonic-gate 70227c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 70237c478bd9Sstevel@tonic-gate { 70247c478bd9Sstevel@tonic-gate char **cpp; 70257c478bd9Sstevel@tonic-gate 70267c478bd9Sstevel@tonic-gate sm_dprintf("regex_map_lookup: key '%s'\n", name); 70277c478bd9Sstevel@tonic-gate for (cpp = av; cpp != NULL && *cpp != NULL; cpp++) 70287c478bd9Sstevel@tonic-gate sm_dprintf("regex_map_lookup: arg '%s'\n", *cpp); 70297c478bd9Sstevel@tonic-gate } 70307c478bd9Sstevel@tonic-gate 70317c478bd9Sstevel@tonic-gate map_p = (struct regex_map *)(map->map_db1); 70327c478bd9Sstevel@tonic-gate reg_res = regexec(map_p->regex_pattern_buf, 70337c478bd9Sstevel@tonic-gate name, MAX_MATCH, pmatch, 0); 70347c478bd9Sstevel@tonic-gate 70357c478bd9Sstevel@tonic-gate if (bitset(MF_REGEX_NOT, map->map_mflags)) 70367c478bd9Sstevel@tonic-gate { 70377c478bd9Sstevel@tonic-gate /* option -n */ 70387c478bd9Sstevel@tonic-gate if (reg_res == REG_NOMATCH) 70397c478bd9Sstevel@tonic-gate return regex_map_rewrite(map, "", (size_t) 0, av); 70407c478bd9Sstevel@tonic-gate else 70417c478bd9Sstevel@tonic-gate return NULL; 70427c478bd9Sstevel@tonic-gate } 70437c478bd9Sstevel@tonic-gate if (reg_res == REG_NOMATCH) 70447c478bd9Sstevel@tonic-gate return NULL; 70457c478bd9Sstevel@tonic-gate 70467c478bd9Sstevel@tonic-gate if (map_p->regex_subfields != NULL) 70477c478bd9Sstevel@tonic-gate { 70487c478bd9Sstevel@tonic-gate /* option -s */ 70497c478bd9Sstevel@tonic-gate static char retbuf[MAXNAME]; 70507c478bd9Sstevel@tonic-gate int fields[MAX_MATCH + 1]; 70517c478bd9Sstevel@tonic-gate bool first = true; 70527c478bd9Sstevel@tonic-gate int anglecnt = 0, cmntcnt = 0, spacecnt = 0; 70537c478bd9Sstevel@tonic-gate bool quotemode = false, bslashmode = false; 70547c478bd9Sstevel@tonic-gate register char *dp, *sp; 70557c478bd9Sstevel@tonic-gate char *endp, *ldp; 70567c478bd9Sstevel@tonic-gate int *ip; 70577c478bd9Sstevel@tonic-gate 70587c478bd9Sstevel@tonic-gate dp = retbuf; 70597c478bd9Sstevel@tonic-gate ldp = retbuf + sizeof(retbuf) - 1; 70607c478bd9Sstevel@tonic-gate 70617c478bd9Sstevel@tonic-gate if (av[1] != NULL) 70627c478bd9Sstevel@tonic-gate { 70637c478bd9Sstevel@tonic-gate if (parse_fields(av[1], fields, MAX_MATCH + 1, 70647c478bd9Sstevel@tonic-gate (int) map_p->regex_pattern_buf->re_nsub + 1) == -1) 70657c478bd9Sstevel@tonic-gate { 70667c478bd9Sstevel@tonic-gate *statp = EX_CONFIG; 70677c478bd9Sstevel@tonic-gate return NULL; 70687c478bd9Sstevel@tonic-gate } 70697c478bd9Sstevel@tonic-gate ip = fields; 70707c478bd9Sstevel@tonic-gate } 70717c478bd9Sstevel@tonic-gate else 70727c478bd9Sstevel@tonic-gate ip = map_p->regex_subfields; 70737c478bd9Sstevel@tonic-gate 70747c478bd9Sstevel@tonic-gate for ( ; *ip != END_OF_FIELDS; ip++) 70757c478bd9Sstevel@tonic-gate { 70767c478bd9Sstevel@tonic-gate if (!first) 70777c478bd9Sstevel@tonic-gate { 70787c478bd9Sstevel@tonic-gate for (sp = map_p->regex_delim; *sp; sp++) 70797c478bd9Sstevel@tonic-gate { 70807c478bd9Sstevel@tonic-gate if (dp < ldp) 70817c478bd9Sstevel@tonic-gate *dp++ = *sp; 70827c478bd9Sstevel@tonic-gate } 70837c478bd9Sstevel@tonic-gate } 70847c478bd9Sstevel@tonic-gate else 70857c478bd9Sstevel@tonic-gate first = false; 70867c478bd9Sstevel@tonic-gate 70877c478bd9Sstevel@tonic-gate if (*ip >= MAX_MATCH || 70887c478bd9Sstevel@tonic-gate pmatch[*ip].rm_so < 0 || pmatch[*ip].rm_eo < 0) 70897c478bd9Sstevel@tonic-gate continue; 70907c478bd9Sstevel@tonic-gate 70917c478bd9Sstevel@tonic-gate sp = name + pmatch[*ip].rm_so; 70927c478bd9Sstevel@tonic-gate endp = name + pmatch[*ip].rm_eo; 70937c478bd9Sstevel@tonic-gate for (; endp > sp; sp++) 70947c478bd9Sstevel@tonic-gate { 70957c478bd9Sstevel@tonic-gate if (dp < ldp) 70967c478bd9Sstevel@tonic-gate { 70977c478bd9Sstevel@tonic-gate if (bslashmode) 70987c478bd9Sstevel@tonic-gate { 70997c478bd9Sstevel@tonic-gate *dp++ = *sp; 71007c478bd9Sstevel@tonic-gate bslashmode = false; 71017c478bd9Sstevel@tonic-gate } 71027c478bd9Sstevel@tonic-gate else if (quotemode && *sp != '"' && 71037c478bd9Sstevel@tonic-gate *sp != '\\') 71047c478bd9Sstevel@tonic-gate { 71057c478bd9Sstevel@tonic-gate *dp++ = *sp; 71067c478bd9Sstevel@tonic-gate } 71077c478bd9Sstevel@tonic-gate else switch (*dp++ = *sp) 71087c478bd9Sstevel@tonic-gate { 71097c478bd9Sstevel@tonic-gate case '\\': 71107c478bd9Sstevel@tonic-gate bslashmode = true; 71117c478bd9Sstevel@tonic-gate break; 71127c478bd9Sstevel@tonic-gate 71137c478bd9Sstevel@tonic-gate case '(': 71147c478bd9Sstevel@tonic-gate cmntcnt++; 71157c478bd9Sstevel@tonic-gate break; 71167c478bd9Sstevel@tonic-gate 71177c478bd9Sstevel@tonic-gate case ')': 71187c478bd9Sstevel@tonic-gate cmntcnt--; 71197c478bd9Sstevel@tonic-gate break; 71207c478bd9Sstevel@tonic-gate 71217c478bd9Sstevel@tonic-gate case '<': 71227c478bd9Sstevel@tonic-gate anglecnt++; 71237c478bd9Sstevel@tonic-gate break; 71247c478bd9Sstevel@tonic-gate 71257c478bd9Sstevel@tonic-gate case '>': 71267c478bd9Sstevel@tonic-gate anglecnt--; 71277c478bd9Sstevel@tonic-gate break; 71287c478bd9Sstevel@tonic-gate 71297c478bd9Sstevel@tonic-gate case ' ': 71307c478bd9Sstevel@tonic-gate spacecnt++; 71317c478bd9Sstevel@tonic-gate break; 71327c478bd9Sstevel@tonic-gate 71337c478bd9Sstevel@tonic-gate case '"': 71347c478bd9Sstevel@tonic-gate quotemode = !quotemode; 71357c478bd9Sstevel@tonic-gate break; 71367c478bd9Sstevel@tonic-gate } 71377c478bd9Sstevel@tonic-gate } 71387c478bd9Sstevel@tonic-gate } 71397c478bd9Sstevel@tonic-gate } 71407c478bd9Sstevel@tonic-gate if (anglecnt != 0 || cmntcnt != 0 || quotemode || 71417c478bd9Sstevel@tonic-gate bslashmode || spacecnt != 0) 71427c478bd9Sstevel@tonic-gate { 71437c478bd9Sstevel@tonic-gate sm_syslog(LOG_WARNING, NOQID, 71447c478bd9Sstevel@tonic-gate "Warning: regex may cause prescan() failure map=%s lookup=%s", 71457c478bd9Sstevel@tonic-gate map->map_mname, name); 71467c478bd9Sstevel@tonic-gate return NULL; 71477c478bd9Sstevel@tonic-gate } 71487c478bd9Sstevel@tonic-gate 71497c478bd9Sstevel@tonic-gate *dp = '\0'; 71507c478bd9Sstevel@tonic-gate 71517c478bd9Sstevel@tonic-gate return regex_map_rewrite(map, retbuf, strlen(retbuf), av); 71527c478bd9Sstevel@tonic-gate } 71537c478bd9Sstevel@tonic-gate return regex_map_rewrite(map, "", (size_t)0, av); 71547c478bd9Sstevel@tonic-gate } 71557c478bd9Sstevel@tonic-gate #endif /* MAP_REGEX */ 71567c478bd9Sstevel@tonic-gate /* 71577c478bd9Sstevel@tonic-gate ** NSD modules 71587c478bd9Sstevel@tonic-gate */ 71597c478bd9Sstevel@tonic-gate #if MAP_NSD 71607c478bd9Sstevel@tonic-gate 71617c478bd9Sstevel@tonic-gate # include <ndbm.h> 71627c478bd9Sstevel@tonic-gate # define _DATUM_DEFINED 71637c478bd9Sstevel@tonic-gate # include <ns_api.h> 71647c478bd9Sstevel@tonic-gate 71657c478bd9Sstevel@tonic-gate typedef struct ns_map_list 71667c478bd9Sstevel@tonic-gate { 71677c478bd9Sstevel@tonic-gate ns_map_t *map; /* XXX ns_ ? */ 71687c478bd9Sstevel@tonic-gate char *mapname; 71697c478bd9Sstevel@tonic-gate struct ns_map_list *next; 71707c478bd9Sstevel@tonic-gate } ns_map_list_t; 71717c478bd9Sstevel@tonic-gate 71727c478bd9Sstevel@tonic-gate static ns_map_t * 71737c478bd9Sstevel@tonic-gate ns_map_t_find(mapname) 71747c478bd9Sstevel@tonic-gate char *mapname; 71757c478bd9Sstevel@tonic-gate { 71767c478bd9Sstevel@tonic-gate static ns_map_list_t *ns_maps = NULL; 71777c478bd9Sstevel@tonic-gate ns_map_list_t *ns_map; 71787c478bd9Sstevel@tonic-gate 71797c478bd9Sstevel@tonic-gate /* walk the list of maps looking for the correctly named map */ 71807c478bd9Sstevel@tonic-gate for (ns_map = ns_maps; ns_map != NULL; ns_map = ns_map->next) 71817c478bd9Sstevel@tonic-gate { 71827c478bd9Sstevel@tonic-gate if (strcmp(ns_map->mapname, mapname) == 0) 71837c478bd9Sstevel@tonic-gate break; 71847c478bd9Sstevel@tonic-gate } 71857c478bd9Sstevel@tonic-gate 71867c478bd9Sstevel@tonic-gate /* if we are looking at a NULL ns_map_list_t, then create a new one */ 71877c478bd9Sstevel@tonic-gate if (ns_map == NULL) 71887c478bd9Sstevel@tonic-gate { 7189058561cbSjbeck ns_map = (ns_map_list_t *) xalloc(sizeof(*ns_map)); 71907c478bd9Sstevel@tonic-gate ns_map->mapname = newstr(mapname); 7191058561cbSjbeck ns_map->map = (ns_map_t *) xalloc(sizeof(*ns_map->map)); 7192058561cbSjbeck memset(ns_map->map, '\0', sizeof(*ns_map->map)); 71937c478bd9Sstevel@tonic-gate ns_map->next = ns_maps; 71947c478bd9Sstevel@tonic-gate ns_maps = ns_map; 71957c478bd9Sstevel@tonic-gate } 71967c478bd9Sstevel@tonic-gate return ns_map->map; 71977c478bd9Sstevel@tonic-gate } 71987c478bd9Sstevel@tonic-gate 71997c478bd9Sstevel@tonic-gate char * 72007c478bd9Sstevel@tonic-gate nsd_map_lookup(map, name, av, statp) 72017c478bd9Sstevel@tonic-gate MAP *map; 72027c478bd9Sstevel@tonic-gate char *name; 72037c478bd9Sstevel@tonic-gate char **av; 72047c478bd9Sstevel@tonic-gate int *statp; 72057c478bd9Sstevel@tonic-gate { 72067c478bd9Sstevel@tonic-gate int buflen, r; 72077c478bd9Sstevel@tonic-gate char *p; 72087c478bd9Sstevel@tonic-gate ns_map_t *ns_map; 72097c478bd9Sstevel@tonic-gate char keybuf[MAXNAME + 1]; 72107c478bd9Sstevel@tonic-gate char buf[MAXLINE]; 72117c478bd9Sstevel@tonic-gate 72127c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 72137c478bd9Sstevel@tonic-gate sm_dprintf("nsd_map_lookup(%s, %s)\n", map->map_mname, name); 72147c478bd9Sstevel@tonic-gate 72157c478bd9Sstevel@tonic-gate buflen = strlen(name); 7216058561cbSjbeck if (buflen > sizeof(keybuf) - 1) 7217058561cbSjbeck buflen = sizeof(keybuf) - 1; /* XXX simply cut off? */ 72187c478bd9Sstevel@tonic-gate memmove(keybuf, name, buflen); 72197c478bd9Sstevel@tonic-gate keybuf[buflen] = '\0'; 72207c478bd9Sstevel@tonic-gate if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 72217c478bd9Sstevel@tonic-gate makelower(keybuf); 72227c478bd9Sstevel@tonic-gate 72237c478bd9Sstevel@tonic-gate ns_map = ns_map_t_find(map->map_file); 72247c478bd9Sstevel@tonic-gate if (ns_map == NULL) 72257c478bd9Sstevel@tonic-gate { 72267c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 72277c478bd9Sstevel@tonic-gate sm_dprintf("nsd_map_t_find failed\n"); 72287c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 72297c478bd9Sstevel@tonic-gate return NULL; 72307c478bd9Sstevel@tonic-gate } 72317c478bd9Sstevel@tonic-gate r = ns_lookup(ns_map, NULL, map->map_file, keybuf, NULL, 7232058561cbSjbeck buf, sizeof(buf)); 72337c478bd9Sstevel@tonic-gate if (r == NS_UNAVAIL || r == NS_TRYAGAIN) 72347c478bd9Sstevel@tonic-gate { 72357c478bd9Sstevel@tonic-gate *statp = EX_TEMPFAIL; 72367c478bd9Sstevel@tonic-gate return NULL; 72377c478bd9Sstevel@tonic-gate } 72387c478bd9Sstevel@tonic-gate if (r == NS_BADREQ 72397c478bd9Sstevel@tonic-gate # ifdef NS_NOPERM 72407c478bd9Sstevel@tonic-gate || r == NS_NOPERM 72417c478bd9Sstevel@tonic-gate # endif /* NS_NOPERM */ 72427c478bd9Sstevel@tonic-gate ) 72437c478bd9Sstevel@tonic-gate { 72447c478bd9Sstevel@tonic-gate *statp = EX_CONFIG; 72457c478bd9Sstevel@tonic-gate return NULL; 72467c478bd9Sstevel@tonic-gate } 72477c478bd9Sstevel@tonic-gate if (r != NS_SUCCESS) 72487c478bd9Sstevel@tonic-gate { 72497c478bd9Sstevel@tonic-gate *statp = EX_NOTFOUND; 72507c478bd9Sstevel@tonic-gate return NULL; 72517c478bd9Sstevel@tonic-gate } 72527c478bd9Sstevel@tonic-gate 72537c478bd9Sstevel@tonic-gate *statp = EX_OK; 72547c478bd9Sstevel@tonic-gate 72557c478bd9Sstevel@tonic-gate /* Null out trailing \n */ 72567c478bd9Sstevel@tonic-gate if ((p = strchr(buf, '\n')) != NULL) 72577c478bd9Sstevel@tonic-gate *p = '\0'; 72587c478bd9Sstevel@tonic-gate 72597c478bd9Sstevel@tonic-gate return map_rewrite(map, buf, strlen(buf), av); 72607c478bd9Sstevel@tonic-gate } 72617c478bd9Sstevel@tonic-gate #endif /* MAP_NSD */ 72627c478bd9Sstevel@tonic-gate 72637c478bd9Sstevel@tonic-gate char * 72647c478bd9Sstevel@tonic-gate arith_map_lookup(map, name, av, statp) 72657c478bd9Sstevel@tonic-gate MAP *map; 72667c478bd9Sstevel@tonic-gate char *name; 72677c478bd9Sstevel@tonic-gate char **av; 72687c478bd9Sstevel@tonic-gate int *statp; 72697c478bd9Sstevel@tonic-gate { 72707c478bd9Sstevel@tonic-gate long r; 72717c478bd9Sstevel@tonic-gate long v[2]; 72727c478bd9Sstevel@tonic-gate bool res = false; 72737c478bd9Sstevel@tonic-gate bool boolres; 72747c478bd9Sstevel@tonic-gate static char result[16]; 72757c478bd9Sstevel@tonic-gate char **cpp; 72767c478bd9Sstevel@tonic-gate 72777c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 72787c478bd9Sstevel@tonic-gate { 72797c478bd9Sstevel@tonic-gate sm_dprintf("arith_map_lookup: key '%s'\n", name); 72807c478bd9Sstevel@tonic-gate for (cpp = av; cpp != NULL && *cpp != NULL; cpp++) 72817c478bd9Sstevel@tonic-gate sm_dprintf("arith_map_lookup: arg '%s'\n", *cpp); 72827c478bd9Sstevel@tonic-gate } 72837c478bd9Sstevel@tonic-gate r = 0; 72847c478bd9Sstevel@tonic-gate boolres = false; 72857c478bd9Sstevel@tonic-gate cpp = av; 72867c478bd9Sstevel@tonic-gate *statp = EX_OK; 72877c478bd9Sstevel@tonic-gate 72887c478bd9Sstevel@tonic-gate /* 72897c478bd9Sstevel@tonic-gate ** read arguments for arith map 72907c478bd9Sstevel@tonic-gate ** - no check is made whether they are really numbers 72917c478bd9Sstevel@tonic-gate ** - just ignores args after the second 72927c478bd9Sstevel@tonic-gate */ 72937c478bd9Sstevel@tonic-gate 72947c478bd9Sstevel@tonic-gate for (++cpp; cpp != NULL && *cpp != NULL && r < 2; cpp++) 72957c478bd9Sstevel@tonic-gate v[r++] = strtol(*cpp, NULL, 0); 72967c478bd9Sstevel@tonic-gate 72977c478bd9Sstevel@tonic-gate /* operator and (at least) two operands given? */ 72987c478bd9Sstevel@tonic-gate if (name != NULL && r == 2) 72997c478bd9Sstevel@tonic-gate { 73007c478bd9Sstevel@tonic-gate switch (*name) 73017c478bd9Sstevel@tonic-gate { 73027c478bd9Sstevel@tonic-gate case '|': 73037c478bd9Sstevel@tonic-gate r = v[0] | v[1]; 73047c478bd9Sstevel@tonic-gate break; 73057c478bd9Sstevel@tonic-gate 73067c478bd9Sstevel@tonic-gate case '&': 73077c478bd9Sstevel@tonic-gate r = v[0] & v[1]; 73087c478bd9Sstevel@tonic-gate break; 73097c478bd9Sstevel@tonic-gate 73107c478bd9Sstevel@tonic-gate case '%': 73117c478bd9Sstevel@tonic-gate if (v[1] == 0) 73127c478bd9Sstevel@tonic-gate return NULL; 73137c478bd9Sstevel@tonic-gate r = v[0] % v[1]; 73147c478bd9Sstevel@tonic-gate break; 73157c478bd9Sstevel@tonic-gate case '+': 73167c478bd9Sstevel@tonic-gate r = v[0] + v[1]; 73177c478bd9Sstevel@tonic-gate break; 73187c478bd9Sstevel@tonic-gate 73197c478bd9Sstevel@tonic-gate case '-': 73207c478bd9Sstevel@tonic-gate r = v[0] - v[1]; 73217c478bd9Sstevel@tonic-gate break; 73227c478bd9Sstevel@tonic-gate 73237c478bd9Sstevel@tonic-gate case '*': 73247c478bd9Sstevel@tonic-gate r = v[0] * v[1]; 73257c478bd9Sstevel@tonic-gate break; 73267c478bd9Sstevel@tonic-gate 73277c478bd9Sstevel@tonic-gate case '/': 73287c478bd9Sstevel@tonic-gate if (v[1] == 0) 73297c478bd9Sstevel@tonic-gate return NULL; 73307c478bd9Sstevel@tonic-gate r = v[0] / v[1]; 73317c478bd9Sstevel@tonic-gate break; 73327c478bd9Sstevel@tonic-gate 73337c478bd9Sstevel@tonic-gate case 'l': 73347c478bd9Sstevel@tonic-gate res = v[0] < v[1]; 73357c478bd9Sstevel@tonic-gate boolres = true; 73367c478bd9Sstevel@tonic-gate break; 73377c478bd9Sstevel@tonic-gate 73387c478bd9Sstevel@tonic-gate case '=': 73397c478bd9Sstevel@tonic-gate res = v[0] == v[1]; 73407c478bd9Sstevel@tonic-gate boolres = true; 73417c478bd9Sstevel@tonic-gate break; 73427c478bd9Sstevel@tonic-gate 7343058561cbSjbeck case 'r': 7344058561cbSjbeck r = v[1] - v[0] + 1; 7345058561cbSjbeck if (r <= 0) 7346058561cbSjbeck return NULL; 7347058561cbSjbeck r = get_random() % r + v[0]; 7348058561cbSjbeck break; 7349058561cbSjbeck 73507c478bd9Sstevel@tonic-gate default: 73517c478bd9Sstevel@tonic-gate /* XXX */ 73527c478bd9Sstevel@tonic-gate *statp = EX_CONFIG; 73537c478bd9Sstevel@tonic-gate if (LogLevel > 10) 73547c478bd9Sstevel@tonic-gate sm_syslog(LOG_WARNING, NOQID, 73557c478bd9Sstevel@tonic-gate "arith_map: unknown operator %c", 7356*e9af4bc0SJohn Beck (isascii(*name) && isprint(*name)) ? 7357*e9af4bc0SJohn Beck *name : '?'); 73587c478bd9Sstevel@tonic-gate return NULL; 73597c478bd9Sstevel@tonic-gate } 73607c478bd9Sstevel@tonic-gate if (boolres) 7361058561cbSjbeck (void) sm_snprintf(result, sizeof(result), 73627c478bd9Sstevel@tonic-gate res ? "TRUE" : "FALSE"); 73637c478bd9Sstevel@tonic-gate else 7364058561cbSjbeck (void) sm_snprintf(result, sizeof(result), "%ld", r); 73657c478bd9Sstevel@tonic-gate return result; 73667c478bd9Sstevel@tonic-gate } 73677c478bd9Sstevel@tonic-gate *statp = EX_CONFIG; 73687c478bd9Sstevel@tonic-gate return NULL; 73697c478bd9Sstevel@tonic-gate } 73707c478bd9Sstevel@tonic-gate 73717c478bd9Sstevel@tonic-gate #if SOCKETMAP 73727c478bd9Sstevel@tonic-gate 73737c478bd9Sstevel@tonic-gate # if NETINET || NETINET6 73747c478bd9Sstevel@tonic-gate # include <arpa/inet.h> 73757c478bd9Sstevel@tonic-gate # endif /* NETINET || NETINET6 */ 73767c478bd9Sstevel@tonic-gate 73777c478bd9Sstevel@tonic-gate # define socket_map_next map_stack[0] 73787c478bd9Sstevel@tonic-gate 73797c478bd9Sstevel@tonic-gate /* 73807c478bd9Sstevel@tonic-gate ** SOCKET_MAP_OPEN -- open socket table 73817c478bd9Sstevel@tonic-gate */ 73827c478bd9Sstevel@tonic-gate 73837c478bd9Sstevel@tonic-gate bool 73847c478bd9Sstevel@tonic-gate socket_map_open(map, mode) 73857c478bd9Sstevel@tonic-gate MAP *map; 73867c478bd9Sstevel@tonic-gate int mode; 73877c478bd9Sstevel@tonic-gate { 73887c478bd9Sstevel@tonic-gate STAB *s; 73897c478bd9Sstevel@tonic-gate int sock = 0; 73907c478bd9Sstevel@tonic-gate SOCKADDR_LEN_T addrlen = 0; 73917c478bd9Sstevel@tonic-gate int addrno = 0; 73927c478bd9Sstevel@tonic-gate int save_errno; 73937c478bd9Sstevel@tonic-gate char *p; 73947c478bd9Sstevel@tonic-gate char *colon; 73957c478bd9Sstevel@tonic-gate char *at; 73967c478bd9Sstevel@tonic-gate struct hostent *hp = NULL; 73977c478bd9Sstevel@tonic-gate SOCKADDR addr; 73987c478bd9Sstevel@tonic-gate 73997c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 74007c478bd9Sstevel@tonic-gate sm_dprintf("socket_map_open(%s, %s, %d)\n", 74017c478bd9Sstevel@tonic-gate map->map_mname, map->map_file, mode); 74027c478bd9Sstevel@tonic-gate 74037c478bd9Sstevel@tonic-gate mode &= O_ACCMODE; 74047c478bd9Sstevel@tonic-gate 74057c478bd9Sstevel@tonic-gate /* sendmail doesn't have the ability to write to SOCKET (yet) */ 74067c478bd9Sstevel@tonic-gate if (mode != O_RDONLY) 74077c478bd9Sstevel@tonic-gate { 74087c478bd9Sstevel@tonic-gate /* issue a pseudo-error message */ 74097c478bd9Sstevel@tonic-gate errno = SM_EMAPCANTWRITE; 74107c478bd9Sstevel@tonic-gate return false; 74117c478bd9Sstevel@tonic-gate } 74127c478bd9Sstevel@tonic-gate 74137c478bd9Sstevel@tonic-gate if (*map->map_file == '\0') 74147c478bd9Sstevel@tonic-gate { 74157c478bd9Sstevel@tonic-gate syserr("socket map \"%s\": empty or missing socket information", 74167c478bd9Sstevel@tonic-gate map->map_mname); 74177c478bd9Sstevel@tonic-gate return false; 74187c478bd9Sstevel@tonic-gate } 74197c478bd9Sstevel@tonic-gate 74207c478bd9Sstevel@tonic-gate s = socket_map_findconn(map->map_file); 74217c478bd9Sstevel@tonic-gate if (s->s_socketmap != NULL) 74227c478bd9Sstevel@tonic-gate { 74237c478bd9Sstevel@tonic-gate /* Copy open connection */ 74247c478bd9Sstevel@tonic-gate map->map_db1 = s->s_socketmap->map_db1; 74257c478bd9Sstevel@tonic-gate 74267c478bd9Sstevel@tonic-gate /* Add this map as head of linked list */ 74277c478bd9Sstevel@tonic-gate map->socket_map_next = s->s_socketmap; 74287c478bd9Sstevel@tonic-gate s->s_socketmap = map; 74297c478bd9Sstevel@tonic-gate 74307c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 74317c478bd9Sstevel@tonic-gate sm_dprintf("using cached connection\n"); 74327c478bd9Sstevel@tonic-gate return true; 74337c478bd9Sstevel@tonic-gate } 74347c478bd9Sstevel@tonic-gate 74357c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 74367c478bd9Sstevel@tonic-gate sm_dprintf("opening new connection\n"); 74377c478bd9Sstevel@tonic-gate 74387c478bd9Sstevel@tonic-gate /* following code is ripped from milter.c */ 74397c478bd9Sstevel@tonic-gate /* XXX It should be put in a library... */ 74407c478bd9Sstevel@tonic-gate 74417c478bd9Sstevel@tonic-gate /* protocol:filename or protocol:port@host */ 7442058561cbSjbeck memset(&addr, '\0', sizeof(addr)); 74437c478bd9Sstevel@tonic-gate p = map->map_file; 74447c478bd9Sstevel@tonic-gate colon = strchr(p, ':'); 74457c478bd9Sstevel@tonic-gate if (colon != NULL) 74467c478bd9Sstevel@tonic-gate { 74477c478bd9Sstevel@tonic-gate *colon = '\0'; 74487c478bd9Sstevel@tonic-gate 74497c478bd9Sstevel@tonic-gate if (*p == '\0') 74507c478bd9Sstevel@tonic-gate { 74517c478bd9Sstevel@tonic-gate # if NETUNIX 74527c478bd9Sstevel@tonic-gate /* default to AF_UNIX */ 74537c478bd9Sstevel@tonic-gate addr.sa.sa_family = AF_UNIX; 74547c478bd9Sstevel@tonic-gate # else /* NETUNIX */ 74557c478bd9Sstevel@tonic-gate # if NETINET 74567c478bd9Sstevel@tonic-gate /* default to AF_INET */ 74577c478bd9Sstevel@tonic-gate addr.sa.sa_family = AF_INET; 74587c478bd9Sstevel@tonic-gate # else /* NETINET */ 74597c478bd9Sstevel@tonic-gate # if NETINET6 74607c478bd9Sstevel@tonic-gate /* default to AF_INET6 */ 74617c478bd9Sstevel@tonic-gate addr.sa.sa_family = AF_INET6; 74627c478bd9Sstevel@tonic-gate # else /* NETINET6 */ 74637c478bd9Sstevel@tonic-gate /* no protocols available */ 74647c478bd9Sstevel@tonic-gate syserr("socket map \"%s\": no valid socket protocols available", 74657c478bd9Sstevel@tonic-gate map->map_mname); 74667c478bd9Sstevel@tonic-gate return false; 74677c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 74687c478bd9Sstevel@tonic-gate # endif /* NETINET */ 74697c478bd9Sstevel@tonic-gate # endif /* NETUNIX */ 74707c478bd9Sstevel@tonic-gate } 74717c478bd9Sstevel@tonic-gate # if NETUNIX 74727c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(p, "unix") == 0 || 74737c478bd9Sstevel@tonic-gate sm_strcasecmp(p, "local") == 0) 74747c478bd9Sstevel@tonic-gate addr.sa.sa_family = AF_UNIX; 74757c478bd9Sstevel@tonic-gate # endif /* NETUNIX */ 74767c478bd9Sstevel@tonic-gate # if NETINET 74777c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(p, "inet") == 0) 74787c478bd9Sstevel@tonic-gate addr.sa.sa_family = AF_INET; 74797c478bd9Sstevel@tonic-gate # endif /* NETINET */ 74807c478bd9Sstevel@tonic-gate # if NETINET6 74817c478bd9Sstevel@tonic-gate else if (sm_strcasecmp(p, "inet6") == 0) 74827c478bd9Sstevel@tonic-gate addr.sa.sa_family = AF_INET6; 74837c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 74847c478bd9Sstevel@tonic-gate else 74857c478bd9Sstevel@tonic-gate { 74867c478bd9Sstevel@tonic-gate # ifdef EPROTONOSUPPORT 74877c478bd9Sstevel@tonic-gate errno = EPROTONOSUPPORT; 74887c478bd9Sstevel@tonic-gate # else /* EPROTONOSUPPORT */ 74897c478bd9Sstevel@tonic-gate errno = EINVAL; 74907c478bd9Sstevel@tonic-gate # endif /* EPROTONOSUPPORT */ 74917c478bd9Sstevel@tonic-gate syserr("socket map \"%s\": unknown socket type %s", 74927c478bd9Sstevel@tonic-gate map->map_mname, p); 74937c478bd9Sstevel@tonic-gate return false; 74947c478bd9Sstevel@tonic-gate } 74957c478bd9Sstevel@tonic-gate *colon++ = ':'; 74967c478bd9Sstevel@tonic-gate } 74977c478bd9Sstevel@tonic-gate else 74987c478bd9Sstevel@tonic-gate { 74997c478bd9Sstevel@tonic-gate colon = p; 75007c478bd9Sstevel@tonic-gate #if NETUNIX 75017c478bd9Sstevel@tonic-gate /* default to AF_UNIX */ 75027c478bd9Sstevel@tonic-gate addr.sa.sa_family = AF_UNIX; 75037c478bd9Sstevel@tonic-gate #else /* NETUNIX */ 75047c478bd9Sstevel@tonic-gate # if NETINET 75057c478bd9Sstevel@tonic-gate /* default to AF_INET */ 75067c478bd9Sstevel@tonic-gate addr.sa.sa_family = AF_INET; 75077c478bd9Sstevel@tonic-gate # else /* NETINET */ 75087c478bd9Sstevel@tonic-gate # if NETINET6 75097c478bd9Sstevel@tonic-gate /* default to AF_INET6 */ 75107c478bd9Sstevel@tonic-gate addr.sa.sa_family = AF_INET6; 75117c478bd9Sstevel@tonic-gate # else /* NETINET6 */ 75127c478bd9Sstevel@tonic-gate syserr("socket map \"%s\": unknown socket type %s", 75137c478bd9Sstevel@tonic-gate map->map_mname, p); 75147c478bd9Sstevel@tonic-gate return false; 75157c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 75167c478bd9Sstevel@tonic-gate # endif /* NETINET */ 75177c478bd9Sstevel@tonic-gate #endif /* NETUNIX */ 75187c478bd9Sstevel@tonic-gate } 75197c478bd9Sstevel@tonic-gate 75207c478bd9Sstevel@tonic-gate # if NETUNIX 75217c478bd9Sstevel@tonic-gate if (addr.sa.sa_family == AF_UNIX) 75227c478bd9Sstevel@tonic-gate { 75237c478bd9Sstevel@tonic-gate long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_EXECOK; 75247c478bd9Sstevel@tonic-gate 75257c478bd9Sstevel@tonic-gate at = colon; 7526058561cbSjbeck if (strlen(colon) >= sizeof(addr.sunix.sun_path)) 75277c478bd9Sstevel@tonic-gate { 75287c478bd9Sstevel@tonic-gate syserr("socket map \"%s\": local socket name %s too long", 75297c478bd9Sstevel@tonic-gate map->map_mname, colon); 75307c478bd9Sstevel@tonic-gate return false; 75317c478bd9Sstevel@tonic-gate } 75327c478bd9Sstevel@tonic-gate errno = safefile(colon, RunAsUid, RunAsGid, RunAsUserName, sff, 75337c478bd9Sstevel@tonic-gate S_IRUSR|S_IWUSR, NULL); 75347c478bd9Sstevel@tonic-gate 75357c478bd9Sstevel@tonic-gate if (errno != 0) 75367c478bd9Sstevel@tonic-gate { 75377c478bd9Sstevel@tonic-gate /* if not safe, don't create */ 75387c478bd9Sstevel@tonic-gate syserr("socket map \"%s\": local socket name %s unsafe", 75397c478bd9Sstevel@tonic-gate map->map_mname, colon); 75407c478bd9Sstevel@tonic-gate return false; 75417c478bd9Sstevel@tonic-gate } 75427c478bd9Sstevel@tonic-gate 75437c478bd9Sstevel@tonic-gate (void) sm_strlcpy(addr.sunix.sun_path, colon, 7544058561cbSjbeck sizeof(addr.sunix.sun_path)); 75457c478bd9Sstevel@tonic-gate addrlen = sizeof(struct sockaddr_un); 75467c478bd9Sstevel@tonic-gate } 75477c478bd9Sstevel@tonic-gate else 75487c478bd9Sstevel@tonic-gate # endif /* NETUNIX */ 75497c478bd9Sstevel@tonic-gate # if NETINET || NETINET6 75507c478bd9Sstevel@tonic-gate if (false 75517c478bd9Sstevel@tonic-gate # if NETINET 75527c478bd9Sstevel@tonic-gate || addr.sa.sa_family == AF_INET 75537c478bd9Sstevel@tonic-gate # endif /* NETINET */ 75547c478bd9Sstevel@tonic-gate # if NETINET6 75557c478bd9Sstevel@tonic-gate || addr.sa.sa_family == AF_INET6 75567c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 75577c478bd9Sstevel@tonic-gate ) 75587c478bd9Sstevel@tonic-gate { 75597c478bd9Sstevel@tonic-gate unsigned short port; 75607c478bd9Sstevel@tonic-gate 75617c478bd9Sstevel@tonic-gate /* Parse port@host */ 75627c478bd9Sstevel@tonic-gate at = strchr(colon, '@'); 75637c478bd9Sstevel@tonic-gate if (at == NULL) 75647c478bd9Sstevel@tonic-gate { 75657c478bd9Sstevel@tonic-gate syserr("socket map \"%s\": bad address %s (expected port@host)", 75667c478bd9Sstevel@tonic-gate map->map_mname, colon); 75677c478bd9Sstevel@tonic-gate return false; 75687c478bd9Sstevel@tonic-gate } 75697c478bd9Sstevel@tonic-gate *at = '\0'; 75707c478bd9Sstevel@tonic-gate if (isascii(*colon) && isdigit(*colon)) 75717c478bd9Sstevel@tonic-gate port = htons((unsigned short) atoi(colon)); 75727c478bd9Sstevel@tonic-gate else 75737c478bd9Sstevel@tonic-gate { 75747c478bd9Sstevel@tonic-gate # ifdef NO_GETSERVBYNAME 75757c478bd9Sstevel@tonic-gate syserr("socket map \"%s\": invalid port number %s", 75767c478bd9Sstevel@tonic-gate map->map_mname, colon); 75777c478bd9Sstevel@tonic-gate return false; 75787c478bd9Sstevel@tonic-gate # else /* NO_GETSERVBYNAME */ 75797c478bd9Sstevel@tonic-gate register struct servent *sp; 75807c478bd9Sstevel@tonic-gate 75817c478bd9Sstevel@tonic-gate sp = getservbyname(colon, "tcp"); 75827c478bd9Sstevel@tonic-gate if (sp == NULL) 75837c478bd9Sstevel@tonic-gate { 75847c478bd9Sstevel@tonic-gate syserr("socket map \"%s\": unknown port name %s", 75857c478bd9Sstevel@tonic-gate map->map_mname, colon); 75867c478bd9Sstevel@tonic-gate return false; 75877c478bd9Sstevel@tonic-gate } 75887c478bd9Sstevel@tonic-gate port = sp->s_port; 75897c478bd9Sstevel@tonic-gate # endif /* NO_GETSERVBYNAME */ 75907c478bd9Sstevel@tonic-gate } 75917c478bd9Sstevel@tonic-gate *at++ = '@'; 75927c478bd9Sstevel@tonic-gate if (*at == '[') 75937c478bd9Sstevel@tonic-gate { 75947c478bd9Sstevel@tonic-gate char *end; 75957c478bd9Sstevel@tonic-gate 75967c478bd9Sstevel@tonic-gate end = strchr(at, ']'); 75977c478bd9Sstevel@tonic-gate if (end != NULL) 75987c478bd9Sstevel@tonic-gate { 75997c478bd9Sstevel@tonic-gate bool found = false; 76007c478bd9Sstevel@tonic-gate # if NETINET 76017c478bd9Sstevel@tonic-gate unsigned long hid = INADDR_NONE; 76027c478bd9Sstevel@tonic-gate # endif /* NETINET */ 76037c478bd9Sstevel@tonic-gate # if NETINET6 76047c478bd9Sstevel@tonic-gate struct sockaddr_in6 hid6; 76057c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 76067c478bd9Sstevel@tonic-gate 76077c478bd9Sstevel@tonic-gate *end = '\0'; 76087c478bd9Sstevel@tonic-gate # if NETINET 76097c478bd9Sstevel@tonic-gate if (addr.sa.sa_family == AF_INET && 76107c478bd9Sstevel@tonic-gate (hid = inet_addr(&at[1])) != INADDR_NONE) 76117c478bd9Sstevel@tonic-gate { 76127c478bd9Sstevel@tonic-gate addr.sin.sin_addr.s_addr = hid; 76137c478bd9Sstevel@tonic-gate addr.sin.sin_port = port; 76147c478bd9Sstevel@tonic-gate found = true; 76157c478bd9Sstevel@tonic-gate } 76167c478bd9Sstevel@tonic-gate # endif /* NETINET */ 76177c478bd9Sstevel@tonic-gate # if NETINET6 7618058561cbSjbeck (void) memset(&hid6, '\0', sizeof(hid6)); 76197c478bd9Sstevel@tonic-gate if (addr.sa.sa_family == AF_INET6 && 76207c478bd9Sstevel@tonic-gate anynet_pton(AF_INET6, &at[1], 76217c478bd9Sstevel@tonic-gate &hid6.sin6_addr) == 1) 76227c478bd9Sstevel@tonic-gate { 76237c478bd9Sstevel@tonic-gate addr.sin6.sin6_addr = hid6.sin6_addr; 76247c478bd9Sstevel@tonic-gate addr.sin6.sin6_port = port; 76257c478bd9Sstevel@tonic-gate found = true; 76267c478bd9Sstevel@tonic-gate } 76277c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 76287c478bd9Sstevel@tonic-gate *end = ']'; 76297c478bd9Sstevel@tonic-gate if (!found) 76307c478bd9Sstevel@tonic-gate { 76317c478bd9Sstevel@tonic-gate syserr("socket map \"%s\": Invalid numeric domain spec \"%s\"", 76327c478bd9Sstevel@tonic-gate map->map_mname, at); 76337c478bd9Sstevel@tonic-gate return false; 76347c478bd9Sstevel@tonic-gate } 76357c478bd9Sstevel@tonic-gate } 76367c478bd9Sstevel@tonic-gate else 76377c478bd9Sstevel@tonic-gate { 76387c478bd9Sstevel@tonic-gate syserr("socket map \"%s\": Invalid numeric domain spec \"%s\"", 76397c478bd9Sstevel@tonic-gate map->map_mname, at); 76407c478bd9Sstevel@tonic-gate return false; 76417c478bd9Sstevel@tonic-gate } 76427c478bd9Sstevel@tonic-gate } 76437c478bd9Sstevel@tonic-gate else 76447c478bd9Sstevel@tonic-gate { 76457c478bd9Sstevel@tonic-gate hp = sm_gethostbyname(at, addr.sa.sa_family); 76467c478bd9Sstevel@tonic-gate if (hp == NULL) 76477c478bd9Sstevel@tonic-gate { 76487c478bd9Sstevel@tonic-gate syserr("socket map \"%s\": Unknown host name %s", 76497c478bd9Sstevel@tonic-gate map->map_mname, at); 76507c478bd9Sstevel@tonic-gate return false; 76517c478bd9Sstevel@tonic-gate } 76527c478bd9Sstevel@tonic-gate addr.sa.sa_family = hp->h_addrtype; 76537c478bd9Sstevel@tonic-gate switch (hp->h_addrtype) 76547c478bd9Sstevel@tonic-gate { 76557c478bd9Sstevel@tonic-gate # if NETINET 76567c478bd9Sstevel@tonic-gate case AF_INET: 76577c478bd9Sstevel@tonic-gate memmove(&addr.sin.sin_addr, 76587c478bd9Sstevel@tonic-gate hp->h_addr, INADDRSZ); 76597c478bd9Sstevel@tonic-gate addr.sin.sin_port = port; 76607c478bd9Sstevel@tonic-gate addrlen = sizeof(struct sockaddr_in); 76617c478bd9Sstevel@tonic-gate addrno = 1; 76627c478bd9Sstevel@tonic-gate break; 76637c478bd9Sstevel@tonic-gate # endif /* NETINET */ 76647c478bd9Sstevel@tonic-gate 76657c478bd9Sstevel@tonic-gate # if NETINET6 76667c478bd9Sstevel@tonic-gate case AF_INET6: 76677c478bd9Sstevel@tonic-gate memmove(&addr.sin6.sin6_addr, 76687c478bd9Sstevel@tonic-gate hp->h_addr, IN6ADDRSZ); 76697c478bd9Sstevel@tonic-gate addr.sin6.sin6_port = port; 76707c478bd9Sstevel@tonic-gate addrlen = sizeof(struct sockaddr_in6); 76717c478bd9Sstevel@tonic-gate addrno = 1; 76727c478bd9Sstevel@tonic-gate break; 76737c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 76747c478bd9Sstevel@tonic-gate 76757c478bd9Sstevel@tonic-gate default: 76767c478bd9Sstevel@tonic-gate syserr("socket map \"%s\": Unknown protocol for %s (%d)", 76777c478bd9Sstevel@tonic-gate map->map_mname, at, hp->h_addrtype); 76787c478bd9Sstevel@tonic-gate # if NETINET6 76797c478bd9Sstevel@tonic-gate freehostent(hp); 76807c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 76817c478bd9Sstevel@tonic-gate return false; 76827c478bd9Sstevel@tonic-gate } 76837c478bd9Sstevel@tonic-gate } 76847c478bd9Sstevel@tonic-gate } 76857c478bd9Sstevel@tonic-gate else 76867c478bd9Sstevel@tonic-gate # endif /* NETINET || NETINET6 */ 76877c478bd9Sstevel@tonic-gate { 76887c478bd9Sstevel@tonic-gate syserr("socket map \"%s\": unknown socket protocol", 76897c478bd9Sstevel@tonic-gate map->map_mname); 76907c478bd9Sstevel@tonic-gate return false; 76917c478bd9Sstevel@tonic-gate } 76927c478bd9Sstevel@tonic-gate 76937c478bd9Sstevel@tonic-gate /* nope, actually connecting */ 76947c478bd9Sstevel@tonic-gate for (;;) 76957c478bd9Sstevel@tonic-gate { 76967c478bd9Sstevel@tonic-gate sock = socket(addr.sa.sa_family, SOCK_STREAM, 0); 76977c478bd9Sstevel@tonic-gate if (sock < 0) 76987c478bd9Sstevel@tonic-gate { 76997c478bd9Sstevel@tonic-gate save_errno = errno; 77007c478bd9Sstevel@tonic-gate if (tTd(38, 5)) 77017c478bd9Sstevel@tonic-gate sm_dprintf("socket map \"%s\": error creating socket: %s\n", 77027c478bd9Sstevel@tonic-gate map->map_mname, 77037c478bd9Sstevel@tonic-gate sm_errstring(save_errno)); 77047c478bd9Sstevel@tonic-gate # if NETINET6 77057c478bd9Sstevel@tonic-gate if (hp != NULL) 77067c478bd9Sstevel@tonic-gate freehostent(hp); 77077c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 77087c478bd9Sstevel@tonic-gate return false; 77097c478bd9Sstevel@tonic-gate } 77107c478bd9Sstevel@tonic-gate 77117c478bd9Sstevel@tonic-gate if (connect(sock, (struct sockaddr *) &addr, addrlen) >= 0) 77127c478bd9Sstevel@tonic-gate break; 77137c478bd9Sstevel@tonic-gate 77147c478bd9Sstevel@tonic-gate /* couldn't connect.... try next address */ 77157c478bd9Sstevel@tonic-gate save_errno = errno; 77167c478bd9Sstevel@tonic-gate p = CurHostName; 77177c478bd9Sstevel@tonic-gate CurHostName = at; 77187c478bd9Sstevel@tonic-gate if (tTd(38, 5)) 77197c478bd9Sstevel@tonic-gate sm_dprintf("socket_open (%s): open %s failed: %s\n", 77207c478bd9Sstevel@tonic-gate map->map_mname, at, sm_errstring(save_errno)); 77217c478bd9Sstevel@tonic-gate CurHostName = p; 77227c478bd9Sstevel@tonic-gate (void) close(sock); 77237c478bd9Sstevel@tonic-gate 77247c478bd9Sstevel@tonic-gate /* try next address */ 77257c478bd9Sstevel@tonic-gate if (hp != NULL && hp->h_addr_list[addrno] != NULL) 77267c478bd9Sstevel@tonic-gate { 77277c478bd9Sstevel@tonic-gate switch (addr.sa.sa_family) 77287c478bd9Sstevel@tonic-gate { 77297c478bd9Sstevel@tonic-gate # if NETINET 77307c478bd9Sstevel@tonic-gate case AF_INET: 77317c478bd9Sstevel@tonic-gate memmove(&addr.sin.sin_addr, 77327c478bd9Sstevel@tonic-gate hp->h_addr_list[addrno++], 77337c478bd9Sstevel@tonic-gate INADDRSZ); 77347c478bd9Sstevel@tonic-gate break; 77357c478bd9Sstevel@tonic-gate # endif /* NETINET */ 77367c478bd9Sstevel@tonic-gate 77377c478bd9Sstevel@tonic-gate # if NETINET6 77387c478bd9Sstevel@tonic-gate case AF_INET6: 77397c478bd9Sstevel@tonic-gate memmove(&addr.sin6.sin6_addr, 77407c478bd9Sstevel@tonic-gate hp->h_addr_list[addrno++], 77417c478bd9Sstevel@tonic-gate IN6ADDRSZ); 77427c478bd9Sstevel@tonic-gate break; 77437c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 77447c478bd9Sstevel@tonic-gate 77457c478bd9Sstevel@tonic-gate default: 77467c478bd9Sstevel@tonic-gate if (tTd(38, 5)) 77477c478bd9Sstevel@tonic-gate sm_dprintf("socket map \"%s\": Unknown protocol for %s (%d)\n", 77487c478bd9Sstevel@tonic-gate map->map_mname, at, 77497c478bd9Sstevel@tonic-gate hp->h_addrtype); 77507c478bd9Sstevel@tonic-gate # if NETINET6 77517c478bd9Sstevel@tonic-gate freehostent(hp); 77527c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 77537c478bd9Sstevel@tonic-gate return false; 77547c478bd9Sstevel@tonic-gate } 77557c478bd9Sstevel@tonic-gate continue; 77567c478bd9Sstevel@tonic-gate } 77577c478bd9Sstevel@tonic-gate p = CurHostName; 77587c478bd9Sstevel@tonic-gate CurHostName = at; 77597c478bd9Sstevel@tonic-gate if (tTd(38, 5)) 77607c478bd9Sstevel@tonic-gate sm_dprintf("socket map \"%s\": error connecting to socket map: %s\n", 77617c478bd9Sstevel@tonic-gate map->map_mname, sm_errstring(save_errno)); 77627c478bd9Sstevel@tonic-gate CurHostName = p; 77637c478bd9Sstevel@tonic-gate # if NETINET6 77647c478bd9Sstevel@tonic-gate if (hp != NULL) 77657c478bd9Sstevel@tonic-gate freehostent(hp); 77667c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 77677c478bd9Sstevel@tonic-gate return false; 77687c478bd9Sstevel@tonic-gate } 77697c478bd9Sstevel@tonic-gate # if NETINET6 77707c478bd9Sstevel@tonic-gate if (hp != NULL) 77717c478bd9Sstevel@tonic-gate { 77727c478bd9Sstevel@tonic-gate freehostent(hp); 77737c478bd9Sstevel@tonic-gate hp = NULL; 77747c478bd9Sstevel@tonic-gate } 77757c478bd9Sstevel@tonic-gate # endif /* NETINET6 */ 77767c478bd9Sstevel@tonic-gate if ((map->map_db1 = (ARBPTR_T) sm_io_open(SmFtStdiofd, 77777c478bd9Sstevel@tonic-gate SM_TIME_DEFAULT, 77787c478bd9Sstevel@tonic-gate (void *) &sock, 77797c478bd9Sstevel@tonic-gate SM_IO_RDWR, 77807c478bd9Sstevel@tonic-gate NULL)) == NULL) 77817c478bd9Sstevel@tonic-gate { 77827c478bd9Sstevel@tonic-gate close(sock); 77837c478bd9Sstevel@tonic-gate if (tTd(38, 2)) 77847c478bd9Sstevel@tonic-gate sm_dprintf("socket_open (%s): failed to create stream: %s\n", 77857c478bd9Sstevel@tonic-gate map->map_mname, sm_errstring(errno)); 77867c478bd9Sstevel@tonic-gate return false; 77877c478bd9Sstevel@tonic-gate } 77887c478bd9Sstevel@tonic-gate 77897c478bd9Sstevel@tonic-gate /* Save connection for reuse */ 77907c478bd9Sstevel@tonic-gate s->s_socketmap = map; 77917c478bd9Sstevel@tonic-gate return true; 77927c478bd9Sstevel@tonic-gate } 77937c478bd9Sstevel@tonic-gate 77947c478bd9Sstevel@tonic-gate /* 77957c478bd9Sstevel@tonic-gate ** SOCKET_MAP_FINDCONN -- find a SOCKET connection to the server 77967c478bd9Sstevel@tonic-gate ** 77977c478bd9Sstevel@tonic-gate ** Cache SOCKET connections based on the connection specifier 77987c478bd9Sstevel@tonic-gate ** and PID so we don't have multiple connections open to 77997c478bd9Sstevel@tonic-gate ** the same server for different maps. Need a separate connection 78007c478bd9Sstevel@tonic-gate ** per PID since a parent process may close the map before the 78017c478bd9Sstevel@tonic-gate ** child is done with it. 78027c478bd9Sstevel@tonic-gate ** 78037c478bd9Sstevel@tonic-gate ** Parameters: 78047c478bd9Sstevel@tonic-gate ** conn -- SOCKET map connection specifier 78057c478bd9Sstevel@tonic-gate ** 78067c478bd9Sstevel@tonic-gate ** Returns: 78077c478bd9Sstevel@tonic-gate ** Symbol table entry for the SOCKET connection. 78087c478bd9Sstevel@tonic-gate */ 78097c478bd9Sstevel@tonic-gate 78107c478bd9Sstevel@tonic-gate static STAB * 78117c478bd9Sstevel@tonic-gate socket_map_findconn(conn) 78127c478bd9Sstevel@tonic-gate const char *conn; 78137c478bd9Sstevel@tonic-gate { 78147c478bd9Sstevel@tonic-gate char *nbuf; 78157c478bd9Sstevel@tonic-gate STAB *SM_NONVOLATILE s = NULL; 78167c478bd9Sstevel@tonic-gate 78177c478bd9Sstevel@tonic-gate nbuf = sm_stringf_x("%s%c%d", conn, CONDELSE, (int) CurrentPid); 78187c478bd9Sstevel@tonic-gate SM_TRY 78197c478bd9Sstevel@tonic-gate s = stab(nbuf, ST_SOCKETMAP, ST_ENTER); 78207c478bd9Sstevel@tonic-gate SM_FINALLY 78217c478bd9Sstevel@tonic-gate sm_free(nbuf); 78227c478bd9Sstevel@tonic-gate SM_END_TRY 78237c478bd9Sstevel@tonic-gate return s; 78247c478bd9Sstevel@tonic-gate } 78257c478bd9Sstevel@tonic-gate 78267c478bd9Sstevel@tonic-gate /* 78277c478bd9Sstevel@tonic-gate ** SOCKET_MAP_CLOSE -- close the socket 78287c478bd9Sstevel@tonic-gate */ 78297c478bd9Sstevel@tonic-gate 78307c478bd9Sstevel@tonic-gate void 78317c478bd9Sstevel@tonic-gate socket_map_close(map) 78327c478bd9Sstevel@tonic-gate MAP *map; 78337c478bd9Sstevel@tonic-gate { 78347c478bd9Sstevel@tonic-gate STAB *s; 78357c478bd9Sstevel@tonic-gate MAP *smap; 78367c478bd9Sstevel@tonic-gate 78377c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 78387c478bd9Sstevel@tonic-gate sm_dprintf("socket_map_close(%s), pid=%ld\n", map->map_file, 78397c478bd9Sstevel@tonic-gate (long) CurrentPid); 78407c478bd9Sstevel@tonic-gate 78417c478bd9Sstevel@tonic-gate /* Check if already closed */ 78427c478bd9Sstevel@tonic-gate if (map->map_db1 == NULL) 78437c478bd9Sstevel@tonic-gate { 78447c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 78457c478bd9Sstevel@tonic-gate sm_dprintf("socket_map_close(%s) already closed\n", 78467c478bd9Sstevel@tonic-gate map->map_file); 78477c478bd9Sstevel@tonic-gate return; 78487c478bd9Sstevel@tonic-gate } 78497c478bd9Sstevel@tonic-gate sm_io_close((SM_FILE_T *)map->map_db1, SM_TIME_DEFAULT); 78507c478bd9Sstevel@tonic-gate 78517c478bd9Sstevel@tonic-gate /* Mark all the maps that share the connection as closed */ 78527c478bd9Sstevel@tonic-gate s = socket_map_findconn(map->map_file); 78537c478bd9Sstevel@tonic-gate smap = s->s_socketmap; 78547c478bd9Sstevel@tonic-gate while (smap != NULL) 78557c478bd9Sstevel@tonic-gate { 78567c478bd9Sstevel@tonic-gate MAP *next; 78577c478bd9Sstevel@tonic-gate 78587c478bd9Sstevel@tonic-gate if (tTd(38, 2) && smap != map) 78597c478bd9Sstevel@tonic-gate sm_dprintf("socket_map_close(%s): closed %s (shared SOCKET connection)\n", 78607c478bd9Sstevel@tonic-gate map->map_mname, smap->map_mname); 78617c478bd9Sstevel@tonic-gate 78627c478bd9Sstevel@tonic-gate smap->map_mflags &= ~(MF_OPEN|MF_WRITABLE); 78637c478bd9Sstevel@tonic-gate smap->map_db1 = NULL; 78647c478bd9Sstevel@tonic-gate next = smap->socket_map_next; 78657c478bd9Sstevel@tonic-gate smap->socket_map_next = NULL; 78667c478bd9Sstevel@tonic-gate smap = next; 78677c478bd9Sstevel@tonic-gate } 78687c478bd9Sstevel@tonic-gate s->s_socketmap = NULL; 78697c478bd9Sstevel@tonic-gate } 78707c478bd9Sstevel@tonic-gate 78717c478bd9Sstevel@tonic-gate /* 78727c478bd9Sstevel@tonic-gate ** SOCKET_MAP_LOOKUP -- look up a datum in a SOCKET table 78737c478bd9Sstevel@tonic-gate */ 78747c478bd9Sstevel@tonic-gate 78757c478bd9Sstevel@tonic-gate char * 78767c478bd9Sstevel@tonic-gate socket_map_lookup(map, name, av, statp) 78777c478bd9Sstevel@tonic-gate MAP *map; 78787c478bd9Sstevel@tonic-gate char *name; 78797c478bd9Sstevel@tonic-gate char **av; 78807c478bd9Sstevel@tonic-gate int *statp; 78817c478bd9Sstevel@tonic-gate { 78827c478bd9Sstevel@tonic-gate unsigned int nettolen, replylen, recvlen; 78837c478bd9Sstevel@tonic-gate char *replybuf, *rval, *value, *status, *key; 78847c478bd9Sstevel@tonic-gate SM_FILE_T *f; 78857c478bd9Sstevel@tonic-gate char keybuf[MAXNAME + 1]; 78867c478bd9Sstevel@tonic-gate 78877c478bd9Sstevel@tonic-gate replybuf = NULL; 78887c478bd9Sstevel@tonic-gate rval = NULL; 78897c478bd9Sstevel@tonic-gate f = (SM_FILE_T *)map->map_db1; 78907c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 78917c478bd9Sstevel@tonic-gate sm_dprintf("socket_map_lookup(%s, %s) %s\n", 78927c478bd9Sstevel@tonic-gate map->map_mname, name, map->map_file); 78937c478bd9Sstevel@tonic-gate 78947c478bd9Sstevel@tonic-gate if (!bitset(MF_NOFOLDCASE, map->map_mflags)) 78957c478bd9Sstevel@tonic-gate { 78967c478bd9Sstevel@tonic-gate nettolen = strlen(name); 7897058561cbSjbeck if (nettolen > sizeof(keybuf) - 1) 7898058561cbSjbeck nettolen = sizeof(keybuf) - 1; 78997c478bd9Sstevel@tonic-gate memmove(keybuf, name, nettolen); 79007c478bd9Sstevel@tonic-gate keybuf[nettolen] = '\0'; 79017c478bd9Sstevel@tonic-gate makelower(keybuf); 79027c478bd9Sstevel@tonic-gate key = keybuf; 79037c478bd9Sstevel@tonic-gate } 79047c478bd9Sstevel@tonic-gate else 79057c478bd9Sstevel@tonic-gate key = name; 79067c478bd9Sstevel@tonic-gate 79077c478bd9Sstevel@tonic-gate nettolen = strlen(map->map_mname) + 1 + strlen(key); 79087c478bd9Sstevel@tonic-gate SM_ASSERT(nettolen > strlen(map->map_mname)); 79097c478bd9Sstevel@tonic-gate SM_ASSERT(nettolen > strlen(key)); 79107c478bd9Sstevel@tonic-gate if ((sm_io_fprintf(f, SM_TIME_DEFAULT, "%u:%s %s,", 79117c478bd9Sstevel@tonic-gate nettolen, map->map_mname, key) == SM_IO_EOF) || 79127c478bd9Sstevel@tonic-gate (sm_io_flush(f, SM_TIME_DEFAULT) != 0) || 79137c478bd9Sstevel@tonic-gate (sm_io_error(f))) 79147c478bd9Sstevel@tonic-gate { 79157c478bd9Sstevel@tonic-gate syserr("451 4.3.0 socket_map_lookup(%s): failed to send lookup request", 79167c478bd9Sstevel@tonic-gate map->map_mname); 79177c478bd9Sstevel@tonic-gate *statp = EX_TEMPFAIL; 79187c478bd9Sstevel@tonic-gate goto errcl; 79197c478bd9Sstevel@tonic-gate } 79207c478bd9Sstevel@tonic-gate 79217c478bd9Sstevel@tonic-gate if (sm_io_fscanf(f, SM_TIME_DEFAULT, "%9u", &replylen) != 1) 79227c478bd9Sstevel@tonic-gate { 79237c478bd9Sstevel@tonic-gate syserr("451 4.3.0 socket_map_lookup(%s): failed to read length parameter of reply", 79247c478bd9Sstevel@tonic-gate map->map_mname); 79257c478bd9Sstevel@tonic-gate *statp = EX_TEMPFAIL; 79267c478bd9Sstevel@tonic-gate goto errcl; 79277c478bd9Sstevel@tonic-gate } 79287c478bd9Sstevel@tonic-gate if (replylen > SOCKETMAP_MAXL) 79297c478bd9Sstevel@tonic-gate { 79307c478bd9Sstevel@tonic-gate syserr("451 4.3.0 socket_map_lookup(%s): reply too long: %u", 79317c478bd9Sstevel@tonic-gate map->map_mname, replylen); 79327c478bd9Sstevel@tonic-gate *statp = EX_TEMPFAIL; 79337c478bd9Sstevel@tonic-gate goto errcl; 79347c478bd9Sstevel@tonic-gate } 79357c478bd9Sstevel@tonic-gate if (sm_io_getc(f, SM_TIME_DEFAULT) != ':') 79367c478bd9Sstevel@tonic-gate { 79377c478bd9Sstevel@tonic-gate syserr("451 4.3.0 socket_map_lookup(%s): missing ':' in reply", 79387c478bd9Sstevel@tonic-gate map->map_mname); 79397c478bd9Sstevel@tonic-gate *statp = EX_TEMPFAIL; 79407c478bd9Sstevel@tonic-gate goto error; 79417c478bd9Sstevel@tonic-gate } 79427c478bd9Sstevel@tonic-gate 79437c478bd9Sstevel@tonic-gate replybuf = (char *) sm_malloc(replylen + 1); 79447c478bd9Sstevel@tonic-gate if (replybuf == NULL) 79457c478bd9Sstevel@tonic-gate { 79467c478bd9Sstevel@tonic-gate syserr("451 4.3.0 socket_map_lookup(%s): can't allocate %u bytes", 79477c478bd9Sstevel@tonic-gate map->map_mname, replylen + 1); 79487c478bd9Sstevel@tonic-gate *statp = EX_OSERR; 79497c478bd9Sstevel@tonic-gate goto error; 79507c478bd9Sstevel@tonic-gate } 79517c478bd9Sstevel@tonic-gate 79527c478bd9Sstevel@tonic-gate recvlen = sm_io_read(f, SM_TIME_DEFAULT, replybuf, replylen); 79537c478bd9Sstevel@tonic-gate if (recvlen < replylen) 79547c478bd9Sstevel@tonic-gate { 79557c478bd9Sstevel@tonic-gate syserr("451 4.3.0 socket_map_lookup(%s): received only %u of %u reply characters", 79567c478bd9Sstevel@tonic-gate map->map_mname, recvlen, replylen); 79577c478bd9Sstevel@tonic-gate *statp = EX_TEMPFAIL; 79587c478bd9Sstevel@tonic-gate goto errcl; 79597c478bd9Sstevel@tonic-gate } 79607c478bd9Sstevel@tonic-gate if (sm_io_getc(f, SM_TIME_DEFAULT) != ',') 79617c478bd9Sstevel@tonic-gate { 79627c478bd9Sstevel@tonic-gate syserr("451 4.3.0 socket_map_lookup(%s): missing ',' in reply", 79637c478bd9Sstevel@tonic-gate map->map_mname); 79647c478bd9Sstevel@tonic-gate *statp = EX_TEMPFAIL; 79657c478bd9Sstevel@tonic-gate goto errcl; 79667c478bd9Sstevel@tonic-gate } 79677c478bd9Sstevel@tonic-gate status = replybuf; 79687c478bd9Sstevel@tonic-gate replybuf[recvlen] = '\0'; 79697c478bd9Sstevel@tonic-gate value = strchr(replybuf, ' '); 79707c478bd9Sstevel@tonic-gate if (value != NULL) 79717c478bd9Sstevel@tonic-gate { 79727c478bd9Sstevel@tonic-gate *value = '\0'; 79737c478bd9Sstevel@tonic-gate value++; 79747c478bd9Sstevel@tonic-gate } 79757c478bd9Sstevel@tonic-gate if (strcmp(status, "OK") == 0) 79767c478bd9Sstevel@tonic-gate { 79777c478bd9Sstevel@tonic-gate *statp = EX_OK; 79787c478bd9Sstevel@tonic-gate 79797c478bd9Sstevel@tonic-gate /* collect the return value */ 79807c478bd9Sstevel@tonic-gate if (bitset(MF_MATCHONLY, map->map_mflags)) 79817c478bd9Sstevel@tonic-gate rval = map_rewrite(map, key, strlen(key), NULL); 79827c478bd9Sstevel@tonic-gate else 79837c478bd9Sstevel@tonic-gate rval = map_rewrite(map, value, strlen(value), av); 79847c478bd9Sstevel@tonic-gate } 79857c478bd9Sstevel@tonic-gate else if (strcmp(status, "NOTFOUND") == 0) 79867c478bd9Sstevel@tonic-gate { 79877c478bd9Sstevel@tonic-gate *statp = EX_NOTFOUND; 79887c478bd9Sstevel@tonic-gate if (tTd(38, 20)) 79897c478bd9Sstevel@tonic-gate sm_dprintf("socket_map_lookup(%s): %s not found\n", 79907c478bd9Sstevel@tonic-gate map->map_mname, key); 79917c478bd9Sstevel@tonic-gate } 79927c478bd9Sstevel@tonic-gate else 79937c478bd9Sstevel@tonic-gate { 79947c478bd9Sstevel@tonic-gate if (tTd(38, 5)) 79957c478bd9Sstevel@tonic-gate sm_dprintf("socket_map_lookup(%s, %s): server returned error: type=%s, reason=%s\n", 79967c478bd9Sstevel@tonic-gate map->map_mname, key, status, 79977c478bd9Sstevel@tonic-gate value ? value : ""); 79987c478bd9Sstevel@tonic-gate if ((strcmp(status, "TEMP") == 0) || 79997c478bd9Sstevel@tonic-gate (strcmp(status, "TIMEOUT") == 0)) 80007c478bd9Sstevel@tonic-gate *statp = EX_TEMPFAIL; 80017c478bd9Sstevel@tonic-gate else if(strcmp(status, "PERM") == 0) 80027c478bd9Sstevel@tonic-gate *statp = EX_UNAVAILABLE; 80037c478bd9Sstevel@tonic-gate else 80047c478bd9Sstevel@tonic-gate *statp = EX_PROTOCOL; 80057c478bd9Sstevel@tonic-gate } 80067c478bd9Sstevel@tonic-gate 80077c478bd9Sstevel@tonic-gate if (replybuf != NULL) 80087c478bd9Sstevel@tonic-gate sm_free(replybuf); 80097c478bd9Sstevel@tonic-gate return rval; 80107c478bd9Sstevel@tonic-gate 80117c478bd9Sstevel@tonic-gate errcl: 80127c478bd9Sstevel@tonic-gate socket_map_close(map); 80137c478bd9Sstevel@tonic-gate error: 80147c478bd9Sstevel@tonic-gate if (replybuf != NULL) 80157c478bd9Sstevel@tonic-gate sm_free(replybuf); 80167c478bd9Sstevel@tonic-gate return rval; 80177c478bd9Sstevel@tonic-gate } 80187c478bd9Sstevel@tonic-gate #endif /* SOCKETMAP */ 8019