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