1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <netdb.h> 27 #include "ldap_common.h" 28 #include <sys/types.h> 29 #include <sys/socket.h> 30 #include <netinet/in.h> 31 #include <arpa/inet.h> 32 #include <sys/tsol/tndb.h> 33 34 /* tnrhdb attributes filters */ 35 #define _TNRHDB_ADDR "ipTnetNumber" 36 #define _TNRHDB_TNAME "ipTnetTemplateName" 37 #define _F_GETTNDBBYADDR "(&(objectClass=ipTnetHost)(ipTnetNumber=%s))" 38 #define _F_GETTNDBBYADDR_SSD "(&(%%s)(ipTnetNumber=%s))" 39 40 static const char *tnrhdb_attrs[] = { 41 _TNRHDB_ADDR, 42 _TNRHDB_TNAME, 43 NULL 44 }; 45 46 static void 47 escape_colon(char *in, char *out) { 48 int i, j; 49 for (i = 0, j = 0; in[i] != '\0'; i++) { 50 if (in[i] == ':') { 51 out[j++] = '\\'; 52 out[j++] = in[i]; 53 } else 54 out[j++] = in[i]; 55 } 56 out[j] = '\0'; 57 } 58 59 /* 60 * _nss_ldap_tnrhdb2str is the data marshaling method for the tnrhdb 61 * (tsol_getrhbyaddr()/tsol_getrhent()) backend processes. 62 * This method is called after a successful ldap search has been performed. 63 * This method will parse the ldap search values into the file format. 64 * 65 * e.g. 66 * 67 * 192.168.120.6:public 68 * fec0\:\:a00\:20ff\:fea0\:21f7:cipso 69 * 70 */ 71 static int 72 _nss_ldap_tnrhdb2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) 73 { 74 int nss_result = NSS_STR_PARSE_SUCCESS; 75 int len = 0; 76 char *buffer = NULL; 77 char **addr, **template, *addr_out; 78 ns_ldap_result_t *result = be->result; 79 char addr6[INET6_ADDRSTRLEN + 5]; /* 5 '\' for ':' at most */ 80 81 if (result == NULL) 82 return (NSS_STR_PARSE_PARSE); 83 84 addr = __ns_ldap_getAttr(result->entry, _TNRHDB_ADDR); 85 if (addr == NULL || addr[0] == NULL || (strlen(addr[0]) < 1)) { 86 nss_result = NSS_STR_PARSE_PARSE; 87 goto result_tnrhdb2str; 88 } 89 90 /* 91 * Escape ':' in IPV6. 92 * The value is stored in LDAP directory without escape charaters. 93 */ 94 if (strchr(addr[0], ':') != NULL) { 95 escape_colon(addr[0], addr6); 96 addr_out = addr6; 97 } else 98 addr_out = addr[0]; 99 100 template = __ns_ldap_getAttr(result->entry, _TNRHDB_TNAME); 101 if (template == NULL || template[0] == NULL || 102 (strlen(template[0]) < 1)) { 103 nss_result = NSS_STR_PARSE_PARSE; 104 goto result_tnrhdb2str; 105 } 106 /* "addr:template" */ 107 len = strlen(addr_out) + strlen(template[0]) + 2; 108 109 if (argp->buf.result != NULL) { 110 if ((be->buffer = calloc(1, len)) == NULL) { 111 nss_result = NSS_STR_PARSE_PARSE; 112 goto result_tnrhdb2str; 113 } 114 be->buflen = len - 1; 115 buffer = be->buffer; 116 } else 117 buffer = argp->buf.buffer; 118 119 (void) snprintf(buffer, len, "%s:%s", addr_out, template[0]); 120 121 result_tnrhdb2str: 122 (void) __ns_ldap_freeResult(&be->result); 123 return (nss_result); 124 } 125 126 127 static nss_status_t 128 getbyaddr(ldap_backend_ptr be, void *a) 129 { 130 char searchfilter[SEARCHFILTERLEN]; 131 char userdata[SEARCHFILTERLEN]; 132 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 133 134 if (argp->key.hostaddr.addr == NULL || 135 (argp->key.hostaddr.type != AF_INET && 136 argp->key.hostaddr.type != AF_INET6)) 137 return (NSS_NOTFOUND); 138 if (strchr(argp->key.hostaddr.addr, ':') != NULL) { 139 /* IPV6 */ 140 if (argp->key.hostaddr.type == AF_INET) 141 return (NSS_NOTFOUND); 142 } else { 143 /* IPV4 */ 144 if (argp->key.hostaddr.type == AF_INET6) 145 return (NSS_NOTFOUND); 146 } 147 148 /* 149 * The IPV6 addresses are saved in the directory without '\'s. 150 * So don't need to escape colons in IPV6 addresses. 151 */ 152 if (snprintf(searchfilter, sizeof (searchfilter), _F_GETTNDBBYADDR, 153 argp->key.hostaddr.addr) < 0) 154 return ((nss_status_t)NSS_NOTFOUND); 155 156 if (snprintf(userdata, sizeof (userdata), _F_GETTNDBBYADDR_SSD, 157 argp->key.hostaddr.addr) < 0) 158 return ((nss_status_t)NSS_NOTFOUND); 159 160 return (_nss_ldap_lookup(be, argp, _TNRHDB, searchfilter, NULL, 161 _merge_SSD_filter, userdata)); 162 } 163 164 165 static ldap_backend_op_t tnrhdb_ops[] = { 166 _nss_ldap_destr, 167 _nss_ldap_endent, 168 _nss_ldap_setent, 169 _nss_ldap_getent, 170 getbyaddr 171 }; 172 173 174 /* ARGSUSED */ 175 nss_backend_t * 176 _nss_ldap_tnrhdb_constr(const char *dummy1, 177 const char *dummy2, 178 const char *dummy3, 179 const char *dummy4, 180 const char *dummy5) 181 { 182 return ((nss_backend_t *)_nss_ldap_constr(tnrhdb_ops, 183 sizeof (tnrhdb_ops)/sizeof (tnrhdb_ops[0]), _TNRHDB, 184 tnrhdb_attrs, _nss_ldap_tnrhdb2str)); 185 } 186